diff options
Diffstat (limited to '')
-rw-r--r-- | ChangeLog | 38 | ||||
-rw-r--r-- | LzmaDec.c | 4 | ||||
-rw-r--r-- | Makefile.in | 8 | ||||
-rw-r--r-- | NEWS | 17 | ||||
-rw-r--r-- | README | 28 | ||||
-rw-r--r-- | carg_parser.c | 18 | ||||
-rw-r--r-- | carg_parser.h | 11 | ||||
-rwxr-xr-x | configure | 4 | ||||
-rw-r--r-- | doc/pdlzip.1 | 24 | ||||
-rw-r--r-- | lzip.h | 11 | ||||
-rw-r--r-- | main.c | 101 | ||||
-rwxr-xr-x | testsuite/check.sh | 100 | ||||
-rw-r--r-- | testsuite/fox_nz.lz | bin | 0 -> 80 bytes | |||
-rw-r--r-- | testsuite/test.txt | 6 | ||||
-rw-r--r-- | testsuite/test.txt.lz | bin | 7376 -> 7341 bytes | |||
-rw-r--r-- | testsuite/test.txt.lzma | bin | 7363 -> 7328 bytes | |||
-rw-r--r-- | testsuite/test_em.txt.lz | bin | 14024 -> 0 bytes |
17 files changed, 216 insertions, 154 deletions
@@ -1,3 +1,10 @@ +2024-11-08 Antonio Diaz Diaz <antonio@gnu.org> + + * Version 1.14-rc1 released. + * main.c (decompress): Return 2 if empty member in multimember file. + (Pp_free): New function. + * check.sh: Use 'cp' instead of 'cat'. + 2024-01-21 Antonio Diaz Diaz <antonio@gnu.org> * Version 1.13 released. @@ -39,12 +46,12 @@ 2018-02-04 Antonio Diaz Diaz <antonio@gnu.org> * Version 1.9 released. - * main.c: New option '--loose-trailing'. - * main.c (decompress): Improve corrupt header detection to HD=3. + * New option '--loose-trailing'. * Replace 'bits/byte' with inverse compression ratio in output. - * main.c: Show final diagnostic when testing multiple files. - * main.c: Do not add a second .lz extension to the arg of -o. - * main.c (lzip_decode): Show stored sizes also in hex. + * main.c (decompress): Improve corrupt header detection to HD=3. + (main): Show final diagnostic when testing multiple files. + (set_c_outname): Do not add a second '.lz' to the arg of '-o'. + (lzip_decode): Show stored sizes also in hex. Show dictionary size at verbosity level 4 (-vvvv). 2017-04-12 Antonio Diaz Diaz <antonio@gnu.org> @@ -58,10 +65,9 @@ * Version 1.7 released. * main.c: New option '-a, --trailing-error'. * main.c (main): Delete '--output' file if infd is a terminal. - * main.c (main): Don't use stdin more than once. + (main): Don't use stdin more than once. * configure: Avoid warning on some shells when testing for gcc. - * check.sh: A POSIX shell is required to run the tests. - * check.sh: Don't check error messages. + * check.sh: Require a POSIX shell. Don't check error messages. 2015-05-26 Antonio Diaz Diaz <antonio@gnu.org> @@ -78,16 +84,16 @@ 2013-05-27 Antonio Diaz Diaz <antonio@gnu.org> * Version 1.4 released. + * Decompression time has been reduced by 5%. * main.c: New options '-f, --force', '-F, --recompress', '-k, --keep', and '-o, --output'. - * main.c: Accept more than one file in command line. - * Decompression time has been reduced by 5%. - * main.c: '--test' no longer needs '/dev/null'. - * Fix return value of '-d' and '-t' in case of data error. - * main.c: Change info shown at verbosity levels 2 and 3. - * Ignore option '-n, --threads' for compatibility with plzip. + Accept more than one file in command line. + (main): '--test' no longer needs '/dev/null'. + (main): Fix return value of '-d' and '-t' in case of data error. + Change info shown at verbosity levels 2 and 3. + (main): Ignore option '-n, --threads' for compatibility with plzip. * configure: Options now accept a separate argument. - * configure: Rename 'datadir' to 'datarootdir'. + Rename 'datadir' to 'datarootdir'. * Makefile.in: New targets 'install-as-lzip' and 'install-bin'. 2012-01-03 Antonio Diaz Diaz <ant_diaz@teleline.es> @@ -95,7 +101,7 @@ * Version 1.3 released. * Small change in '--help' output and man page. * Change quote characters in messages as advised by GNU Standards. - * main.c: Set stdin/stdout in binary mode on OS2. + * main.c (main): Set stdin/stdout in binary mode on OS2. 2011-01-05 Antonio Diaz Diaz <ant_diaz@teleline.es> @@ -716,8 +716,8 @@ static bool LzmaDec_DecodeToDic(CLzmaDec *p, uint32_t dicLimit, *status = LZMA_STATUS_NEEDS_MORE_INPUT; return true; } - if (p->tempBuf[0] != 0) - return false; + /* check first byte of the LZMA stream */ + if (p->tempBuf[0] != 0) return false; LzmaDec_InitRc(p, p->tempBuf); p->tempBufSize = 0; diff --git a/Makefile.in b/Makefile.in index 4b8c791..fc59256 100644 --- a/Makefile.in +++ b/Makefile.in @@ -2,8 +2,8 @@ DISTNAME = $(pkgname)-$(pkgversion) INSTALL = install INSTALL_PROGRAM = $(INSTALL) -m 755 -INSTALL_DATA = $(INSTALL) -m 644 INSTALL_DIR = $(INSTALL) -d -m 755 +INSTALL_DATA = $(INSTALL) -m 644 SHELL = /bin/sh CAN_RUN_INSTALLINFO = $(SHELL) -c "install-info --version" > /dev/null 2>&1 @@ -30,7 +30,8 @@ main.o : main.c # prevent 'make' from trying to remake source files $(VPATH)/configure $(VPATH)/Makefile.in $(VPATH)/doc/$(pkgname).texi : ; -%.h %.c : ; +MAKEFLAGS += -r +.SUFFIXES : $(objs) : Makefile carg_parser.o : carg_parser.h @@ -125,8 +126,7 @@ dist : doc $(DISTNAME)/testsuite/fox.lz \ $(DISTNAME)/testsuite/fox_*.lz \ $(DISTNAME)/testsuite/test.txt.lz \ - $(DISTNAME)/testsuite/test.txt.lzma \ - $(DISTNAME)/testsuite/test_em.txt.lz + $(DISTNAME)/testsuite/test.txt.lzma rm -f $(DISTNAME) lzip -v -9 $(DISTNAME).tar @@ -1,15 +1,4 @@ -Changes in version 1.13: +Changes in version 1.14: -File diagnostics have been reformatted as 'PROGRAM: FILE: MESSAGE'. - -Diagnostics caused by invalid arguments to command-line options now show the -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 variable MAKEINFO has been added to configure and Makefile.in. - -It has been documented in INSTALL that when choosing a C standard, the POSIX -features need to be enabled explicitly: - ./configure CFLAGS+='--std=c99 -D_XOPEN_SOURCE=500' +pdlzip now exits with error status 2 if any empty member is found in a +multimember file. @@ -3,19 +3,19 @@ Description Pdlzip is a permissively licensed implementation of the lzip data compressor, intended for those who can't distribute (or even use) GPL licensed Free Software. The name of pdlzip comes from 'public domain lzip'. -Pdlzip is written in C and is compatible with lzip 1.4 or newer. +Pdlzip is written in C. 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 -chain-Algorithm' (LZMA) stream format to maximize interoperability. The -maximum dictionary size is 512 MiB so that any lzip file can be decompressed -on 32-bit machines. Lzip provides accurate and robust 3-factor integrity -checking. Lzip can compress about as fast as gzip (lzip -0) or compress most -files more than bzip2 (lzip -9). Decompression speed is intermediate between -gzip and bzip2. Lzip is better than gzip and bzip2 from a data recovery -perspective. Lzip has been designed, written, and tested with great care to -replace gzip and bzip2 as the standard general-purpose compressed format for -Unix-like systems. +of gzip or bzip2. Lzip uses a simplified form of LZMA (Lempel-Ziv-Markov +chain-Algorithm) designed to achieve complete interoperability between +implementations. The maximum dictionary size is 512 MiB so that any lzip +file can be decompressed on 32-bit machines. Lzip provides accurate and +robust 3-factor integrity checking. 'lzip -0' compresses about as fast as +gzip, while 'lzip -9' compresses most files more than bzip2. Decompression +speed is intermediate between gzip and bzip2. Lzip provides better data +recovery capabilities than gzip and bzip2. Lzip has been designed, written, +and tested with great care to replace gzip and bzip2 as general-purpose +compressed format for Unix-like systems. The lzip file format is designed for data sharing and long-term archiving, taking into account both data integrity and decoder availability: @@ -50,12 +50,6 @@ without recompressing. Pdlzip includes public domain compression/decompression code from the LZMA SDK (Software Development Kit) written by Igor Pavlov. -I would not write non-copylefted software unless it is too simple to be -worth copylefting it, but one of the uses of the lzip format is the -interchange of information, and it is therefore desirable that even the -users of the most non-free platforms can share lzip files with everybody -else. - Copyright (C) 2010-2024 Antonio Diaz Diaz. diff --git a/carg_parser.c b/carg_parser.c index edb4eb9..e16fa73 100644 --- a/carg_parser.c +++ b/carg_parser.c @@ -148,21 +148,21 @@ static char parse_long_option( struct Arg_parser * const ap, add_error( ap, "' requires an argument" ); return 1; } - return push_back_record( ap, options[index].code, - options[index].long_name, &opt[len+3] ); + return push_back_record( ap, options[index].code, options[index].long_name, + &opt[len+3] ); /* argument may be empty */ } - if( options[index].has_arg == ap_yes ) + if( options[index].has_arg == ap_yes || options[index].has_arg == ap_yme ) { - if( !arg || !arg[0] ) + if( !arg || ( options[index].has_arg == ap_yes && !arg[0] ) ) { add_error( ap, "option '--" ); add_error( ap, options[index].long_name ); add_error( ap, "' requires an argument" ); return 1; } ++*argindp; - return push_back_record( ap, options[index].code, - options[index].long_name, arg ); + return push_back_record( ap, options[index].code, options[index].long_name, + arg ); /* argument may be empty */ } return push_back_record( ap, options[index].code, @@ -204,15 +204,15 @@ static char parse_short_option( struct Arg_parser * const ap, if( !push_back_record( ap, c, 0, &opt[cind] ) ) return 0; ++*argindp; cind = 0; } - else if( options[index].has_arg == ap_yes ) + else if( options[index].has_arg == ap_yes || options[index].has_arg == ap_yme ) { - if( !arg || !arg[0] ) + if( !arg || ( options[index].has_arg == ap_yes && !arg[0] ) ) { add_error( ap, "option requires an argument -- '" ); add_error( ap, code_str ); add_error( ap, "'" ); return 1; } - ++*argindp; cind = 0; + ++*argindp; cind = 0; /* argument may be empty */ if( !push_back_record( ap, c, 0, arg ) ) return 0; } else if( !push_back_record( ap, c, 0, 0 ) ) return 0; diff --git a/carg_parser.h b/carg_parser.h index 69ce271..65a6d7d 100644 --- a/carg_parser.h +++ b/carg_parser.h @@ -37,15 +37,20 @@ The argument '--' terminates all options; any following arguments are treated as non-option arguments, even if they begin with a hyphen. - The syntax for optional option arguments is '-<short_option><argument>' - (without whitespace), or '--<long_option>=<argument>'. + The syntax of options with an optional argument is + '-<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>=""'. */ #ifdef __cplusplus extern "C" { #endif -enum ap_Has_arg { ap_no, ap_yes, ap_maybe }; +/* ap_yme = yes but maybe empty */ +enum ap_Has_arg { ap_no, ap_yes, ap_maybe, ap_yme }; struct ap_Option { @@ -6,7 +6,7 @@ # to copy, distribute, and modify it. pkgname=pdlzip -pkgversion=1.13 +pkgversion=1.14-rc1 progname=pdlzip srctrigger=doc/${progname}.1 @@ -109,7 +109,7 @@ while [ $# != 0 ] ; do exit 1 ;; esac - # Check if the option took a separate argument + # Check whether the option took a separate argument if [ "${arg2}" = yes ] ; then if [ $# != 0 ] ; then args="${args} \"$1\"" ; shift else echo "configure: Missing argument to '${option}'" 1>&2 diff --git a/doc/pdlzip.1 b/doc/pdlzip.1 index 1a16448..15fb29a 100644 --- a/doc/pdlzip.1 +++ b/doc/pdlzip.1 @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.2. -.TH PDLZIP "1" "January 2024" "pdlzip 1.13" "User Commands" +.TH PDLZIP "1" "November 2024" "pdlzip 1.14-rc1" "User Commands" .SH NAME pdlzip \- reduces the size of files .SH SYNOPSIS @@ -9,19 +9,19 @@ pdlzip \- reduces the size of files Pdlzip is a permissively licensed implementation of the lzip data compressor, intended for those who can't distribute (or even use) GPL licensed Free Software. The name of pdlzip comes from 'public domain lzip'. -Pdlzip is written in C and is compatible with lzip 1.4 or newer. +Pdlzip is written in C. .PP 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 -chain\-Algorithm' (LZMA) stream format to maximize interoperability. The -maximum dictionary size is 512 MiB so that any lzip file can be decompressed -on 32\-bit machines. Lzip provides accurate and robust 3\-factor integrity -checking. Lzip can compress about as fast as gzip (lzip \fB\-0\fR) or compress most -files more than bzip2 (lzip \fB\-9\fR). Decompression speed is intermediate between -gzip and bzip2. Lzip is better than gzip and bzip2 from a data recovery -perspective. Lzip has been designed, written, and tested with great care to -replace gzip and bzip2 as the standard general\-purpose compressed format for -Unix\-like systems. +of gzip or bzip2. Lzip uses a simplified form of LZMA (Lempel\-Ziv\-Markov +chain\-Algorithm) designed to achieve complete interoperability between +implementations. The maximum dictionary size is 512 MiB so that any lzip +file can be decompressed on 32\-bit machines. Lzip provides accurate and +robust 3\-factor integrity checking. 'lzip \fB\-0\fR' compresses about as fast as +gzip, while 'lzip \fB\-9\fR' compresses most files more than bzip2. Decompression +speed is intermediate between gzip and bzip2. Lzip provides better data +recovery capabilities than gzip and bzip2. Lzip has been designed, written, +and tested with great care to replace gzip and bzip2 as general\-purpose +compressed format for Unix\-like systems. .PP Pdlzip is also able to decompress legacy lzma\-alone (.lzma) files. Lzma\-alone is a very bad format; it is essentially a raw LZMA stream. @@ -188,9 +188,20 @@ static inline void Lt_set_member_size( Lzip_trailer data, unsigned long long sz { int i; for( i = 12; i <= 19; ++i ) { data[i] = (uint8_t)sz; sz >>= 8; } } +struct Cl_options /* command-line options */ + { + bool ignore_trailing; + bool loose_trailing; + }; + +static inline void Cl_options_init( struct Cl_options * cl_opts ) + { cl_opts->ignore_trailing = true; cl_opts->loose_trailing = false; } + + static inline void set_retval( int * retval, const int new_val ) { if( *retval < new_val ) *retval = new_val; } +static const char * const empty_msg = "Empty member not allowed."; static const char * const trailing_msg = "Trailing data not allowed."; static const char * const mem_msg = "Not enough memory."; @@ -28,7 +28,7 @@ #include <errno.h> #include <fcntl.h> -#include <limits.h> /* SSIZE_MAX */ +#include <limits.h> /* CHAR_BIT, SSIZE_MAX */ #include <signal.h> #include <stdbool.h> #include <stdint.h> /* SIZE_MAX */ @@ -114,18 +114,18 @@ static void show_help( void ) printf( "Pdlzip is a permissively licensed implementation of the lzip data\n" "compressor, intended for those who can't distribute (or even use) GPL\n" "licensed Free Software. The name of pdlzip comes from 'public domain lzip'.\n" - "Pdlzip is written in C and is compatible with lzip 1.4 or newer.\n" + "Pdlzip is written in C.\n" "\nLzip 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" - "chain-Algorithm' (LZMA) stream format to maximize interoperability. The\n" - "maximum dictionary size is 512 MiB so that any lzip file can be decompressed\n" - "on 32-bit machines. Lzip provides accurate and robust 3-factor integrity\n" - "checking. Lzip can compress about as fast as gzip (lzip -0) or compress most\n" - "files more than bzip2 (lzip -9). Decompression speed is intermediate between\n" - "gzip and bzip2. Lzip is better than gzip and bzip2 from a data recovery\n" - "perspective. Lzip has been designed, written, and tested with great care to\n" - "replace gzip and bzip2 as the standard general-purpose compressed format for\n" - "Unix-like systems.\n" + "of gzip or bzip2. Lzip uses a simplified form of LZMA (Lempel-Ziv-Markov\n" + "chain-Algorithm) designed to achieve complete interoperability between\n" + "implementations. The maximum dictionary size is 512 MiB so that any lzip\n" + "file can be decompressed on 32-bit machines. Lzip provides accurate and\n" + "robust 3-factor integrity checking. 'lzip -0' compresses about as fast as\n" + "gzip, while 'lzip -9' compresses most files more than bzip2. Decompression\n" + "speed is intermediate between gzip and bzip2. Lzip provides better data\n" + "recovery capabilities than gzip and bzip2. Lzip has been designed, written,\n" + "and tested with great care to replace gzip and bzip2 as general-purpose\n" + "compressed format for Unix-like systems.\n" "\nPdlzip is also able to decompress legacy lzma-alone (.lzma) files.\n" "Lzma-alone is a very bad format; it is essentially a raw LZMA stream.\n" "If you keep any lzma-alone files, it is advisable to recompress them to\n" @@ -226,6 +226,9 @@ static void Pp_init( struct Pretty_print * const pp, if( pp->longest_name == 0 ) pp->longest_name = stdin_name_len; } +void Pp_free( struct Pretty_print * const pp ) + { if( pp->padded_name ) { free( pp->padded_name ); pp->padded_name = 0; } } + static void Pp_set_name( struct Pretty_print * const pp, const char * const filename ) { @@ -268,7 +271,7 @@ static void show_header( const unsigned dictionary_size ) const char * p = ""; const char * np = " "; unsigned num = dictionary_size; - bool exact = ( num % factor == 0 ); + bool exact = num % factor == 0; int i; for( i = 0; i < n && ( num > 9999 || ( exact && num >= factor ) ); ++i ) { num /= factor; if( num % factor != 0 ) exact = false; @@ -277,7 +280,7 @@ static void show_header( const unsigned dictionary_size ) } -/* separate numbers of 5 or more digits in groups of 3 digits using '_' */ +/* separate numbers of 6 or more digits in groups of 3 digits using '_' */ static const char * format_num3( unsigned long long num ) { enum { buffers = 8, bufsize = 4 * sizeof num, n = 10 }; @@ -289,7 +292,7 @@ static const char * format_num3( unsigned long long num ) char * const buf = buffer[current++]; current %= buffers; char * p = buf + bufsize - 1; /* fill the buffer backwards */ *p = 0; /* terminator */ - if( num > 1024 ) + if( num > 9999 ) { char prefix = 0; /* try binary first, then si */ for( i = 0; i < n && num != 0 && num % 1024 == 0; ++i ) @@ -300,7 +303,7 @@ static const char * format_num3( unsigned long long num ) { num /= 1000; prefix = si_prefix[i]; } if( prefix ) *(--p) = prefix; } - const bool split = num >= 10000; + const bool split = num >= 100000; for( i = 0; ; ) { @@ -335,7 +338,7 @@ static unsigned long getnum( const char * const arg, 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 i; switch( tail[0] ) @@ -458,7 +461,7 @@ static int open_instream( const char * const name, struct stat * const in_statsp if( program_mode == m_compress && !recompress && eindex >= 0 ) { if( verbosity >= 0 ) - fprintf( stderr, "%s: %s: Input file already has '%s' suffix.\n", + fprintf( stderr, "%s: %s: Input file already has '%s' suffix, ignored.\n", program_name, name, known_extensions[eindex].from ); return -1; } @@ -469,9 +472,9 @@ static int open_instream( const char * const name, struct stat * const in_statsp { const int i = fstat( infd, in_statsp ); const mode_t mode = in_statsp->st_mode; - const bool can_read = ( i == 0 && - ( S_ISBLK( mode ) || S_ISCHR( mode ) || - S_ISFIFO( mode ) || S_ISSOCK( mode ) ) ); + const bool can_read = i == 0 && + ( S_ISBLK( mode ) || S_ISCHR( mode ) || + S_ISFIFO( mode ) || S_ISSOCK( mode ) ); if( i != 0 || ( !S_ISREG( mode ) && ( !can_read || one_to_one ) ) ) { if( verbosity >= 0 ) @@ -616,7 +619,7 @@ static int compress( const int infd, const struct Lzma_options * const } if( writeblock( outfd, header, Lh_size ) != Lh_size ) - { show_error( "Can't write output file", errno, false ); retval = 1; } + { show_error( "Write error", errno, false ); retval = 1; } else if( LzmaEnc_Encode( encoder ) != 0 ) { Pp_show_msg( pp, "Encoder error." ); retval = 1; } @@ -684,7 +687,7 @@ static int lzma_decode( uint64_t unpackSize, CLzmaDec *decoder, const int infd, unsigned long long member_size = lzma_header_size, data_size = 0; uint8_t outBuf[OUT_BUF_SIZE]; int outPos = 0; - const bool thereIsSize = (unpackSize != (uint64_t)-1); + const bool thereIsSize = unpackSize != (uint64_t)-1; for (;;) { @@ -711,7 +714,7 @@ static int lzma_decode( uint64_t unpackSize, CLzmaDec *decoder, const int infd, unpackSize -= outProcessed; if( outfd >= 0 && writeblock( outfd, outBuf, outPos ) != outPos ) - { show_error( "Can't write output file", errno, false ); return 1; } + { show_error( "Write error", errno, false ); return 1; } data_size += outPos; outPos = 0; @@ -734,7 +737,7 @@ static int lzma_decode( uint64_t unpackSize, CLzmaDec *decoder, const int infd, static int lzip_decode( CLzmaDec *decoder, const int infd, struct Pretty_print * const pp, uint8_t inBuf[], int * const inPos, int * const inSize, - const unsigned dictionary_size ) + const unsigned dictionary_size, bool * const data0p ) { unsigned long long member_size = Lh_size, data_size = 0; uint8_t outBuf[OUT_BUF_SIZE]; @@ -762,7 +765,7 @@ static int lzip_decode( CLzmaDec *decoder, const int infd, outPos += outProcessed; if( outfd >= 0 && writeblock( outfd, outBuf, outPos ) != outPos ) - { show_error( "Can't write output file", errno, false ); return 1; } + { show_error( "Write error", errno, false ); return 1; } CRC32_update_buf( &crc, outBuf, outPos ); data_size += outPos; @@ -830,15 +833,16 @@ static int lzip_decode( CLzmaDec *decoder, const int infd, } if( error ) return 2; show_results( data_size, member_size, td_crc, dictionary_size, true ); + *data0p = data_size == 0; return 0; } } } -static int decompress( const int infd, struct Pretty_print * const pp, - const bool ignore_trailing, const bool loose_trailing, - const bool testing ) +static int decompress( const int infd, const struct Cl_options * const cl_opts, + struct Pretty_print * const pp, + const bool from_stdin, const bool testing ) { uint64_t unpackSize = 0; CLzmaDec decoder; @@ -848,6 +852,7 @@ static int decompress( const int infd, struct Pretty_print * const pp, bool lzip_mode = true; bool first_member; uint8_t raw_props[lzma_header_size]; + bool empty = false, multi = false; for( first_member = true; ; first_member = false ) { @@ -867,7 +872,7 @@ static int decompress( const int infd, struct Pretty_print * const pp, else if( Lh_check_prefix( header, size ) ) { Pp_show_msg( pp, "Truncated header in multimember file." ); retval = 2; } - else if( size > 0 && !ignore_trailing ) + else if( size > 0 && !cl_opts->ignore_trailing ) { Pp_show_msg( pp, trailing_msg ); retval = 2; } break; } @@ -875,10 +880,10 @@ static int decompress( const int infd, struct Pretty_print * const pp, { if( !first_member ) { - if( !loose_trailing && Lh_check_corrupt( header ) ) + if( !cl_opts->loose_trailing && Lh_check_corrupt( header ) ) { Pp_show_msg( pp, "Corrupt header in multimember file." ); retval = 2; } - else if( !ignore_trailing ) + else if( !cl_opts->ignore_trailing ) { Pp_show_msg( pp, trailing_msg ); retval = 2; } break; } @@ -929,19 +934,23 @@ static int decompress( const int infd, struct Pretty_print * const pp, if( !LzmaDec_Init( &decoder, raw_props ) ) { Pp_show_msg( pp, mem_msg ); return 1; } + bool data0 = false; if( lzip_mode ) retval = lzip_decode( &decoder, infd, pp, inBuf, &inPos, &inSize, - dictionary_size ); + dictionary_size, &data0 ); else retval = lzma_decode( unpackSize, &decoder, infd, inBuf, &inPos, &inSize, dictionary_size, testing ); LzmaDec_Free(&decoder); if( retval != 0 || !lzip_mode ) break; + if( !from_stdin ) { multi = !first_member; if( data0 ) empty = true; } if( verbosity >= 2 ) { fputs( testing ? "ok\n" : "done\n", stderr ); Pp_reset( pp ); } } if( lzip_mode && verbosity == 1 && retval == 0 ) fputs( testing ? "ok\n" : "done\n", stderr ); + if( empty && multi && retval == 0 ) + { show_file_error( pp->name, empty_msg, 0 ); retval = 2; } return retval; } @@ -1038,10 +1047,10 @@ int main( const int argc, const char * const argv[] ) const char * default_output_filename = ""; enum Mode program_mode = m_compress; int i; + struct Cl_options cl_opts; /* command-line options */ + Cl_options_init( &cl_opts ); bool force = false; - bool ignore_trailing = true; bool keep_input_files = false; - bool loose_trailing = false; bool recompress = false; bool to_stdout = false; if( argc > 0 ) invocation_name = argv[0]; @@ -1077,7 +1086,7 @@ int main( const int argc, const char * const argv[] ) { 'v', "verbose", ap_no }, { 'V', "version", ap_no }, { opt_lt, "loose-trailing", ap_no }, - { 0, 0, ap_no } }; + { 0, 0, ap_no } }; CRC32_init(); @@ -1097,11 +1106,11 @@ int main( const int argc, const char * const argv[] ) const char * const arg = ap_argument( &parser, argind ); switch( code ) { - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': + case '0': case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': encoder_options = option_mapping[code-'0']; break; - case 'a': ignore_trailing = false; break; - case 'b': break; + case 'a': cl_opts.ignore_trailing = false; break; + case 'b': break; /* ignored */ case 'c': to_stdout = true; break; case 'd': set_mode( &program_mode, m_decompress ); break; case 'f': force = true; break; @@ -1110,17 +1119,17 @@ int main( const int argc, const char * const argv[] ) case 'k': keep_input_files = true; break; case 'm': encoder_options.match_len_limit = getnum( arg, pn, min_match_len_limit, max_match_len ); break; - case 'n': break; + case 'n': break; /* ignored */ case 'o': if( strcmp( arg, "-" ) == 0 ) to_stdout = true; else { default_output_filename = arg; } break; case 'q': verbosity = -1; break; case 's': encoder_options.dictionary_size = get_dict_size( arg, pn ); break; - case 'S': break; + case 'S': break; /* ignored */ case 't': set_mode( &program_mode, m_test ); break; case 'v': if( verbosity < 4 ) ++verbosity; break; case 'V': show_version(); return 0; - case opt_lt: loose_trailing = true; break; + case opt_lt: cl_opts.loose_trailing = true; break; default: internal_error( "uncaught option." ); } } /* end process options */ @@ -1168,9 +1177,10 @@ int main( const int argc, const char * const argv[] ) { const char * input_filename = ""; int infd; + const bool from_stdin = strcmp( filenames[i], "-" ) == 0; Pp_set_name( &pp, filenames[i] ); - if( strcmp( filenames[i], "-" ) == 0 ) + if( from_stdin ) { if( stdin_used ) continue; else stdin_used = true; infd = STDIN_FILENO; @@ -1215,7 +1225,7 @@ int main( const int argc, const char * const argv[] ) if( program_mode == m_compress ) tmp = compress( infd, &encoder_options, &pp ); else - tmp = decompress( infd, &pp, ignore_trailing, loose_trailing, + tmp = decompress( infd, &cl_opts, &pp, from_stdin, program_mode == m_test ); if( close( infd ) != 0 ) { show_file_error( pp.name, "Error closing input file", errno ); @@ -1243,6 +1253,7 @@ int main( const int argc, const char * const argv[] ) program_name, failed_tests, ( failed_tests == 1 ) ? "file" : "files" ); free( output_filename ); + Pp_free( &pp ); free( filenames ); ap_free( &parser ); return retval; diff --git a/testsuite/check.sh b/testsuite/check.sh index 6b7522e..0651ab3 100755 --- a/testsuite/check.sh +++ b/testsuite/check.sh @@ -28,10 +28,10 @@ if [ -d tmp ] ; then rm -rf tmp ; fi mkdir tmp 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_em="${testdir}"/test_em.txt.lz fox_lz="${testdir}"/fox.lz +fnz_lz="${testdir}"/fox_nz.lz fail=0 test_failed() { fail=1 ; printf " $1" ; [ -z "$2" ] || printf "($2)" ; } @@ -95,7 +95,7 @@ printf "LZIP\001+.............................." | "${LZIP}" -t 2> /dev/null printf "\ntesting decompression..." -for i in "${in_lz}" "${in_em}" "${testdir}"/test.txt.lzma ; do +for i in "${in_lz}" "${testdir}"/test.txt.lzma ; do "${LZIP}" -t "$i" || test_failed $LINENO "$i" "${LZIP}" -d "$i" -o out || test_failed $LINENO "$i" cmp in out || test_failed $LINENO "$i" @@ -108,16 +108,13 @@ for i in "${in_lz}" "${in_em}" "${testdir}"/test.txt.lzma ; do rm -f out || framework_failure done -lines=`"${LZIP}" -tvv "${in_em}" 2>&1 | wc -l` || test_failed $LINENO -[ "${lines}" -eq 8 ] || test_failed $LINENO "${lines}" - -cat "${in_lz}" > out.lz || framework_failure +cp "${in_lz}" out.lz || framework_failure "${LZIP}" -dk out.lz || test_failed $LINENO cmp in out || test_failed $LINENO rm -f out || framework_failure "${LZIP}" -cd "${fox_lz}" > fox || test_failed $LINENO -cat fox > copy || framework_failure -cat "${in_lz}" > copy.lz || framework_failure +cp fox copy || framework_failure +cp "${in_lz}" copy.lz || framework_failure "${LZIP}" -d copy.lz out.lz 2> /dev/null # skip copy, decompress out [ $? = 1 ] || test_failed $LINENO [ ! -e out.lz ] || test_failed $LINENO @@ -139,7 +136,7 @@ rm -f ./- || framework_failure cmp in ./- || test_failed $LINENO 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 || test_failed $LINENO cmp in out || test_failed $LINENO @@ -157,7 +154,7 @@ cat out in | cmp in - || test_failed $LINENO # out must be empty [ $? = 1 ] || test_failed $LINENO cmp in out || test_failed $LINENO 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 printf "g" >> out.lz || framework_failure "${LZIP}" -atvvvv out.lz "${in_lz}" 2> /dev/null @@ -186,6 +183,9 @@ cmp in2 out2 || test_failed $LINENO rm -f out2 || 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}" + printf "\ngarbage" >> out2.lz || framework_failure "${LZIP}" -tvvvv out2.lz 2> /dev/null || test_failed $LINENO "${LZIP}" -atq out2.lz @@ -203,6 +203,20 @@ printf "to be overwritten" > out2 || framework_failure cmp in2 out2 || test_failed $LINENO rm -f out2 || framework_failure +touch empty em || framework_failure +"${LZIP}" -0 em || 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..." "${LZIP}" -c -0 in in in -o out3.lz > copy2.lz || test_failed $LINENO @@ -211,7 +225,7 @@ printf "\ntesting compression..." "${LZIP}" -d copy2.lz -o out2 || test_failed $LINENO [ -e copy2.lz ] || 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 [ $? = 1 ] || test_failed $LINENO @@ -259,11 +273,38 @@ rm -f copy out.lz || framework_failure printf "\ntesting bad input..." +cat em.lz em.lz > ee.lz || framework_failure +"${LZIP}" -t < ee.lz || test_failed $LINENO +"${LZIP}" -d < ee.lz > em || test_failed $LINENO +cmp empty em || 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}" -t < inein.lz || test_failed $LINENO +"${LZIP}" -d < inein.lz > out2 || test_failed $LINENO +cmp in2 out2 || 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' -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' -cat "${in_lz}" > int.lz || framework_failure +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' +cp "${in_lz}" 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 printf "${header}${body}" > int.lz || framework_failure "${LZIP}" -tq int.lz # first member @@ -278,7 +319,7 @@ if "${LZIP}" -tq int.lz ; then [ $? = 2 ] || test_failed $LINENO ${header} "${LZIP}" -cdq --loose-trailing int.lz > /dev/null [ $? = 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 "${LZIP}" -tq int.lz # trailing data [ $? = 2 ] || test_failed $LINENO ${header} @@ -300,10 +341,13 @@ if "${LZIP}" -tq int.lz ; then [ $? = 2 ] || test_failed $LINENO ${header} done 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 rm -f int.lz || framework_failure +"${LZIP}" -tq "${fnz_lz}" +[ $? = 2 ] || test_failed $LINENO + 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 "${LZIP}" -tq "${testdir}"/$i @@ -315,13 +359,13 @@ for i in fox_bcrc.lz fox_crc0.lz fox_das46.lz fox_mes81.lz ; do [ $? = 2 ] || test_failed $LINENO $i cmp fox out || test_failed $LINENO $i 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}" "${in_lz}" > in3.lz || framework_failure -if dd if=in3.lz of=trunc.lz bs=14752 count=1 2> /dev/null && - [ -e trunc.lz ] && cmp in2.lz trunc.lz > /dev/null 2>&1 ; then - for i in 6 20 14734 14753 14754 14755 14756 14757 14758 ; do +if dd if=in3.lz of=trunc.lz bs=14682 count=1 2> /dev/null && + [ -e trunc.lz ] && cmp in2.lz trunc.lz ; then + 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 "${LZIP}" -tq trunc.lz [ $? = 2 ] || test_failed $LINENO $i @@ -333,28 +377,32 @@ if dd if=in3.lz of=trunc.lz bs=14752 count=1 2> /dev/null && [ $? = 2 ] || test_failed $LINENO $i done 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 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 cat "${in_lz}" >> ingin.lz || framework_failure "${LZIP}" -atq ingin.lz [ $? = 2 ] || test_failed $LINENO "${LZIP}" -atq < ingin.lz [ $? = 2 ] || test_failed $LINENO -"${LZIP}" -acdq ingin.lz > /dev/null +"${LZIP}" -acdq ingin.lz > out [ $? = 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 +cmp in out || 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 cmp in out || test_failed $LINENO "${LZIP}" -d < ingin.lz > 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 if [ ${fail} = 0 ] ; then diff --git a/testsuite/fox_nz.lz b/testsuite/fox_nz.lz Binary files differnew file mode 100644 index 0000000..44a4b58 --- /dev/null +++ b/testsuite/fox_nz.lz diff --git a/testsuite/test.txt b/testsuite/test.txt index 9196a3a..423f0c0 100644 --- a/testsuite/test.txt +++ b/testsuite/test.txt @@ -1,8 +1,7 @@ GNU GENERAL PUBLIC LICENSE Version 2, June 1991 - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Copyright (C) 1989, 1991 Free Software Foundation, Inc. <http://fsf.org/> Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. @@ -339,8 +338,7 @@ Public License instead of this License. GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
diff --git a/testsuite/test.txt.lz b/testsuite/test.txt.lz Binary files differindex 22cea6e..5dc169f 100644 --- a/testsuite/test.txt.lz +++ b/testsuite/test.txt.lz diff --git a/testsuite/test.txt.lzma b/testsuite/test.txt.lzma Binary files differindex 53e54ea..091c023 100644 --- a/testsuite/test.txt.lzma +++ b/testsuite/test.txt.lzma diff --git a/testsuite/test_em.txt.lz b/testsuite/test_em.txt.lz Binary files differdeleted file mode 100644 index 7e96250..0000000 --- a/testsuite/test_em.txt.lz +++ /dev/null |