1
0
Fork 0

Merging upstream version 1.25~rc1.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-20 23:19:31 +01:00
parent 16efb25d5d
commit 278b811fe2
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
28 changed files with 1131 additions and 1065 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,7 +1,16 @@
2024-11-26 Antonio Diaz Diaz <antonio@gnu.org>
* Version 1.25-rc1 released.
* Remove options '--empty-error' and '--marking-error'.
* decoder.cc (decode_member): Remove support for Sync Flush marker.
* lzip.texi: New chapter 'Syntax of command-line arguments'.
* check.sh: Use 'cp' instead of 'cat'.
* testsuite: Add fox_nz.lz. Remove fox6.lz,fox6_mark.lz,test_em.txt.lz.
2024-03-01 Antonio Diaz Diaz <antonio@gnu.org> 2024-03-01 Antonio Diaz Diaz <antonio@gnu.org>
* Version 1.24.1 released. * Version 1.24.1 released.
* main.cc: Fix compilation failure on MinGW because of mkdir. * main.cc: Fix compilation failure on MinGW caused by mkdir.
2024-01-26 Antonio Diaz Diaz <antonio@gnu.org> 2024-01-26 Antonio Diaz Diaz <antonio@gnu.org>
@ -31,13 +40,13 @@
Make '-o' behave like '-c', but writing to file instead of stdout. Make '-o' behave like '-c', but writing to file instead of stdout.
Make '-c' and '-o' check whether the output is a terminal only once. Make '-c' and '-o' check whether the output is a terminal only once.
Do not open output if input is a terminal. Do not open output if input is a terminal.
Set a valid invocation_name even if argc == 0.
* configure: Build, check, and install without 'make'. * configure: Build, check, and install without 'make'.
* Replace 'decompressed', 'compressed' with 'out', 'in' in output. * Replace 'decompressed', 'compressed' with 'out', 'in' in output.
* lzip_index.cc: Improve messages for corruption in last header. * lzip_index.cc: Improve messages for corruption in last header.
* main.cc: Set a valid invocation_name even if argc == 0.
* Document extraction from tar.lz in manual, '--help', and man page. * Document extraction from tar.lz in manual, '--help', and man page.
* lzip.texi (Introduction): Mention plzip and tarlz as alternatives. * lzip.texi (Introduction): Mention plzip and tarlz as alternatives.
* lzip.texi: Several fixes and improvements. Several fixes and improvements.
* testsuite: Add 9 new test files. * testsuite: Add 9 new test files.
2019-01-03 Antonio Diaz Diaz <antonio@gnu.org> 2019-01-03 Antonio Diaz Diaz <antonio@gnu.org>
@ -47,9 +56,9 @@
* lzip.h (Lzip_trailer): New function 'verify_consistency'. * lzip.h (Lzip_trailer): New function 'verify_consistency'.
* lzip_index.cc: Detect some kinds of corrupt trailers. * lzip_index.cc: Detect some kinds of corrupt trailers.
* main.cc (main): Check return value of close( infd ). * main.cc (main): Check return value of close( infd ).
* main.cc: Compile on DOS with DJGPP. Compile on DOS with DJGPP. (Reported by Robert Riebisch).
* Fix a GCC warning about catching std::bad_alloc by value. Fix a GCC warning about catching std::bad_alloc by value.
* lzip.texi: Improve description of '-0..-9', '-m', and '-s'. * lzip.texi: Improve descriptions of '-0..-9', '-m', and '-s'.
* configure: Accept appending to CXXFLAGS; 'CXXFLAGS+=OPTIONS'. * configure: Accept appending to CXXFLAGS; 'CXXFLAGS+=OPTIONS'.
* INSTALL: Document use of CXXFLAGS+='-D __USE_MINGW_ANSI_STDIO'. * INSTALL: Document use of CXXFLAGS+='-D __USE_MINGW_ANSI_STDIO'.
@ -59,13 +68,13 @@
* New option '--loose-trailing'. * New option '--loose-trailing'.
* Improve corrupt header detection to HD=3. * Improve corrupt header detection to HD=3.
* main.cc: Show corrupt or truncated header in multimember file. * main.cc: Show corrupt or truncated header in multimember file.
* main.cc (main): Option '-S, --volume-size' now keeps input files. (main): Make option '-S, --volume-size' keep input files.
(main): Show final diagnostic when testing multiple files.
(set_c_outname): Do not add a second '.lz' to the arg of '-o'.
* encoder_base.*: Adjust dictionary size for each member. * encoder_base.*: Adjust dictionary size for each member.
* Replace 'bits/byte' with inverse compression ratio in output. * Replace 'bits/byte' with inverse compression ratio in output.
* Show progress of decompression at verbosity level 2 (-vv). * Show progress of decompression at verbosity level 2 (-vv).
* Show progress of (de)compression only if stderr is a terminal. * Show progress of (de)compression only if stderr is a terminal.
* main.cc: Show final diagnostic when testing multiple files.
* main.cc: Do not add a second extension '.lz' to the arg of '-o'.
* decoder.cc (verify_trailer): Show stored sizes also in hex. * decoder.cc (verify_trailer): Show stored sizes also in hex.
Show dictionary size at verbosity level 4 (-vvvv). Show dictionary size at verbosity level 4 (-vvvv).
* lzip.texi: New chapter 'Meaning of lzip's output'. * lzip.texi: New chapter 'Meaning of lzip's output'.
@ -78,7 +87,7 @@
* Compression time of option '-0' has been slightly reduced. * Compression time of option '-0' has been slightly reduced.
* Decompression time has been reduced by 2%. * Decompression time has been reduced by 2%.
* main.cc: Continue testing if any input file is a terminal. * main.cc: Continue testing if any input file is a terminal.
* main.cc: Show trailing data in both hexadecimal and ASCII. Show trailing data in both hexadecimal and ASCII.
* encoder.cc (Matchfinder_base): Check the size passed to new. * encoder.cc (Matchfinder_base): Check the size passed to new.
* lzip_index.cc: Improve detection of bad dict and trailing data. * lzip_index.cc: Improve detection of bad dict and trailing data.
* lzip.h: Unify messages for bad magic, trailing data, etc. * lzip.h: Unify messages for bad magic, trailing data, etc.
@ -88,15 +97,14 @@
* Version 1.18 released. * Version 1.18 released.
* New option '-a, --trailing-error'. * New option '-a, --trailing-error'.
* Decompression time has been reduced by 2%. * Decompression time has been reduced by 2%.
* decoder.cc (verify_trailer): Remove test of final code.
* main.cc (main): Delete '--output' file if infd is a terminal. * main.cc (main): Delete '--output' file if infd is a terminal.
* main.cc (main): Don't use stdin more than once. (main): Don't use stdin more than once.
* Remove decompression support for version 0 files. * Remove decompression support for version 0 files.
* decoder.cc (verify_trailer): Remove test of final code.
* lzip.texi: New chapter 'Trailing data'. * lzip.texi: New chapter 'Trailing data'.
* 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. Don't check error messages.
* check.sh: Don't check error messages.
2015-07-12 Antonio Diaz Diaz <antonio@gnu.org> 2015-07-12 Antonio Diaz Diaz <antonio@gnu.org>
@ -134,8 +142,8 @@
* Compression time has been reduced by 5%. * Compression time has been reduced by 5%.
* Decompression time has been reduced by 12%. * Decompression time has been reduced by 12%.
* Makefile.in: New target 'install-bin'. * Makefile.in: New target 'install-bin'.
* main.cc: Use 'setmode' instead of '_setmode' on Windows and OS/2.
* main.cc: Define 'strtoull' to 'std::strtoul' on Windows. * main.cc: Define 'strtoull' to 'std::strtoul' on Windows.
(main): Use 'setmode' instead of '_setmode' on Windows and OS/2.
2012-02-24 Antonio Diaz Diaz <ant_diaz@teleline.es> 2012-02-24 Antonio Diaz Diaz <ant_diaz@teleline.es>
@ -163,14 +171,12 @@
* Compression time of option '-0' has been reduced by 2%. * Compression time of option '-0' has been reduced by 2%.
* main.cc (decompress): Print only one status line for each * main.cc (decompress): Print only one status line for each
multimember file when only one '-v' is specified. multimember file when only one '-v' is specified.
* main.cc (decompress): Print up to 6 bytes of trailing data when (decompress): Print 6 bytes of trailing data at verbosity level 4.
'-vvvv' is specified. (open_instream): Don't show the message
* main.cc (open_instream): Don't show the message
" and '--stdout' was not specified" for directories, etc. " and '--stdout' was not specified" for directories, etc.
* lziprecover.cc: If '-v' is not specified show errors only. * lziprecover.cc: If '-v' is not specified show errors only.
* unzcrash.cc: Use Arg_parser. * unzcrash.cc: Use Arg_parser.
* unzcrash.cc: New options '-b, --bits', '-p, --position', and New options '-b, --bits', '-p, --position', and '-s, --size'.
'-s, --size'.
2010-09-16 Antonio Diaz Diaz <ant_diaz@teleline.es> 2010-09-16 Antonio Diaz Diaz <ant_diaz@teleline.es>
@ -183,28 +189,26 @@
compress less but faster. (-1 now takes 43% less time for only 20% compress less but faster. (-1 now takes 43% less time for only 20%
larger compressed size). larger compressed size).
Exit with status 1 if any output file exists and is skipped. Exit with status 1 if any output file exists and is skipped.
Fix warning about fchown's return value being ignored.
(main): Set stdin/stdout in binary mode on MSVC and OS2.
* Compression ratio of option '-9' has been slightly increased. * Compression ratio of option '-9' has been slightly increased.
* lziprecover.cc: New option '-m, --merge', which tries to produce a
correct file by merging the good parts of two or more damaged copies.
* lziprecover.cc: New option '-R, --repair' for repairing a
1-byte error in single-member files.
* decoder.cc (decode_member): Detect file errors earlier to improve * decoder.cc (decode_member): Detect file errors earlier to improve
efficiency of lziprecover's new repair capability. efficiency of lziprecover's new repair capability.
This change also prevents (harmless) access to uninitialized This change also prevents (harmless) access to uninitialized
memory when decompressing a corrupt file. memory when decompressing a corrupt file.
* lziprecover.cc: New options '-f, --force' and '-o, --output'. (verify_trailer): '-tvvvv' now also shows compression ratio.
* lziprecover.cc: New option '-s, --split' to select the until now * lziprecover.cc: New option '-m, --merge', which tries to produce a
only operation of splitting multimember files. correct file by merging the good parts of two or more damaged copies.
* lziprecover.cc: If no operation is specified, warn the user and do New option '-R, --repair' for repairing a 1-byte error in
nothing. single-member files.
* main.cc: Fix warning about fchown's return value being ignored. New options '-f, --force' and '-o, --output'.
* decoder.cc: '-tvvvv' now also shows compression ratio. New option '-s, --split' to select the until now only operation of
* main.cc: Set stdin/stdout in binary mode on MSVC and OS2. splitting multimember files.
If no operation is specified, warn the user and do nothing.
* lzip.texinfo: New examples. * lzip.texinfo: New examples.
* testsuite: Rename 'test1' to 'test.txt'. New tests. * testsuite: Rename 'test1' to 'test.txt'. New tests.
* Matchfinder types HC4 (4 bytes hash-chain) and HT4 (4 bytes * Matchfinder types HC4 (4 bytes hash-chain) and HT4 (4 bytes
hash-table) have been tested and found no better than the current hash-table) have been tested and found no better than current BT4.
BT4.
2010-04-05 Antonio Diaz Diaz <ant_diaz@teleline.es> 2010-04-05 Antonio Diaz Diaz <ant_diaz@teleline.es>
@ -212,9 +216,9 @@
* decoder.h: Input_buffer integrated in Range_decoder. * decoder.h: Input_buffer integrated in Range_decoder.
* main.cc: File specified with option '-o' is now created with mode * main.cc: File specified with option '-o' is now created with mode
0666 if umask allows it, deleted if interrupted by user. 0666 if umask allows it, deleted if interrupted by user.
* main.cc: New constant 'o_binary'. New constant 'o_binary'.
* main.cc: Dictionary size for options -2, -3, -4 and -8 has been (main): Change dictionary size for options -2, -3, -4 and -8 to
changed to improve linearity of compressed sizes. improve linearity of compressed sizes.
* lzip.h: Fix warnings produced by over-optimization (-O3). * lzip.h: Fix warnings produced by over-optimization (-O3).
* Makefile.in: Add quotes to directory names. * Makefile.in: Add quotes to directory names.
@ -241,7 +245,7 @@
* Version 1.6 released. * Version 1.6 released.
* Decompression time has been reduced by 17%. * Decompression time has been reduced by 17%.
* Add decompression support for Sync Flush marker. * decoder.cc (decode_member): Add support for Sync Flush marker.
* Add support for the extension '.tbz' to lzdiff and lzgrep. * Add support for the extension '.tbz' to lzdiff and lzgrep.
* Add man pages for lzdiff, lzgrep and lziprecover. * Add man pages for lzdiff, lzgrep and lziprecover.
* encoder.cc (Matchfinder): Reduce memory use to 9x if input file is * encoder.cc (Matchfinder): Reduce memory use to 9x if input file is
@ -265,8 +269,7 @@
* Compression speed has been improved. * Compression speed has been improved.
* Implement bt4 type matchfinder. * Implement bt4 type matchfinder.
* lzip.texinfo: New chapter 'Algorithm'. * lzip.texinfo: New chapter 'Algorithm'.
* Lzdiff and lzgrep now accept '-h' for '--help' and * lzdiff, lzgrep: Accept '-h' for '--help' and '-V' for '--version'.
'-V' for '--version'.
* Makefile.in: Man page is now installed by default. * Makefile.in: Man page is now installed by default.
* check.sh: Check that files are opened in binary mode. * check.sh: Check that files are opened in binary mode.
@ -330,7 +333,7 @@
* Version 0.3 released. * Version 0.3 released.
* encoder.cc: Compression is now 15% faster, 1% worse. * encoder.cc: Compression is now 15% faster, 1% worse.
* main.cc (main): Make option '-t' override '-c'. * main.cc (main): Make option '-t' override '-c'.
* main.cc (decompress): Show 'done' instead of 'ok' when not testing. (decompress): Show 'done' instead of 'ok' when not testing.
* encoder.h: Use trials[] to return the list of pairs. * encoder.h: Use trials[] to return the list of pairs.
2008-09-09 Antonio Diaz Diaz <ant_diaz@teleline.es> 2008-09-09 Antonio Diaz Diaz <ant_diaz@teleline.es>

