1
0
Fork 0

Merging upstream version 1.14~rc1.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-24 06:04:53 +01:00
parent 1ef198b95d
commit acae34f9f5
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
26 changed files with 387 additions and 232 deletions

View file

@ -1,8 +1,7 @@
GNU GENERAL PUBLIC LICENSE GNU GENERAL PUBLIC LICENSE
Version 2, June 1991 Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc., Copyright (C) 1989, 1991 Free Software Foundation, Inc. <http://fsf.org/>
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed. of this license document, but changing it is not allowed.

View file

@ -1,3 +1,10 @@
2024-11-29 Antonio Diaz Diaz <antonio@gnu.org>
* Version 1.14-rc1 released.
* zupdate.cc: '-r -d' now keeps last component of dir arguments.
* zutils.texi: New chapter 'Syntax of command-line arguments'.
* check.sh: Use 'cp' instead of 'cat'.
2024-01-23 Antonio Diaz Diaz <antonio@gnu.org> 2024-01-23 Antonio Diaz Diaz <antonio@gnu.org>
* Version 1.13 released. * Version 1.13 released.
@ -110,7 +117,7 @@
* zdiff.cc (set_fifonames): Use '_' if both names are different. * zdiff.cc (set_fifonames): Use '_' if both names are different.
* configure: Avoid warning on some shells when testing for g++. * configure: Avoid warning on some shells when testing for g++.
* Makefile.in: Detect the existence of install-info. * Makefile.in: Detect the existence of install-info.
* check.sh: A POSIX shell is required to run the tests. * check.sh: Require a POSIX shell.
2015-05-29 Antonio Diaz Diaz <antonio@gnu.org> 2015-05-29 Antonio Diaz Diaz <antonio@gnu.org>

View file

@ -3,8 +3,8 @@ DISTNAME = $(pkgname)-$(pkgversion)
INSTALL = install INSTALL = install
INSTALL_PROGRAM = $(INSTALL) -m 755 INSTALL_PROGRAM = $(INSTALL) -m 755
INSTALL_SCRIPT = $(INSTALL) -m 755 INSTALL_SCRIPT = $(INSTALL) -m 755
INSTALL_DATA = $(INSTALL) -m 644
INSTALL_DIR = $(INSTALL) -d -m 755 INSTALL_DIR = $(INSTALL) -d -m 755
INSTALL_DATA = $(INSTALL) -m 644
SHELL = /bin/sh SHELL = /bin/sh
CAN_RUN_INSTALLINFO = $(SHELL) -c "install-info --version" > /dev/null 2>&1 CAN_RUN_INSTALLINFO = $(SHELL) -c "install-info --version" > /dev/null 2>&1
@ -68,7 +68,8 @@ zgrep.o : zgrep.cc
# prevent 'make' from trying to remake source files # prevent 'make' from trying to remake source files
$(VPATH)/configure $(VPATH)/Makefile.in $(VPATH)/doc/$(pkgname).texi : ; $(VPATH)/configure $(VPATH)/Makefile.in $(VPATH)/doc/$(pkgname).texi : ;
%.h %.cc : ; MAKEFLAGS += -r
.SUFFIXES :
$(objs) : Makefile $(objs) : Makefile
$(scripts) : Makefile $(scripts) : Makefile

22
NEWS
View file

@ -1,18 +1,8 @@
Changes in version 1.13: Changes in version 1.14:
The detection of bzip2 files with no compressed blocks has been fixed. 'zupdate --recursive --destdir=dir' now keeps the file name component
(Error introduced in version 1.9). following the last slash in directory arguments;
'../a' recompresses the file ../a/b.gz to dir/a/b.lz, while
'../a/' recompresses the file ../a/b.gz to dir/b.lz.
When zcat, zcmp, zdiff, or zgrep need to try compressed file names, gzip The chapter 'Syntax of command-line arguments' has been added to the manual.
(.gz) is now tried before bzip2 (.bz2).
When only one compressed file is passed to zcmp or zdiff, they now try to
compare it with a compressed file of any of the remaining formats if the
corresponding uncompressed file does not exist.
zcmp now reports EOF on empty file like GNU cmp:
"zcmp: EOF on FILE which is empty".
File diagnostics in zupdate have been reformatted as 'PROGRAM: FILE: MESSAGE'.
The variable MAKEINFO has been added to configure and Makefile.in.

9
README
View file

@ -1,3 +1,5 @@
See the file INSTALL for compilation and installation instructions.
Description Description
Zutils is a collection of utilities able to process any combination of Zutils is a collection of utilities able to process any combination of
@ -8,8 +10,8 @@ created. Data format is detected by its identifier string (magic bytes), not
by the file name extension. Empty files are considered uncompressed. by the file name extension. Empty files are considered uncompressed.
These utilities are not wrapper scripts but safer and more efficient C++ These utilities are not wrapper scripts but safer and more efficient C++
programs. In particular the option '--recursive' is very efficient in programs. In particular the option '--recursive' is efficient in those
those utilities supporting it. utilities supporting it.
The utilities provided are zcat, zcmp, zdiff, zgrep, ztest, and zupdate. The utilities provided are zcat, zcmp, zdiff, zgrep, ztest, and zupdate.
The formats supported are bzip2, gzip, lzip, xz, and zstd. The formats supported are bzip2, gzip, lzip, xz, and zstd.
@ -39,6 +41,9 @@ LANGUAGE NOTE: Uncompressed = not compressed = plain data; it may never have
been compressed. Decompressed is used to refer to data which have undergone been compressed. Decompressed is used to refer to data which have undergone
the process of decompression. the process of decompression.
Zutils uses Arg_parser for command-line argument parsing:
http://www.nongnu.org/arg-parser/arg_parser.html
Copyright (C) 2009-2024 Antonio Diaz Diaz. Copyright (C) 2009-2024 Antonio Diaz Diaz.

View file

@ -75,19 +75,19 @@ bool Arg_parser::parse_long_option( const char * const opt, const char * const a
error_ += "' requires an argument"; error_ += "' requires an argument";
return false; return false;
} }
data.back().argument = &opt[len+3]; data.back().argument = &opt[len+3]; // argument may be empty
return true; return true;
} }
if( options[index].has_arg == yes ) if( options[index].has_arg == yes || options[index].has_arg == yme )
{ {
if( !arg || !arg[0] ) if( !arg || ( options[index].has_arg == yes && !arg[0] ) )
{ {
error_ = "option '--"; error_ += options[index].long_name; error_ = "option '--"; error_ += options[index].long_name;
error_ += "' requires an argument"; error_ += "' requires an argument";
return false; return false;
} }
++argind; data.back().argument = arg; ++argind; data.back().argument = arg; // argument may be empty
return true; return true;
} }
@ -123,15 +123,16 @@ bool Arg_parser::parse_short_option( const char * const opt, const char * const
{ {
data.back().argument = &opt[cind]; ++argind; cind = 0; data.back().argument = &opt[cind]; ++argind; cind = 0;
} }
else if( options[index].has_arg == yes ) else if( options[index].has_arg == yes || options[index].has_arg == yme )
{ {
if( !arg || !arg[0] ) if( !arg || ( options[index].has_arg == yes && !arg[0] ) )
{ {
error_ = "option requires an argument -- '"; error_ += c; error_ = "option requires an argument -- '"; error_ += c;
error_ += '\''; error_ += '\'';
return false; return false;
} }
data.back().argument = arg; ++argind; cind = 0; ++argind; cind = 0;
data.back().argument = arg; // argument may be empty
} }
} }
return true; return true;

View file

