summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--INSTALL2
-rw-r--r--Makefile.in10
-rw-r--r--NEWS11
-rw-r--r--README10
-rw-r--r--arg_parser.cc16
-rw-r--r--arg_parser.h5
-rwxr-xr-xconfigure21
-rw-r--r--doc/zcat.16
-rw-r--r--doc/zcmp.118
-rw-r--r--doc/zdiff.116
-rw-r--r--doc/zgrep.16
-rw-r--r--doc/ztest.114
-rw-r--r--doc/zupdate.14
-rw-r--r--doc/zutils.info60
-rw-r--r--doc/zutils.texi33
-rw-r--r--rc.cc22
-rw-r--r--rc.h6
-rw-r--r--recursive.cc2
-rwxr-xr-xtestsuite/check.sh509
-rw-r--r--zcat.cc7
-rw-r--r--zcatgrep.cc2
-rw-r--r--zcmp.cc44
-rw-r--r--zcmpdiff.cc2
-rw-r--r--zdiff.cc27
-rw-r--r--zgrep.cc9
-rw-r--r--ztest.cc14
-rw-r--r--zupdate.cc2
-rw-r--r--zutils.cc16
-rw-r--r--zutils.h7
30 files changed, 436 insertions, 473 deletions
diff --git a/ChangeLog b/ChangeLog
index 8ae4053..1e37d85 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2017-04-05 Antonio Diaz Diaz <antonio@gnu.org>
+
+ * Version 1.6 released.
+ * zcmp.cc: Accept 'B' suffix in '--ignore-initial=1kB:1234B'.
+ * zutils.cc (feed_data): Show input filename in error messages.
+
2016-05-15 Antonio Diaz Diaz <antonio@gnu.org>
* Version 1.5 released.
@@ -128,7 +134,7 @@
* Version 0.1 released.
-Copyright (C) 2009-2016 Antonio Diaz Diaz.
+Copyright (C) 2009-2017 Antonio Diaz Diaz.
This file is a collection of facts, and thus it is not copyrightable,
but just in case, you have unlimited permission to copy, distribute and
diff --git a/INSTALL b/INSTALL
index ae495e7..11a4d6c 100644
--- a/INSTALL
+++ b/INSTALL
@@ -70,7 +70,7 @@ After running 'configure', you can run 'make' and 'make install' as
explained above.
-Copyright (C) 2009-2016 Antonio Diaz Diaz.
+Copyright (C) 2009-2017 Antonio Diaz Diaz.
This file is free documentation: you have unlimited permission to copy,
distribute and modify it.
diff --git a/Makefile.in b/Makefile.in
index f21f0b6..67b6998 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -106,7 +106,7 @@ $(VPATH)/doc/zgrep.1 : zgrep
-o $@ --no-info ./zgrep
$(VPATH)/doc/ztest.1 : ztest
- help2man -n 'verify integrity of compressed files' \
+ help2man -n 'verify the integrity of compressed files' \
-o $@ --no-info ./ztest
$(VPATH)/doc/zupdate.1 : zupdate
@@ -217,13 +217,13 @@ dist : doc
$(DISTNAME)/doc/*.1 \
$(DISTNAME)/doc/$(pkgname).info \
$(DISTNAME)/doc/$(pkgname).texi \
- $(DISTNAME)/testsuite/check.sh \
- $(DISTNAME)/testsuite/test.txt \
- $(DISTNAME)/testsuite/test.txt.tar \
$(DISTNAME)/$(pkgname)rc \
$(DISTNAME)/*.h \
$(DISTNAME)/*.cc \
- $(DISTNAME)/z*.in
+ $(DISTNAME)/z*.in \
+ $(DISTNAME)/testsuite/check.sh \
+ $(DISTNAME)/testsuite/test.txt \
+ $(DISTNAME)/testsuite/test.txt.tar
rm -f $(DISTNAME)
lzip -v -9 $(DISTNAME).tar
diff --git a/NEWS b/NEWS
index dbdef2a..086ba3c 100644
--- a/NEWS
+++ b/NEWS
@@ -1,9 +1,6 @@
-Changes in version 1.5:
+Changes in version 1.6:
-zupdate now passes '-q' to zcmp if specified.
+zcmp now accepts the 'B' suffix in the values of '--ignore-initial' as
+in '--ignore-initial=1kB:1234B'.
-zcat, zgrep and ztest no longer read from standard input more than once
-if '-' is specified multiple times.
-
-zdiff now uses '_' as separator if both temporary file names are
-otherwise different. For example 'xxx_file.lz' and 'xxx_file.gz'.
+The input filename is now shown in more error messages.
diff --git a/README b/README
index 1493410..fd6296b 100644
--- a/README
+++ b/README
@@ -23,9 +23,9 @@ NOTE: Bzip2 and lzip provide well-defined values of exit status, which
makes them safe to use with zutils. Gzip and xz may return ambiguous
warning values, making them less reliable back ends for zutils.
-FORMAT NOTE: The "--format" option allows the processing of a subset of
-formats in search and recursive modes:
-"zgrep foo -r --format=bz2,lz somedir".
+FORMAT NOTE 1: The "--format" option allows the processing of a subset
+of formats in recursive mode and when trying compressed file names:
+"zgrep foo -r --format=bz2,lz somedir somefile.tar".
FORMAT NOTE 2: If the "--force-format" option is given, the files are
passed to the corresponding decompressor without verifying their format,
@@ -33,11 +33,11 @@ allowing for example the processing of compress'd (.Z) files with gzip:
"zcmp --force-format=gz file.Z file.lz".
LANGUAGE NOTE: Uncompressed = not compressed = plain data; it may never
-have been compressed. Decompressed is used to refer to data which has
+have been compressed. Decompressed is used to refer to data which have
undergone the process of decompression.
-Copyright (C) 2009-2016 Antonio Diaz Diaz.
+Copyright (C) 2009-2017 Antonio Diaz Diaz.
This file is free documentation: you have unlimited permission to copy,
distribute and modify it.
diff --git a/arg_parser.cc b/arg_parser.cc
index 82972ad..cc7d1e2 100644
--- a/arg_parser.cc
+++ b/arg_parser.cc
@@ -1,5 +1,5 @@
/* Arg_parser - POSIX/GNU command line argument parser. (C++ version)
- Copyright (C) 2006-2016 Antonio Diaz Diaz.
+ Copyright (C) 2006-2017 Antonio Diaz Diaz.
This library is free software. Redistribution and use in source and
binary forms, with or without modification, are permitted provided
@@ -42,7 +42,7 @@ bool Arg_parser::parse_long_option( const char * const opt, const char * const a
else if( index < 0 ) index = i; // First nonexact match found
else if( options[index].code != options[i].code ||
options[index].has_arg != options[i].has_arg )
- ambig = true; // Second or later nonexact match found
+ ambig = true; // Second or later nonexact match found
}
if( ambig && !exact )
@@ -142,7 +142,7 @@ Arg_parser::Arg_parser( const int argc, const char * const argv[],
{
if( argc < 2 || !argv || !options ) return;
- std::vector< std::string > non_options; // skipped non-options
+ std::vector< const char * > non_options; // skipped non-options
int argind = 1; // index in argv
while( argind < argc )
@@ -163,17 +163,17 @@ Arg_parser::Arg_parser( const int argc, const char * const argv[],
}
else
{
- if( !in_order ) non_options.push_back( argv[argind++] );
- else { data.push_back( Record() ); data.back().argument = argv[argind++]; }
+ if( in_order ) data.push_back( Record( argv[argind++] ) );
+ else non_options.push_back( argv[argind++] );
}
}
if( error_.size() ) data.clear();
else
{
for( unsigned i = 0; i < non_options.size(); ++i )
- { data.push_back( Record() ); data.back().argument.swap( non_options[i] ); }
+ data.push_back( Record( non_options[i] ) );
while( argind < argc )
- { data.push_back( Record() ); data.back().argument = argv[argind++]; }
+ data.push_back( Record( argv[argind++] ) );
}
}
@@ -192,5 +192,5 @@ Arg_parser::Arg_parser( const char * const opt, const char * const arg,
parse_short_option( opt, arg, options, argind );
if( error_.size() ) data.clear();
}
- else { data.push_back( Record() ); data.back().argument = opt; }
+ else data.push_back( Record( opt ) );
}
diff --git a/arg_parser.h b/arg_parser.h
index f45b9ac..95b0320 100644
--- a/arg_parser.h
+++ b/arg_parser.h
@@ -1,5 +1,5 @@
/* Arg_parser - POSIX/GNU command line argument parser. (C++ version)
- Copyright (C) 2006-2016 Antonio Diaz Diaz.
+ Copyright (C) 2006-2017 Antonio Diaz Diaz.
This library is free software. Redistribution and use in source and
binary forms, with or without modification, are permitted provided
@@ -57,7 +57,8 @@ private:
{
int code;
std::string argument;
- explicit Record( const int c = 0 ) : code( c ) {}
+ explicit Record( const int c ) : code( c ) {}
+ explicit Record( const char * const arg ) : code( 0 ), argument( arg ) {}
};
std::string error_;
diff --git a/configure b/configure
index ddb3140..10ab602 100755
--- a/configure
+++ b/configure
@@ -1,12 +1,12 @@
#! /bin/sh
# configure script for Zutils - Utilities dealing with compressed files
-# Copyright (C) 2009-2016 Antonio Diaz Diaz.
+# Copyright (C) 2009-2017 Antonio Diaz Diaz.
#
# This configure script is free software: you have unlimited permission
# to copy, distribute and modify it.
pkgname=zutils
-pkgversion=1.5
+pkgversion=1.6
srctrigger=doc/${pkgname}.texi
# clear some things potentially inherited from environment.
@@ -28,11 +28,11 @@ DIFF=diff
GREP=grep
# checking whether we are using GNU C++.
-if /bin/sh -c "${CXX} --version" > /dev/null 2>&1 ; then true
-else
+/bin/sh -c "${CXX} --version" > /dev/null 2>&1 ||
+ {
CXX=c++
- CXXFLAGS='-W -O2'
-fi
+ CXXFLAGS=-O2
+ }
# Loop over all args
args=
@@ -54,9 +54,12 @@ while [ $# != 0 ] ; do
# Process the options
case ${option} in
--help | -h)
- echo "Usage: configure [options]"
+ echo "Usage: $0 [OPTION]... [VAR=VALUE]..."
+ echo
+ echo "To assign makefile variables (e.g., CXX, CXXFLAGS...), specify them as"
+ echo "arguments to configure in the form VAR=VALUE."
echo
- echo "Options: [defaults in brackets]"
+ echo "Options and variables: [defaults in brackets]"
echo " -h, --help display this help and exit"
echo " -V, --version output version information and exit"
echo " --srcdir=DIR find the sources in DIR [. or ..]"
@@ -177,7 +180,7 @@ echo "GREP = ${GREP}"
rm -f Makefile
cat > Makefile << EOF
# Makefile for Zutils - Utilities dealing with compressed files
-# Copyright (C) 2009-2016 Antonio Diaz Diaz.
+# Copyright (C) 2009-2017 Antonio Diaz Diaz.
# This file was generated automatically by configure. Don't edit.
#
# This Makefile is free software: you have unlimited permission
diff --git a/doc/zcat.1 b/doc/zcat.1
index b67aa40..9a76208 100644
--- a/doc/zcat.1
+++ b/doc/zcat.1
@@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.46.1.
-.TH ZCAT "1" "May 2016" "zcat (zutils) 1.5" "User Commands"
+.TH ZCAT "1" "April 2017" "zcat (zutils) 1.6" "User Commands"
.SH NAME
zcat \- decompress and concatenate files to standard output
.SH SYNOPSIS
@@ -11,7 +11,7 @@ compressed, its decompressed content is used. If a given file does not
exist, and its name does not end with one of the known extensions, zcat
tries the compressed file names corresponding to the supported formats.
.PP
-If no files are specified, or if a file is specified as '\-', data is
+If no files are specified, or if a file is specified as '\-', data are
read from standard input, decompressed if needed, and sent to standard
output. Data read from standard input must be of the same type; all
uncompressed or all in the same compression format.
@@ -88,7 +88,7 @@ Report bugs to zutils\-bug@nongnu.org
.br
Zutils home page: http://www.nongnu.org/zutils/zutils.html
.SH COPYRIGHT
-Copyright \(co 2016 Antonio Diaz Diaz.
+Copyright \(co 2017 Antonio Diaz Diaz.
License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html>
.br
This is free software: you are free to change and redistribute it.
diff --git a/doc/zcmp.1 b/doc/zcmp.1
index 33f725e..c9583f8 100644
--- a/doc/zcmp.1
+++ b/doc/zcmp.1
@@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.46.1.
-.TH ZCMP "1" "May 2016" "zcmp (zutils) 1.5" "User Commands"
+.TH ZCMP "1" "April 2017" "zcmp (zutils) 1.6" "User Commands"
.SH NAME
zcmp \- decompress and compare two files byte by byte
.SH SYNOPSIS
@@ -14,17 +14,17 @@ fly; no temporary files are created.
.PP
The supported formats are bzip2, gzip, lzip and xz.
.PP
-Compares <file1> to <file2>. If <file2> is omitted zcmp tries the
+Zcmp compares file1 to file2. If file2 is omitted zcmp tries the
following:
.IP
-1. If <file1> is compressed, compares its decompressed contents with
-the corresponding uncompressed file (the name of <file1> with the
+1. If file1 is compressed, compares its decompressed contents with
+the corresponding uncompressed file (the name of file1 with the
extension removed).
.IP
-2. If <file1> is uncompressed, compares it with the decompressed
-contents of <file1>.[lz|bz2|gz|xz] (the first one that is found).
+2. If file1 is uncompressed, compares it with the decompressed
+contents of file1.[lz|bz2|gz|xz] (the first one that is found).
.IP
-3. If no suitable file is found, compares <file1> with data read from
+3. If no suitable file is found, compares file1 with data read from
standard input.
.PP
Exit status is 0 if inputs are identical, 1 if different, 2 if trouble.
@@ -39,7 +39,7 @@ output version information and exit
\fB\-b\fR, \fB\-\-print\-bytes\fR
print differing bytes
.TP
-\fB\-i\fR, \fB\-\-ignore\-initial=\fR<n>[,<n2>]
+\fB\-i\fR, \fB\-\-ignore\-initial=\fR<n>[:<n2>]
ignore differences in the first <n> bytes
.TP
\fB\-l\fR, \fB\-\-list\fR
@@ -85,7 +85,7 @@ Report bugs to zutils\-bug@nongnu.org
.br
Zutils home page: http://www.nongnu.org/zutils/zutils.html
.SH COPYRIGHT
-Copyright \(co 2016 Antonio Diaz Diaz.
+Copyright \(co 2017 Antonio Diaz Diaz.
License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html>
.br
This is free software: you are free to change and redistribute it.
diff --git a/doc/zdiff.1 b/doc/zdiff.1
index 3e1d607..f803ee8 100644
--- a/doc/zdiff.1
+++ b/doc/zdiff.1
@@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.46.1.
-.TH ZDIFF "1" "May 2016" "zdiff (zutils) 1.5" "User Commands"
+.TH ZDIFF "1" "April 2017" "zdiff (zutils) 1.6" "User Commands"
.SH NAME
zdiff \- decompress and compare two files line by line
.SH SYNOPSIS
@@ -14,17 +14,17 @@ temporary filenames instead of those specified.
.PP
The supported formats are bzip2, gzip, lzip and xz.
.PP
-Compares <file1> to <file2>. If <file2> is omitted zdiff tries the
+Zdiff compares file1 to file2. If file2 is omitted zdiff tries the
following:
.IP
-1. If <file1> is compressed, compares its decompressed contents with
-the corresponding uncompressed file (the name of <file1> with the
+1. If file1 is compressed, compares its decompressed contents with
+the corresponding uncompressed file (the name of file1 with the
extension removed).
.IP
-2. If <file1> is uncompressed, compares it with the decompressed
-contents of <file1>.[lz|bz2|gz|xz] (the first one that is found).
+2. If file1 is uncompressed, compares it with the decompressed
+contents of file1.[lz|bz2|gz|xz] (the first one that is found).
.IP
-3. If no suitable file is found, compares <file1> with data read from
+3. If no suitable file is found, compares file1 with data read from
standard input.
.PP
Exit status is 0 if inputs are identical, 1 if different, 2 if trouble.
@@ -109,7 +109,7 @@ Report bugs to zutils\-bug@nongnu.org
.br
Zutils home page: http://www.nongnu.org/zutils/zutils.html
.SH COPYRIGHT
-Copyright \(co 2016 Antonio Diaz Diaz.
+Copyright \(co 2017 Antonio Diaz Diaz.
License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html>
.br
This is free software: you are free to change and redistribute it.
diff --git a/doc/zgrep.1 b/doc/zgrep.1
index 67d8277..571d410 100644
--- a/doc/zgrep.1
+++ b/doc/zgrep.1
@@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.46.1.
-.TH ZGREP "1" "May 2016" "zgrep (zutils) 1.5" "User Commands"
+.TH ZGREP "1" "April 2017" "zgrep (zutils) 1.6" "User Commands"
.SH NAME
zgrep \- search compressed files for a regular expression
.SH SYNOPSIS
@@ -13,7 +13,7 @@ does not exist, and its name does not end with one of the known
extensions, zgrep tries the compressed file names corresponding to the
supported formats.
.PP
-If no files are specified, or if a file is specified as '\-', data is
+If no files are specified, or if a file is specified as '\-', data are
read from standard input, decompressed if needed, and fed to grep. Data
read from standard input must be of the same type; all uncompressed or
all in the same compression format.
@@ -135,7 +135,7 @@ Report bugs to zutils\-bug@nongnu.org
.br
Zutils home page: http://www.nongnu.org/zutils/zutils.html
.SH COPYRIGHT
-Copyright \(co 2016 Antonio Diaz Diaz.
+Copyright \(co 2017 Antonio Diaz Diaz.
License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html>
.br
This is free software: you are free to change and redistribute it.
diff --git a/doc/ztest.1 b/doc/ztest.1
index 3311667..252489b 100644
--- a/doc/ztest.1
+++ b/doc/ztest.1
@@ -1,7 +1,7 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.46.1.
-.TH ZTEST "1" "May 2016" "ztest (zutils) 1.5" "User Commands"
+.TH ZTEST "1" "April 2017" "ztest (zutils) 1.6" "User Commands"
.SH NAME
-ztest \- verify integrity of compressed files
+ztest \- verify the integrity of compressed files
.SH SYNOPSIS
.B ztest
[\fI\,options\/\fR] [\fI\,files\/\fR]
@@ -14,8 +14,12 @@ compression format.
.PP
The supported formats are bzip2, gzip, lzip and xz.
.PP
-Note that some xz files lack integrity information, and therefore can't
-be verified as reliably as the other formats can.
+Note that error detection in the xz format is broken. First, some xz
+files lack integrity information. Second, not all xz decompressors can
+verify the integrity of all xz files. Third, section 2.1.1.2 'Stream
+Flags' of the xz format specification allows xz decompressors to produce
+garbage output without issuing any warning. Therefore, xz files can't
+always be verified as reliably as files in the other formats can.
.PP
Exit status is 0 if all compressed files verify OK, 1 if environmental
problems (file not found, invalid flags, I/O errors, etc), 2 if any
@@ -62,7 +66,7 @@ Report bugs to zutils\-bug@nongnu.org
.br
Zutils home page: http://www.nongnu.org/zutils/zutils.html
.SH COPYRIGHT
-Copyright \(co 2016 Antonio Diaz Diaz.
+Copyright \(co 2017 Antonio Diaz Diaz.
License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html>
.br
This is free software: you are free to change and redistribute it.
diff --git a/doc/zupdate.1 b/doc/zupdate.1
index 059867e..6894418 100644
--- a/doc/zupdate.1
+++ b/doc/zupdate.1
@@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.46.1.
-.TH ZUPDATE "1" "May 2016" "zupdate (zutils) 1.5" "User Commands"
+.TH ZUPDATE "1" "April 2017" "zupdate (zutils) 1.6" "User Commands"
.SH NAME
zupdate \- recompress bzip2, gzip, xz files to lzip format
.SH SYNOPSIS
@@ -76,7 +76,7 @@ Report bugs to zutils\-bug@nongnu.org
.br
Zutils home page: http://www.nongnu.org/zutils/zutils.html
.SH COPYRIGHT
-Copyright \(co 2016 Antonio Diaz Diaz.
+Copyright \(co 2017 Antonio Diaz Diaz.
License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html>
.br
This is free software: you are free to change and redistribute it.
diff --git a/doc/zutils.info b/doc/zutils.info
index b753ec0..98ddf49 100644
--- a/doc/zutils.info
+++ b/doc/zutils.info
@@ -12,7 +12,7 @@ File: zutils.info, Node: Top, Next: Introduction, Up: (dir)
Zutils Manual
*************
-This manual is for Zutils (version 1.5, 15 May 2016).
+This manual is for Zutils (version 1.6, 5 April 2017).
* Menu:
@@ -23,13 +23,13 @@ This manual is for Zutils (version 1.5, 15 May 2016).
* Zcmp:: Comparing compressed files byte by byte
* Zdiff:: Comparing compressed files line by line
* Zgrep:: Searching inside compressed files
-* Ztest:: Testing integrity of compressed files
+* Ztest:: Testing the integrity of compressed files
* Zupdate:: Recompressing files to lzip format
* Problems:: Reporting bugs
* Concept index:: Index of concepts
- Copyright (C) 2009-2016 Antonio Diaz Diaz.
+ Copyright (C) 2009-2017 Antonio Diaz Diaz.
This manual is free documentation: you have unlimited permission to
copy, distribute and modify it.
@@ -64,9 +64,9 @@ which makes them safe to use with zutils. Gzip and xz may return
ambiguous warning values, making them less reliable back ends for
zutils. *Note compressor-requirements::.
- FORMAT NOTE: The '--format' option allows the processing of a subset
-of formats in search and recursive modes:
-'zgrep foo -r --format=bz2,lz somedir'.
+ FORMAT NOTE 1: The '--format' option allows the processing of a
+subset of formats in recursive mode and when trying compressed file
+names: 'zgrep foo -r --format=bz2,lz somedir somefile.tar'.
FORMAT NOTE 2: If the '--force-format' option is given, the files
are passed to the corresponding decompressor without verifying their
@@ -75,7 +75,7 @@ with gzip: 'zcmp --force-format=gz file.Z file.lz'.
LANGUAGE NOTE: Uncompressed = not compressed = plain data; it may
never have been compressed. Decompressed is used to refer to data which
-has undergone the process of decompression.
+have undergone the process of decompression.
Numbers given as arguments to options (positions, sizes) may be
@@ -192,10 +192,10 @@ compressed, its decompressed content is used. If a given file does not
exist, and its name does not end with one of the known extensions, zcat
tries the compressed file names corresponding to the supported formats.
- If no files are specified, or if a file is specified as '-', data is
-read from standard input, decompressed if needed, and sent to standard
-output. Data read from standard input must be of the same type; all
-uncompressed or all in the same compression format.
+ If no files are specified, or if a file is specified as '-', data
+are read from standard input, decompressed if needed, and sent to
+standard output. Data read from standard input must be of the same type;
+all uncompressed or all in the same compression format.
The format for running zcat is:
@@ -307,7 +307,7 @@ differences were found, and 2 means trouble.
'--ignore-initial=SIZE'
Ignore any differences in the first SIZE bytes of the input files.
Treat files with fewer than SIZE bytes as if they were empty. If
- SIZE is in the form 'SIZE1,SIZE2', ignore the first SIZE1 bytes of
+ SIZE is in the form 'SIZE1:SIZE2', ignore the first SIZE1 bytes of
the first input file and the first SIZE2 bytes of the second input
file.
@@ -460,8 +460,8 @@ does not exist, and its name does not end with one of the known
extensions, zgrep tries the compressed file names corresponding to the
supported formats.
- If no files are specified, or if a file is specified as '-', data is
-read from standard input, decompressed if needed, and fed to grep.
+ If no files are specified, or if a file is specified as '-', data
+are read from standard input, decompressed if needed, and fed to grep.
Data read from standard input must be of the same type; all uncompressed
or all in the same compression format.
@@ -602,8 +602,12 @@ is specified as '-', the integrity of compressed data read from
standard input is verified. Data read from standard input must be all in
the same compression format.
- Note that some xz files lack integrity information, and therefore
-can't be verified as reliably as the other formats can.
+ Note that error detection in the xz format is broken. First, some xz
+files lack integrity information. Second, not all xz decompressors can
+verify the integrity of all xz files. Third, section 2.1.1.2 'Stream
+Flags' of the xz format specification allows xz decompressors to
+produce garbage output without issuing any warning. Therefore, xz files
+can't always be verified as reliably as files in the other formats can.
The format for running ztest is:
@@ -761,18 +765,18 @@ Concept index

Tag Table:
Node: Top222
-Node: Introduction1142
-Node: Common options3726
-Ref: compressor-requirements5484
-Node: The zutilsrc file5856
-Node: Zcat6781
-Node: Zcmp8834
-Node: Zdiff11293
-Node: Zgrep13933
-Node: Ztest17271
-Node: Zupdate18809
-Node: Problems21681
-Node: Concept index22215
+Node: Introduction1147
+Node: Common options3773
+Ref: compressor-requirements5531
+Node: The zutilsrc file5903
+Node: Zcat6828
+Node: Zcmp8882
+Node: Zdiff11341
+Node: Zgrep13981
+Node: Ztest17320
+Node: Zupdate19154
+Node: Problems22026
+Node: Concept index22560

End Tag Table
diff --git a/doc/zutils.texi b/doc/zutils.texi
index 34c15b4..ea9fb2d 100644
--- a/doc/zutils.texi
+++ b/doc/zutils.texi
@@ -6,8 +6,8 @@
@finalout
@c %**end of header
-@set UPDATED 15 May 2016
-@set VERSION 1.5
+@set UPDATED 5 April 2017
+@set VERSION 1.6
@dircategory Data Compression
@direntry
@@ -42,14 +42,14 @@ This manual is for Zutils (version @value{VERSION}, @value{UPDATED}).
* Zcmp:: Comparing compressed files byte by byte
* Zdiff:: Comparing compressed files line by line
* Zgrep:: Searching inside compressed files
-* Ztest:: Testing integrity of compressed files
+* Ztest:: Testing the integrity of compressed files
* Zupdate:: Recompressing files to lzip format
* Problems:: Reporting bugs
* Concept index:: Index of concepts
@end menu
@sp 1
-Copyright @copyright{} 2009-2016 Antonio Diaz Diaz.
+Copyright @copyright{} 2009-2017 Antonio Diaz Diaz.
This manual is free documentation: you have unlimited permission
to copy, distribute and modify it.
@@ -84,9 +84,9 @@ makes them safe to use with zutils. Gzip and xz may return ambiguous
warning values, making them less reliable back ends for zutils.
@xref{compressor-requirements}.
-FORMAT NOTE: The @samp{--format} option allows the processing of a
-subset of formats in search and recursive modes:
-@w{@samp{zgrep foo -r --format=bz2,lz somedir}}.
+FORMAT NOTE 1: The @samp{--format} option allows the processing of a
+subset of formats in recursive mode and when trying compressed file
+names: @w{@samp{zgrep foo -r --format=bz2,lz somedir somefile.tar}}.
FORMAT NOTE 2: If the @samp{--force-format} option is given, the files
are passed to the corresponding decompressor without verifying their
@@ -94,7 +94,7 @@ format, allowing for example the processing of compress'd (.Z) files
with gzip: @w{@samp{zcmp --force-format=gz file.Z file.lz}}.
LANGUAGE NOTE: Uncompressed = not compressed = plain data; it may never
-have been compressed. Decompressed is used to refer to data which has
+have been compressed. Decompressed is used to refer to data which have
undergone the process of decompression.
@sp 1
@@ -224,7 +224,7 @@ exist, and its name does not end with one of the known extensions, zcat
tries the compressed file names corresponding to the supported formats.
If no files are specified, or if a file is specified as @samp{-}, data
-is read from standard input, decompressed if needed, and sent to
+are read from standard input, decompressed if needed, and sent to
standard output. Data read from standard input must be of the same type;
all uncompressed or all in the same compression format.
@@ -349,7 +349,7 @@ for "meta").
@itemx --ignore-initial=@var{size}
Ignore any differences in the first @var{size} bytes of the input files.
Treat files with fewer than @var{size} bytes as if they were empty. If
-@var{size} is in the form @samp{@var{size1},@var{size2}}, ignore the
+@var{size} is in the form @samp{@var{size1}:@var{size2}}, ignore the
first @var{size1} bytes of the first input file and the first
@var{size2} bytes of the second input file.
@@ -511,7 +511,7 @@ extensions, zgrep tries the compressed file names corresponding to the
supported formats.
If no files are specified, or if a file is specified as @samp{-}, data
-is read from standard input, decompressed if needed, and fed to grep.
+are read from standard input, decompressed if needed, and fed to grep.
Data read from standard input must be of the same type; all uncompressed
or all in the same compression format.
@@ -657,8 +657,15 @@ is specified as @samp{-}, the integrity of compressed data read from
standard input is verified. Data read from standard input must be all in
the same compression format.
-Note that some xz files lack integrity information, and therefore can't
-be verified as reliably as the other formats can.
+Note that error detection in the xz format is broken. First, some xz
+files lack integrity information. Second, not all xz decompressors can
+@uref{http://www.nongnu.org/lzip/xz_inadequate.html#fragmented,,verify the integrity}
+of all xz files. Third, section 2.1.1.2 'Stream Flags' of the
+@uref{http://tukaani.org/xz/xz-file-format.txt,,xz format specification}
+allows xz decompressors to produce garbage output without issuing any
+warning. Therefore, xz files can't always be verified as reliably as
+files in the other formats can.
+@c We can only hope that xz is soon abandoned.
The format for running ztest is:
diff --git a/rc.cc b/rc.cc
index 2326465..9af190d 100644
--- a/rc.cc
+++ b/rc.cc
@@ -1,5 +1,5 @@
/* Zutils - Utilities dealing with compressed files
- Copyright (C) 2009-2016 Antonio Diaz Diaz.
+ Copyright (C) 2009-2017 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -37,7 +37,7 @@ int verbosity = 0;
namespace {
const char * const config_file_name = "zutilsrc";
-const char * const program_year = "2016";
+const char * const program_year = "2017";
std::string compressor_names[num_formats] =
{ "bzip2", "gzip", "lzip", "xz" }; // default compressor names
@@ -49,7 +49,7 @@ std::vector< std::string > compressor_args[num_formats];
// empty means all enabled.
std::vector< bool > enabled_formats;
-struct { const char * from; const char * to; int format_index; } const
+const struct { const char * from; const char * to; int format_index; }
known_extensions[] = {
{ ".bz2", "", fmt_bz2 },
{ ".tbz", ".tar", fmt_bz2 },
@@ -253,12 +253,12 @@ int parse_format_type( const std::string & arg )
int extension_index( const std::string & name )
{
- for( int i = 0; known_extensions[i].from; ++i )
+ for( int eindex = 0; known_extensions[eindex].from; ++eindex )
{
- const std::string ext( known_extensions[i].from );
+ const std::string ext( known_extensions[eindex].from );
if( name.size() > ext.size() &&
name.compare( name.size() - ext.size(), ext.size(), ext ) == 0 )
- return i;
+ return eindex;
}
return -1;
}
@@ -347,6 +347,16 @@ void show_error( const char * const msg, const int errcode, const bool help )
}
+void show_file_error( const char * const filename, const char * const msg,
+ const int errcode )
+ {
+ if( verbosity < 0 ) return;
+ std::fprintf( stderr, "%s: %s: %s", program_name, filename, msg );
+ if( errcode > 0 ) std::fprintf( stderr, ": %s", std::strerror( errcode ) );
+ std::fputc( '\n', stderr );
+ }
+
+
void show_error2( const char * const msg, const char * const name )
{
if( verbosity >= 0 )
diff --git a/rc.h b/rc.h
index fa9175c..c75a36f 100644
--- a/rc.h
+++ b/rc.h
@@ -1,5 +1,5 @@
/* Zutils - Utilities dealing with compressed files
- Copyright (C) 2009-2016 Antonio Diaz Diaz.
+ Copyright (C) 2009-2017 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -20,7 +20,7 @@ const char * const format_names[num_formats] = { "bz2", "gz", "lz", "xz" };
const char * const simple_extensions[num_formats] =
{ ".bz2", ".gz", ".lz", ".xz" };
const int format_order[num_formats] =
- { fmt_lz, fmt_bz2, fmt_gz, fmt_xz }; // search order
+ { fmt_lz, fmt_bz2, fmt_gz, fmt_xz }; // search order
bool enabled_format( const int format_index );
void parse_format_list( const std::string & arg );
@@ -49,6 +49,8 @@ void show_help_addr();
void show_version();
void show_error( const char * const msg, const int errcode = 0,
const bool help = false );
+void show_file_error( const char * const filename, const char * const msg,
+ const int errcode = 0 );
void show_error2( const char * const msg, const char * const name );
void internal_error( const char * const msg );
void show_close_error( const char * const prog_name = "data feeder" );
diff --git a/recursive.cc b/recursive.cc
index b08122d..5301772 100644
--- a/recursive.cc
+++ b/recursive.cc
@@ -1,5 +1,5 @@
/* Zutils - Utilities dealing with compressed files
- Copyright (C) 2009-2016 Antonio Diaz Diaz.
+ Copyright (C) 2009-2017 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/testsuite/check.sh b/testsuite/check.sh
index 70b49d3..3986d71 100755
--- a/testsuite/check.sh
+++ b/testsuite/check.sh
@@ -1,6 +1,6 @@
#! /bin/sh
# check script for Zutils - Utilities dealing with compressed files
-# Copyright (C) 2009-2016 Antonio Diaz Diaz.
+# Copyright (C) 2009-2017 Antonio Diaz Diaz.
#
# This script is free software: you have unlimited permission
# to copy, distribute and modify it.
@@ -27,12 +27,12 @@ if [ ! -f "${ZUPDATE}" ] || [ ! -x "${ZUPDATE}" ] ; then
exit 1
fi
-if [ -e "${ZUPDATE}" ] 2> /dev/null ; then true
-else
+[ -e "${ZUPDATE}" ] 2> /dev/null ||
+ {
echo "$0: a POSIX shell is required to run the tests"
echo "Try bash -c \"$0 $1 $2\""
exit 1
-fi
+ }
if [ -d tmp ] ; then rm -rf tmp ; fi
mkdir tmp
@@ -52,343 +52,261 @@ cat in.lz > -in-.lz || framework_failure
cat in.lz > lz_only.lz || framework_failure
cat in in in in in in > in6 || framework_failure
fail=0
+test_failed() { fail=1 ; printf " $1" ; [ -z "$2" ] || printf "($2)" ; }
printf "testing zcat-%s..." "$2"
for i in ${extensions}; do
- "${ZCAT}" -N in.$i > copy || fail=1
- cmp in copy || fail=1
- printf .
- "${ZCAT}" -N --format=un in.$i > copy || fail=1
- cmp in copy || fail=1
- printf .
- "${ZCAT}" -N --force-format=$i in.$i > copy || fail=1
- cmp in copy || fail=1
- printf .
- "${ZCAT}" -N in.$i | dd bs=1000 count=1 > copy 2> /dev/null || fail=1
- dd if=in bs=1000 count=1 2> /dev/null | cmp - copy || fail=1
- printf .
+ "${ZCAT}" -N in.$i > copy || test_failed $LINENO $i
+ cmp in copy || test_failed $LINENO $i
+ "${ZCAT}" -N --format=un in.$i > copy || test_failed $LINENO $i
+ cmp in copy || test_failed $LINENO $i
+ "${ZCAT}" -N --force-format=$i in.$i > copy || test_failed $LINENO $i
+ cmp in copy || test_failed $LINENO $i
+ "${ZCAT}" -N in.$i | dd bs=1000 count=1 > copy 2> /dev/null ||
+ test_failed $LINENO $i
+ dd if=in bs=1000 count=1 2> /dev/null | cmp - copy ||
+ test_failed $LINENO $i
done
-"${ZCAT}" -N < in > copy || fail=1
-cmp in copy || fail=1
-printf .
-"${ZCAT}" -N < in.gz > copy || fail=1
-cmp in copy || fail=1
-printf .
-"${ZCAT}" -N < in.bz2 > copy || fail=1
-cmp in copy || fail=1
-printf .
-"${ZCAT}" -N < in.lz > copy || fail=1
-cmp in copy || fail=1
-printf .
-"${ZCAT}" -N -O lz - - < in.lz > copy || fail=1
-cmp in copy || fail=1
-printf .
-"${ZCAT}" -N --lz='lzip -q' < in.lz > copy || fail=1
-cmp in copy || fail=1
-printf .
-"${ZCAT}" -N in > copy || fail=1
-cmp in copy || fail=1
-printf .
-"${ZCAT}" -N lz_only > copy || fail=1
-cmp in copy || fail=1
-printf .
-"${ZCAT}" -N in in.gz in.bz2 in.lz -- -in- -in-.lz > copy || fail=1
-cmp in6 copy || fail=1
-printf .
+"${ZCAT}" -N < in > copy || test_failed $LINENO
+cmp in copy || test_failed $LINENO
+"${ZCAT}" -N < in.gz > copy || test_failed $LINENO
+cmp in copy || test_failed $LINENO
+"${ZCAT}" -N < in.bz2 > copy || test_failed $LINENO
+cmp in copy || test_failed $LINENO
+"${ZCAT}" -N < in.lz > copy || test_failed $LINENO
+cmp in copy || test_failed $LINENO
+"${ZCAT}" -N -O lz - - < in.lz > copy || test_failed $LINENO
+cmp in copy || test_failed $LINENO
+"${ZCAT}" -N --lz='lzip -q' < in.lz > copy || test_failed $LINENO
+cmp in copy || test_failed $LINENO
+"${ZCAT}" -N in > copy || test_failed $LINENO
+cmp in copy || test_failed $LINENO
+"${ZCAT}" -N lz_only > copy || test_failed $LINENO
+cmp in copy || test_failed $LINENO
+"${ZCAT}" -N in in.gz in.bz2 in.lz -- -in- -in-.lz > copy || test_failed $LINENO
+cmp in6 copy || test_failed $LINENO
"${ZCAT}" -Nq --format=, in.lz
-if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi
+[ $? = 1 ] || test_failed $LINENO
"${ZCAT}" -Nq --format=,lz in.lz
-if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi
+[ $? = 1 ] || test_failed $LINENO
"${ZCAT}" -Nq --format=gz,,lz in.lz
-if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi
+[ $? = 1 ] || test_failed $LINENO
"${ZCAT}" -Nq --format=lz,, in.lz
-if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi
+[ $? = 1 ] || test_failed $LINENO
"${ZCAT}" -Nq --format=nc in.lz
-if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi
+[ $? = 1 ] || test_failed $LINENO
"${ZCAT}" -Nq --lz='-lzip -q' in.lz
-if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi
+[ $? = 1 ] || test_failed $LINENO
"${ZCAT}" -N --force-format=gz in.bz2 2> /dev/null
-if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi
+[ $? = 1 ] || test_failed $LINENO
"${ZCAT}" -N --force-format=bz2 in.lz 2> /dev/null
-if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi
+[ $? = 1 ] || test_failed $LINENO
"${ZCAT}" -Nq --force-format=lz in.gz
-if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi
+[ $? = 1 ] || test_failed $LINENO
"${ZCAT}" -N --bad-option 2> /dev/null
-if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi
+[ $? = 1 ] || test_failed $LINENO
printf "\ntesting zcmp-%s..." "$2"
for i in ${extensions}; do
- "${ZCMP}" -N in.$i || fail=1
- printf .
- "${ZCMP}" -N in in.$i || fail=1
- printf .
- "${ZCMP}" -N -i 100 -n 500 in6 in.$i || fail=1
- printf .
- "${ZCMP}" -N in in.$i --force-format=,$i || fail=1
- printf .
- "${ZCMP}" -N in.$i in || fail=1
- printf .
- "${ZCMP}" -N -i 1000:1000 -n 50 in.$i in6 || fail=1
- printf .
- "${ZCMP}" -N in.$i in --force-format=$i || fail=1
- printf .
+ "${ZCMP}" -N in.$i || test_failed $LINENO $i
+ "${ZCMP}" -N in in.$i || test_failed $LINENO $i
+ "${ZCMP}" -N -i 1kB:1000 -n 500 in6 in.$i || test_failed $LINENO $i
+ "${ZCMP}" -N in in.$i --force-format=,$i || test_failed $LINENO $i
+ "${ZCMP}" -N in.$i in || test_failed $LINENO $i
+ "${ZCMP}" -N -i 1KiB:1024 -n 50 in.$i in6 || test_failed $LINENO $i
+ "${ZCMP}" -N in.$i in --force-format=$i || test_failed $LINENO $i
done
"${ZCMP}" -Nq in in6
-if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi
-"${ZCMP}" -N -n 0 in in6 || fail=1
-"${ZCMP}" -N -n 100 in in6 || fail=1
-"${ZCMP}" -N -n 1000 in in6 || fail=1
-"${ZCMP}" -N -n 10000 in in6 || fail=1
-printf .
+[ $? = 1 ] || test_failed $LINENO
+"${ZCMP}" -N -n 0 in in6 || test_failed $LINENO
+"${ZCMP}" -N -n 100B in in6 || test_failed $LINENO
+"${ZCMP}" -N -n 1k in in6 || test_failed $LINENO
+"${ZCMP}" -N -n 10kB in in6 || test_failed $LINENO
"${ZCMP}" -Nq in.tar pin.tar
-if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi
-"${ZCMP}" -Nq -i 0,11 in.tar pin.tar
-if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi
-"${ZCMP}" -N -i 0,11 -n 0 in.tar pin.tar || fail=1
-"${ZCMP}" -N -i 0,11 -n 100 in.tar pin.tar || fail=1
-"${ZCMP}" -N -i 0,11 -n 1000 in.tar pin.tar || fail=1
-"${ZCMP}" -N -i 0,11 -n 10000 in.tar pin.tar || fail=1
-printf .
-"${ZCMP}" -N - || fail=1
-printf .
-"${ZCMP}" -N in in || fail=1
-printf .
-"${ZCMP}" -N in || fail=1
-printf .
-"${ZCMP}" -N in.lz in.gz || fail=1
-printf .
-"${ZCMP}" -N --lz='lzip -q' in.lz in.gz || fail=1
-printf .
-"${ZCMP}" -N in.gz -- -in-.lz || fail=1
-printf .
-"${ZCMP}" -N -- -in-.lz in.gz || fail=1
-printf .
-"${ZCMP}" -N in -- -in-.lz || fail=1
-printf .
-"${ZCMP}" -N -- -in- in.lz || fail=1
-printf .
-"${ZCMP}" -N in.lz -- -in- || fail=1
-printf .
-"${ZCMP}" -N -- -in-.lz in || fail=1
-printf .
-"${ZCMP}" -N -- -in- in || fail=1
-printf .
-"${ZCMP}" -N in -- -in- || fail=1
-printf .
-"${ZCMP}" -N lz_only.lz < in || fail=1
-printf .
-"${ZCMP}" -N in.lz - < in || fail=1
-printf .
-"${ZCMP}" -N - in.lz < in || fail=1
-printf .
-"${ZCMP}" -N in - < in.lz || fail=1
-printf .
-"${ZCMP}" -N - in < in.lz || fail=1
-printf .
+[ $? = 1 ] || test_failed $LINENO
+"${ZCMP}" -Nq -i 0B:11B in.tar pin.tar
+[ $? = 1 ] || test_failed $LINENO
+"${ZCMP}" -N -i 0:11 -n 0 in.tar pin.tar || test_failed $LINENO
+"${ZCMP}" -N -i 0:11 -n 100 in.tar pin.tar || test_failed $LINENO
+"${ZCMP}" -N -i 0:11 -n 1Ki in.tar pin.tar || test_failed $LINENO
+"${ZCMP}" -N -i 0:11 -n 10KiB in.tar pin.tar || test_failed $LINENO
+"${ZCMP}" -N - || test_failed $LINENO
+"${ZCMP}" -N in in || test_failed $LINENO
+"${ZCMP}" -N in || test_failed $LINENO
+"${ZCMP}" -N in.lz in.gz || test_failed $LINENO
+"${ZCMP}" -N --lz='lzip -q' in.lz in.gz || test_failed $LINENO
+"${ZCMP}" -N in.gz -- -in-.lz || test_failed $LINENO
+"${ZCMP}" -N -- -in-.lz in.gz || test_failed $LINENO
+"${ZCMP}" -N in -- -in-.lz || test_failed $LINENO
+"${ZCMP}" -N -- -in- in.lz || test_failed $LINENO
+"${ZCMP}" -N in.lz -- -in- || test_failed $LINENO
+"${ZCMP}" -N -- -in-.lz in || test_failed $LINENO
+"${ZCMP}" -N -- -in- in || test_failed $LINENO
+"${ZCMP}" -N in -- -in- || test_failed $LINENO
+"${ZCMP}" -N lz_only.lz < in || test_failed $LINENO
+"${ZCMP}" -N in.lz - < in || test_failed $LINENO
+"${ZCMP}" -N - in.lz < in || test_failed $LINENO
+"${ZCMP}" -N in - < in.lz || test_failed $LINENO
+"${ZCMP}" -N - in < in.lz || test_failed $LINENO
"${ZCMP}" -N -q --force-format=lz in.lz
-if [ $? = 2 ] ; then printf . ; else printf - ; fail=1 ; fi
+[ $? = 2 ] || test_failed $LINENO
"${ZCMP}" -Nq --force-format=lz in.gz in.lz
r=$?
-if [ $r = 1 ] || [ $r = 2 ] ; then printf . ; else printf - ; fail=1 ; fi
+{ [ $r = 1 ] || [ $r = 2 ] ; } || test_failed $LINENO
+"${ZCMP}" -Nq -i 100BB in in
+[ $? = 2 ] || test_failed $LINENO
+"${ZCMP}" -Nq -i 100BB:100 in in
+[ $? = 2 ] || test_failed $LINENO
+"${ZCMP}" -Nq -i 100: in in
+[ $? = 2 ] || test_failed $LINENO
"${ZCMP}" -Nq -n -1 in in
-if [ $? = 2 ] ; then printf . ; else printf - ; fail=1 ; fi
+[ $? = 2 ] || test_failed $LINENO
+"${ZCMP}" -Nq -n 100BB in in
+[ $? = 2 ] || test_failed $LINENO
"${ZCMP}" -N --bad-option in in 2> /dev/null
-if [ $? = 2 ] ; then printf . ; else printf - ; fail=1 ; fi
+[ $? = 2 ] || test_failed $LINENO
printf "\ntesting zdiff-%s..." "$2"
for i in ${extensions}; do
- "${ZDIFF}" -N in.$i > /dev/null || fail=1
- printf .
- "${ZDIFF}" -N in in.$i > /dev/null || fail=1
- printf .
- "${ZDIFF}" -N --force-format=,$i in in.$i > /dev/null || fail=1
- printf .
- "${ZDIFF}" -N in.$i in > /dev/null || fail=1
- printf .
- "${ZDIFF}" -N --force-format=$i, in.$i in > /dev/null || fail=1
- printf .
+ "${ZDIFF}" -N in.$i > /dev/null || test_failed $LINENO $i
+ "${ZDIFF}" -N in in.$i > /dev/null || test_failed $LINENO $i
+ "${ZDIFF}" -N --force-format=,$i in in.$i > /dev/null ||
+ test_failed $LINENO $i
+ "${ZDIFF}" -N in.$i in > /dev/null || test_failed $LINENO $i
+ "${ZDIFF}" -N --force-format=$i, in.$i in > /dev/null ||
+ test_failed $LINENO $i
done
-"${ZDIFF}" -N in in6 > /dev/null
-if [ $? != 0 ] ; then printf . ; else printf - ; fail=1 ; fi
-"${ZDIFF}" -N in.tar pin.tar > /dev/null
-if [ $? != 0 ] ; then printf . ; else printf - ; fail=1 ; fi
-"${ZDIFF}" -N - || fail=1
-printf .
-"${ZDIFF}" -N in in || fail=1
-printf .
-"${ZDIFF}" -N in || fail=1
-printf .
-"${ZDIFF}" -N --format=gz,bz2 in || fail=1
-printf .
-"${ZDIFF}" -N --format=gz in || fail=1
-printf .
-"${ZDIFF}" -N in.lz in.gz > /dev/null || fail=1
-printf .
-"${ZDIFF}" -N --lz='lzip -q' in.lz in.gz > /dev/null || fail=1
-printf .
-"${ZDIFF}" -N in.gz -- -in-.lz > /dev/null || fail=1
-printf .
-"${ZDIFF}" -N -- -in-.lz in.gz > /dev/null || fail=1
-printf .
-"${ZDIFF}" -N in -- -in-.lz > /dev/null || fail=1
-printf .
-"${ZDIFF}" -N -- -in- in.lz > /dev/null || fail=1
-printf .
-"${ZDIFF}" -N in.lz -- -in- > /dev/null || fail=1
-printf .
-"${ZDIFF}" -N -- -in-.lz in > /dev/null || fail=1
-printf .
-"${ZDIFF}" -N -- -in- in > /dev/null || fail=1
-printf .
-"${ZDIFF}" -N in -- -in- > /dev/null || fail=1
-printf .
-"${ZDIFF}" -N lz_only.lz < in > /dev/null || fail=1
-printf .
-"${ZDIFF}" -N in.lz - < in > /dev/null || fail=1
-printf .
-"${ZDIFF}" -N - in.lz < in > /dev/null || fail=1
-printf .
-"${ZDIFF}" -N in - < in.lz > /dev/null || fail=1
-printf .
-"${ZDIFF}" -N - in < in.lz > /dev/null || fail=1
-printf .
+"${ZDIFF}" -N in in6 > /dev/null && test_failed $LINENO
+"${ZDIFF}" -N in.tar pin.tar > /dev/null && test_failed $LINENO
+"${ZDIFF}" -N - || test_failed $LINENO
+"${ZDIFF}" -N in in || test_failed $LINENO
+"${ZDIFF}" -N in || test_failed $LINENO
+"${ZDIFF}" -N --format=gz,bz2 in || test_failed $LINENO
+"${ZDIFF}" -N --format=gz in || test_failed $LINENO
+"${ZDIFF}" -N in.lz in.gz > /dev/null || test_failed $LINENO
+"${ZDIFF}" -N --lz='lzip -q' in.lz in.gz > /dev/null || test_failed $LINENO
+"${ZDIFF}" -N in.gz -- -in-.lz > /dev/null || test_failed $LINENO
+"${ZDIFF}" -N -- -in-.lz in.gz > /dev/null || test_failed $LINENO
+"${ZDIFF}" -N in -- -in-.lz > /dev/null || test_failed $LINENO
+"${ZDIFF}" -N -- -in- in.lz > /dev/null || test_failed $LINENO
+"${ZDIFF}" -N in.lz -- -in- > /dev/null || test_failed $LINENO
+"${ZDIFF}" -N -- -in-.lz in > /dev/null || test_failed $LINENO
+"${ZDIFF}" -N -- -in- in > /dev/null || test_failed $LINENO
+"${ZDIFF}" -N in -- -in- > /dev/null || test_failed $LINENO
+"${ZDIFF}" -N lz_only.lz < in > /dev/null || test_failed $LINENO
+"${ZDIFF}" -N in.lz - < in > /dev/null || test_failed $LINENO
+"${ZDIFF}" -N - in.lz < in > /dev/null || test_failed $LINENO
+"${ZDIFF}" -N in - < in.lz > /dev/null || test_failed $LINENO
+"${ZDIFF}" -N - in < in.lz > /dev/null || test_failed $LINENO
"${ZDIFF}" -N --bz2='-bzip2' in.bz2 2> /dev/null
-if [ $? = 2 ] ; then printf . ; else printf - ; fail=1 ; fi
+[ $? = 2 ] || test_failed $LINENO
"${ZDIFF}" -N -q --force-format=bz2 in.bz2 2> /dev/null
-if [ $? = 2 ] ; then printf . ; else printf - ; fail=1 ; fi
+[ $? = 2 ] || test_failed $LINENO
"${ZDIFF}" -N -q --force-format=,lz in.lz in.bz2 > /dev/null 2>&1
r=$?
-if [ $r = 1 ] || [ $r = 2 ] ; then printf . ; else printf - ; fail=1 ; fi
+{ [ $r = 1 ] || [ $r = 2 ] ; } || test_failed $LINENO
"${ZDIFF}" -N --bad-option 2> /dev/null
-if [ $? = 2 ] ; then printf . ; else printf - ; fail=1 ; fi
+[ $? = 2 ] || test_failed $LINENO
mkdir tmp2
cat in > tmp2/a || framework_failure
cat in.lz > tmp2/a.lz || framework_failure
"${ZDIFF}" -N --format=bz2 tmp2/a < /dev/null > /dev/null
-if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi
+[ $? = 1 ] || test_failed $LINENO
"${ZDIFF}" -N --format=gz tmp2/a < /dev/null > /dev/null
-if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi
+[ $? = 1 ] || test_failed $LINENO
"${ZDIFF}" -N --format=lz tmp2/a.lz < /dev/null > /dev/null
-if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi
-"${ZDIFF}" -N --format=lz tmp2/a < /dev/null
-if [ $? = 0 ] ; then printf . ; else printf - ; fail=1 ; fi
-"${ZDIFF}" -N --format=un tmp2/a.lz < /dev/null
-if [ $? = 0 ] ; then printf . ; else printf - ; fail=1 ; fi
+[ $? = 1 ] || test_failed $LINENO
+"${ZDIFF}" -N --format=lz tmp2/a < /dev/null || test_failed $LINENO
+"${ZDIFF}" -N --format=un tmp2/a.lz < /dev/null || test_failed $LINENO
rm -r tmp2 || framework_failure
printf "\ntesting zgrep-%s..." "$2"
for i in ${extensions}; do
- "${ZGREP}" -N "GNU" in.$i > /dev/null || fail=1
- printf .
- "${ZGREP}" -N "GNU" < in.$i > /dev/null || fail=1
- printf .
- "${ZGREP}" -N -l "GNU" in.$i > /dev/null || fail=1
- printf .
- "${ZGREP}" -N -L "GNU" in.$i || fail=1
- printf .
- "${ZGREP}" -N --force-format=$i "GNU" in.$i > /dev/null || fail=1
- printf .
- "${ZGREP}" -N -v "nx_pattern" in.$i > /dev/null || fail=1
- printf .
- "${ZGREP}" -N "nx_pattern" in.$i
- if [ $? != 0 ] ; then printf . ; else printf - ; fail=1 ; fi
- "${ZGREP}" -N -l "nx_pattern" in.$i
- if [ $? != 0 ] ; then printf . ; else printf - ; fail=1 ; fi
- "${ZGREP}" -N -L "nx_pattern" in.$i > /dev/null
- if [ $? != 0 ] ; then printf . ; else printf - ; fail=1 ; fi
+ "${ZGREP}" -N "GNU" in.$i > /dev/null || test_failed $LINENO $i
+ "${ZGREP}" -N "GNU" < in.$i > /dev/null || test_failed $LINENO $i
+ "${ZGREP}" -N -l "GNU" in.$i > /dev/null || test_failed $LINENO $i
+ "${ZGREP}" -N -L "GNU" in.$i || test_failed $LINENO $i
+ "${ZGREP}" -N --force-format=$i "GNU" in.$i > /dev/null ||
+ test_failed $LINENO $i
+ "${ZGREP}" -N -v "nx_pattern" in.$i > /dev/null ||
+ test_failed $LINENO $i
+ "${ZGREP}" -N "nx_pattern" in.$i && test_failed $LINENO $i
+ "${ZGREP}" -N -l "nx_pattern" in.$i && test_failed $LINENO $i
+ "${ZGREP}" -N -L "nx_pattern" in.$i > /dev/null &&
+ test_failed $LINENO $i
"${ZGREP}" -N --force-format=$i "GNU" in 2> /dev/null
- if [ $? = 2 ] ; then printf . ; else printf - ; fail=1 ; fi
+ [ $? = 2 ] || test_failed $LINENO $i
done
-"${ZGREP}" -N pin.tar -e "GNU" > /dev/null || fail=1
-printf .
-"${ZGREP}" -N "GNU" < pin.tar > /dev/null || fail=1
-printf .
-"${ZGREP}" -N -r "GNU" . > /dev/null || fail=1
-printf .
-"${ZGREP}" -N "nx_pattern" -r . in > /dev/null
-if [ $? != 0 ] ; then printf . ; else printf - ; fail=1 ; fi
-"${ZGREP}" -N -e "GNU" in > /dev/null || fail=1
-printf .
-"${ZGREP}" -N "GNU" < in > /dev/null || fail=1
-printf .
-"${ZGREP}" -N -O lz "nx_pattern" - - < in.lz > /dev/null
-if [ $? != 0 ] ; then printf . ; else printf - ; fail=1 ; fi
-"${ZGREP}" -N -e "-free" --lz='lzip -q' < in.lz > /dev/null || fail=1
-printf .
-"${ZGREP}" -N -- "-free" -in- > /dev/null || fail=1
-printf .
-"${ZGREP}" -N -q -- "-free" nx_file -in-.lz
-if [ $? = 0 ] ; then printf . ; else printf - ; fail=1 ; fi
-"${ZGREP}" -N "GNU" in in.gz in.bz2 in.lz -- -in- > /dev/null || fail=1
-printf .
-"${ZGREP}" -N -l "GNU" in in.gz in.bz2 in.lz -- -in- > /dev/null || fail=1
-printf .
-"${ZGREP}" -N -L "GNU" in in.gz in.bz2 in.lz -- -in- || fail=1
-printf .
-"${ZGREP}" -N -l "nx_pattern" in in.gz in.bz2 in.lz -- -in-
-if [ $? != 0 ] ; then printf . ; else printf - ; fail=1 ; fi
-"${ZGREP}" -N -L "nx_pattern" in in.gz in.bz2 in.lz -- -in- > /dev/null
-if [ $? != 0 ] ; then printf . ; else printf - ; fail=1 ; fi
+"${ZGREP}" -N pin.tar -e "GNU" > /dev/null || test_failed $LINENO
+"${ZGREP}" -N "GNU" < pin.tar > /dev/null || test_failed $LINENO
+"${ZGREP}" -N -r "GNU" . > /dev/null || test_failed $LINENO
+"${ZGREP}" -N "nx_pattern" -r . in > /dev/null && test_failed $LINENO
+"${ZGREP}" -N -e "GNU" in > /dev/null || test_failed $LINENO
+"${ZGREP}" -N "GNU" < in > /dev/null || test_failed $LINENO
+"${ZGREP}" -N -O lz "nx_pattern" - - < in.lz > /dev/null && test_failed $LINENO
+"${ZGREP}" -N -e "-free" --lz='lzip -q' < in.lz > /dev/null ||
+ test_failed $LINENO
+"${ZGREP}" -N -- "-free" -in- > /dev/null || test_failed $LINENO
+"${ZGREP}" -N -q -- "-free" nx_file -in-.lz || test_failed $LINENO
+"${ZGREP}" -N "GNU" in in.gz in.bz2 in.lz -- -in- > /dev/null ||
+ test_failed $LINENO
+"${ZGREP}" -N -l "GNU" in in.gz in.bz2 in.lz -- -in- > /dev/null ||
+ test_failed $LINENO
+"${ZGREP}" -N -L "GNU" in in.gz in.bz2 in.lz -- -in- || test_failed $LINENO
+"${ZGREP}" -N -l "nx_pattern" in in.gz in.bz2 in.lz -- -in- &&
+ test_failed $LINENO
+"${ZGREP}" -N -L "nx_pattern" in in.gz in.bz2 in.lz -- -in- > /dev/null &&
+ test_failed $LINENO
"${ZGREP}" -N --bad-option 2> /dev/null
-if [ $? = 2 ] ; then printf . ; else printf - ; fail=1 ; fi
+[ $? = 2 ] || test_failed $LINENO
"${ZGREP}" -N "GNU" -s nx_file
-if [ $? = 2 ] ; then printf . ; else printf - ; fail=1 ; fi
+[ $? = 2 ] || test_failed $LINENO
"${ZGREP}" -N -q
-if [ $? = 2 ] ; then printf . ; else printf - ; fail=1 ; fi
+[ $? = 2 ] || test_failed $LINENO
-"${ZEGREP}" -N "GNU" in > /dev/null || fail=1
-printf .
-"${ZFGREP}" -N "GNU" in > /dev/null || fail=1
-printf .
+"${ZEGREP}" -N "GNU" in > /dev/null || test_failed $LINENO
+"${ZFGREP}" -N "GNU" in > /dev/null || test_failed $LINENO
printf "\ntesting ztest-%s..." "$2"
for i in ${extensions}; do
- "${ZTEST}" -N --force-format=$i < in.$i || fail=1
- printf .
+ "${ZTEST}" -N --force-format=$i < in.$i || test_failed $LINENO $i
"${ZTEST}" -N --force-format=$i < in 2> /dev/null
- if [ $? = 2 ] ; then printf . ; else printf - ; fail=1 ; fi
+ [ $? = 2 ] || test_failed $LINENO $i
"${ZTEST}" -N --force-format=$i in 2> /dev/null
- if [ $? = 2 ] ; then printf . ; else printf - ; fail=1 ; fi
+ [ $? = 2 ] || test_failed $LINENO $i
done
-"${ZTEST}" -N in in.gz in.bz2 in.lz -- -in- || fail=1
-printf .
-"${ZTEST}" -N < in.gz || fail=1
-printf .
-"${ZTEST}" -N < in.bz2 || fail=1
-printf .
-"${ZTEST}" -N < in.lz || fail=1
-printf .
-"${ZTEST}" -N - in.gz - < in.lz || fail=1
-printf .
-"${ZTEST}" -N --lz='lzip -q' < in.lz || fail=1
-printf .
-"${ZTEST}" -N -r . || fail=1
-printf .
+"${ZTEST}" -N in in.gz in.bz2 in.lz -- -in- || test_failed $LINENO
+"${ZTEST}" -N < in.gz || test_failed $LINENO
+"${ZTEST}" -N < in.bz2 || test_failed $LINENO
+"${ZTEST}" -N < in.lz || test_failed $LINENO
+"${ZTEST}" -N - in.gz - < in.lz || test_failed $LINENO
+"${ZTEST}" -N --lz='lzip -q' < in.lz || test_failed $LINENO
+"${ZTEST}" -N -r . || test_failed $LINENO
"${ZTEST}" -Nq < in
-if [ $? = 2 ] ; then printf . ; else printf - ; fail=1 ; fi
+[ $? = 2 ] || test_failed $LINENO
dd if=in.lz bs=1000 count=1 2> /dev/null | "${ZTEST}" -N -q
-if [ $? = 2 ] ; then printf . ; else printf - ; fail=1 ; fi
+[ $? = 2 ] || test_failed $LINENO
"${ZTEST}" -Nq --force-format=lz in.bz2
-if [ $? = 2 ] ; then printf . ; else printf - ; fail=1 ; fi
+[ $? = 2 ] || test_failed $LINENO
"${ZTEST}" -N --lz='lzip --bad-option' in.lz 2> /dev/null
-if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi
+[ $? = 1 ] || test_failed $LINENO
"${ZTEST}" -N --bad-option 2> /dev/null
-if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi
+[ $? = 1 ] || test_failed $LINENO
printf "\ntesting zupdate-%s..." "$2"
@@ -396,68 +314,59 @@ printf "\ntesting zupdate-%s..." "$2"
cat in.bz2 > a.bz2 || framework_failure
cat in.gz > a.gz || framework_failure
"${ZUPDATE}" -Nq --bz2=bad_command a.bz2
-if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi
+[ $? = 1 ] || test_failed $LINENO
"${ZUPDATE}" -N --bz2='bzip2 --bad-option' a.bz2 > /dev/null 2>&1
-if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi
+[ $? = 1 ] || test_failed $LINENO
"${ZUPDATE}" -Nq --gz=bad_command a.gz
-if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi
+[ $? = 1 ] || test_failed $LINENO
"${ZUPDATE}" -N --gz='gzip --bad-option' a.gz 2> /dev/null
-if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi
+[ $? = 1 ] || test_failed $LINENO
"${ZUPDATE}" -Nq --lz=bad_command a.gz
-if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi
+[ $? = 1 ] || test_failed $LINENO
"${ZUPDATE}" -N --lz='lzip --bad-option' a.gz 2> /dev/null
-if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi
+[ $? = 1 ] || test_failed $LINENO
"${ZUPDATE}" -N --bad-option 2> /dev/null
-if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi
+[ $? = 1 ] || test_failed $LINENO
cat in.lz in.lz > a.lz || framework_failure
"${ZUPDATE}" -Nq -f a.bz2 a.gz
-if [ $? = 1 ] && [ -e a.bz2 ] && [ -e a.gz ] && [ -e a.lz ] ; then printf .
-else printf - ; fail=1
-fi
+{ [ $? = 1 ] && [ -e a.bz2 ] && [ -e a.gz ] && [ -e a.lz ] ; } ||
+ test_failed $LINENO
rm -f a.lz || framework_failure
"${ZUPDATE}" -N a.bz2
-if [ $? = 0 ] && [ ! -e a.bz2 ] && [ -e a.gz ] && [ -e a.lz ] ; then printf .
-else printf - ; fail=1
-fi
+{ [ $? = 0 ] && [ ! -e a.bz2 ] && [ -e a.gz ] && [ -e a.lz ] ; } ||
+ test_failed $LINENO
rm -f a.lz || framework_failure
"${ZUPDATE}" -N a.gz
-if [ $? = 0 ] && [ ! -e a.bz2 ] && [ ! -e a.gz ] && [ -e a.lz ] ; then printf .
-else printf - ; fail=1
-fi
+{ [ $? = 0 ] && [ ! -e a.bz2 ] && [ ! -e a.gz ] && [ -e a.lz ] ; } ||
+ test_failed $LINENO
rm -f a.lz || framework_failure
cat in.bz2 > a.bz2 || framework_failure
cat in.gz > a.gz || framework_failure
"${ZUPDATE}" -Nq a.bz2 a.gz
-if [ $? = 1 ] && [ ! -e a.bz2 ] && [ -e a.gz ] && [ -e a.lz ] ; then printf .
-else printf - ; fail=1
-fi
+{ [ $? = 1 ] && [ ! -e a.bz2 ] && [ -e a.gz ] && [ -e a.lz ] ; } ||
+ test_failed $LINENO
rm -f a.lz || framework_failure
cat in.bz2 > a.bz2 || framework_failure
cat in.gz > a.gz || framework_failure
"${ZUPDATE}" -N -f -k a.bz2 a.gz
-if [ $? = 0 ] && [ -e a.bz2 ] && [ -e a.gz ] && [ -e a.lz ] ; then printf .
-else printf - ; fail=1
-fi
+{ [ $? = 0 ] && [ -e a.bz2 ] && [ -e a.gz ] && [ -e a.lz ] ; } ||
+ test_failed $LINENO
rm -f a.lz || framework_failure
cat in.bz2 > a.bz2 || framework_failure
cat in.gz > a.gz || framework_failure
"${ZUPDATE}" -N -f a.bz2 a.gz
-if [ $? = 0 ] && [ ! -e a.bz2 ] && [ ! -e a.gz ] &&
- [ ! -e a ] && [ -e a.lz ] ; then printf .
-else printf - ; fail=1
-fi
+{ [ $? = 0 ] && [ ! -e a.bz2 ] && [ ! -e a.gz ] && [ ! -e a ] &&
+ [ -e a.lz ] ; } || test_failed $LINENO
rm -f a.lz || framework_failure
cat in.bz2 > a.bz2 || framework_failure
"${ZUPDATE}" -N -1 -q a.bz2
-if [ $? = 0 ] && [ ! -e a.bz2 ] && [ -e a.lz ] ; then printf .
-else printf - ; fail=1
-fi
+{ [ $? = 0 ] && [ ! -e a.bz2 ] && [ -e a.lz ] ; } || test_failed $LINENO
rm -f a.lz || framework_failure
mkdir tmp2
@@ -465,16 +374,12 @@ mkdir tmp2/tmp3
cat in.bz2 > tmp2/tmp3/a.bz2 || framework_failure
cat in.gz > tmp2/tmp3/a.gz || framework_failure
"${ZUPDATE}" -N -r --format=gz tmp2
-if [ $? = 0 ] && [ -e tmp2/tmp3/a.bz2 ] && [ ! -e tmp2/tmp3/a.gz ] &&
- [ -e tmp2/tmp3/a.lz ] ; then printf .
-else printf - ; fail=1
-fi
+{ [ $? = 0 ] && [ -e tmp2/tmp3/a.bz2 ] && [ ! -e tmp2/tmp3/a.gz ] &&
+ [ -e tmp2/tmp3/a.lz ] ; } || test_failed $LINENO
rm -f tmp2/tmp3/a.lz || framework_failure
"${ZUPDATE}" -N -r --format=bz2 tmp2
-if [ $? = 0 ] && [ ! -e tmp2/tmp3/a.bz2 ] && [ ! -e tmp2/tmp3/a.gz ] &&
- [ -e tmp2/tmp3/a.lz ] ; then printf .
-else printf - ; fail=1
-fi
+{ [ $? = 0 ] && [ ! -e tmp2/tmp3/a.bz2 ] && [ ! -e tmp2/tmp3/a.gz ] &&
+ [ -e tmp2/tmp3/a.lz ] ; } || test_failed $LINENO
rm -r tmp2 || framework_failure
echo
diff --git a/zcat.cc b/zcat.cc
index 98081c3..aba5e54 100644
--- a/zcat.cc
+++ b/zcat.cc
@@ -1,5 +1,5 @@
/* Zcat - decompress and concatenate files to standard output
- Copyright (C) 2010-2016 Antonio Diaz Diaz.
+ Copyright (C) 2010-2017 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -94,7 +94,7 @@ void show_help()
"compressed, its decompressed content is used. If a given file does not\n"
"exist, and its name does not end with one of the known extensions, zcat\n"
"tries the compressed file names corresponding to the supported formats.\n"
- "\nIf no files are specified, or if a file is specified as '-', data is\n"
+ "\nIf no files are specified, or if a file is specified as '-', data are\n"
"read from standard input, decompressed if needed, and sent to standard\n"
"output. Data read from standard input must be of the same type; all\n"
"uncompressed or all in the same compression format.\n"
@@ -233,7 +233,8 @@ int cat( int infd, const int format_index, const std::string & input_filename,
uint8_t * const outbuf = new uint8_t[(4*buffer_size)+256];
int retval = 0;
Children children;
- if( !set_data_feeder( &infd, children, format_index ) ) retval = 1;
+ if( !set_data_feeder( input_filename, &infd, children, format_index ) )
+ retval = 1;
else
retval = do_cat( infd, buffer_size, inbuf, outbuf,
input_filename, cat_options );
diff --git a/zcatgrep.cc b/zcatgrep.cc
index d1e2d81..5b08b78 100644
--- a/zcatgrep.cc
+++ b/zcatgrep.cc
@@ -1,5 +1,5 @@
/* Common code for zcat and zgrep
- Copyright (C) 2010-2016 Antonio Diaz Diaz.
+ Copyright (C) 2010-2017 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/zcmp.cc b/zcmp.cc
index 1cbd384..78debcc 100644
--- a/zcmp.cc
+++ b/zcmp.cc
@@ -1,5 +1,5 @@
/* Zcmp - decompress and compare two files byte by byte
- Copyright (C) 2010-2016 Antonio Diaz Diaz.
+ Copyright (C) 2010-2017 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -57,21 +57,21 @@ void show_help()
"fly; no temporary files are created.\n"
"\nThe supported formats are bzip2, gzip, lzip and xz.\n"
"\nUsage: zcmp [options] file1 [file2]\n"
- "\nCompares <file1> to <file2>. If <file2> is omitted zcmp tries the\n"
+ "\nZcmp compares file1 to file2. If file2 is omitted zcmp tries the\n"
"following:\n"
- "\n 1. If <file1> is compressed, compares its decompressed contents with\n"
- " the corresponding uncompressed file (the name of <file1> with the\n"
+ "\n 1. If file1 is compressed, compares its decompressed contents with\n"
+ " the corresponding uncompressed file (the name of file1 with the\n"
" extension removed).\n"
- "\n 2. If <file1> is uncompressed, compares it with the decompressed\n"
- " contents of <file1>.[lz|bz2|gz|xz] (the first one that is found).\n"
- "\n 3. If no suitable file is found, compares <file1> with data read from\n"
+ "\n 2. If file1 is uncompressed, compares it with the decompressed\n"
+ " contents of file1.[lz|bz2|gz|xz] (the first one that is found).\n"
+ "\n 3. If no suitable file is found, compares file1 with data read from\n"
" standard input.\n"
"\nExit status is 0 if inputs are identical, 1 if different, 2 if trouble.\n"
"\nOptions:\n"
" -h, --help display this help and exit\n"
" -V, --version output version information and exit\n"
" -b, --print-bytes print differing bytes\n"
- " -i, --ignore-initial=<n>[,<n2>] ignore differences in the first <n> bytes\n"
+ " -i, --ignore-initial=<n>[:<n2>] ignore differences in the first <n> bytes\n"
" -l, --list list position, value of all differing bytes\n"
" -M, --format=<list> process only the formats in <list>\n"
" -n, --bytes=<n> compare at most <n> bytes\n"
@@ -94,8 +94,8 @@ long long getnum( const char * const ptr, const char ** const tailp = 0,
const long long llimit = 0,
const long long ulimit = LLONG_MAX )
{
- errno = 0;
char * tail;
+ errno = 0;
long long result = strtoll( ptr, &tail, 0 );
if( tail == ptr )
{
@@ -106,9 +106,13 @@ long long getnum( const char * const ptr, const char ** const tailp = 0,
if( !errno && tail[0] && std::isalpha( tail[0] ) )
{
- const int factor = ( tail[1] == 'i' ) ? 1024 : 1000;
- int exponent = 0; // 0 = bad multiplier
- switch( tail[0] )
+ const unsigned char ch = *tail++;
+ int factor;
+ bool bsuf; // 'B' suffix is present
+ if( tail[0] == 'i' ) { ++tail; factor = 1024; } else factor = 1000;
+ if( tail[0] == 'B' ) { ++tail; bsuf = true; } else bsuf = false;
+ int exponent = -1; // -1 = bad multiplier
+ switch( ch )
{
case 'Y': exponent = 8; break;
case 'Z': exponent = 7; break;
@@ -119,8 +123,9 @@ long long getnum( const char * const ptr, const char ** const tailp = 0,
case 'M': exponent = 2; break;
case 'K': if( factor == 1024 ) exponent = 1; break;
case 'k': if( factor == 1000 ) exponent = 1; break;
+ case 'B': if( factor == 1000 && !bsuf ) exponent = 0; break;
}
- if( exponent <= 0 )
+ if( exponent < 0 )
{
show_error( "Bad multiplier in numerical argument.", 0, true );
std::exit( 2 );
@@ -146,9 +151,14 @@ void parse_ignore_initial( const char * const arg, long long ignore_initial[2] )
{
const char * tail;
ignore_initial[0] = getnum( arg, &tail );
- if( *tail == ',' || *tail == ':' )
+ if( *tail == ':' || *tail == ',' )
ignore_initial[1] = getnum( ++tail );
- else ignore_initial[1] = ignore_initial[0];
+ else if( *tail == 0 ) ignore_initial[1] = ignore_initial[0];
+ else
+ {
+ show_error( "Bad separator in argument of '--ignore-initial'", 0, true );
+ std::exit( 2 );
+ }
}
@@ -418,8 +428,8 @@ int main( const int argc, const char * const argv[] )
int old_infd[2]; // copy of file descriptors of the two files
old_infd[0] = infd[0]; old_infd[1] = infd[1];
Children children[2];
- if( !set_data_feeder( &infd[0], children[0], format_types[0] ) ||
- !set_data_feeder( &infd[1], children[1], format_types[1] ) )
+ if( !set_data_feeder( filenames[0], &infd[0], children[0], format_types[0] ) ||
+ !set_data_feeder( filenames[1], &infd[1], children[1], format_types[1] ) )
return 2;
for( int i = 0; i < 2; ++i )
diff --git a/zcmpdiff.cc b/zcmpdiff.cc
index 6de2eac..013a2d9 100644
--- a/zcmpdiff.cc
+++ b/zcmpdiff.cc
@@ -1,5 +1,5 @@
/* Common code for zcmp and zdiff
- Copyright (C) 2010-2016 Antonio Diaz Diaz.
+ Copyright (C) 2010-2017 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/zdiff.cc b/zdiff.cc
index 26a7365..735eb0b 100644
--- a/zdiff.cc
+++ b/zdiff.cc
@@ -1,5 +1,5 @@
/* Zdiff - decompress and compare two files line by line
- Copyright (C) 2010-2016 Antonio Diaz Diaz.
+ Copyright (C) 2010-2017 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -55,14 +55,14 @@ void show_help()
"temporary filenames instead of those specified.\n"
"\nThe supported formats are bzip2, gzip, lzip and xz.\n"
"\nUsage: zdiff [options] file1 [file2]\n"
- "\nCompares <file1> to <file2>. If <file2> is omitted zdiff tries the\n"
+ "\nZdiff compares file1 to file2. If file2 is omitted zdiff tries the\n"
"following:\n"
- "\n 1. If <file1> is compressed, compares its decompressed contents with\n"
- " the corresponding uncompressed file (the name of <file1> with the\n"
+ "\n 1. If file1 is compressed, compares its decompressed contents with\n"
+ " the corresponding uncompressed file (the name of file1 with the\n"
" extension removed).\n"
- "\n 2. If <file1> is uncompressed, compares it with the decompressed\n"
- " contents of <file1>.[lz|bz2|gz|xz] (the first one that is found).\n"
- "\n 3. If no suitable file is found, compares <file1> with data read from\n"
+ "\n 2. If file1 is uncompressed, compares it with the decompressed\n"
+ " contents of file1.[lz|bz2|gz|xz] (the first one that is found).\n"
+ "\n 3. If no suitable file is found, compares file1 with data read from\n"
" standard input.\n"
"\nExit status is 0 if inputs are identical, 1 if different, 2 if trouble.\n"
"\nOptions:\n"
@@ -148,7 +148,8 @@ bool set_fifonames( const std::string filenames[2] )
}
-bool set_data_feeder( const std::string & fifoname, const int infd,
+bool set_data_feeder( const std::string & filename,
+ const std::string & fifoname, const int infd,
Children & children, int format_index )
{
const uint8_t * magic_data = 0;
@@ -166,7 +167,7 @@ bool set_data_feeder( const std::string & fifoname, const int infd,
if( pid == 0 ) // child 1 (compressor feeder)
{
if( close( fda[0] ) != 0 ||
- !feed_data( infd, fda[1], magic_data, magic_size ) )
+ !feed_data( filename, infd, fda[1], magic_data, magic_size ) )
_exit( 2 );
if( close( fda[1] ) != 0 )
{ show_close_error(); _exit( 2 ); }
@@ -225,7 +226,7 @@ bool set_data_feeder( const std::string & fifoname, const int infd,
program_name, fifoname.c_str(), std::strerror( errno ) );
_exit( 2 );
}
- if( !feed_data( infd, outfd, magic_data, magic_size ) )
+ if( !feed_data( filename, infd, outfd, magic_data, magic_size ) )
_exit( 2 );
if( close( outfd ) != 0 )
{ show_close_error(); _exit( 2 ); }
@@ -386,8 +387,10 @@ int main( const int argc, const char * const argv[] )
if( !set_fifonames( filenames ) ) return 2;
Children children[2];
- if( !set_data_feeder( fifonames[0], infd[0], children[0], format_types[0] ) ||
- !set_data_feeder( fifonames[1], infd[1], children[1], format_types[1] ) )
+ if( !set_data_feeder( filenames[0], fifonames[0], infd[0], children[0],
+ format_types[0] ) ||
+ !set_data_feeder( filenames[1], fifonames[1], infd[1], children[1],
+ format_types[1] ) )
return 2;
const pid_t diff_pid = fork();
diff --git a/zgrep.cc b/zgrep.cc
index 6c8ceb1..5bcb968 100644
--- a/zgrep.cc
+++ b/zgrep.cc
@@ -1,5 +1,5 @@
/* Zgrep - search compressed files for a regular expression
- Copyright (C) 2010-2016 Antonio Diaz Diaz.
+ Copyright (C) 2010-2017 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -53,7 +53,7 @@ void show_help()
"does not exist, and its name does not end with one of the known\n"
"extensions, zgrep tries the compressed file names corresponding to the\n"
"supported formats.\n"
- "\nIf no files are specified, or if a file is specified as '-', data is\n"
+ "\nIf no files are specified, or if a file is specified as '-', data are\n"
"read from standard input, decompressed if needed, and fed to grep. Data\n"
"read from standard input must be of the same type; all uncompressed or\n"
"all in the same compression format.\n"
@@ -106,7 +106,7 @@ int zgrep_stdin( int infd, const int format_index,
const std::vector< const char * > & grep_args )
{
Children children;
- if( !set_data_feeder( &infd, children, format_index ) ) return 2;
+ if( !set_data_feeder( "", &infd, children, format_index ) ) return 2;
const pid_t grep_pid = fork();
if( grep_pid == 0 ) // child (grep)
{
@@ -141,7 +141,8 @@ int zgrep_file( int infd, const int format_index,
const int list_mode, const bool show_name )
{
Children children;
- if( !set_data_feeder( &infd, children, format_index ) ) return 2;
+ if( !set_data_feeder( input_filename, &infd, children, format_index ) )
+ return 2;
int fda[2]; // pipe from grep
if( pipe( fda ) < 0 )
{ show_error( "Can't create pipe", errno ); return 2; }
diff --git a/ztest.cc b/ztest.cc
index 8d9d8cd..6f0d209 100644
--- a/ztest.cc
+++ b/ztest.cc
@@ -1,5 +1,5 @@
-/* Ztest - verify integrity of compressed files
- Copyright (C) 2010-2016 Antonio Diaz Diaz.
+/* Ztest - verify the integrity of compressed files
+ Copyright (C) 2010-2017 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -56,8 +56,12 @@ void show_help()
"input is verified. Data read from standard input must be all in the same\n"
"compression format.\n"
"\nThe supported formats are bzip2, gzip, lzip and xz.\n"
- "\nNote that some xz files lack integrity information, and therefore can't\n"
- "be verified as reliably as the other formats can.\n"
+ "\nNote that error detection in the xz format is broken. First, some xz\n"
+ "files lack integrity information. Second, not all xz decompressors can\n"
+ "verify the integrity of all xz files. Third, section 2.1.1.2 'Stream\n"
+ "Flags' of the xz format specification allows xz decompressors to produce\n"
+ "garbage output without issuing any warning. Therefore, xz files can't\n"
+ "always be verified as reliably as files in the other formats can.\n"
"\nUsage: ztest [options] [files]\n"
"\nExit status is 0 if all compressed files verify OK, 1 if environmental\n"
"problems (file not found, invalid flags, I/O errors, etc), 2 if any\n"
@@ -106,7 +110,7 @@ int ztest_stdin( const int infd, int format_index,
if( pid == 0 ) // child1 (compressor feeder)
{
if( close( fda[0] ) != 0 ||
- !feed_data( infd, fda[1], magic_data, magic_size ) )
+ !feed_data( "", infd, fda[1], magic_data, magic_size ) )
_exit( 1 );
if( close( fda[1] ) != 0 )
{ show_close_error(); _exit( 1 ); }
diff --git a/zupdate.cc b/zupdate.cc
index 7f08504..14e15f8 100644
--- a/zupdate.cc
+++ b/zupdate.cc
@@ -1,5 +1,5 @@
/* Zupdate - recompress bzip2, gzip, xz files to lzip format
- Copyright (C) 2013-2016 Antonio Diaz Diaz.
+ Copyright (C) 2013-2017 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/zutils.cc b/zutils.cc
index 460ceec..536a5bd 100644
--- a/zutils.cc
+++ b/zutils.cc
@@ -1,5 +1,5 @@
/* Zutils - Utilities dealing with compressed files
- Copyright (C) 2009-2016 Antonio Diaz Diaz.
+ Copyright (C) 2009-2017 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -112,7 +112,9 @@ int writeblock( const int fd, const uint8_t * const buf, const int size )
}
-bool feed_data( const int infd, const int outfd,
+// Empty filename means stdin.
+//
+bool feed_data( const std::string & filename, const int infd, const int outfd,
const uint8_t * magic_data, const int magic_size )
{
if( magic_size && writeblock( outfd, magic_data, magic_size ) != magic_size )
@@ -123,7 +125,8 @@ bool feed_data( const int infd, const int outfd,
{
const int size = readblock( infd, buffer, buffer_size );
if( size != buffer_size && errno )
- { show_error( "Read error", errno ); return false; }
+ { const char * const name = filename.empty() ? "-" : filename.c_str();
+ show_file_error( name, "Read error", errno ); return false; }
if( size > 0 && writeblock( outfd, buffer, size ) != size )
{ show_error( "Write error", errno ); return false; }
if( size < buffer_size ) break;
@@ -156,7 +159,8 @@ bool good_status( const Children & children, const bool finished )
}
-bool set_data_feeder( int * const infdp, Children & children, int format_index )
+bool set_data_feeder( const std::string & filename, int * const infdp,
+ Children & children, int format_index )
{
const uint8_t * magic_data = 0;
int magic_size = 0;
@@ -177,7 +181,7 @@ bool set_data_feeder( int * const infdp, Children & children, int format_index )
{
if( close( fda[0] ) != 0 ||
close( fda2[0] ) != 0 || close( fda2[1] ) != 0 ||
- !feed_data( old_infd, fda[1], magic_data, magic_size ) )
+ !feed_data( filename, old_infd, fda[1], magic_data, magic_size ) )
_exit( 2 );
if( close( fda[1] ) != 0 )
{ show_close_error(); _exit( 2 ); }
@@ -226,7 +230,7 @@ bool set_data_feeder( int * const infdp, Children & children, int format_index )
if( pid == 0 ) // child (feeder)
{
if( close( fda[0] ) != 0 ||
- !feed_data( old_infd, fda[1], magic_data, magic_size ) )
+ !feed_data( filename, old_infd, fda[1], magic_data, magic_size ) )
_exit( 2 );
if( close( fda[1] ) != 0 )
{ show_close_error(); _exit( 2 ); }
diff --git a/zutils.h b/zutils.h
index d91ca52..f5d57b5 100644
--- a/zutils.h
+++ b/zutils.h
@@ -1,5 +1,5 @@
/* Zutils - Utilities dealing with compressed files
- Copyright (C) 2009-2016 Antonio Diaz Diaz.
+ Copyright (C) 2009-2017 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -17,7 +17,7 @@
int readblock( const int fd, uint8_t * const buf, const int size );
int writeblock( const int fd, const uint8_t * const buf, const int size );
-bool feed_data( const int infd, const int outfd,
+bool feed_data( const std::string & filename, const int infd, const int outfd,
const uint8_t * magic_data, const int magic_size );
struct Children
@@ -26,7 +26,8 @@ struct Children
pid_t pid[2]; // data feeder, compressor
};
bool good_status( const Children & children, const bool finished );
-bool set_data_feeder( int * const infdp, Children & children, int format_index );
+bool set_data_feeder( const std::string & filename, int * const infdp,
+ Children & children, int format_index );
// Returns format index or -1 if uncompressed
//