View file

@ -2,8 +2,8 @@
DISTNAME = $(pkgname)-$(pkgversion) DISTNAME = $(pkgname)-$(pkgversion)
INSTALL = install INSTALL = install
INSTALL_PROGRAM = $(INSTALL) -m 755 INSTALL_PROGRAM = $(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
@ -28,6 +28,11 @@ main.o : main.cc
%.o : %.cc %.o : %.cc
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $< $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $<
# prevent 'make' from trying to remake source files
$(VPATH)/configure $(VPATH)/Makefile.in $(VPATH)/doc/$(pkgname).texi : ;
MAKEFLAGS += -r
.SUFFIXES :
$(objs) : Makefile $(objs) : Makefile
arg_parser.o : arg_parser.h arg_parser.o : arg_parser.h
decoder.o : lzip.h decoder.h decoder.o : lzip.h decoder.h
@ -121,10 +126,7 @@ dist : doc
$(DISTNAME)/testsuite/test.txt \ $(DISTNAME)/testsuite/test.txt \
$(DISTNAME)/testsuite/fox.lz \ $(DISTNAME)/testsuite/fox.lz \
$(DISTNAME)/testsuite/fox_*.lz \ $(DISTNAME)/testsuite/fox_*.lz \
$(DISTNAME)/testsuite/fox6.lz \ $(DISTNAME)/testsuite/test.txt.lz
$(DISTNAME)/testsuite/fox6_mark.lz \
$(DISTNAME)/testsuite/test.txt.lz \
$(DISTNAME)/testsuite/test_em.txt.lz
rm -f $(DISTNAME) rm -f $(DISTNAME)
lzip -v -9 $(DISTNAME).tar lzip -v -9 $(DISTNAME).tar

23
NEWS
View file

@ -1,20 +1,11 @@
Changes in version 1.24: Changes in version 1.25:
The option '--empty-error', which forces exit status 2 if any empty member lzip now exits with error status 2 if any empty member is found in a
is found, has been added. multimember file.
The option '--marking-error', which forces exit status 2 if the first LZMA lzip now exits with error status 2 if the first byte of the LZMA stream is
byte is non-zero in any member, has been added. not 0.
File diagnostics have been reformatted as 'PROGRAM: FILE: MESSAGE'. Options '--empty-error' and '--marking-error' have been removed.
Diagnostics caused by invalid arguments to command-line options now show the The chapter 'Syntax of command-line arguments' has been added to the manual.
argument and the name of the option.
The option '-o, --output' now preserves dates, permissions, and ownership of
the file when (de)compressing exactly one file.
The option '-o, --output' now creates missing intermediate directories when
writing to a file.
The variable MAKEINFO has been added to configure and Makefile.in.

43
README
View file

@ -1,16 +1,18 @@
See the file INSTALL for compilation and installation instructions.
Description Description
Lzip is a lossless data compressor with a user interface similar to the one Lzip is a lossless data compressor with a user interface similar to the one
of gzip or bzip2. Lzip uses a simplified form of the 'Lempel-Ziv-Markov of gzip or bzip2. Lzip uses a simplified form of LZMA (Lempel-Ziv-Markov
chain-Algorithm' (LZMA) stream format to maximize interoperability. The chain-Algorithm) designed to achieve complete interoperability between
maximum dictionary size is 512 MiB so that any lzip file can be decompressed implementations. The maximum dictionary size is 512 MiB so that any lzip
on 32-bit machines. Lzip provides accurate and robust 3-factor integrity file can be decompressed on 32-bit machines. Lzip provides accurate and
checking. Lzip can compress about as fast as gzip (lzip -0) or compress most robust 3-factor integrity checking. 'lzip -0' compresses about as fast as
files more than bzip2 (lzip -9). Decompression speed is intermediate between gzip, while 'lzip -9' compresses most files more than bzip2. Decompression
gzip and bzip2. Lzip is better than gzip and bzip2 from a data recovery speed is intermediate between gzip and bzip2. Lzip provides better data
perspective. Lzip has been designed, written, and tested with great care to recovery capabilities than gzip and bzip2. Lzip has been designed, written,
replace gzip and bzip2 as the standard general-purpose compressed format for and tested with great care to replace gzip and bzip2 as general-purpose
Unix-like systems. compressed format for Unix-like systems.
For compressing/decompressing large files on multiprocessor machines plzip For compressing/decompressing large files on multiprocessor machines plzip
can be much faster than lzip at the cost of a slightly reduced compression can be much faster than lzip at the cost of a slightly reduced compression
@ -23,11 +25,10 @@ alignment between tar members and lzip members.
The lzip file format is designed for data sharing and long-term archiving, The lzip file format is designed for data sharing and long-term archiving,
taking into account both data integrity and decoder availability: taking into account both data integrity and decoder availability:
* The lzip format provides very safe integrity checking and some data * The program lziprecover can repair bit flip errors (one of the most
recovery means. The program lziprecover can repair bit flip errors common forms of data corruption) in lzip files, and provides data
(one of the most common forms of data corruption) in lzip files, and recovery capabilities, including error-checked merging of damaged
provides data recovery capabilities, including error-checked merging copies of a file.
of damaged copies of a file.
* The lzip format is as simple as possible (but not simpler). The lzip * The lzip format is as simple as possible (but not simpler). The lzip
manual provides the source code of a simple decompressor along with a manual provides the source code of a simple decompressor along with a
@ -91,7 +92,6 @@ also supported.
Lzip can produce multimember files, and lziprecover can safely recover the Lzip can produce multimember files, and lziprecover can safely recover the
undamaged members in case of file damage. Lzip can also split the compressed undamaged members in case of file damage. Lzip can also split the compressed
output in volumes of a given size, even when reading from standard input. output in volumes of a given size, even when reading from standard input.
This allows the direct creation of multivolume compressed tar archives.
Lzip is able to compress and decompress streams of unlimited size by Lzip is able to compress and decompress streams of unlimited size by
automatically creating multimember output. The members so created are large, automatically creating multimember output. The members so created are large,
@ -101,10 +101,10 @@ In spite of its name (Lempel-Ziv-Markov chain-Algorithm), LZMA is not a
concrete algorithm; it is more like "any algorithm using the LZMA coding concrete algorithm; it is more like "any algorithm using the LZMA coding
scheme". For example, the option '-0' of lzip uses the scheme in almost the scheme". For example, the option '-0' of lzip uses the scheme in almost the
simplest way possible; issuing the longest match it can find, or a literal simplest way possible; issuing the longest match it can find, or a literal
byte if it can't find a match. Inversely, a much more elaborated way of byte if it can't find a match. Inversely, a more elaborate way of finding
finding coding sequences of minimum size than the one currently used by lzip coding sequences of minimum size than the one currently used by lzip could
could be developed, and the resulting sequence could also be coded using the be developed, and the resulting sequence could also be coded using the LZMA
LZMA coding scheme. coding scheme.
Lzip currently implements two variants of the LZMA algorithm: fast Lzip currently implements two variants of the LZMA algorithm: fast
(used by option '-0') and normal (used by all other compression levels). (used by option '-0') and normal (used by all other compression levels).
@ -121,6 +121,9 @@ definition of Markov chains), G.N.N. Martin (for the definition of range
encoding), Igor Pavlov (for putting all the above together in LZMA), and encoding), Igor Pavlov (for putting all the above together in LZMA), and
Julian Seward (for bzip2's CLI). Julian Seward (for bzip2's CLI).
Lzip uses Arg_parser for command-line argument parsing:
http://www.nongnu.org/arg-parser/arg_parser.html
LANGUAGE NOTE: Uncompressed = not compressed = plain data; it may never have 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.

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=lzip pkgname=lzip
pkgversion=1.24.1 pkgversion=1.25-rc1
progname=lzip progname=lzip
srctrigger=doc/${pkgname}.texi srctrigger=doc/${pkgname}.texi
@ -119,7 +119,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