@ -36,14 +36,18 @@
The argument '--' terminates all options; any following arguments are The argument '--' terminates all options; any following arguments are
treated as non-option arguments, even if they begin with a hyphen. treated as non-option arguments, even if they begin with a hyphen.
The syntax for optional option arguments is '-<short_option><argument>' The syntax of options with an optional argument is
(without whitespace), or '--<long_option>=<argument>'. '-<short_option><argument>' (without whitespace), or
'--<long_option>=<argument>'.
The syntax of options with an empty argument is '-<short_option> ""',
'--<long_option> ""', or '--<long_option>=""'.
*/ */
class Arg_parser class Arg_parser
{ {
public: public:
enum Has_arg { no, yes, maybe }; enum Has_arg { no, yes, maybe, yme }; // yme = yes but maybe empty
struct Option struct Option
{ {

4
configure vendored
View file

@ -6,7 +6,7 @@
# to copy, distribute, and modify it. # to copy, distribute, and modify it.
pkgname=zutils pkgname=zutils
pkgversion=1.13 pkgversion=1.14-rc1
srctrigger=doc/${pkgname}.texi srctrigger=doc/${pkgname}.texi
# clear some things potentially inherited from environment. # clear some things potentially inherited from environment.
@ -118,7 +118,7 @@ while [ $# != 0 ] ; do
exit 1 ;; exit 1 ;;
esac esac
# Check if the option took a separate argument # Check whether the option took a separate argument
if [ "${arg2}" = yes ] ; then if [ "${arg2}" = yes ] ; then
if [ $# != 0 ] ; then args="${args} \"$1\"" ; shift if [ $# != 0 ] ; then args="${args} \"$1\"" ; shift
else echo "configure: Missing argument to '${option}'" 1>&2 else echo "configure: Missing argument to '${option}'" 1>&2

View file

@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.2. .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.2.
.TH ZCAT "1" "January 2024" "zutils 1.13" "User Commands" .TH ZCAT "1" "November 2024" "zutils 1.14-rc1" "User Commands"
.SH NAME .SH NAME
zcat \- decompress and concatenate files to standard output zcat \- decompress and concatenate files to standard output
.SH SYNOPSIS .SH SYNOPSIS
@ -38,6 +38,12 @@ equivalent to '\-vET'
\fB\-b\fR, \fB\-\-number\-nonblank\fR \fB\-b\fR, \fB\-\-number\-nonblank\fR
number nonblank output lines number nonblank output lines
.TP .TP
\fB\-c\fR, \fB\-\-stdout\fR
ignored, for gzip compatibility
.TP
\fB\-d\fR, \fB\-\-decompress\fR
ignored, for gzip compatibility
.TP
\fB\-e\fR \fB\-e\fR
equivalent to '\-vE' equivalent to '\-vE'
.TP .TP

View file

@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.2. .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.2.
.TH ZCMP "1" "January 2024" "zutils 1.13" "User Commands" .TH ZCMP "1" "November 2024" "zutils 1.14-rc1" "User Commands"
.SH NAME .SH NAME
zcmp \- decompress and compare two files byte by byte zcmp \- decompress and compare two files byte by byte
.SH SYNOPSIS .SH SYNOPSIS

View file

@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.2. .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.2.
.TH ZDIFF "1" "January 2024" "zutils 1.13" "User Commands" .TH ZDIFF "1" "November 2024" "zutils 1.14-rc1" "User Commands"
.SH NAME .SH NAME
zdiff \- decompress and compare two files line by line zdiff \- decompress and compare two files line by line
.SH SYNOPSIS .SH SYNOPSIS

View file

@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.2. .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.2.
.TH ZGREP "1" "January 2024" "zutils 1.13" "User Commands" .TH ZGREP "1" "November 2024" "zutils 1.14-rc1" "User Commands"
.SH NAME .SH NAME
zgrep \- search compressed files for a regular expression zgrep \- search compressed files for a regular expression
.SH SYNOPSIS .SH SYNOPSIS

View file

@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.2. .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.2.
.TH ZTEST "1" "January 2024" "zutils 1.13" "User Commands" .TH ZTEST "1" "November 2024" "zutils 1.14-rc1" "User Commands"
.SH NAME .SH NAME
ztest \- check the integrity of compressed files ztest \- check the integrity of compressed files
.SH SYNOPSIS .SH SYNOPSIS

View file

@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.2. .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.2.
.TH ZUPDATE "1" "January 2024" "zutils 1.13" "User Commands" .TH ZUPDATE "1" "November 2024" "zutils 1.14-rc1" "User Commands"
.SH NAME .SH NAME
zupdate \- recompress bzip2, gzip, xz, zstd files to lzip format zupdate \- recompress bzip2, gzip, xz, zstd files to lzip format
.SH SYNOPSIS .SH SYNOPSIS
@ -97,7 +97,7 @@ set compressor and options for xz format
\fB\-\-zst=\fR<command> \fB\-\-zst=\fR<command>
set compressor and options for zstd format set compressor and options for zstd format
.PP .PP
Valid formats for option '\-M' are 'bz2', 'gz', 'lz', 'xz', and 'zst'. Valid formats for option '\-M' are 'bz2', 'gz', 'xz', and 'zst'.
.SH "REPORTING BUGS" .SH "REPORTING BUGS"
Report bugs to zutils\-bug@nongnu.org Report bugs to zutils\-bug@nongnu.org
.br .br

View file

@ -11,7 +11,7 @@ File: zutils.info, Node: Top, Next: Introduction, Up: (dir)
Zutils Manual Zutils Manual
************* *************
This manual is for Zutils (version 1.13, 23 January 2024). This manual is for Zutils (version 1.14-rc1, 29 November 2024).
* Menu: * Menu:
@ -24,6 +24,7 @@ This manual is for Zutils (version 1.13, 23 January 2024).
* Zgrep:: Searching inside compressed files * Zgrep:: Searching inside compressed files
* Ztest:: Testing the integrity of compressed files * Ztest:: Testing the integrity of compressed files
* Zupdate:: Recompressing files to lzip format * Zupdate:: Recompressing files to lzip format
* Argument syntax:: By convention, options start with a hyphen
* Problems:: Reporting bugs * Problems:: Reporting bugs
* Concept index:: Index of concepts * Concept index:: Index of concepts
@ -47,7 +48,7 @@ created. Data format is detected by its identifier string (magic bytes), not
by the file name extension. Empty files are considered uncompressed. by the file name extension. Empty files are considered uncompressed.
These utilities are not wrapper scripts but safer and more efficient C++ These utilities are not wrapper scripts but safer and more efficient C++
programs. In particular the option '--recursive' is very efficient in those programs. In particular the option '--recursive' is efficient in those
utilities supporting it. utilities supporting it.
The utilities provided are 'zcat', 'zcmp', 'zdiff', 'zgrep', 'ztest', and The utilities provided are 'zcat', 'zcmp', 'zdiff', 'zgrep', 'ztest', and
@ -89,10 +90,10 @@ File: zutils.info, Node: Common options, Next: Configuration, Prev: Introduct
2 Common options 2 Common options
**************** ****************
The following options: are available in all the utilities. Rather than The following options are available in all the utilities. Rather than
writing identical descriptions for each of the programs, they are described writing identical descriptions for each of the programs, they are described
here. Remember to prepend './' to any file name beginning with a hyphen, or here. Remember to prepend './' to any file name beginning with a hyphen, or
use '--'. *Note Argument syntax: (arg_parser)Argument syntax. use '--'. *Note Argument syntax::.
'-h' '-h'
'--help' '--help'
@ -113,7 +114,7 @@ use '--'. *Note Argument syntax: (arg_parser)Argument syntax.
'--format=FORMAT_LIST' '--format=FORMAT_LIST'
Process only the formats listed in the comma-separated FORMAT_LIST. Process only the formats listed in the comma-separated FORMAT_LIST.
Valid formats are 'bz2', 'gz', 'lz', 'xz', 'zst', and 'un' for Valid formats are 'bz2', 'gz', 'lz', 'xz', 'zst', and 'un' for
'uncompressed', meaning "any file name without a known extension". 'uncompressed', meaning 'any file name without a known extension'.
This option excludes files based on extension, instead of format, This option excludes files based on extension, instead of format,
because it is more efficient. The exclusion only applies to names because it is more efficient. The exclusion only applies to names
generated automatically (for example when adding extensions to a file generated automatically (for example when adding extensions to a file
@ -153,7 +154,7 @@ use '--'. *Note Argument syntax: (arg_parser)Argument syntax.
2. If the option '-q' is passed to zutils, the compression program 2. If the option '-q' is passed to zutils, the compression program
must also accept it. must also accept it.
3. It must return 0 if no errors occurred, and a non-zero value 3. It must return 0 if no errors occurred, and a nonzero value
otherwise. otherwise.
@ -164,6 +165,7 @@ and may be followed by a multiplier and an optional 'B' for "byte".
Table of SI and binary prefixes (unit multipliers): Table of SI and binary prefixes (unit multipliers):
Prefix Value | Prefix Value Prefix Value | Prefix Value
----------------------------------------------------------------------
k kilobyte (10^3 = 1000) | Ki kibibyte (2^10 = 1024) k kilobyte (10^3 = 1000) | Ki kibibyte (2^10 = 1024)
M megabyte (10^6) | Mi mebibyte (2^20) M megabyte (10^6) | Mi mebibyte (2^20)
G gigabyte (10^9) | Gi gibibyte (2^30) G gigabyte (10^9) | Gi gibibyte (2^30)
@ -239,6 +241,12 @@ Exit status is 0 if no errors occurred, 1 otherwise.
Number all nonblank output lines, starting with 1. The line count is Number all nonblank output lines, starting with 1. The line count is
unlimited. unlimited.
'-c'
'--stdout'
'-d'
'--decompress'
Ignored, for gzip compatibility.
'-e' '-e'
Equivalent to '-vE'. Equivalent to '-vE'.
@ -287,8 +295,8 @@ Exit status is 0 if no errors occurred, 1 otherwise.
'-v' '-v'
'--show-nonprinting' '--show-nonprinting'
Print control characters except for LF (newline) and TAB using '^' Print control characters except for LF (newline) and TAB using '^'
notation and precede characters larger than 127 with 'M-' (which notation and precede characters larger than 127 with 'M-' (which stands
stands for "meta"). for "meta").
'--verbose' '--verbose'
Verbose mode. Show error messages. Repeating it increases the verbosity Verbose mode. Show error messages. Repeating it increases the verbosity
@ -356,10 +364,10 @@ differences were found, and 2 means trouble.
Force the compressed formats given. If FORMAT1 or FORMAT2 is omitted, Force the compressed formats given. If FORMAT1 or FORMAT2 is omitted,
the corresponding format is automatically detected. Valid values for the corresponding format is automatically detected. Valid values for
FORMAT are 'bz2', 'gz', 'lz', 'xz', 'zst', and 'un' for FORMAT are 'bz2', 'gz', 'lz', 'xz', 'zst', and 'un' for
'uncompressed'. If at least one format is specified with this option, 'uncompressed'. If this option is specified, the corresponding file is
the file is passed to the corresponding decompressor (or transmitted passed to the decompressor (or transmitted unmodified) without
unmodified) without checking its format, and the exact file names of checking its format, and the exact file names of both FILE1 and FILE2
both FILE1 and FILE2 must be given. Other names are not tried. must be given. Other names are not tried.
'-q' '-q'
'--quiet' '--quiet'
@ -409,8 +417,8 @@ remaining formats until one is found. *Note search-order::.
An exit status of 0 means no differences were found, 1 means some An exit status of 0 means no differences were found, 1 means some
differences were found, and 2 means trouble. differences were found, and 2 means trouble.
'zdiff' supports the following options (some options only work if the 'zdiff' supports the following options (some options only work if the diff
diff program used supports them): program used supports them):
'-a' '-a'
'--text' '--text'
@ -449,10 +457,10 @@ diff program used supports them):
Force the compressed formats given. If FORMAT1 or FORMAT2 is omitted, Force the compressed formats given. If FORMAT1 or FORMAT2 is omitted,
the corresponding format is automatically detected. Valid values for the corresponding format is automatically detected. Valid values for
FORMAT are 'bz2', 'gz', 'lz', 'xz', 'zst', and 'un' for FORMAT are 'bz2', 'gz', 'lz', 'xz', 'zst', and 'un' for
'uncompressed'. If at least one format is specified with this option, 'uncompressed'. If this option is specified, the corresponding file is
the file is passed to the corresponding decompressor (or transmitted passed to the decompressor (or transmitted unmodified) without
unmodified) without checking its format, and the exact file names of checking its format, and the exact file names of both FILE1 and FILE2
both FILE1 and FILE2 must be given. Other names are not tried. must be given. Other names are not tried.
'-p' '-p'
'--show-c-function' '--show-c-function'
@ -536,9 +544,9 @@ with a nonzero status because base64 cannot write to its output pipe after
An exit status of 0 means at least one match was found, 1 means no matches An exit status of 0 means at least one match was found, 1 means no matches
were found, and 2 means trouble. were found, and 2 means trouble.
'zgrep' supports the following options (Some options only work if the 'zgrep' supports the following options (Some options only work if the grep
grep program used supports them. Options -h, -H, -r, -R, and -Z are managed program used supports them. Options -h, -H, -r, -R, and -Z are managed by
by 'zgrep' and not passed to grep): 'zgrep' and not passed to grep):
'-a' '-a'
'--text' '--text'
@ -680,8 +688,8 @@ by 'zgrep' and not passed to grep):
'-U' '-U'
'--binary' '--binary'
Use binary I/O on platforms affected by the bug known as "text mode Use binary I/O on platforms affected by the bug known as 'text mode
I/O". (MS-DOS, MS-Windows, OS/2). I/O'. (MS-DOS, MS-Windows, OS/2).
'-v' '-v'
'--invert-match' '--invert-match'
@ -781,7 +789,7 @@ incorrect file name extension.
 
File: zutils.info, Node: Zupdate, Next: Problems, Prev: Ztest, Up: Top File: zutils.info, Node: Zupdate, Next: Argument syntax, Prev: Ztest, Up: Top
9 Zupdate 9 Zupdate
********* *********
@ -843,13 +851,24 @@ compressor can't be run, or comparison fails).
'--destdir=DIR' '--destdir=DIR'
Write recompressed files to another directory, using DIR as base Write recompressed files to another directory, using DIR as base
directory, instead of writing them in the same directory as the directory, instead of writing them in the same directory as the
original files. In recursive mode, this is done by replacing each original files. This is done by removing the (possibly empty) prefix
directory specified in the command line with DIR to produce the preceding the last slash (if any) of each FILE specified in the
recompressed file names. For example, 'zupdate -r -d DIR ../a' command line, and then prepending DIR to produce the recompressed file
recompresses a file named '../a/b/c.gz' to 'DIR/b/c.lz'. Regular files names.
specified in the command line are recompressed directly into DIR. For
example, 'zupdate -d DIR ../a/b/c.gz' writes the recompressed file to In recursive mode, if FILE ends with a slash and names a directory, it
'DIR/c.lz'. is completely replaced with DIR. Therefore, if FILE ends with a slash,
all the files in FILE are recompressed directly into DIR, but if FILE
does not end with a slash, the files in FILE are recompressed into the
subdirectory DIR/`basename( FILE )`. 'FILE/' is thus equivalent to
'FILE/*', but without the danger of exceeding the length limit of the
command line.
For example, 'zupdate -r -d DIR ../a' recompresses the file
'../a/b.gz' to 'DIR/a/b.lz', while 'zupdate -r -d DIR ../a/'
recompresses the same file to 'DIR/b.lz'. Regular files specified in
the command line are recompressed directly into DIR. For example,
'zupdate -d DIR ../a/b.gz' writes the recompressed file to 'DIR/b.lz'.
This option allows recompressing files from a read-only file system to This option allows recompressing files from a read-only file system to
another place without the need to copy or link them to the destination another place without the need to copy or link them to the destination
@ -925,9 +944,56 @@ compressor can't be run, or comparison fails).
 
File: zutils.info, Node: Problems, Next: Concept index, Prev: Zupdate, Up: Top File: zutils.info, Node: Argument syntax, Next: Problems, Prev: Zupdate, Up: Top
10 Reporting bugs 10 Syntax of command-line arguments
***********************************
POSIX recommends these conventions for command-line arguments.
* A command-line argument is an option if it begins with a hyphen ('-').
* Option names are single alphanumeric characters.
* Certain options require an argument.
* An option and its argument may or may not appear as separate tokens.
(In other words, the whitespace separating them is optional). Thus,
'-o foo' and '-ofoo' are equivalent.
* One or more options without arguments, followed by at most one option
that takes an argument, may follow a hyphen in a single token. Thus,
'-abc' is equivalent to '-a -b -c'.
* Options typically precede other non-option arguments.
* The argument '--' terminates all options; any following arguments are
treated as non-option arguments, even if they begin with a hyphen.
* A token consisting of a single hyphen character is interpreted as an
ordinary non-option argument. By convention, it is used to specify
standard input, standard output, or a file named '-'.
GNU adds "long options" to these conventions:
* A long option consists of two hyphens ('--') followed by a name made
of alphanumeric characters and hyphens. Option names are typically one
to three words long, with hyphens to separate words. Abbreviations can
be used for the long option names as long as the abbreviations are
unique.
* A long option and its argument may or may not appear as separate
tokens. In the latter case they must be separated by an equal sign '='.
Thus, '--foo bar' and '--foo=bar' are equivalent.
The syntax of options with an optional argument is
'-<short_option><argument>' (without whitespace), or
'--<long_option>=<argument>'.

File: zutils.info, Node: Problems, Next: Concept index, Prev: Argument syntax, Up: Top
11 Reporting bugs
***************** *****************
There are probably bugs in zutils. There are certainly errors and omissions There are probably bugs in zutils. There are certainly errors and omissions
@ -948,6 +1014,7 @@ Concept index
[index] [index]
* Menu: * Menu:
* argument syntax: Argument syntax. (line 6)
* bugs: Problems. (line 6) * bugs: Problems. (line 6)
* common options: Common options. (line 6) * common options: Common options. (line 6)
* getting help: Problems. (line 6) * getting help: Problems. (line 6)
@ -964,21 +1031,22 @@ Concept index
 
Tag Table: Tag Table:
Node: Top217 Node: Top217
Node: Introduction1152 Node: Introduction1224
Ref: search-order2304 Ref: search-order2371
Node: Common options3461 Node: Common options3528
Ref: version4027 Ref: version4066
Ref: compressor-requirements5978 Ref: compressor-requirements6017
Node: Configuration7367 Node: Configuration7476
Node: Zcat8400 Node: Zcat8509
Node: Zcmp11139 Node: Zcmp11320
Node: Zdiff14407 Node: Zdiff14560
Node: Zgrep17490 Node: Zgrep17615
Node: Ztest23637 Node: Ztest23759
Node: Zupdate26430 Node: Zupdate26549
Ref: lz-compressor31838 Ref: lz-compressor32564
Node: Problems32539 Node: Argument syntax33265
Node: Concept index33073 Node: Problems35157
Node: Concept index35699
 
End Tag Table End Tag Table

View file

@ -6,8 +6,8 @@
@finalout @finalout
@c %**end of header @c %**end of header
@set UPDATED 23 January 2024 @set UPDATED 29 November 2024
@set VERSION 1.13 @set VERSION 1.14-rc1
@dircategory Compression @dircategory Compression
@direntry @direntry
@ -45,6 +45,7 @@ This manual is for Zutils (version @value{VERSION}, @value{UPDATED}).
* Zgrep:: Searching inside compressed files * Zgrep:: Searching inside compressed files
* Ztest:: Testing the integrity of compressed files * Ztest:: Testing the integrity of compressed files
* Zupdate:: Recompressing files to lzip format * Zupdate:: Recompressing files to lzip format
* Argument syntax:: By convention, options start with a hyphen
* Problems:: Reporting bugs * Problems:: Reporting bugs
* Concept index:: Index of concepts * Concept index:: Index of concepts
@end menu @end menu
@ -70,8 +71,8 @@ created. Data format is detected by its identifier string (magic bytes), not
by the file name extension. Empty files are considered uncompressed. by the file name extension. Empty files are considered uncompressed.
These utilities are not wrapper scripts but safer and more efficient C++ These utilities are not wrapper scripts but safer and more efficient C++
programs. In particular the option @option{--recursive} is very efficient in programs. In particular the option @option{--recursive} is efficient in those
those utilities supporting it. utilities supporting it.
@noindent @noindent
The utilities provided are @command{zcat}, @command{zcmp}, @command{zdiff}, The utilities provided are @command{zcat}, @command{zcmp}, @command{zdiff},
@ -116,14 +117,10 @@ the process of decompression.
@chapter Common options @chapter Common options
@cindex common options @cindex common options
The following The following options are available in all the utilities. Rather than
@uref{http://www.nongnu.org/arg-parser/manual/arg_parser_manual.html#Argument-syntax,,options}: writing identical descriptions for each of the programs, they are described
are available in all the utilities. Rather than writing identical here. Remember to prepend @file{./} to any file name beginning with a
descriptions for each of the programs, they are described here. Remember to hyphen, or use @samp{--}. @xref{Argument syntax}.
prepend @file{./} to any file name beginning with a hyphen, or use @samp{--}.
@ifnothtml
@xref{Argument syntax,,,arg_parser}.
@end ifnothtml
@table @code @table @code
@item -h @item -h
@ -146,8 +143,8 @@ compressors used must support the option @option{-V} for this to work).
@itemx --format=@var{format_list} @itemx --format=@var{format_list}
Process only the formats listed in the comma-separated @var{format_list}. Process only the formats listed in the comma-separated @var{format_list}.
Valid formats are @samp{bz2}, @samp{gz}, @samp{lz}, @samp{xz}, @samp{zst}, Valid formats are @samp{bz2}, @samp{gz}, @samp{lz}, @samp{xz}, @samp{zst},
and @samp{un} for @samp{uncompressed}, meaning "any file name without a and @samp{un} for @samp{uncompressed}, meaning 'any file name without a
known extension". This option excludes files based on extension, instead of known extension'. This option excludes files based on extension, instead of
format, because it is more efficient. The exclusion only applies to names format, because it is more efficient. The exclusion only applies to names
generated automatically (for example when adding extensions to a file name generated automatically (for example when adding extensions to a file name
or when operating recursively on directories). Files given in the command or when operating recursively on directories). Files given in the command
@ -192,7 +189,7 @@ standard output.
If the option @option{-q} is passed to zutils, the compression program must If the option @option{-q} is passed to zutils, the compression program must
also accept it. also accept it.
@item @item
It must return 0 if no errors occurred, and a non-zero value otherwise. It must return 0 if no errors occurred, and a nonzero value otherwise.
@end enumerate @end enumerate
@end table @end table
@ -204,7 +201,7 @@ and may be followed by a multiplier and an optional @samp{B} for "byte".
Table of SI and binary prefixes (unit multipliers): Table of SI and binary prefixes (unit multipliers):
@multitable {Prefix} {kilobyte (10^3 = 1000)} {|} {Prefix} {kibibyte (2^10 = 1024)} @multitable {Prefix} {kilobyte (10^3 = 1000)} {|} {Prefix} {kibibyte (2^10 = 1024)}
@item Prefix @tab Value @tab | @tab Prefix @tab Value @headitem Prefix @tab Value @tab | @tab Prefix @tab Value
@item k @tab kilobyte (10^3 = 1000) @tab | @tab Ki @tab kibibyte (2^10 = 1024) @item k @tab kilobyte (10^3 = 1000) @tab | @tab Ki @tab kibibyte (2^10 = 1024)
@item M @tab megabyte (10^6) @tab | @tab Mi @tab mebibyte (2^20) @item M @tab megabyte (10^6) @tab | @tab Mi @tab mebibyte (2^20)
@item G @tab gigabyte (10^9) @tab | @tab Gi @tab gibibyte (2^30) @item G @tab gigabyte (10^9) @tab | @tab Gi @tab gibibyte (2^30)
@ -278,6 +275,7 @@ zcat [@var{options}] [@var{files}]
@noindent @noindent
Exit status is 0 if no errors occurred, 1 otherwise. Exit status is 0 if no errors occurred, 1 otherwise.
@noindent
@command{zcat} supports the following options: @command{zcat} supports the following options:
@table @code @table @code
@ -290,6 +288,12 @@ Equivalent to @option{-vET}.
Number all nonblank output lines, starting with 1. The line count is Number all nonblank output lines, starting with 1. The line count is
unlimited. unlimited.
@item -c
@itemx --stdout
@itemx -d
@itemx --decompress
Ignored, for gzip compatibility.
@item -e @item -e
Equivalent to @option{-vE}. Equivalent to @option{-vE}.
@ -339,8 +343,8 @@ Print TAB characters as @samp{^I}.
@item -v @item -v
@itemx --show-nonprinting @itemx --show-nonprinting
Print control characters except for LF (newline) and TAB using @samp{^} Print control characters except for LF (newline) and TAB using @samp{^}
notation and precede characters larger than 127 with @samp{M-} (which notation and precede characters larger than 127 with @samp{M-} (which stands
stands for "meta"). for "meta").
@item --verbose @item --verbose
Verbose mode. Show error messages. Repeating it increases the verbosity Verbose mode. Show error messages. Repeating it increases the verbosity
@ -378,6 +382,7 @@ corresponding compressed files of the remaining formats until one is found.
An exit status of 0 means no differences were found, 1 means some An exit status of 0 means no differences were found, 1 means some
differences were found, and 2 means trouble. differences were found, and 2 means trouble.
@noindent
@command{zcmp} supports the following options: @command{zcmp} supports the following options:
@table @code @table @code
@ -414,11 +419,11 @@ Compare at most @var{count} input bytes.
Force the compressed formats given. If @var{format1} or @var{format2} is Force the compressed formats given. If @var{format1} or @var{format2} is
omitted, the corresponding format is automatically detected. Valid values omitted, the corresponding format is automatically detected. Valid values
for @var{format} are @samp{bz2}, @samp{gz}, @samp{lz}, @samp{xz}, for @var{format} are @samp{bz2}, @samp{gz}, @samp{lz}, @samp{xz},
@samp{zst}, and @samp{un} for @samp{uncompressed}. If at least one format is @samp{zst}, and @samp{un} for @samp{uncompressed}. If this option is
specified with this option, the file is passed to the corresponding specified, the corresponding file is passed to the decompressor (or
decompressor (or transmitted unmodified) without checking its format, and transmitted unmodified) without checking its format, and the exact file
the exact file names of both @var{file1} and @var{file2} must be given. names of both @var{file1} and @var{file2} must be given. Other names are not
Other names are not tried. tried.
@item -q @item -q
@itemx --quiet @itemx --quiet
@ -473,6 +478,7 @@ corresponding compressed files of the remaining formats until one is found.
An exit status of 0 means no differences were found, 1 means some An exit status of 0 means no differences were found, 1 means some
differences were found, and 2 means trouble. differences were found, and 2 means trouble.
@noindent
@command{zdiff} supports the following options (some options only work if @command{zdiff} supports the following options (some options only work if
the diff program used supports them): the diff program used supports them):
@ -513,11 +519,11 @@ Ignore case differences. Consider uppercase and lowercase letters equivalent.
Force the compressed formats given. If @var{format1} or @var{format2} is Force the compressed formats given. If @var{format1} or @var{format2} is
omitted, the corresponding format is automatically detected. Valid values omitted, the corresponding format is automatically detected. Valid values
for @var{format} are @samp{bz2}, @samp{gz}, @samp{lz}, @samp{xz}, for @var{format} are @samp{bz2}, @samp{gz}, @samp{lz}, @samp{xz},
@samp{zst}, and @samp{un} for @samp{uncompressed}. If at least one format is @samp{zst}, and @samp{un} for @samp{uncompressed}. If this option is
specified with this option, the file is passed to the corresponding specified, the corresponding file is passed to the decompressor (or
decompressor (or transmitted unmodified) without checking its format, and transmitted unmodified) without checking its format, and the exact file
the exact file names of both @var{file1} and @var{file2} must be given. names of both @var{file1} and @var{file2} must be given. Other names are not
Other names are not tried. tried.
@item -p @item -p
@itemx --show-c-function @itemx --show-c-function
@ -603,6 +609,7 @@ zgrep [@var{options}] @var{pattern} [@var{files}]
An exit status of 0 means at least one match was found, 1 means no An exit status of 0 means at least one match was found, 1 means no
matches were found, and 2 means trouble. matches were found, and 2 means trouble.
@noindent
@command{zgrep} supports the following options (Some options only work if @command{zgrep} supports the following options (Some options only work if
the grep program used supports them. Options -h, -H, -r, -R, and -Z are the grep program used supports them. Options -h, -H, -r, -R, and -Z are
managed by @command{zgrep} and not passed to grep): managed by @command{zgrep} and not passed to grep):
@ -750,7 +757,7 @@ stop, so that the alignment of tabs looks normal.
@item -U @item -U
@itemx --binary @itemx --binary
Use binary I/O on platforms affected by the bug known as "text mode I/O". Use binary I/O on platforms affected by the bug known as 'text mode I/O'.
(MS-DOS, MS-Windows, OS/2). (MS-DOS, MS-Windows, OS/2).
@item -v @item -v
@ -825,6 +832,7 @@ problems (file not found, invalid command-line options, I/O errors, etc),
2 if any compressed file is corrupt or invalid, or if any file has an 2 if any compressed file is corrupt or invalid, or if any file has an
incorrect file name extension. incorrect file name extension.
@noindent
@command{ztest} supports the following options: @command{ztest} supports the following options:
@table @code @table @code
@ -887,11 +895,11 @@ Combining the options @option{--force} and @option{--keep}, as in
each pair of files in a multiformat set of files. each pair of files in a multiformat set of files.
The names of the original files must have one of the following extensions:@* The names of the original files must have one of the following extensions:@*
@samp{.bz2}, @samp{.gz}, @samp{.xz}, @samp{.zst}, or @samp{.Z}, which are @file{.bz2}, @file{.gz}, @file{.xz}, @file{.zst}, or @file{.Z}, which are
recompressed to @samp{.lz};@* recompressed to @file{.lz};@*
@samp{.tbz}, @samp{.tbz2}, @samp{.tgz}, @samp{.txz}, or @samp{.tzst}, which @file{.tbz}, @file{.tbz2}, @file{.tgz}, @file{.txz}, or @file{.tzst}, which
are recompressed to @samp{.tlz}.@* are recompressed to @file{.tlz}.@*
Keeping the combined extensions @w{(@samp{.tgz} ---> @samp{.tlz})} may be Keeping the combined extensions @w{(@file{.tgz} ---> @file{.tlz})} may be
useful when recompressing Slackware packages, for example. useful when recompressing Slackware packages, for example.
Bzip2, gzip, and lzip are the primary formats. Xz and zstd are optional. If Bzip2, gzip, and lzip are the primary formats. Xz and zstd are optional. If
@ -917,6 +925,7 @@ occurred (file not found or not regular, or has invalid format, or can't be
deleted). 2 if a fatal error occurred (invalid command-line options, deleted). 2 if a fatal error occurred (invalid command-line options,
compressor can't be run, or comparison fails). compressor can't be run, or comparison fails).
@noindent
@command{zupdate} supports the following options: @command{zupdate} supports the following options:
@table @code @table @code
@ -924,13 +933,25 @@ compressor can't be run, or comparison fails).
@itemx --destdir=@var{dir} @itemx --destdir=@var{dir}
Write recompressed files to another directory, using @var{dir} as base Write recompressed files to another directory, using @var{dir} as base
directory, instead of writing them in the same directory as the original directory, instead of writing them in the same directory as the original
files. In recursive mode, this is done by replacing each directory specified files. This is done by removing the (possibly empty) prefix preceding the
in the command line with @var{dir} to produce the recompressed file names. last slash (if any) of each @var{file} specified in the command line, and
For example, @w{@samp{zupdate -r -d @var{dir} ../a}} recompresses a file then prepending @var{dir} to produce the recompressed file names.
named @file{../a/b/c.gz} to @file{@var{dir}/b/c.lz}. Regular files specified
in the command line are recompressed directly into @var{dir}. For example, In recursive mode, if @var{file} ends with a slash and names a directory, it
@w{@samp{zupdate -d @var{dir} ../a/b/c.gz}} writes the recompressed file to is completely replaced with @var{dir}. Therefore, if @var{file} ends with a
@file{@var{dir}/c.lz}. slash, all the files in @var{file} are recompressed directly into @var{dir},
but if @var{file} does not end with a slash, the files in @var{file} are
recompressed into the subdirectory @w{@var{dir}/`basename( @var{file} )`}.
@samp{@var{file/}} is thus equivalent to @samp{@var{file/*}}, but without
the danger of exceeding the length limit of the command line.
For example, @w{@samp{zupdate -r -d @var{dir} ../a}} recompresses the file
@file{../a/b.gz} to @file{@var{dir}/a/b.lz}, while
@w{@samp{zupdate -r -d @var{dir} ../a/}} recompresses the same file to
@file{@var{dir}/b.lz}. Regular files specified in the command line are
recompressed directly into @var{dir}. For example,
@w{@samp{zupdate -d @var{dir} ../a/b.gz}} writes the recompressed file to
@file{@var{dir}/b.lz}.
This option allows recompressing files from a read-only file system to This option allows recompressing files from a read-only file system to
another place without the need to copy or link them to the destination another place without the need to copy or link them to the destination
@ -939,8 +960,8 @@ read-only files to avoid warnings about files that can't be deleted).
@item -e @item -e
@itemx --expand-extensions @itemx --expand-extensions
Expand combined file name extensions; recompress @samp{.tbz}, @samp{.tbz2}, Expand combined file name extensions; recompress @file{.tbz}, @file{.tbz2},
@samp{.tgz}, @samp{.txz}, and @samp{.tzst} to @samp{tar.lz}. @file{.tgz}, @file{.txz}, and @file{.tzst} to @file{tar.lz}.
@item -f @item -f
@itemx --force @itemx --force
@ -1011,6 +1032,58 @@ archives by using a command like
@end table @end table
@node Argument syntax
@chapter Syntax of command-line arguments
@cindex argument syntax
POSIX recommends these conventions for command-line arguments.
@itemize @bullet
@item A command-line argument is an option if it begins with a hyphen
(@samp{-}).
@item Option names are single alphanumeric characters.
@item Certain options require an argument.
@item An option and its argument may or may not appear as separate tokens.
(In other words, the whitespace separating them is optional).
Thus, @w{@option{-o foo}} and @option{-ofoo} are equivalent.
@item One or more options without arguments, followed by at most one option
that takes an argument, may follow a hyphen in a single token.
Thus, @option{-abc} is equivalent to @w{@option{-a -b -c}}.
@item Options typically precede other non-option arguments.
@item The argument @samp{--} terminates all options; any following arguments
are treated as non-option arguments, even if they begin with a hyphen.
@item A token consisting of a single hyphen character is interpreted as an
ordinary non-option argument. By convention, it is used to specify standard
input, standard output, or a file named @samp{-}.
@end itemize
@noindent
GNU adds @dfn{long options} to these conventions:
@itemize @bullet
@item A long option consists of two hyphens (@samp{--}) followed by a name
made of alphanumeric characters and hyphens. Option names are typically one
to three words long, with hyphens to separate words. Abbreviations can be
used for the long option names as long as the abbreviations are unique.
@item A long option and its argument may or may not appear as separate
tokens. In the latter case they must be separated by an equal sign @samp{=}.
Thus, @w{@option{--foo bar}} and @option{--foo=bar} are equivalent.
@end itemize
@noindent
The syntax of options with an optional argument is
@option{-<short_option><argument>} (without whitespace), or
@option{--<long_option>=<argument>}.
@node Problems @node Problems
@chapter Reporting bugs @chapter Reporting bugs
@cindex bugs @cindex bugs

View file

@ -39,7 +39,7 @@ mkdir tmp
cd "${objdir}"/tmp || framework_failure cd "${objdir}"/tmp || framework_failure
for i in ${compressors}; do for i in ${compressors}; do
cat "${testdir}"/test.txt > in || framework_failure cp "${testdir}"/test.txt in || framework_failure
$i in || compressor_needed $i in || compressor_needed
printf "Hello World!\n" > hello || framework_failure printf "Hello World!\n" > hello || framework_failure
$i hello || compressor_needed $i hello || compressor_needed
@ -47,13 +47,13 @@ for i in ${compressors}; do
$i zero || compressor_needed $i zero || compressor_needed
done done
cat "${testdir}"/test.txt > in || framework_failure cp "${testdir}"/test.txt in || framework_failure
cat "${testdir}"/test.txt.tar > in.tar || framework_failure cp "${testdir}"/test.txt.tar in.tar || framework_failure
printf "01234567890" > pin.tar4 || framework_failure printf "01234567890" > pin.tar4 || framework_failure
cat in.tar in.tar in.tar in.tar >> pin.tar4 || framework_failure cat in.tar in.tar in.tar in.tar >> pin.tar4 || framework_failure
cat in > -in- || framework_failure cp in -- -in- || framework_failure
cat in.lz > -in-.lz || framework_failure cp in.lz -- -in-.lz || framework_failure
cat in.lz > lz_only.lz || framework_failure cp in.lz lz_only.lz || framework_failure
cat in in in in in in > in6 || framework_failure cat in in in in in in > in6 || framework_failure
bad0_lz="${testdir}"/zero_bad_crc.lz bad0_lz="${testdir}"/zero_bad_crc.lz
bad0_gz="${testdir}"/zero_bad_crc.gz bad0_gz="${testdir}"/zero_bad_crc.gz
@ -94,9 +94,9 @@ printf "LZIP\001-.............................." | "${ZCAT}" -N > /dev/null 2>&1
printf "LZIPxxxxxx" | "${ZCAT}" -N > /dev/null || test_failed $LINENO printf "LZIPxxxxxx" | "${ZCAT}" -N > /dev/null || test_failed $LINENO
printf "BZh9xxxxxx" | "${ZCAT}" -N > /dev/null || test_failed $LINENO printf "BZh9xxxxxx" | "${ZCAT}" -N > /dev/null || test_failed $LINENO
"${ZCAT}" -N -v -s "${testdir}"/zcat_vs.dat > /dev/null || test_failed $LINENO "${ZCAT}" -N -v -s "${testdir}"/zcat_vs.dat > /dev/null || test_failed $LINENO
"${ZCAT}" -N < in > out || test_failed $LINENO "${ZCAT}" -N -c < in > out || test_failed $LINENO
cmp in out || test_failed $LINENO cmp in out || test_failed $LINENO
"${ZCAT}" -N < in.gz > out || test_failed $LINENO "${ZCAT}" -N -d < in.gz > out || test_failed $LINENO
cmp in out || test_failed $LINENO cmp in out || test_failed $LINENO
"${ZCAT}" -N < in.bz2 > out || test_failed $LINENO "${ZCAT}" -N < in.bz2 > out || test_failed $LINENO
cmp in out || test_failed $LINENO cmp in out || test_failed $LINENO
@ -227,8 +227,8 @@ cat in.lz | "${ZCMP}" -N -O un,un in.lz - || test_failed $LINENO
[ $? = 2 ] || test_failed $LINENO [ $? = 2 ] || test_failed $LINENO
"${ZCMP}" -N --bad-option in in 2> /dev/null "${ZCMP}" -N --bad-option in in 2> /dev/null
[ $? = 2 ] || test_failed $LINENO [ $? = 2 ] || test_failed $LINENO
cat in.gz > a.gz || framework_failure cp in.gz a.gz || framework_failure
cat in.lz > a.lz || framework_failure cp in.lz a.lz || framework_failure
"${ZCMP}" -N a.gz || test_failed $LINENO "${ZCMP}" -N a.gz || test_failed $LINENO
"${ZCMP}" -N a.lz || test_failed $LINENO "${ZCMP}" -N a.lz || test_failed $LINENO
@ -294,8 +294,8 @@ cat in.gz | "${ZDIFF}" -N -O un,un - in.gz || test_failed $LINENO
[ $? = 2 ] || test_failed $LINENO [ $? = 2 ] || test_failed $LINENO
mkdir tmp2 mkdir tmp2
cat in > tmp2/a || framework_failure cp in tmp2/a || framework_failure
cat in.lz > tmp2/a.lz || framework_failure cp in.lz tmp2/a.lz || framework_failure
"${ZDIFF}" -N --format=bz2 tmp2/a 2> /dev/null "${ZDIFF}" -N --format=bz2 tmp2/a 2> /dev/null
[ $? = 2 ] || test_failed $LINENO [ $? = 2 ] || test_failed $LINENO
"${ZDIFF}" -N --format=gz tmp2/a 2> /dev/null "${ZDIFF}" -N --format=gz tmp2/a 2> /dev/null
@ -405,10 +405,10 @@ rm -f empty.bz2 empty.gz empty.lz || framework_failure
"${ZTEST}" -N empty || test_failed $LINENO "${ZTEST}" -N empty || test_failed $LINENO
# test wrong compressed extensions # test wrong compressed extensions
cat in.bz2 > in_bz2.gz || framework_failure cp in.bz2 in_bz2.gz || framework_failure
cat in.gz > in_gz.lz || framework_failure cp in.gz in_gz.lz || framework_failure
cat in.lz > in_lz.bz2 || framework_failure cp in.lz in_lz.bz2 || framework_failure
cat in > in_un.lz || framework_failure cp in in_un.lz || framework_failure
"${ZTEST}" -Nq in_bz2.gz "${ZTEST}" -Nq in_bz2.gz
[ $? = 2 ] || test_failed $LINENO [ $? = 2 ] || test_failed $LINENO
"${ZTEST}" -Nq in_gz.lz "${ZTEST}" -Nq in_gz.lz
@ -446,8 +446,8 @@ dd if=in.lz bs=1000 count=1 2> /dev/null | "${ZTEST}" -N -q
printf "\ntesting zupdate-%s..." "$2" printf "\ntesting zupdate-%s..." "$2"
"${ZUPDATE}" -N "" || test_failed $LINENO "${ZUPDATE}" -N "" || test_failed $LINENO
cat in.bz2 > a.bz2 || framework_failure cp in.bz2 a.bz2 || framework_failure
cat in.gz > a.gz || framework_failure cp in.gz a.gz || framework_failure
"${ZUPDATE}" -Nq --bz2=bad_command a.bz2 "${ZUPDATE}" -Nq --bz2=bad_command a.bz2
[ $? = 1 ] || test_failed $LINENO [ $? = 1 ] || test_failed $LINENO
"${ZUPDATE}" -N --bz2='bzip2 --bad-option' a.bz2 > /dev/null 2>&1 "${ZUPDATE}" -N --bz2='bzip2 --bad-option' a.bz2 > /dev/null 2>&1
@ -492,8 +492,8 @@ rm -f a.lz || framework_failure
[ -e a.lz ] || test_failed $LINENO [ -e a.lz ] || test_failed $LINENO
rm -f a.lz || framework_failure rm -f a.lz || framework_failure
cat in.bz2 > a.bz2 || framework_failure cp in.bz2 a.bz2 || framework_failure
cat in.gz > a.gz || framework_failure cp in.gz a.gz || framework_failure
"${ZUPDATE}" -N -q -0 a.bz2 a.gz "${ZUPDATE}" -N -q -0 a.bz2 a.gz
[ $? = 1 ] || test_failed $LINENO [ $? = 1 ] || test_failed $LINENO
[ ! -e a.bz2 ] || test_failed $LINENO [ ! -e a.bz2 ] || test_failed $LINENO
@ -501,16 +501,16 @@ cat in.gz > a.gz || framework_failure
[ -e a.lz ] || test_failed $LINENO [ -e a.lz ] || test_failed $LINENO
rm -f a.lz || framework_failure rm -f a.lz || framework_failure
cat in.bz2 > a.bz2 || framework_failure cp in.bz2 a.bz2 || framework_failure
cat in.gz > a.gz || framework_failure cp in.gz a.gz || framework_failure
"${ZUPDATE}" -N -0 -f -k a.bz2 a.gz || test_failed $LINENO "${ZUPDATE}" -N -0 -f -k a.bz2 a.gz || test_failed $LINENO
[ -e a.bz2 ] || test_failed $LINENO [ -e a.bz2 ] || test_failed $LINENO
[ -e a.gz ] || test_failed $LINENO [ -e a.gz ] || test_failed $LINENO
[ -e a.lz ] || test_failed $LINENO [ -e a.lz ] || test_failed $LINENO
rm -f a.lz || framework_failure rm -f a.lz || framework_failure
cat in.bz2 > a.bz2 || framework_failure cp in.bz2 a.bz2 || framework_failure
cat in.gz > a.gz || framework_failure cp in.gz a.gz || framework_failure
"${ZUPDATE}" -N -0 -f a.bz2 a.gz || test_failed $LINENO "${ZUPDATE}" -N -0 -f a.bz2 a.gz || test_failed $LINENO
[ ! -e a.bz2 ] || test_failed $LINENO [ ! -e a.bz2 ] || test_failed $LINENO
[ ! -e a.gz ] || test_failed $LINENO [ ! -e a.gz ] || test_failed $LINENO
@ -518,9 +518,9 @@ cat in.gz > a.gz || framework_failure
[ -e a.lz ] || test_failed $LINENO [ -e a.lz ] || test_failed $LINENO
rm -f a.lz || framework_failure rm -f a.lz || framework_failure
cat in.bz2 > a.tbz || framework_failure # keep combined extensions cp in.bz2 a.tbz || framework_failure # keep combined extensions
cat in.bz2 > b.tbz2 || framework_failure cp in.bz2 b.tbz2 || framework_failure
cat in.gz > c.tgz || framework_failure cp in.gz c.tgz || framework_failure
"${ZUPDATE}" -N -0 a.tbz b.tbz2 c.tgz || test_failed $LINENO "${ZUPDATE}" -N -0 a.tbz b.tbz2 c.tgz || test_failed $LINENO
[ ! -e a.tbz ] || test_failed $LINENO [ ! -e a.tbz ] || test_failed $LINENO
[ ! -e b.tbz2 ] || test_failed $LINENO [ ! -e b.tbz2 ] || test_failed $LINENO
@ -536,9 +536,9 @@ cat in.gz > c.tgz || framework_failure
[ -e c.tlz ] || test_failed $LINENO [ -e c.tlz ] || test_failed $LINENO
rm -f a.tlz b.tlz c.tlz || framework_failure rm -f a.tlz b.tlz c.tlz || framework_failure
cat in.bz2 > a.tbz || framework_failure # expand combined extensions cp in.bz2 a.tbz || framework_failure # expand combined extensions
cat in.bz2 > b.tbz2 || framework_failure cp in.bz2 b.tbz2 || framework_failure
cat in.gz > c.tgz || framework_failure cp in.gz c.tgz || framework_failure
"${ZUPDATE}" -N -0 -e a.tbz b.tbz2 c.tgz || test_failed $LINENO "${ZUPDATE}" -N -0 -e a.tbz b.tbz2 c.tgz || test_failed $LINENO
[ ! -e a.tbz ] || test_failed $LINENO [ ! -e a.tbz ] || test_failed $LINENO
[ ! -e b.tbz2 ] || test_failed $LINENO [ ! -e b.tbz2 ] || test_failed $LINENO
@ -555,9 +555,9 @@ cat in.gz > c.tgz || framework_failure
rm -f a.tar.lz b.tar.lz c.tar.lz || framework_failure rm -f a.tar.lz b.tar.lz c.tar.lz || framework_failure
# test decompression error # test decompression error
cat in.bz2 > a.bz2 || framework_failure cp in.bz2 a.bz2 || framework_failure
cat "${bad0_gz}" > b.gz || framework_failure cp "${bad0_gz}" b.gz || framework_failure
cat in.gz > c.gz || framework_failure cp in.gz c.gz || framework_failure
"${ZUPDATE}" -N -0 -f a.bz2 b.gz c.gz 2> /dev/null "${ZUPDATE}" -N -0 -f a.bz2 b.gz c.gz 2> /dev/null
[ $? = 1 ] || test_failed $LINENO [ $? = 1 ] || test_failed $LINENO
[ ! -e a.bz2 ] || test_failed $LINENO [ ! -e a.bz2 ] || test_failed $LINENO
@ -568,9 +568,9 @@ cat in.gz > c.gz || framework_failure
[ ! -e c ] || test_failed $LINENO [ ! -e c ] || test_failed $LINENO
[ -e a.lz ] || test_failed $LINENO [ -e a.lz ] || test_failed $LINENO
# ignore error # ignore error
cat in.bz2 > a.bz2 || framework_failure cp in.bz2 a.bz2 || framework_failure
cat "${bad0_gz}" > b.gz || framework_failure cp "${bad0_gz}" b.gz || framework_failure
cat in.gz > c.gz || framework_failure cp in.gz c.gz || framework_failure
"${ZUPDATE}" -N -0 -f -i a.bz2 b.gz c.gz 2> /dev/null "${ZUPDATE}" -N -0 -f -i a.bz2 b.gz c.gz 2> /dev/null
[ $? = 1 ] || test_failed $LINENO [ $? = 1 ] || test_failed $LINENO
[ ! -e a.bz2 ] || test_failed $LINENO [ ! -e a.bz2 ] || test_failed $LINENO
@ -579,20 +579,20 @@ cat in.gz > c.gz || framework_failure
[ -e a.lz ] || test_failed $LINENO [ -e a.lz ] || test_failed $LINENO
rm -f a.lz b.gz c.gz || framework_failure rm -f a.lz b.gz c.gz || framework_failure
cat in.bz2 > a.bz2 || framework_failure cp in.bz2 a.bz2 || framework_failure
"${ZUPDATE}" -N -0 -q a.bz2 || test_failed $LINENO "${ZUPDATE}" -N -0 -q a.bz2 || test_failed $LINENO
[ ! -e a.bz2 ] || test_failed $LINENO [ ! -e a.bz2 ] || test_failed $LINENO
[ -e a.lz ] || test_failed $LINENO [ -e a.lz ] || test_failed $LINENO
rm -f a.lz || framework_failure rm -f a.lz || framework_failure
cat in.gz > 'name with spaces.gz' || framework_failure cp in.gz 'name with spaces.gz' || framework_failure
"${ZUPDATE}" -N -0 -q 'name with spaces.gz' || test_failed $LINENO "${ZUPDATE}" -N -0 -q 'name with spaces.gz' || test_failed $LINENO
[ ! -e 'name with spaces.gz' ] || test_failed $LINENO [ ! -e 'name with spaces.gz' ] || test_failed $LINENO
[ -e 'name with spaces.lz' ] || test_failed $LINENO [ -e 'name with spaces.lz' ] || test_failed $LINENO
"${ZCMP}" -N in 'name with spaces.lz' || test_failed $LINENO "${ZCMP}" -N in 'name with spaces.lz' || test_failed $LINENO
rm -f 'name with spaces.lz' || framework_failure rm -f 'name with spaces.lz' || framework_failure
cat zero.gz > z.gz || framework_failure cp zero.gz z.gz || framework_failure
"${ZUPDATE}" -N -0 -q z.gz || test_failed $LINENO "${ZUPDATE}" -N -0 -q z.gz || test_failed $LINENO
[ ! -e z.gz ] || test_failed $LINENO [ ! -e z.gz ] || test_failed $LINENO
[ -e z.lz ] || test_failed $LINENO [ -e z.lz ] || test_failed $LINENO
@ -601,14 +601,14 @@ rm -f empty z.lz || framework_failure
mkdir tmp2 mkdir tmp2
mkdir tmp2/tmp3 mkdir tmp2/tmp3
cat in.bz2 > tmp2/tmp3/a.bz2 || framework_failure cp in.bz2 tmp2/tmp3/a.bz2 || framework_failure
cat in.gz > tmp2/tmp3/a.gz || framework_failure cp in.gz tmp2/tmp3/a.gz || framework_failure
# test recursive to destdir # test recursive to destdir
"${ZUPDATE}" -N -0 -k -r --format=gz --destdir=ddir1 tmp2 || test_failed $LINENO "${ZUPDATE}" -N -0 -k -r --format=gz --destdir=ddir1 tmp2 || test_failed $LINENO
[ -e tmp2/tmp3/a.bz2 ] || test_failed $LINENO [ -e tmp2/tmp3/a.bz2 ] || test_failed $LINENO
[ -e tmp2/tmp3/a.gz ] || test_failed $LINENO [ -e tmp2/tmp3/a.gz ] || test_failed $LINENO
[ -e ddir1/tmp3/a.lz ] || test_failed $LINENO [ -e ddir1/tmp2/tmp3/a.lz ] || test_failed $LINENO
"${ZUPDATE}" -N -0 -k -r --format=bz2 --destdir="${objdir}"/tmp/ddir2 tmp2 || "${ZUPDATE}" -N -0 -k -r --format=bz2 --destdir="${objdir}"/tmp/ddir2 tmp2/ ||
test_failed $LINENO test_failed $LINENO
[ -e tmp2/tmp3/a.bz2 ] || test_failed $LINENO [ -e tmp2/tmp3/a.bz2 ] || test_failed $LINENO
[ -e tmp2/tmp3/a.gz ] || test_failed $LINENO [ -e tmp2/tmp3/a.gz ] || test_failed $LINENO
@ -618,11 +618,11 @@ cat in.gz > tmp2/tmp3/a.gz || framework_failure
[ -e tmp2/tmp3/a.bz2 ] || test_failed $LINENO [ -e tmp2/tmp3/a.bz2 ] || test_failed $LINENO
[ -e tmp2/tmp3/a.gz ] || test_failed $LINENO [ -e tmp2/tmp3/a.gz ] || test_failed $LINENO
[ -e ddir3/a.lz ] || test_failed $LINENO [ -e ddir3/a.lz ] || test_failed $LINENO
"${ZUPDATE}" -N -0 -k --destdir=ddir4/tmp2/tmp3 tmp2/tmp3/a.gz || "${ZUPDATE}" -N -0 -k --destdir=ddir4/tmp0/tmp1 tmp2/tmp3/a.gz ||
test_failed $LINENO test_failed $LINENO
[ -e tmp2/tmp3/a.bz2 ] || test_failed $LINENO [ -e tmp2/tmp3/a.bz2 ] || test_failed $LINENO
[ -e tmp2/tmp3/a.gz ] || test_failed $LINENO [ -e tmp2/tmp3/a.gz ] || test_failed $LINENO
[ -e ddir4/tmp2/tmp3/a.lz ] || test_failed $LINENO [ -e ddir4/tmp0/tmp1/a.lz ] || test_failed $LINENO
rm -rf ddir1 ddir2 ddir3 ddir4 || framework_failure rm -rf ddir1 ddir2 ddir3 ddir4 || framework_failure
# test recursive in place # test recursive in place
"${ZUPDATE}" -N -0 -r --format=gz tmp2 || test_failed $LINENO "${ZUPDATE}" -N -0 -r --format=gz tmp2 || test_failed $LINENO
@ -635,8 +635,8 @@ rm -f tmp2/tmp3/a.lz || framework_failure
[ ! -e tmp2/tmp3/a.gz ] || test_failed $LINENO [ ! -e tmp2/tmp3/a.gz ] || test_failed $LINENO
[ -e tmp2/tmp3/a.lz ] || test_failed $LINENO [ -e tmp2/tmp3/a.lz ] || test_failed $LINENO
rm -f tmp2/tmp3/a.lz || framework_failure rm -f tmp2/tmp3/a.lz || framework_failure
cat in.bz2 > tmp2/tmp3/a.bz2 || framework_failure cp in.bz2 tmp2/tmp3/a.bz2 || framework_failure
cat in.gz > tmp2/tmp3/a.gz || framework_failure cp in.gz tmp2/tmp3/a.gz || framework_failure
cd tmp2 || framework_failure cd tmp2 || framework_failure
"${ZUPDATE}" -N -0 -r -k -f . || test_failed $LINENO "${ZUPDATE}" -N -0 -r -k -f . || test_failed $LINENO
[ -e tmp3/a.bz2 ] || test_failed $LINENO [ -e tmp3/a.bz2 ] || test_failed $LINENO

View file

@ -1,8 +1,7 @@
GNU GENERAL PUBLIC LICENSE GNU GENERAL PUBLIC LICENSE
Version 2, June 1991 Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc., Copyright (C) 1989, 1991 Free Software Foundation, Inc. <http://fsf.org/>
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed. of this license document, but changing it is not allowed.
@ -339,8 +338,7 @@ Public License instead of this License.
GNU GENERAL PUBLIC LICENSE GNU GENERAL PUBLIC LICENSE
Version 2, June 1991 Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc., Copyright (C) 1989, 1991 Free Software Foundation, Inc. <http://fsf.org/>
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed. of this license document, but changing it is not allowed.

Binary file not shown.

Binary file not shown.

10
zcat.cc
View file

@ -110,6 +110,8 @@ void show_help()
" -V, --version output version information and exit\n" " -V, --version output version information and exit\n"
" -A, --show-all equivalent to '-vET'\n" " -A, --show-all equivalent to '-vET'\n"
" -b, --number-nonblank number nonblank output lines\n" " -b, --number-nonblank number nonblank output lines\n"
" -c, --stdout ignored, for gzip compatibility\n"
" -d, --decompress ignored, for gzip compatibility\n"
" -e equivalent to '-vE'\n" " -e equivalent to '-vE'\n"
" -E, --show-ends display '$' at end of each line\n" " -E, --show-ends display '$' at end of each line\n"
" -M, --format=<list> process only the formats in <list>\n" " -M, --format=<list> process only the formats in <list>\n"
@ -318,14 +320,14 @@ int main( const int argc, const char * const argv[] )
cat_options.show_nonprinting = true; cat_options.show_nonprinting = true;
cat_options.show_tabs = true; break; cat_options.show_tabs = true; break;
case 'b': cat_options.number_lines = 1; break; case 'b': cat_options.number_lines = 1; break;
case 'c': break; case 'c': break; // ignored
case 'd': break; case 'd': break; // ignored
case 'e': cat_options.show_nonprinting = true; // fall through case 'e': cat_options.show_nonprinting = true; // fall through
case 'E': cat_options.show_ends = true; break; case 'E': cat_options.show_ends = true; break;
case 'f': break; case 'f': break;
case 'h': show_help(); return 0; case 'h': show_help(); return 0;
case 'l': break; case 'l': break; // ignored
case 'L': break; case 'L': break; // ignored
case 'M': parse_format_list( arg, pn ); break; case 'M': parse_format_list( arg, pn ); break;
case 'n': if( cat_options.number_lines == 0 ) case 'n': if( cat_options.number_lines == 0 )
{ cat_options.number_lines = 2; } break; { cat_options.number_lines = 2; } break;

View file

@ -105,7 +105,7 @@ const char * format_num3( long long num )
char * p = buf + bufsize - 1; // fill the buffer backwards char * p = buf + bufsize - 1; // fill the buffer backwards
*p = 0; // terminator *p = 0; // terminator
const bool negative = num < 0; const bool negative = num < 0;
if( num > 1024 || num < -1024 ) if( num > 9999 || num < -9999 )
{ {
char prefix = 0; // try binary first, then si char prefix = 0; // try binary first, then si
for( int i = 0; i < n && num != 0 && num % 1024 == 0; ++i ) for( int i = 0; i < n && num != 0 && num % 1024 == 0; ++i )
@ -430,7 +430,7 @@ int main( const int argc, const char * const argv[] )
case 'l': list = true; break; case 'l': list = true; break;
case 'M': parse_format_list( sarg, pn ); break; case 'M': parse_format_list( sarg, pn ); break;
case 'n': max_size = getnum( arg, pn ); break; case 'n': max_size = getnum( arg, pn ); break;
case 'N': break; case 'N': break; // already processed
case 'O': parse_format_types2( sarg, pn, format_types ); break; case 'O': parse_format_types2( sarg, pn, format_types ); break;
case 'q': verbosity = -1; break; case 'q': verbosity = -1; break;
case 's': scripted = true; break; case 's': scripted = true; break;

View file

@ -381,8 +381,8 @@ int main( const int argc, const char * const argv[] )
int retval = 1; int retval = 1;
bool error = false; bool error = false;
bool stdin_used = false; bool stdin_used = false;
while( next_filename( filenames, input_filename, error, recursive, while( next_filename( filenames, input_filename, error, recursive, false,
false, no_messages ) ) no_messages ) )
{ {
int infd; int infd;
if( input_filename == "." ) if( input_filename == "." )

View file

@ -35,6 +35,10 @@
#include <sys/wait.h> #include <sys/wait.h>
#if defined __MSVCRT__ || defined __OS2__ #if defined __MSVCRT__ || defined __OS2__
#include <io.h> #include <io.h>
#if defined __MSVCRT__
#include <direct.h>
#define mkdir(name,mode) _mkdir(name)
#endif
#endif #endif
#include "arg_parser.h" #include "arg_parser.h"
@ -96,24 +100,21 @@ void show_help()
" --lz=<command> set compressor and options for lzip format\n" " --lz=<command> set compressor and options for lzip format\n"
" --xz=<command> set compressor and options for xz format\n" " --xz=<command> set compressor and options for xz format\n"
" --zst=<command> set compressor and options for zstd format\n" " --zst=<command> set compressor and options for zstd format\n"
"\nValid formats for option '-M' are 'bz2', 'gz', 'lz', 'xz', and 'zst'.\n" ); "\nValid formats for option '-M' are 'bz2', 'gz', 'xz', and 'zst'.\n" );
show_help_addr(); show_help_addr();
} }
void extract_srcdir_name( const std::string & name, std::string & srcdir ) /* if name contains slash(es), copy name into srcdir up to the last slash,
removing a leading dot followed by slash(es) */
void extract_dirname( const std::string & name, std::string & srcdir )
{ {
if( name.empty() || name == "." ) return; // leave srcdir empty unsigned i = 0;
if( name[name.size()-1] == '/' ) // remove last slash unsigned j = name.size();
{ srcdir.assign( name, 0, name.size() - 1 ); return; } if( j >= 2 && name[0] == '.' && name[1] == '/' ) // remove leading "./"
struct stat st; for( i = 2; i < j && name[i] == '/'; ) ++i;
if( stat( name.c_str(), &st ) == 0 && S_ISDIR( st.st_mode ) ) while( j > i && name[j-1] != '/' ) --j; // remove last component if any
{ srcdir = name; return; } if( j > i ) srcdir.assign( name, i, j - i );
unsigned size = 0; // size of srcdir without last slash nor basename
for( unsigned i = name.size(); i > 0; --i )
if( name[i-1] == '/' ) { size = i - 1; break; }
if( size > 0 ) srcdir.assign( name, 0, size );
} }
@ -214,7 +215,7 @@ int zupdate_file( const std::string & name, const char * const lzip_name,
if( srcdir.size() && name.compare( 0, srcdir.size(), srcdir ) != 0 ) if( srcdir.size() && name.compare( 0, srcdir.size(), srcdir ) != 0 )
internal_error( "srcdir mismatch." ); internal_error( "srcdir mismatch." );
rname = destdir; rname = destdir;
if( rname[rname.size()-1] != '/' && name[srcdir.size()] != '/' ) if( rname.end()[-1] != '/' && name[srcdir.size()] != '/' )
rname += '/'; rname += '/';
rname.append( name, srcdir.size(), name.size() - srcdir.size() - rname.append( name, srcdir.size(), name.size() - srcdir.size() -
std::strlen( extension_from( eindex ) ) ); std::strlen( extension_from( eindex ) ) );
@ -488,7 +489,7 @@ int main( const int argc, const char * const argv[] )
while( true ) while( true )
{ {
std::string srcdir; // dirname to be replaced by destdir std::string srcdir; // dirname to be replaced by destdir
if( destdir.size() ) extract_srcdir_name( filenames.front(), srcdir ); if( destdir.size() ) extract_dirname( filenames.front(), srcdir );
while( next_filename( filenames, input_filename, error, recursive, true ) ) while( next_filename( filenames, input_filename, error, recursive, true ) )
{ {
int tmp = zupdate_file( input_filename, lzip_name, lzip_args2, srcdir, int tmp = zupdate_file( input_filename, lzip_name, lzip_args2, srcdir,