diff options
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | INSTALL | 2 | ||||
-rw-r--r-- | Makefile.in | 10 | ||||
-rw-r--r-- | NEWS | 11 | ||||
-rw-r--r-- | README | 10 | ||||
-rw-r--r-- | arg_parser.cc | 16 | ||||
-rw-r--r-- | arg_parser.h | 5 | ||||
-rwxr-xr-x | configure | 21 | ||||
-rw-r--r-- | doc/zcat.1 | 6 | ||||
-rw-r--r-- | doc/zcmp.1 | 18 | ||||
-rw-r--r-- | doc/zdiff.1 | 16 | ||||
-rw-r--r-- | doc/zgrep.1 | 6 | ||||
-rw-r--r-- | doc/ztest.1 | 14 | ||||
-rw-r--r-- | doc/zupdate.1 | 4 | ||||
-rw-r--r-- | doc/zutils.info | 60 | ||||
-rw-r--r-- | doc/zutils.texi | 33 | ||||
-rw-r--r-- | rc.cc | 22 | ||||
-rw-r--r-- | rc.h | 6 | ||||
-rw-r--r-- | recursive.cc | 2 | ||||
-rwxr-xr-x | testsuite/check.sh | 509 | ||||
-rw-r--r-- | zcat.cc | 7 | ||||
-rw-r--r-- | zcatgrep.cc | 2 | ||||
-rw-r--r-- | zcmp.cc | 44 | ||||
-rw-r--r-- | zcmpdiff.cc | 2 | ||||
-rw-r--r-- | zdiff.cc | 27 | ||||
-rw-r--r-- | zgrep.cc | 9 | ||||
-rw-r--r-- | ztest.cc | 14 | ||||
-rw-r--r-- | zupdate.cc | 2 | ||||
-rw-r--r-- | zutils.cc | 16 | ||||
-rw-r--r-- | zutils.h | 7 |
30 files changed, 436 insertions, 473 deletions
@@ -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 @@ -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 @@ -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. @@ -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_; @@ -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 @@ -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. @@ -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: @@ -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 ) @@ -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 @@ -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 @@ -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 @@ -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(); @@ -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; } @@ -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 ); } @@ -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 @@ -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 ); } @@ -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 // |