@ -74,7 +74,7 @@ bool Range_decoder::read_block()
{ {
stream_pos = readblock( infd, buffer, buffer_size ); stream_pos = readblock( infd, buffer, buffer_size );
if( stream_pos != buffer_size && errno ) throw Error( "Read error" ); if( stream_pos != buffer_size && errno ) throw Error( "Read error" );
at_stream_end = ( stream_pos < buffer_size ); at_stream_end = stream_pos < buffer_size;
partial_member_pos += pos; partial_member_pos += pos;
pos = 0; pos = 0;
show_dprogress(); show_dprogress();
@ -90,7 +90,7 @@ void LZ_decoder::flush_data()
const int size = pos - stream_pos; const int size = pos - stream_pos;
crc32.update_buf( crc_, buffer + stream_pos, size ); crc32.update_buf( crc_, buffer + stream_pos, size );
if( outfd >= 0 && writeblock( outfd, buffer + stream_pos, size ) != size ) if( outfd >= 0 && writeblock( outfd, buffer + stream_pos, size ) != size )
throw Error( "Write error" ); throw Error( write_error_msg );
if( pos >= dictionary_size ) if( pos >= dictionary_size )
{ partial_data_pos += pos; pos = 0; pos_wrapped = true; } { partial_data_pos += pos; pos = 0; pos_wrapped = true; }
stream_pos = pos; stream_pos = pos;
@ -98,8 +98,7 @@ void LZ_decoder::flush_data()
} }
int LZ_decoder::check_trailer( const Pretty_print & pp, bool LZ_decoder::check_trailer( const Pretty_print & pp ) const
const bool ignore_empty ) const
{ {
Lzip_trailer trailer; Lzip_trailer trailer;
int size = rdec.read_data( trailer.data, trailer.size ); int size = rdec.read_data( trailer.data, trailer.size );
@ -144,8 +143,7 @@ int LZ_decoder::check_trailer( const Pretty_print & pp,
std::fprintf( stderr, "Member size mismatch; stored %llu (0x%llX), computed %llu (0x%llX)\n", std::fprintf( stderr, "Member size mismatch; stored %llu (0x%llX), computed %llu (0x%llX)\n",
tm_size, tm_size, member_size, member_size ); } tm_size, tm_size, member_size, member_size ); }
} }
if( error ) return 3; if( error ) return false;
if( !ignore_empty && data_size == 0 ) return 5;
if( verbosity >= 2 ) if( verbosity >= 2 )
{ {
if( verbosity >= 4 ) show_header( dictionary_size ); if( verbosity >= 4 ) show_header( dictionary_size );
@ -160,15 +158,14 @@ int LZ_decoder::check_trailer( const Pretty_print & pp,
if( verbosity >= 3 ) if( verbosity >= 3 )
std::fprintf( stderr, "%9llu out, %8llu in. ", data_size, member_size ); std::fprintf( stderr, "%9llu out, %8llu in. ", data_size, member_size );
} }
return 0; return true;
} }
/* Return value: 0 = OK, 1 = decoder error, 2 = unexpected EOF, /* Return value: 0 = OK, 1 = decoder error, 2 = unexpected EOF,
3 = trailer error, 4 = unknown marker found, 3 = trailer error, 4 = unknown marker found,
5 = empty member found, 6 = marked member found. */ 5 = nonzero first LZMA byte found. */
int LZ_decoder::decode_member( const Cl_options & cl_opts, int LZ_decoder::decode_member( const Pretty_print & pp )
const Pretty_print & pp )
{ {
Bit_model bm_literal[1<<literal_context_bits][0x300]; Bit_model bm_literal[1<<literal_context_bits][0x300];
Bit_model bm_match[State::states][pos_states]; Bit_model bm_match[State::states][pos_states];
@ -188,7 +185,7 @@ int LZ_decoder::decode_member( const Cl_options & cl_opts,
unsigned rep3 = 0; unsigned rep3 = 0;
State state; State state;
if( !rdec.load( cl_opts.ignore_marking ) ) return 6; if( !rdec.load() ) return 5;
while( !rdec.finished() ) while( !rdec.finished() )
{ {
const int pos_state = data_position() & pos_state_mask; const int pos_state = data_position() & pos_state_mask;
@ -232,39 +229,33 @@ int LZ_decoder::decode_member( const Cl_options & cl_opts,
} }
else // match else // match
{ {
rep3 = rep2; rep2 = rep1; rep1 = rep0;
len = rdec.decode_len( match_len_model, pos_state ); len = rdec.decode_len( match_len_model, pos_state );
unsigned distance = rdec.decode_tree6( bm_dis_slot[get_len_state(len)] ); rep0 = rdec.decode_tree6( bm_dis_slot[get_len_state(len)] );
if( distance >= start_dis_model ) if( rep0 >= start_dis_model )
{ {
const unsigned dis_slot = distance; const unsigned dis_slot = rep0;
const int direct_bits = ( dis_slot >> 1 ) - 1; const int direct_bits = ( dis_slot >> 1 ) - 1;
distance = ( 2 | ( dis_slot & 1 ) ) << direct_bits; rep0 = ( 2 | ( dis_slot & 1 ) ) << direct_bits;
if( dis_slot < end_dis_model ) if( dis_slot < end_dis_model )
distance += rdec.decode_tree_reversed( rep0 += rdec.decode_tree_reversed( bm_dis + ( rep0 - dis_slot ),
bm_dis + ( distance - dis_slot ), direct_bits ); direct_bits );
else else
{ {
distance += rep0 += rdec.decode( direct_bits - dis_align_bits ) << dis_align_bits;
rdec.decode( direct_bits - dis_align_bits ) << dis_align_bits; rep0 += rdec.decode_tree_reversed4( bm_align );
distance += rdec.decode_tree_reversed4( bm_align ); if( rep0 == 0xFFFFFFFFU ) // marker found
if( distance == 0xFFFFFFFFU ) // marker found
{ {
rdec.normalize(); rdec.normalize();
flush_data(); flush_data();
if( len == min_match_len ) // End Of Stream marker if( len == min_match_len ) // End Of Stream marker
return check_trailer( pp, cl_opts.ignore_empty ); { if( check_trailer( pp ) ) return 0; else return 3; }
if( len == min_match_len + 1 ) // Sync Flush marker if( verbosity >= 0 ) { pp();
{ rdec.load(); continue; } std::fprintf( stderr, "Unsupported marker code '%d'\n", len ); }
if( verbosity >= 0 )
{
pp();
std::fprintf( stderr, "Unsupported marker code '%d'\n", len );
}
return 4; return 4;
} }
} }
} }
rep3 = rep2; rep2 = rep1; rep1 = rep0; rep0 = distance;
state.set_match(); state.set_match();
if( rep0 >= dictionary_size || ( rep0 >= pos && !pos_wrapped ) ) if( rep0 >= dictionary_size || ( rep0 >= pos && !pos_wrapped ) )
{ flush_data(); return 1; } { flush_data(); return 1; }

View file

@ -75,12 +75,12 @@ public:
return sz; return sz;
} }
bool load( const bool ignore_marking = true ) bool load()
{ {
code = 0; code = 0;
range = 0xFFFFFFFFU; range = 0xFFFFFFFFU;
// check and discard first byte of the LZMA stream // check first byte of the LZMA stream
if( get_byte() != 0 && !ignore_marking ) return false; if( get_byte() != 0 ) return false;
for( int i = 0; i < 4; ++i ) code = ( code << 8 ) | get_byte(); for( int i = 0; i < 4; ++i ) code = ( code << 8 ) | get_byte();
return true; return true;
} }
@ -100,7 +100,7 @@ public:
range >>= 1; range >>= 1;
// symbol <<= 1; // symbol <<= 1;
// if( code >= range ) { code -= range; symbol |= 1; } // if( code >= range ) { code -= range; symbol |= 1; }
const bool bit = ( code >= range ); const bool bit = code >= range;
symbol <<= 1; symbol += bit; symbol <<= 1; symbol += bit;
code -= range & ( 0U - bit ); code -= range & ( 0U - bit );
} }
@ -270,7 +270,7 @@ class LZ_decoder
bool pos_wrapped; bool pos_wrapped;
void flush_data(); void flush_data();
int check_trailer( const Pretty_print & pp, const bool ignore_empty ) const; bool check_trailer( const Pretty_print & pp ) const;
uint8_t peek_prev() const uint8_t peek_prev() const
{ return buffer[((pos > 0) ? pos : dictionary_size)-1]; } { return buffer[((pos > 0) ? pos : dictionary_size)-1]; }
@ -294,14 +294,14 @@ class LZ_decoder
bool fast, fast2; bool fast, fast2;
if( lpos > distance ) if( lpos > distance )
{ {
fast = ( len < dictionary_size - lpos ); fast = len < dictionary_size - lpos;
fast2 = ( fast && len <= lpos - i ); fast2 = fast && len <= lpos - i;
} }
else else
{ {
i += dictionary_size; i += dictionary_size;
fast = ( len < dictionary_size - i ); // (i == pos) may happen fast = len < dictionary_size - i; // (i == pos) may happen
fast2 = ( fast && len <= i - lpos ); fast2 = fast && len <= i - lpos;
} }
if( fast ) // no wrap if( fast ) // no wrap
{ {
@ -342,5 +342,5 @@ public:
unsigned crc() const { return crc_ ^ 0xFFFFFFFFU; } unsigned crc() const { return crc_ ^ 0xFFFFFFFFU; }
unsigned long long data_position() const { return partial_data_pos + pos; } unsigned long long data_position() const { return partial_data_pos + pos; }
int decode_member( const Cl_options & cl_opts, const Pretty_print & pp ); int decode_member( const Pretty_print & pp );
}; };

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 LZIP "1" "March 2024" "lzip 1.24.1" "User Commands" .TH LZIP "1" "November 2024" "lzip 1.25-rc1" "User Commands"
.SH NAME .SH NAME
lzip \- reduces the size of files lzip \- reduces the size of files
.SH SYNOPSIS .SH SYNOPSIS
@ -7,16 +7,16 @@ lzip \- reduces the size of files
[\fI\,options\/\fR] [\fI\,files\/\fR] [\fI\,options\/\fR] [\fI\,files\/\fR]
.SH DESCRIPTION .SH DESCRIPTION
Lzip is a lossless data compressor with a user interface similar to the one Lzip is a lossless data compressor with a user interface similar to the one
of gzip or bzip2. Lzip uses a simplified form of the 'Lempel\-Ziv\-Markov of gzip or bzip2. Lzip uses a simplified form of LZMA (Lempel\-Ziv\-Markov
chain\-Algorithm' (LZMA) stream format to maximize interoperability. The chain\-Algorithm) designed to achieve complete interoperability between
maximum dictionary size is 512 MiB so that any lzip file can be decompressed implementations. The maximum dictionary size is 512 MiB so that any lzip
on 32\-bit machines. Lzip provides accurate and robust 3\-factor integrity file can be decompressed on 32\-bit machines. Lzip provides accurate and
checking. Lzip can compress about as fast as gzip (lzip \fB\-0\fR) or compress most robust 3\-factor integrity checking. 'lzip \fB\-0\fR' compresses about as fast as
files more than bzip2 (lzip \fB\-9\fR). Decompression speed is intermediate between gzip, while 'lzip \fB\-9\fR' compresses most files more than bzip2. Decompression
gzip and bzip2. Lzip is better than gzip and bzip2 from a data recovery speed is intermediate between gzip and bzip2. Lzip provides better data
perspective. Lzip has been designed, written, and tested with great care to recovery capabilities than gzip and bzip2. Lzip has been designed, written,
replace gzip and bzip2 as the standard general\-purpose compressed format for and tested with great care to replace gzip and bzip2 as general\-purpose
Unix\-like systems. compressed format for Unix\-like systems.
.SH OPTIONS .SH OPTIONS
.TP .TP
\fB\-h\fR, \fB\-\-help\fR \fB\-h\fR, \fB\-\-help\fR
@ -29,7 +29,7 @@ output version information and exit
exit with error status if trailing data exit with error status if trailing data
.TP .TP
\fB\-b\fR, \fB\-\-member\-size=\fR<bytes> \fB\-b\fR, \fB\-\-member\-size=\fR<bytes>
set member size limit in bytes set member size limit of multimember files
.TP .TP
\fB\-c\fR, \fB\-\-stdout\fR \fB\-c\fR, \fB\-\-stdout\fR
write to standard output, keep input files write to standard output, keep input files
@ -79,12 +79,6 @@ alias for \fB\-0\fR
\fB\-\-best\fR \fB\-\-best\fR
alias for \fB\-9\fR alias for \fB\-9\fR
.TP .TP
\fB\-\-empty\-error\fR
exit with error status if empty member in file
.TP
\fB\-\-marking\-error\fR
exit with error status if 1st LZMA byte not 0
.TP
\fB\-\-loose\-trailing\fR \fB\-\-loose\-trailing\fR
allow trailing data seeming corrupt header allow trailing data seeming corrupt header
.PP .PP

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -478,7 +478,7 @@ bool LZ_encoder::encode_member( const unsigned long long member_size )
{ {
const unsigned long long member_size_limit = const unsigned long long member_size_limit =
member_size - Lzip_trailer::size - max_marker_size; member_size - Lzip_trailer::size - max_marker_size;
const bool best = ( match_len_limit > 12 ); const bool best = match_len_limit > 12;
const int dis_price_count = best ? 1 : 512; const int dis_price_count = best ? 1 : 512;
const int align_price_count = best ? 1 : dis_align_size; const int align_price_count = best ? 1 : dis_align_size;
const int price_count = ( match_len_limit > 36 ) ? 1013 : 4093; const int price_count = ( match_len_limit > 36 ) ? 1013 : 4093;
@ -529,7 +529,7 @@ bool LZ_encoder::encode_member( const unsigned long long member_size )
const int len = trials[i].price; const int len = trials[i].price;
int dis = trials[i].dis4; int dis = trials[i].dis4;
bool bit = ( dis < 0 ); bool bit = dis < 0;
renc.encode_bit( bm_match[state()][pos_state], !bit ); renc.encode_bit( bm_match[state()][pos_state], !bit );
if( bit ) // literal byte if( bit ) // literal byte
{ {
@ -548,11 +548,11 @@ bool LZ_encoder::encode_member( const unsigned long long member_size )
{ {
crc32.update_buf( crc_, ptr_to_current_pos() - ahead, len ); crc32.update_buf( crc_, ptr_to_current_pos() - ahead, len );
mtf_reps( dis, reps ); mtf_reps( dis, reps );
bit = ( dis < num_rep_distances ); bit = dis < num_rep_distances;
renc.encode_bit( bm_rep[state()], bit ); renc.encode_bit( bm_rep[state()], bit );
if( bit ) // repeated match if( bit ) // repeated match
{ {
bit = ( dis == 0 ); bit = dis == 0;
renc.encode_bit( bm_rep0[state()], !bit ); renc.encode_bit( bm_rep0[state()], !bit );
if( bit ) if( bit )
renc.encode_bit( bm_len[state()][pos_state], len > 1 ); renc.encode_bit( bm_len[state()][pos_state], len > 1 );

View file

@ -147,7 +147,7 @@ void Range_encoder::flush_data()
if( pos > 0 ) if( pos > 0 )
{ {
if( outfd >= 0 && writeblock( outfd, buffer, pos ) != pos ) if( outfd >= 0 && writeblock( outfd, buffer, pos ) != pos )
throw Error( "Write error" ); throw Error( write_error_msg );
partial_member_pos += pos; partial_member_pos += pos;
pos = 0; pos = 0;
show_cprogress(); show_cprogress();

View file

@ -238,7 +238,7 @@ class Range_encoder
{ {
if( low >> 24 != 0xFF ) if( low >> 24 != 0xFF )
{ {
const bool carry = ( low > 0xFFFFFFFFU ); const bool carry = low > 0xFFFFFFFFU;
put_byte( cache + carry ); put_byte( cache + carry );
for( ; ff_count > 0; --ff_count ) put_byte( 0xFF + carry ); for( ; ff_count > 0; --ff_count ) put_byte( 0xFF + carry );
cache = low >> 24; cache = low >> 24;
@ -378,13 +378,13 @@ public:
void encode_len( Len_model & lm, int symbol, const int pos_state ) void encode_len( Len_model & lm, int symbol, const int pos_state )
{ {
bool bit = ( ( symbol -= min_match_len ) >= len_low_symbols ); bool bit = ( symbol -= min_match_len ) >= len_low_symbols;
encode_bit( lm.choice1, bit ); encode_bit( lm.choice1, bit );
if( !bit ) if( !bit )
encode_tree3( lm.bm_low[pos_state], symbol ); encode_tree3( lm.bm_low[pos_state], symbol );
else else
{ {
bit = ( ( symbol -= len_low_symbols ) >= len_mid_symbols ); bit = ( symbol -= len_low_symbols ) >= len_mid_symbols;
encode_bit( lm.choice2, bit ); encode_bit( lm.choice2, bit );
if( !bit ) if( !bit )
encode_tree3( lm.bm_mid[pos_state], symbol ); encode_tree3( lm.bm_mid[pos_state], symbol );

13
list.cc
View file

@ -17,6 +17,7 @@
#define _FILE_OFFSET_BITS 64 #define _FILE_OFFSET_BITS 64
#include <cerrno>
#include <cstdio> #include <cstdio>
#include <cstring> #include <cstring>
#include <string> #include <string>
@ -57,7 +58,7 @@ int list_files( const std::vector< std::string > & filenames,
for( unsigned i = 0; i < filenames.size(); ++i ) for( unsigned i = 0; i < filenames.size(); ++i )
{ {
const bool from_stdin = ( filenames[i] == "-" ); const bool from_stdin = filenames[i] == "-";
if( from_stdin ) { if( stdin_used ) continue; else stdin_used = true; } if( from_stdin ) { if( stdin_used ) continue; else stdin_used = true; }
const char * const input_filename = const char * const input_filename =
from_stdin ? "(stdin)" : filenames[i].c_str(); from_stdin ? "(stdin)" : filenames[i].c_str();
@ -74,6 +75,8 @@ int list_files( const std::vector< std::string > & filenames,
set_retval( retval, lzip_index.retval() ); set_retval( retval, lzip_index.retval() );
continue; continue;
} }
const bool multi_empty = !from_stdin && lzip_index.multi_empty();
if( multi_empty ) set_retval( retval, 2 );
if( verbosity < 0 ) continue; if( verbosity < 0 ) continue;
const unsigned long long udata_size = lzip_index.udata_size(); const unsigned long long udata_size = lzip_index.udata_size();
const unsigned long long cdata_size = lzip_index.cdata_size(); const unsigned long long cdata_size = lzip_index.cdata_size();
@ -85,6 +88,8 @@ int list_files( const std::vector< std::string > & filenames,
if( verbosity >= 1 ) std::fputs( " dict memb trail ", stdout ); if( verbosity >= 1 ) std::fputs( " dict memb trail ", stdout );
std::fputs( " uncompressed compressed saved name\n", stdout ); std::fputs( " uncompressed compressed saved name\n", stdout );
} }
if( multi_empty )
{ std::fflush( stdout ); show_file_error( input_filename, empty_msg ); }
if( verbosity >= 1 ) if( verbosity >= 1 )
std::printf( "%s %5ld %6lld ", format_ds( lzip_index.dictionary_size() ), std::printf( "%s %5ld %6lld ", format_ds( lzip_index.dictionary_size() ),
members, lzip_index.file_size() - cdata_size ); members, lzip_index.file_size() - cdata_size );
@ -103,12 +108,16 @@ int list_files( const std::vector< std::string > & filenames,
first_post = true; // reprint heading after list of members first_post = true; // reprint heading after list of members
} }
std::fflush( stdout ); std::fflush( stdout );
if( std::ferror( stdout ) ) break;
} }
if( verbosity >= 0 && files > 1 ) if( verbosity >= 0 && files > 1 && !std::ferror( stdout ) )
{ {
if( verbosity >= 1 ) std::fputs( " ", stdout ); if( verbosity >= 1 ) std::fputs( " ", stdout );
list_line( total_uncomp, total_comp, "(totals)" ); list_line( total_uncomp, total_comp, "(totals)" );
std::fflush( stdout ); std::fflush( stdout );
} }
if( verbosity >= 0 && ( std::ferror( stdout ) || std::fclose( stdout ) != 0 ) )
{ show_file_error( "(stdout)", write_error_msg, errno );
set_retval( retval, 1 ); }
return retval; return retval;
} }

9
lzip.h
View file

@ -313,14 +313,10 @@ struct Lzip_trailer
struct Cl_options // command-line options struct Cl_options // command-line options
{ {
bool ignore_empty;
bool ignore_marking;
bool ignore_trailing; bool ignore_trailing;
bool loose_trailing; bool loose_trailing;
Cl_options() Cl_options() : ignore_trailing( true ), loose_trailing( false ) {}
: ignore_empty( true ), ignore_marking( true ),
ignore_trailing( true ), loose_trailing( false ) {}
}; };
@ -337,8 +333,9 @@ const char * const bad_magic_msg = "Bad magic number (file not in lzip format)."
const char * const bad_dict_msg = "Invalid dictionary size in member header."; const char * const bad_dict_msg = "Invalid dictionary size in member header.";
const char * const corrupt_mm_msg = "Corrupt header in multimember file."; const char * const corrupt_mm_msg = "Corrupt header in multimember file.";
const char * const empty_msg = "Empty member not allowed."; const char * const empty_msg = "Empty member not allowed.";
const char * const marking_msg = "Marking data not allowed."; const char * const nonzero_msg = "Nonzero first LZMA byte.";
const char * const trailing_msg = "Trailing data not allowed."; const char * const trailing_msg = "Trailing data not allowed.";
const char * const write_error_msg = "Write error";
// defined in decoder.cc // defined in decoder.cc
int readblock( const int fd, uint8_t * const buf, const int size ); int readblock( const int fd, uint8_t * const buf, const int size );

View file

@ -70,13 +70,10 @@ void Lzip_index::set_num_error( const char * const msg, unsigned long long num )
bool Lzip_index::read_header( const int fd, Lzip_header & header, bool Lzip_index::read_header( const int fd, Lzip_header & header,
const long long pos, const bool ignore_marking ) const long long pos )
{ {
if( seek_read( fd, header.data, header.size, pos ) != header.size ) if( seek_read( fd, header.data, header.size, pos ) != header.size )
{ set_errno_error( "Error reading member header: " ); return false; } { set_errno_error( "Error reading member header: " ); return false; }
uint8_t byte;
if( !ignore_marking && readblock( fd, &byte, 1 ) == 1 && byte != 0 )
{ error_ = marking_msg; retval_ = 2; return false; }
return true; return true;
} }
@ -110,8 +107,7 @@ bool Lzip_index::skip_trailing_data( const int fd, unsigned long long & pos,
{ while( i > trailer.size && buffer[i-9] == 0 ) --i; continue; } { while( i > trailer.size && buffer[i-9] == 0 ) --i; continue; }
if( member_size > ipos + i || !trailer.check_consistency() ) continue; if( member_size > ipos + i || !trailer.check_consistency() ) continue;
Lzip_header header; Lzip_header header;
if( !read_header( fd, header, ipos + i - member_size, if( !read_header( fd, header, ipos + i - member_size ) ) return false;
cl_opts.ignore_marking ) ) return false;
if( !header.check() ) continue; if( !header.check() ) continue;
const Lzip_header & header2 = *(const Lzip_header *)( buffer + i ); const Lzip_header & header2 = *(const Lzip_header *)( buffer + i );
const bool full_h2 = bsize - i >= header.size; const bool full_h2 = bsize - i >= header.size;
@ -126,15 +122,12 @@ bool Lzip_index::skip_trailing_data( const int fd, unsigned long long & pos,
{ error_ = corrupt_mm_msg; retval_ = 2; return false; } { error_ = corrupt_mm_msg; retval_ = 2; return false; }
if( !cl_opts.ignore_trailing ) if( !cl_opts.ignore_trailing )
{ error_ = trailing_msg; retval_ = 2; return false; } { error_ = trailing_msg; retval_ = 2; return false; }
const unsigned long long data_size = trailer.data_size();
if( !cl_opts.ignore_empty && data_size == 0 )
{ error_ = empty_msg; retval_ = 2; return false; }
pos = ipos + i - member_size; // good member pos = ipos + i - member_size; // good member
const unsigned dictionary_size = header.dictionary_size(); const unsigned dictionary_size = header.dictionary_size();
if( dictionary_size_ < dictionary_size ) if( dictionary_size_ < dictionary_size )
dictionary_size_ = dictionary_size; dictionary_size_ = dictionary_size;
member_vector.push_back( Member( 0, data_size, pos, member_size, member_vector.push_back( Member( 0, trailer.data_size(), pos,
dictionary_size ) ); member_size, dictionary_size ) );
return true; return true;
} }
if( ipos == 0 ) if( ipos == 0 )
@ -154,16 +147,16 @@ Lzip_index::Lzip_index( const int infd, const Cl_options & cl_opts )
{ {
if( insize < 0 ) if( insize < 0 )
{ set_errno_error( "Input file is not seekable: " ); return; } { set_errno_error( "Input file is not seekable: " ); return; }
Lzip_header header;
if( insize >= header.size &&
( !read_header( infd, header, 0 ) ||
!check_header( header ) ) ) return;
if( insize < min_member_size ) if( insize < min_member_size )
{ error_ = "Input file is too short."; retval_ = 2; return; } { error_ = "Input file is truncated."; retval_ = 2; return; }
if( insize > INT64_MAX ) if( insize > INT64_MAX )
{ error_ = "Input file is too long (2^63 bytes or more)."; { error_ = "Input file is too long (2^63 bytes or more).";
retval_ = 2; return; } retval_ = 2; return; }
Lzip_header header;
if( !read_header( infd, header, 0, cl_opts.ignore_marking ) ||
!check_header( header ) ) return;
unsigned long long pos = insize; // always points to a header or to EOF unsigned long long pos = insize; // always points to a header or to EOF
while( pos >= min_member_size ) while( pos >= min_member_size )
{ {
@ -178,23 +171,19 @@ Lzip_index::Lzip_index( const int infd, const Cl_options & cl_opts )
{ if( skip_trailing_data( infd, pos, cl_opts ) ) continue; return; } { if( skip_trailing_data( infd, pos, cl_opts ) ) continue; return; }
set_num_error( "Bad trailer at pos ", pos - trailer.size ); break; set_num_error( "Bad trailer at pos ", pos - trailer.size ); break;
} }
if( !read_header( infd, header, pos - member_size, cl_opts.ignore_marking ) ) if( !read_header( infd, header, pos - member_size ) ) break;
break;
if( !header.check() ) // bad header if( !header.check() ) // bad header
{ {
if( member_vector.empty() ) if( member_vector.empty() )
{ if( skip_trailing_data( infd, pos, cl_opts ) ) continue; return; } { if( skip_trailing_data( infd, pos, cl_opts ) ) continue; return; }
set_num_error( "Bad header at pos ", pos - member_size ); break; set_num_error( "Bad header at pos ", pos - member_size ); break;
} }
const unsigned long long data_size = trailer.data_size();
if( !cl_opts.ignore_empty && data_size == 0 )
{ error_ = empty_msg; retval_ = 2; break; }
pos -= member_size; // good member pos -= member_size; // good member
const unsigned dictionary_size = header.dictionary_size(); const unsigned dictionary_size = header.dictionary_size();
if( dictionary_size_ < dictionary_size ) if( dictionary_size_ < dictionary_size )
dictionary_size_ = dictionary_size; dictionary_size_ = dictionary_size;
member_vector.push_back( Member( 0, data_size, pos, member_size, member_vector.push_back( Member( 0, trailer.data_size(), pos,
dictionary_size ) ); member_size, dictionary_size ) );
} }
if( pos != 0 || member_vector.empty() || retval_ != 0 ) if( pos != 0 || member_vector.empty() || retval_ != 0 )
{ {

View file

@ -59,8 +59,7 @@ class Lzip_index
bool check_header( const Lzip_header & header ); bool check_header( const Lzip_header & header );
void set_errno_error( const char * const msg ); void set_errno_error( const char * const msg );
void set_num_error( const char * const msg, unsigned long long num ); void set_num_error( const char * const msg, unsigned long long num );
bool read_header( const int fd, Lzip_header & header, const long long pos, bool read_header( const int fd, Lzip_header & header, const long long pos );
const bool ignore_marking );
bool skip_trailing_data( const int fd, unsigned long long & pos, bool skip_trailing_data( const int fd, unsigned long long & pos,
const Cl_options & cl_opts ); const Cl_options & cl_opts );
@ -72,6 +71,14 @@ public:
int retval() const { return retval_; } int retval() const { return retval_; }
unsigned dictionary_size() const { return dictionary_size_; } unsigned dictionary_size() const { return dictionary_size_; }
bool multi_empty() const // multimember file with empty member(s)
{
if( member_vector.size() > 1 )
for( unsigned long i = 0; i < member_vector.size(); ++i )
if( member_vector[i].dblock.size() == 0 ) return true;
return false;
}
long long udata_size() const long long udata_size() const
{ if( member_vector.empty() ) return 0; { if( member_vector.empty() ) return 0;
return member_vector.back().dblock.end(); } return member_vector.back().dblock.end(); }

139
main.cc
View file

@ -113,22 +113,22 @@ bool delete_output_on_interrupt = false;
void show_help() void show_help()
{ {
std::printf( "Lzip is a lossless data compressor with a user interface similar to the one\n" std::printf( "Lzip is a lossless data compressor with a user interface similar to the one\n"
"of gzip or bzip2. Lzip uses a simplified form of the 'Lempel-Ziv-Markov\n" "of gzip or bzip2. Lzip uses a simplified form of LZMA (Lempel-Ziv-Markov\n"
"chain-Algorithm' (LZMA) stream format to maximize interoperability. The\n" "chain-Algorithm) designed to achieve complete interoperability between\n"
"maximum dictionary size is 512 MiB so that any lzip file can be decompressed\n" "implementations. The maximum dictionary size is 512 MiB so that any lzip\n"
"on 32-bit machines. Lzip provides accurate and robust 3-factor integrity\n" "file can be decompressed on 32-bit machines. Lzip provides accurate and\n"
"checking. Lzip can compress about as fast as gzip (lzip -0) or compress most\n" "robust 3-factor integrity checking. 'lzip -0' compresses about as fast as\n"
"files more than bzip2 (lzip -9). Decompression speed is intermediate between\n" "gzip, while 'lzip -9' compresses most files more than bzip2. Decompression\n"
"gzip and bzip2. Lzip is better than gzip and bzip2 from a data recovery\n" "speed is intermediate between gzip and bzip2. Lzip provides better data\n"
"perspective. Lzip has been designed, written, and tested with great care to\n" "recovery capabilities than gzip and bzip2. Lzip has been designed, written,\n"
"replace gzip and bzip2 as the standard general-purpose compressed format for\n" "and tested with great care to replace gzip and bzip2 as general-purpose\n"
"Unix-like systems.\n" "compressed format for Unix-like systems.\n"
"\nUsage: %s [options] [files]\n", invocation_name ); "\nUsage: %s [options] [files]\n", invocation_name );
std::printf( "\nOptions:\n" std::printf( "\nOptions:\n"
" -h, --help display this help and exit\n" " -h, --help display this help and exit\n"
" -V, --version output version information and exit\n" " -V, --version output version information and exit\n"
" -a, --trailing-error exit with error status if trailing data\n" " -a, --trailing-error exit with error status if trailing data\n"
" -b, --member-size=<bytes> set member size limit in bytes\n" " -b, --member-size=<bytes> set member size limit of multimember files\n"
" -c, --stdout write to standard output, keep input files\n" " -c, --stdout write to standard output, keep input files\n"
" -d, --decompress decompress, test compressed file integrity\n" " -d, --decompress decompress, test compressed file integrity\n"
" -f, --force overwrite existing output files\n" " -f, --force overwrite existing output files\n"
@ -145,8 +145,6 @@ void show_help()
" -0 .. -9 set compression level [default 6]\n" " -0 .. -9 set compression level [default 6]\n"
" --fast alias for -0\n" " --fast alias for -0\n"
" --best alias for -9\n" " --best alias for -9\n"
" --empty-error exit with error status if empty member in file\n"
" --marking-error exit with error status if 1st LZMA byte not 0\n"
" --loose-trailing allow trailing data seeming corrupt header\n" " --loose-trailing allow trailing data seeming corrupt header\n"
"\nIf no file names are given, or if a file is '-', lzip compresses or\n" "\nIf no file names are given, or if a file is '-', lzip compresses or\n"
"decompresses from standard input to standard output.\n" "decompresses from standard input to standard output.\n"
@ -215,7 +213,7 @@ const char * format_ds( const unsigned dictionary_size )
const char * p = ""; const char * p = "";
const char * np = " "; const char * np = " ";
unsigned num = dictionary_size; unsigned num = dictionary_size;
bool exact = ( num % factor == 0 ); bool exact = num % factor == 0;
for( int i = 0; i < n && ( num > 9999 || ( exact && num >= factor ) ); ++i ) for( int i = 0; i < n && ( num > 9999 || ( exact && num >= factor ) ); ++i )
{ num /= factor; if( num % factor != 0 ) exact = false; { num /= factor; if( num % factor != 0 ) exact = false;
@ -244,7 +242,7 @@ const char * format_num3( unsigned long long num )
char * const buf = buffer[current++]; current %= buffers; char * const buf = buffer[current++]; current %= buffers;
char * p = buf + bufsize - 1; // fill the buffer backwards char * p = buf + bufsize - 1; // fill the buffer backwards
*p = 0; // terminator *p = 0; // terminator
if( num > 1024 ) if( 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 )
@ -290,7 +288,7 @@ unsigned long long getnum( const char * const arg,
if( !errno && tail[0] ) if( !errno && tail[0] )
{ {
const unsigned factor = ( tail[1] == 'i' ) ? 1024 : 1000; const unsigned factor = (tail[1] == 'i') ? 1024 : 1000;
int exponent = 0; // 0 = bad multiplier int exponent = 0; // 0 = bad multiplier
switch( tail[0] ) switch( tail[0] )
{ {
@ -406,9 +404,9 @@ int open_instream( const char * const name, struct stat * const in_statsp,
{ {
const int i = fstat( infd, in_statsp ); const int i = fstat( infd, in_statsp );
const mode_t mode = in_statsp->st_mode; const mode_t mode = in_statsp->st_mode;
const bool can_read = ( i == 0 && !reg_only && const bool can_read = i == 0 && !reg_only &&
( S_ISBLK( mode ) || S_ISCHR( mode ) || ( S_ISBLK( mode ) || S_ISCHR( mode ) ||
S_ISFIFO( mode ) || S_ISSOCK( mode ) ) ); S_ISFIFO( mode ) || S_ISSOCK( mode ) );
if( i != 0 || ( !S_ISREG( mode ) && ( !can_read || one_to_one ) ) ) if( i != 0 || ( !S_ISREG( mode ) && ( !can_read || one_to_one ) ) )
{ {
if( verbosity >= 0 ) if( verbosity >= 0 )
@ -431,7 +429,7 @@ int open_instream2( const char * const name, struct stat * const in_statsp,
if( program_mode == m_compress && !recompress && eindex >= 0 ) if( program_mode == m_compress && !recompress && eindex >= 0 )
{ {
if( verbosity >= 0 ) if( verbosity >= 0 )
std::fprintf( stderr, "%s: %s: Input file already has '%s' suffix.\n", std::fprintf( stderr, "%s: %s: Input file already has '%s' suffix, ignored.\n",
program_name, name, known_extensions[eindex].from ); program_name, name, known_extensions[eindex].from );
return -1; return -1;
} }
@ -475,8 +473,8 @@ bool open_outstream( const bool force, const bool protect )
if( force ) flags |= O_TRUNC; else flags |= O_EXCL; if( force ) flags |= O_TRUNC; else flags |= O_EXCL;
outfd = -1; outfd = -1;
if( output_filename.size() && if( output_filename.size() && output_filename.end()[-1] == '/' )
output_filename[output_filename.size()-1] == '/' ) errno = EISDIR; errno = EISDIR;
else { else {
if( !protect && !make_dirs( output_filename ) ) if( !protect && !make_dirs( output_filename ) )
{ show_file_error( output_filename.c_str(), { show_file_error( output_filename.c_str(),
@ -600,7 +598,6 @@ int compress( const unsigned long long cfile_size,
const Lzma_options & encoder_options, const Pretty_print & pp, const Lzma_options & encoder_options, const Pretty_print & pp,
const struct stat * const in_statsp, const bool zero ) const struct stat * const in_statsp, const bool zero )
{ {
int retval = 0;
LZ_encoder_base * encoder = 0; // polymorphic encoder LZ_encoder_base * encoder = 0; // polymorphic encoder
if( verbosity >= 1 ) pp(); if( verbosity >= 1 ) pp();
@ -618,9 +615,10 @@ int compress( const unsigned long long cfile_size,
} }
unsigned long long in_size = 0, out_size = 0, partial_volume_size = 0; unsigned long long in_size = 0, out_size = 0, partial_volume_size = 0;
int retval = 0;
while( true ) // encode one member per iteration while( true ) // encode one member per iteration
{ {
const unsigned long long size = ( volume_size > 0 ) ? const unsigned long long size = (volume_size > 0) ?
std::min( member_size, volume_size - partial_volume_size ) : member_size; std::min( member_size, volume_size - partial_volume_size ) : member_size;
show_cprogress( cfile_size, in_size, encoder, &pp ); // init show_cprogress( cfile_size, in_size, encoder, &pp ); // init
if( !encoder->encode_member( size ) ) if( !encoder->encode_member( size ) )
@ -699,11 +697,12 @@ bool show_trailing_data( const uint8_t * const data, const int size,
int decompress( const unsigned long long cfile_size, const int infd, int decompress( const unsigned long long cfile_size, const int infd,
const Cl_options & cl_opts, const Pretty_print & pp, const Cl_options & cl_opts, const Pretty_print & pp,
const bool testing ) const bool from_stdin, const bool testing )
{ {
unsigned long long partial_file_pos = 0; unsigned long long partial_file_pos = 0;
Range_decoder rdec( infd ); Range_decoder rdec( infd );
int retval = 0; int retval = 0;
bool empty = false, multi = false;
for( bool first_member = true; ; first_member = false ) for( bool first_member = true; ; first_member = false )
{ {
@ -743,7 +742,7 @@ int decompress( const unsigned long long cfile_size, const int infd,
LZ_decoder decoder( rdec, dictionary_size, outfd ); LZ_decoder decoder( rdec, dictionary_size, outfd );
show_dprogress( cfile_size, partial_file_pos, &rdec, &pp ); // init show_dprogress( cfile_size, partial_file_pos, &rdec, &pp ); // init
const int result = decoder.decode_member( cl_opts, pp ); const int result = decoder.decode_member( pp );
partial_file_pos += rdec.member_position(); partial_file_pos += rdec.member_position();
if( result != 0 ) if( result != 0 )
{ {
@ -754,15 +753,18 @@ int decompress( const unsigned long long cfile_size, const int infd,
"File ends unexpectedly" : "Decoder error", "File ends unexpectedly" : "Decoder error",
partial_file_pos ); partial_file_pos );
} }
else if( result == 5 ) pp( empty_msg ); else if( result == 5 ) pp( nonzero_msg );
else if( result == 6 ) pp( marking_msg );
retval = 2; break; retval = 2; break;
} }
if( !from_stdin ) { multi = !first_member;
if( decoder.data_position() == 0 ) empty = true; }
if( verbosity >= 2 ) if( verbosity >= 2 )
{ std::fputs( testing ? "ok\n" : "done\n", stderr ); pp.reset(); } { std::fputs( testing ? "ok\n" : "done\n", stderr ); pp.reset(); }
} }
if( verbosity == 1 && retval == 0 ) if( verbosity == 1 && retval == 0 )
std::fputs( testing ? "ok\n" : "done\n", stderr ); std::fputs( testing ? "ok\n" : "done\n", stderr );
if( empty && multi && retval == 0 )
{ show_file_error( pp.name(), empty_msg ); retval = 2; }
return retval; return retval;
} }
@ -891,41 +893,39 @@ int main( const int argc, const char * const argv[] )
bool zero = false; bool zero = false;
if( argc > 0 ) invocation_name = argv[0]; if( argc > 0 ) invocation_name = argv[0];
enum { opt_eer = 256, opt_lt, opt_mer }; enum { opt_lt = 256 };
const Arg_parser::Option options[] = const Arg_parser::Option options[] =
{ {
{ '0', "fast", Arg_parser::no }, { '0', "fast", Arg_parser::no },
{ '1', 0, Arg_parser::no }, { '1', 0, Arg_parser::no },
{ '2', 0, Arg_parser::no }, { '2', 0, Arg_parser::no },
{ '3', 0, Arg_parser::no }, { '3', 0, Arg_parser::no },
{ '4', 0, Arg_parser::no }, { '4', 0, Arg_parser::no },
{ '5', 0, Arg_parser::no }, { '5', 0, Arg_parser::no },
{ '6', 0, Arg_parser::no }, { '6', 0, Arg_parser::no },
{ '7', 0, Arg_parser::no }, { '7', 0, Arg_parser::no },
{ '8', 0, Arg_parser::no }, { '8', 0, Arg_parser::no },
{ '9', "best", Arg_parser::no }, { '9', "best", Arg_parser::no },
{ 'a', "trailing-error", Arg_parser::no }, { 'a', "trailing-error", Arg_parser::no },
{ 'b', "member-size", Arg_parser::yes }, { 'b', "member-size", Arg_parser::yes },
{ 'c', "stdout", Arg_parser::no }, { 'c', "stdout", Arg_parser::no },
{ 'd', "decompress", Arg_parser::no }, { 'd', "decompress", Arg_parser::no },
{ 'f', "force", Arg_parser::no }, { 'f', "force", Arg_parser::no },
{ 'F', "recompress", Arg_parser::no }, { 'F', "recompress", Arg_parser::no },
{ 'h', "help", Arg_parser::no }, { 'h', "help", Arg_parser::no },
{ 'k', "keep", Arg_parser::no }, { 'k', "keep", Arg_parser::no },
{ 'l', "list", Arg_parser::no }, { 'l', "list", Arg_parser::no },
{ 'm', "match-length", Arg_parser::yes }, { 'm', "match-length", Arg_parser::yes },
{ 'n', "threads", Arg_parser::yes }, { 'n', "threads", Arg_parser::yes },
{ 'o', "output", Arg_parser::yes }, { 'o', "output", Arg_parser::yes },
{ 'q', "quiet", Arg_parser::no }, { 'q', "quiet", Arg_parser::no },
{ 's', "dictionary-size", Arg_parser::yes }, { 's', "dictionary-size", Arg_parser::yes },
{ 'S', "volume-size", Arg_parser::yes }, { 'S', "volume-size", Arg_parser::yes },
{ 't', "test", Arg_parser::no }, { 't', "test", Arg_parser::no },
{ 'v', "verbose", Arg_parser::no }, { 'v', "verbose", Arg_parser::no },
{ 'V', "version", Arg_parser::no }, { 'V', "version", Arg_parser::no },
{ opt_eer, "empty-error", Arg_parser::no }, { opt_lt, "loose-trailing", Arg_parser::no },
{ opt_lt, "loose-trailing", Arg_parser::no }, { 0, 0, Arg_parser::no } };
{ opt_mer, "marking-error", Arg_parser::no },
{ 0, 0, Arg_parser::no } };
const Arg_parser parser( argc, argv, options ); const Arg_parser parser( argc, argv, options );
if( parser.error().size() ) // bad option if( parser.error().size() ) // bad option
@ -941,9 +941,8 @@ int main( const int argc, const char * const argv[] )
const char * const arg = sarg.c_str(); const char * const arg = sarg.c_str();
switch( code ) switch( code )
{ {
case '0': case '1': case '2': case '3': case '4': case '0': case '1': case '2': case '3': case '4': case '5':
case '5': case '6': case '7': case '8': case '9': case '6': case '7': case '8': case '9': zero = code == '0';
zero = ( code == '0' );
encoder_options = option_mapping[code-'0']; break; encoder_options = option_mapping[code-'0']; break;
case 'a': cl_opts.ignore_trailing = false; break; case 'a': cl_opts.ignore_trailing = false; break;
case 'b': member_size = getnum( arg, pn, 100000, max_member_size ); break; case 'b': member_size = getnum( arg, pn, 100000, max_member_size ); break;
@ -957,7 +956,7 @@ int main( const int argc, const char * const argv[] )
case 'm': encoder_options.match_len_limit = case 'm': encoder_options.match_len_limit =
getnum( arg, pn, min_match_len_limit, max_match_len ); getnum( arg, pn, min_match_len_limit, max_match_len );
zero = false; break; zero = false; break;
case 'n': break; case 'n': break; // ignored
case 'o': if( sarg == "-" ) to_stdout = true; case 'o': if( sarg == "-" ) to_stdout = true;
else { default_output_filename = sarg; } break; else { default_output_filename = sarg; } break;
case 'q': verbosity = -1; break; case 'q': verbosity = -1; break;
@ -967,9 +966,7 @@ int main( const int argc, const char * const argv[] )
case 't': set_mode( program_mode, m_test ); break; case 't': set_mode( program_mode, m_test ); break;
case 'v': if( verbosity < 4 ) ++verbosity; break; case 'v': if( verbosity < 4 ) ++verbosity; break;
case 'V': show_version(); return 0; case 'V': show_version(); return 0;
case opt_eer: cl_opts.ignore_empty = false; break; case opt_lt: cl_opts.loose_trailing = true; break;
case opt_lt: cl_opts.loose_trailing = true; break;
case opt_mer: cl_opts.ignore_marking = false; break;
default: internal_error( "uncaught option." ); default: internal_error( "uncaught option." );
} }
} // end process options } // end process options
@ -1023,9 +1020,10 @@ int main( const int argc, const char * const argv[] )
{ {
std::string input_filename; std::string input_filename;
int infd; int infd;
const bool from_stdin = filenames[i] == "-";
pp.set_name( filenames[i] ); pp.set_name( filenames[i] );
if( filenames[i] == "-" ) if( from_stdin )
{ {
if( stdin_used ) continue; else stdin_used = true; if( stdin_used ) continue; else stdin_used = true;
infd = STDIN_FILENO; infd = STDIN_FILENO;
@ -1072,7 +1070,8 @@ int main( const int argc, const char * const argv[] )
tmp = compress( cfile_size, member_size, volume_size, infd, tmp = compress( cfile_size, member_size, volume_size, infd,
encoder_options, pp, in_statsp, zero ); encoder_options, pp, in_statsp, zero );
else else
tmp = decompress( cfile_size, infd, cl_opts, pp, program_mode == m_test ); tmp = decompress( cfile_size, infd, cl_opts, pp, from_stdin,
program_mode == m_test );
} }
catch( std::bad_alloc & ) catch( std::bad_alloc & )
{ pp( ( program_mode == m_compress ) ? { pp( ( program_mode == m_compress ) ?

View file

@ -28,12 +28,10 @@ if [ -d tmp ] ; then rm -rf tmp ; fi
mkdir tmp mkdir tmp
cd "${objdir}"/tmp || framework_failure cd "${objdir}"/tmp || framework_failure
cat "${testdir}"/test.txt > in || framework_failure cp "${testdir}"/test.txt in || framework_failure
in_lz="${testdir}"/test.txt.lz in_lz="${testdir}"/test.txt.lz
in_em="${testdir}"/test_em.txt.lz
fox_lz="${testdir}"/fox.lz fox_lz="${testdir}"/fox.lz
fox6_lz="${testdir}"/fox6.lz fnz_lz="${testdir}"/fox_nz.lz
f6mk_lz="${testdir}"/fox6_mark.lz
fail=0 fail=0
test_failed() { fail=1 ; printf " $1" ; [ -z "$2" ] || printf "($2)" ; } test_failed() { fail=1 ; printf " $1" ; [ -z "$2" ] || printf "($2)" ; }
@ -70,7 +68,7 @@ done
"${LZIP}" -q -o out.lz nx_file "${LZIP}" -q -o out.lz nx_file
[ $? = 1 ] || test_failed $LINENO [ $? = 1 ] || test_failed $LINENO
[ ! -e out.lz ] || test_failed $LINENO [ ! -e out.lz ] || test_failed $LINENO
"${LZIP}" -qf -S100k -o out in in "${LZIP}" -qf -S100k -o out in in # only one file with -o and -S
[ $? = 1 ] || test_failed $LINENO [ $? = 1 ] || test_failed $LINENO
{ [ ! -e out ] && [ ! -e out.lz ] ; } || test_failed $LINENO { [ ! -e out ] && [ ! -e out.lz ] ; } || test_failed $LINENO
# these are for code coverage # these are for code coverage
@ -106,37 +104,25 @@ printf "LZIP\001+.............................." | "${LZIP}" -t 2> /dev/null
printf "\ntesting decompression..." printf "\ntesting decompression..."
for i in "${in_lz}" "${in_em}" ; do "${LZIP}" -l "${in_lz}" > /dev/null || test_failed $LINENO
"${LZIP}" -lq "$i" || test_failed $LINENO "$i" "${LZIP}" -t "${in_lz}" || test_failed $LINENO
"${LZIP}" -t "$i" || test_failed $LINENO "$i" "${LZIP}" -d "${in_lz}" -o out || test_failed $LINENO
"${LZIP}" -d "$i" -o out || test_failed $LINENO "$i" cmp in out || test_failed $LINENO
cmp in out || test_failed $LINENO "$i" "${LZIP}" -cd "${in_lz}" > out || test_failed $LINENO
"${LZIP}" -cd "$i" > out || test_failed $LINENO "$i" cmp in out || test_failed $LINENO
cmp in out || test_failed $LINENO "$i" "${LZIP}" -d "${in_lz}" -o - > out || test_failed $LINENO
"${LZIP}" -d "$i" -o - > out || test_failed $LINENO "$i" cmp in out || test_failed $LINENO
cmp in out || test_failed $LINENO "$i" "${LZIP}" -d < "${in_lz}" > out || test_failed $LINENO
"${LZIP}" -d < "$i" > out || test_failed $LINENO "$i" cmp in out || test_failed $LINENO
cmp in out || test_failed $LINENO "$i" rm -f out || framework_failure
rm -f out || framework_failure
done
lines=`"${LZIP}" -tvv "${in_em}" 2>&1 | wc -l` || test_failed $LINENO cp "${in_lz}" out.lz || framework_failure
[ "${lines}" -eq 8 ] || test_failed $LINENO "${lines}"
"${LZIP}" -tq "${in_em}" --empty-error
[ $? = 2 ] || test_failed $LINENO
lines=`"${LZIP}" -lvv "${in_em}" | wc -l` || test_failed $LINENO
[ "${lines}" -eq 11 ] || test_failed $LINENO "${lines}"
"${LZIP}" -lq "${in_em}" --empty-error
[ $? = 2 ] || test_failed $LINENO
cat "${in_lz}" > out.lz || framework_failure
"${LZIP}" -dk out.lz || test_failed $LINENO "${LZIP}" -dk out.lz || test_failed $LINENO
cmp in out || test_failed $LINENO cmp in out || test_failed $LINENO
rm -f out || framework_failure rm -f out || framework_failure
"${LZIP}" -cd "${fox_lz}" > fox || test_failed $LINENO "${LZIP}" -cd "${fox_lz}" > fox || test_failed $LINENO
cat fox > copy || framework_failure cp fox copy || framework_failure
cat "${in_lz}" > copy.lz || framework_failure cp "${in_lz}" copy.lz || framework_failure
"${LZIP}" -d copy.lz out.lz 2> /dev/null # skip copy, decompress out "${LZIP}" -d copy.lz out.lz 2> /dev/null # skip copy, decompress out
[ $? = 1 ] || test_failed $LINENO [ $? = 1 ] || test_failed $LINENO
[ ! -e out.lz ] || test_failed $LINENO [ ! -e out.lz ] || test_failed $LINENO
@ -147,7 +133,7 @@ cmp in out || test_failed $LINENO
cmp in copy || test_failed $LINENO cmp in copy || test_failed $LINENO
rm -f copy out || framework_failure rm -f copy out || framework_failure
cat "${in_lz}" > out.lz || framework_failure cp "${in_lz}" out.lz || framework_failure
"${LZIP}" -d -S100k out.lz || test_failed $LINENO # ignore -S "${LZIP}" -d -S100k out.lz || test_failed $LINENO # ignore -S
[ ! -e out.lz ] || test_failed $LINENO [ ! -e out.lz ] || test_failed $LINENO
cmp in out || test_failed $LINENO cmp in out || test_failed $LINENO
@ -155,7 +141,6 @@ cmp in out || test_failed $LINENO
printf "to be overwritten" > out || framework_failure printf "to be overwritten" > out || framework_failure
"${LZIP}" -df -o out < "${in_lz}" || test_failed $LINENO "${LZIP}" -df -o out < "${in_lz}" || test_failed $LINENO
cmp in out || test_failed $LINENO cmp in out || test_failed $LINENO
rm -f out || framework_failure
"${LZIP}" -d -o ./- "${in_lz}" || test_failed $LINENO "${LZIP}" -d -o ./- "${in_lz}" || test_failed $LINENO
cmp in ./- || test_failed $LINENO cmp in ./- || test_failed $LINENO
rm -f ./- || framework_failure rm -f ./- || framework_failure
@ -163,12 +148,12 @@ rm -f ./- || framework_failure
cmp in ./- || test_failed $LINENO cmp in ./- || test_failed $LINENO
rm -f ./- || framework_failure rm -f ./- || framework_failure
cat "${in_lz}" > anyothername || framework_failure cp "${in_lz}" anyothername || framework_failure
"${LZIP}" -dv - anyothername - < "${in_lz}" > out 2> /dev/null || "${LZIP}" -dv - anyothername - < "${in_lz}" > out 2> /dev/null ||
test_failed $LINENO test_failed $LINENO
cmp in out || test_failed $LINENO cmp in out || test_failed $LINENO
cmp in anyothername.out || test_failed $LINENO cmp in anyothername.out || test_failed $LINENO
rm -f out anyothername.out || framework_failure rm -f anyothername.out || framework_failure
"${LZIP}" -lq in "${in_lz}" "${LZIP}" -lq in "${in_lz}"
[ $? = 2 ] || test_failed $LINENO [ $? = 2 ] || test_failed $LINENO
@ -185,7 +170,7 @@ cat out in | cmp in - || test_failed $LINENO # out must be empty
[ $? = 1 ] || test_failed $LINENO [ $? = 1 ] || test_failed $LINENO
cmp in out || test_failed $LINENO cmp in out || test_failed $LINENO
rm -f out || framework_failure rm -f out || framework_failure
cat "${in_lz}" > out.lz || framework_failure cp "${in_lz}" out.lz || framework_failure
for i in 1 2 3 4 5 6 7 ; do for i in 1 2 3 4 5 6 7 ; do
printf "g" >> out.lz || framework_failure printf "g" >> out.lz || framework_failure
"${LZIP}" -alvv out.lz "${in_lz}" > /dev/null 2>&1 "${LZIP}" -alvv out.lz "${in_lz}" > /dev/null 2>&1
@ -206,7 +191,7 @@ cmp in out || test_failed $LINENO
rm -f out || framework_failure rm -f out || framework_failure
cat in in > in2 || framework_failure cat in in > in2 || framework_failure
"${LZIP}" -lq "${in_lz}" "${in_lz}" || test_failed $LINENO "${LZIP}" -l "${in_lz}" "${in_lz}" > /dev/null || test_failed $LINENO
"${LZIP}" -t "${in_lz}" "${in_lz}" || test_failed $LINENO "${LZIP}" -t "${in_lz}" "${in_lz}" || test_failed $LINENO
"${LZIP}" -cd "${in_lz}" "${in_lz}" -o out > out2 || test_failed $LINENO "${LZIP}" -cd "${in_lz}" "${in_lz}" -o out > out2 || test_failed $LINENO
[ ! -e out ] || test_failed $LINENO # override -o [ ! -e out ] || test_failed $LINENO # override -o
@ -217,6 +202,11 @@ cmp in2 out2 || test_failed $LINENO
rm -f out2 || framework_failure rm -f out2 || framework_failure
cat "${in_lz}" "${in_lz}" > out2.lz || framework_failure cat "${in_lz}" "${in_lz}" > out2.lz || framework_failure
lines=`"${LZIP}" -tvv out2.lz 2>&1 | wc -l` || test_failed $LINENO
[ "${lines}" -eq 2 ] || test_failed $LINENO "${lines}"
lines=`"${LZIP}" -lvv out2.lz | wc -l` || test_failed $LINENO
[ "${lines}" -eq 5 ] || test_failed $LINENO "${lines}"
printf "\ngarbage" >> out2.lz || framework_failure printf "\ngarbage" >> out2.lz || framework_failure
"${LZIP}" -tvvvv out2.lz 2> /dev/null || test_failed $LINENO "${LZIP}" -tvvvv out2.lz 2> /dev/null || test_failed $LINENO
"${LZIP}" -alq out2.lz "${LZIP}" -alq out2.lz
@ -236,15 +226,6 @@ printf "to be overwritten" > out2 || framework_failure
cmp in2 out2 || test_failed $LINENO cmp in2 out2 || test_failed $LINENO
rm -f out2 || framework_failure rm -f out2 || framework_failure
"${LZIP}" -cd "${fox6_lz}" > out || test_failed $LINENO
"${LZIP}" -cd "${f6mk_lz}" > copy || test_failed $LINENO
cmp copy out || test_failed $LINENO
rm -f copy out || framework_failure
"${LZIP}" -lq "${f6mk_lz}" --marking-error
[ $? = 2 ] || test_failed $LINENO
"${LZIP}" -tq "${f6mk_lz}" --marking-error
[ $? = 2 ] || test_failed $LINENO
"${LZIP}" -d "${fox_lz}" -o a/b/c/fox || test_failed $LINENO "${LZIP}" -d "${fox_lz}" -o a/b/c/fox || test_failed $LINENO
cmp fox a/b/c/fox || test_failed $LINENO cmp fox a/b/c/fox || test_failed $LINENO
rm -rf a || framework_failure rm -rf a || framework_failure
@ -255,6 +236,21 @@ rm -rf a || framework_failure
[ $? = 1 ] || test_failed $LINENO [ $? = 1 ] || test_failed $LINENO
[ ! -e a ] || test_failed $LINENO [ ! -e a ] || test_failed $LINENO
touch empty em || framework_failure
"${LZIP}" -0 em || test_failed $LINENO
"${LZIP}" -l em.lz > /dev/null || test_failed $LINENO
"${LZIP}" -dk em.lz || test_failed $LINENO
cmp empty em || test_failed $LINENO
cat em.lz em.lz | "${LZIP}" -t || test_failed $LINENO
cat em.lz em.lz | "${LZIP}" -d > em || test_failed $LINENO
cmp empty em || test_failed $LINENO
cat em.lz "${in_lz}" | "${LZIP}" -t || test_failed $LINENO
cat em.lz "${in_lz}" | "${LZIP}" -d > out || test_failed $LINENO
cmp in out || test_failed $LINENO
cat "${in_lz}" em.lz | "${LZIP}" -t || test_failed $LINENO
cat "${in_lz}" em.lz | "${LZIP}" -d > out || test_failed $LINENO
cmp in out || test_failed $LINENO
printf "\ntesting compression..." printf "\ntesting compression..."
"${LZIP}" -c -0 in in in -S100k -o out3.lz > copy2.lz || test_failed $LINENO "${LZIP}" -c -0 in in in -S100k -o out3.lz > copy2.lz || test_failed $LINENO
@ -263,7 +259,7 @@ printf "\ntesting compression..."
"${LZIP}" -d copy2.lz -o out2 || test_failed $LINENO "${LZIP}" -d copy2.lz -o out2 || test_failed $LINENO
[ -e copy2.lz ] || test_failed $LINENO [ -e copy2.lz ] || test_failed $LINENO
cmp in2 out2 || test_failed $LINENO cmp in2 out2 || test_failed $LINENO
rm -f in2 out2 copy2.lz || framework_failure rm -f copy2.lz || framework_failure
"${LZIP}" -cf "${in_lz}" > lzlz 2> /dev/null # /dev/null is a tty on OS/2 "${LZIP}" -cf "${in_lz}" > lzlz 2> /dev/null # /dev/null is a tty on OS/2
[ $? = 1 ] || test_failed $LINENO [ $? = 1 ] || test_failed $LINENO
@ -331,7 +327,7 @@ rm -f in8 || framework_failure
"${LZIP}" -t out00001.lz out00002.lz || test_failed $LINENO "${LZIP}" -t out00001.lz out00002.lz || test_failed $LINENO
"${LZIP}" -cd out00001.lz out00002.lz | cmp in8.lz - || test_failed $LINENO "${LZIP}" -cd out00001.lz out00002.lz | cmp in8.lz - || test_failed $LINENO
[ ! -e out00003.lz ] || test_failed $LINENO [ ! -e out00003.lz ] || test_failed $LINENO
rm -f out00001.lz || framework_failure rm -f out00001.lz out00002.lz || framework_failure
"${LZIP}" -1 -S100k -o a/b/c/out < in8.lz || test_failed $LINENO "${LZIP}" -1 -S100k -o a/b/c/out < in8.lz || test_failed $LINENO
"${LZIP}" -t a/b/c/out00001.lz a/b/c/out00002.lz || test_failed $LINENO "${LZIP}" -t a/b/c/out00001.lz a/b/c/out00002.lz || test_failed $LINENO
"${LZIP}" -cd a/b/c/out00001.lz a/b/c/out00002.lz | cmp in8.lz - || "${LZIP}" -cd a/b/c/out00001.lz a/b/c/out00002.lz | cmp in8.lz - ||
@ -357,11 +353,44 @@ rm -rf a || framework_failure
printf "\ntesting bad input..." printf "\ntesting bad input..."
cat em.lz em.lz > ee.lz || framework_failure
"${LZIP}" -l < ee.lz > /dev/null || test_failed $LINENO
"${LZIP}" -t < ee.lz || test_failed $LINENO
"${LZIP}" -d < ee.lz > em || test_failed $LINENO
cmp empty em || test_failed $LINENO
"${LZIP}" -lq ee.lz
[ $? = 2 ] || test_failed $LINENO
"${LZIP}" -tq ee.lz
[ $? = 2 ] || test_failed $LINENO
"${LZIP}" -dq ee.lz
[ $? = 2 ] || test_failed $LINENO
[ ! -e ee ] || test_failed $LINENO
"${LZIP}" -cdq ee.lz > em
[ $? = 2 ] || test_failed $LINENO
cmp empty em || test_failed $LINENO
rm -f empty em || framework_failure
cat "${in_lz}" em.lz "${in_lz}" > inein.lz || framework_failure
"${LZIP}" -l < inein.lz > /dev/null || test_failed $LINENO
"${LZIP}" -t < inein.lz || test_failed $LINENO
"${LZIP}" -d < inein.lz > out2 || test_failed $LINENO
cmp in2 out2 || test_failed $LINENO
"${LZIP}" -lq inein.lz
[ $? = 2 ] || test_failed $LINENO
"${LZIP}" -tq inein.lz
[ $? = 2 ] || test_failed $LINENO
"${LZIP}" -dq inein.lz
[ $? = 2 ] || test_failed $LINENO
[ ! -e inein ] || test_failed $LINENO
"${LZIP}" -cdq inein.lz > out2
[ $? = 2 ] || test_failed $LINENO
cmp in2 out2 || test_failed $LINENO
rm -f in2 out2 inein.lz em.lz || framework_failure
headers='LZIp LZiP LZip LzIP LzIp LziP lZIP lZIp lZiP lzIP' headers='LZIp LZiP LZip LzIP LzIp LziP lZIP lZIp lZiP lzIP'
body='\001\014\000\203\377\373\377\377\300\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000$\000\000\000\000\000\000\000' body='\001\014\000\000\101\376\367\377\377\340\000\200\000\215\357\002\322\001\000\000\000\000\000\000\000\045\000\000\000\000\000\000\000'
cat "${in_lz}" > int.lz || framework_failure cp "${in_lz}" int.lz || framework_failure
printf "LZIP${body}" >> int.lz || framework_failure printf "LZIP${body}" >> int.lz || framework_failure
if "${LZIP}" -tq int.lz ; then if "${LZIP}" -t int.lz ; then
for header in ${headers} ; do for header in ${headers} ; do
printf "${header}${body}" > int.lz || framework_failure printf "${header}${body}" > int.lz || framework_failure
"${LZIP}" -lq int.lz # first member "${LZIP}" -lq int.lz # first member
@ -380,7 +409,7 @@ if "${LZIP}" -tq int.lz ; then
[ $? = 2 ] || test_failed $LINENO ${header} [ $? = 2 ] || test_failed $LINENO ${header}
"${LZIP}" -cdq --loose-trailing int.lz > /dev/null "${LZIP}" -cdq --loose-trailing int.lz > /dev/null
[ $? = 2 ] || test_failed $LINENO ${header} [ $? = 2 ] || test_failed $LINENO ${header}
cat "${in_lz}" > int.lz || framework_failure cp "${in_lz}" int.lz || framework_failure
printf "${header}${body}" >> int.lz || framework_failure printf "${header}${body}" >> int.lz || framework_failure
"${LZIP}" -lq int.lz # trailing data "${LZIP}" -lq int.lz # trailing data
[ $? = 2 ] || test_failed $LINENO ${header} [ $? = 2 ] || test_failed $LINENO ${header}
@ -390,7 +419,7 @@ if "${LZIP}" -tq int.lz ; then
[ $? = 2 ] || test_failed $LINENO ${header} [ $? = 2 ] || test_failed $LINENO ${header}
"${LZIP}" -cdq int.lz > /dev/null "${LZIP}" -cdq int.lz > /dev/null
[ $? = 2 ] || test_failed $LINENO ${header} [ $? = 2 ] || test_failed $LINENO ${header}
"${LZIP}" -lq --loose-trailing int.lz || "${LZIP}" -l --loose-trailing int.lz > /dev/null ||
test_failed $LINENO ${header} test_failed $LINENO ${header}
"${LZIP}" -t --loose-trailing int.lz || "${LZIP}" -t --loose-trailing int.lz ||
test_failed $LINENO ${header} test_failed $LINENO ${header}
@ -408,10 +437,14 @@ if "${LZIP}" -tq int.lz ; then
[ $? = 2 ] || test_failed $LINENO ${header} [ $? = 2 ] || test_failed $LINENO ${header}
done done
else else
printf "\nwarning: skipping header test: 'printf' does not work on your system." printf "warning: skipping header test: 'printf' does not work on your system."
fi fi
rm -f int.lz || framework_failure rm -f int.lz || framework_failure
"${LZIP}" -l "${fnz_lz}" > /dev/null || test_failed $LINENO
"${LZIP}" -tq "${fnz_lz}"
[ $? = 2 ] || test_failed $LINENO
for i in fox_v2.lz fox_s11.lz fox_de20.lz \ for i in fox_v2.lz fox_s11.lz fox_de20.lz \
fox_bcrc.lz fox_crc0.lz fox_das46.lz fox_mes81.lz ; do fox_bcrc.lz fox_crc0.lz fox_das46.lz fox_mes81.lz ; do
"${LZIP}" -tq "${testdir}"/$i "${LZIP}" -tq "${testdir}"/$i
@ -423,13 +456,13 @@ for i in fox_bcrc.lz fox_crc0.lz fox_das46.lz fox_mes81.lz ; do
[ $? = 2 ] || test_failed $LINENO $i [ $? = 2 ] || test_failed $LINENO $i
cmp fox out || test_failed $LINENO $i cmp fox out || test_failed $LINENO $i
done done
rm -f fox out || framework_failure rm -f fox || framework_failure
cat "${in_lz}" "${in_lz}" > in2.lz || framework_failure cat "${in_lz}" "${in_lz}" > in2.lz || framework_failure
cat "${in_lz}" "${in_lz}" "${in_lz}" > in3.lz || framework_failure cat "${in_lz}" "${in_lz}" "${in_lz}" > in3.lz || framework_failure
if dd if=in3.lz of=trunc.lz bs=14752 count=1 2> /dev/null && if dd if=in3.lz of=trunc.lz bs=14682 count=1 2> /dev/null &&
[ -e trunc.lz ] && cmp in2.lz trunc.lz > /dev/null 2>&1 ; then [ -e trunc.lz ] && cmp in2.lz trunc.lz ; then
for i in 6 20 14734 14753 14754 14755 14756 14757 14758 ; do for i in 6 20 14664 14683 14684 14685 14686 14687 14688 ; do
dd if=in3.lz of=trunc.lz bs=$i count=1 2> /dev/null dd if=in3.lz of=trunc.lz bs=$i count=1 2> /dev/null
"${LZIP}" -lq trunc.lz "${LZIP}" -lq trunc.lz
[ $? = 2 ] || test_failed $LINENO $i [ $? = 2 ] || test_failed $LINENO $i
@ -443,11 +476,11 @@ if dd if=in3.lz of=trunc.lz bs=14752 count=1 2> /dev/null &&
[ $? = 2 ] || test_failed $LINENO $i [ $? = 2 ] || test_failed $LINENO $i
done done
else else
printf "\nwarning: skipping truncation test: 'dd' does not work on your system." printf "warning: skipping truncation test: 'dd' does not work on your system."
fi fi
rm -f in2.lz in3.lz trunc.lz || framework_failure rm -f in2.lz in3.lz trunc.lz || framework_failure
cat "${in_lz}" > ingin.lz || framework_failure cp "${in_lz}" ingin.lz || framework_failure
printf "g" >> ingin.lz || framework_failure printf "g" >> ingin.lz || framework_failure
cat "${in_lz}" >> ingin.lz || framework_failure cat "${in_lz}" >> ingin.lz || framework_failure
"${LZIP}" -lq ingin.lz "${LZIP}" -lq ingin.lz
@ -456,17 +489,21 @@ cat "${in_lz}" >> ingin.lz || framework_failure
[ $? = 2 ] || test_failed $LINENO [ $? = 2 ] || test_failed $LINENO
"${LZIP}" -atq < ingin.lz "${LZIP}" -atq < ingin.lz
[ $? = 2 ] || test_failed $LINENO [ $? = 2 ] || test_failed $LINENO
"${LZIP}" -acdq ingin.lz > /dev/null "${LZIP}" -acdq ingin.lz > out
[ $? = 2 ] || test_failed $LINENO [ $? = 2 ] || test_failed $LINENO
"${LZIP}" -adq < ingin.lz > /dev/null cmp in out || test_failed $LINENO
"${LZIP}" -adq < ingin.lz > out
[ $? = 2 ] || test_failed $LINENO [ $? = 2 ] || test_failed $LINENO
cmp in out || test_failed $LINENO
"${LZIP}" -t ingin.lz || test_failed $LINENO "${LZIP}" -t ingin.lz || test_failed $LINENO
"${LZIP}" -t < ingin.lz || test_failed $LINENO "${LZIP}" -t < ingin.lz || test_failed $LINENO
"${LZIP}" -dk ingin.lz || test_failed $LINENO
cmp in ingin || test_failed $LINENO
"${LZIP}" -cd ingin.lz > out || test_failed $LINENO "${LZIP}" -cd ingin.lz > out || test_failed $LINENO
cmp in out || test_failed $LINENO cmp in out || test_failed $LINENO
"${LZIP}" -d < ingin.lz > out || test_failed $LINENO "${LZIP}" -d < ingin.lz > out || test_failed $LINENO
cmp in out || test_failed $LINENO cmp in out || test_failed $LINENO
rm -f out ingin.lz || framework_failure rm -f out ingin ingin.lz || framework_failure
echo echo
if [ ${fail} = 0 ] ; then if [ ${fail} = 0 ] ; then

Binary file not shown.

Binary file not shown.

BIN
testsuite/fox_nz.lz Normal file

Binary file not shown.

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.