diff --git a/ChangeLog b/ChangeLog index 74c2b8c..5d52edb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,16 +1,8 @@ -2025-01-07 Antonio Diaz Diaz +2023-12-21 Antonio Diaz Diaz - * Version 1.14 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 - - * Version 1.13 released. + * Version 1.13-rc1 released. * main.c: Reformat file diagnostics as 'PROGRAM: FILE: MESSAGE'. (show_option_error): New function showing argument and option name. - (main): Make -o preserve date/mode/owner if 1 input file. * lzip.h: Rename verify_* to check_*. * configure, Makefile.in: New variable 'MAKEINFO'. * INSTALL: Document use of CFLAGS+='--std=c99 -D_XOPEN_SOURCE=500'. @@ -46,12 +38,12 @@ 2018-02-04 Antonio Diaz Diaz * Version 1.9 released. - * New option '--loose-trailing'. - * Replace 'bits/byte' with inverse compression ratio in output. + * main.c: New option '--loose-trailing'. * 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. + * 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. Show dictionary size at verbosity level 4 (-vvvv). 2017-04-12 Antonio Diaz Diaz @@ -65,9 +57,10 @@ * Version 1.7 released. * main.c: New option '-a, --trailing-error'. * main.c (main): Delete '--output' file if infd is a terminal. - (main): Don't use stdin more than once. + * main.c (main): Don't use stdin more than once. * configure: Avoid warning on some shells when testing for gcc. - * check.sh: Require a POSIX shell. Don't check error messages. + * check.sh: A POSIX shell is required to run the tests. + * check.sh: Don't check error messages. 2015-05-26 Antonio Diaz Diaz @@ -84,16 +77,16 @@ 2013-05-27 Antonio Diaz Diaz * Version 1.4 released. - * Decompression time has been reduced by 5%. * main.c: New options '-f, --force', '-F, --recompress', '-k, --keep', and '-o, --output'. - 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. + * 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. * configure: Options now accept a separate argument. - Rename 'datadir' to 'datarootdir'. + * configure: Rename 'datadir' to 'datarootdir'. * Makefile.in: New targets 'install-as-lzip' and 'install-bin'. 2012-01-03 Antonio Diaz Diaz @@ -101,7 +94,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 (main): Set stdin/stdout in binary mode on OS2. + * main.c: Set stdin/stdout in binary mode on OS2. 2011-01-05 Antonio Diaz Diaz @@ -125,7 +118,8 @@ * Using LZMA SDK 9.10 (public domain) from Igor Pavlov. -Copyright (C) 2010-2025 Antonio Diaz Diaz. +Copyright (C) 2010-2023 Antonio Diaz Diaz. -This file is a collection of facts, and thus it is not copyrightable, but just -in case, you have unlimited permission to copy, distribute, and modify it. +This file is a collection of facts, and thus it is not copyrightable, +but just in case, you have unlimited permission to copy, distribute, and +modify it. diff --git a/INSTALL b/INSTALL index e500eb9..594420c 100644 --- a/INSTALL +++ b/INSTALL @@ -3,8 +3,7 @@ Requirements You will need a C99 compiler. (gcc 3.3.6 or newer is recommended). I use gcc 6.1.0 and 3.3.6, but the code should compile with any standards compliant compiler. -Gcc is available at http://gcc.gnu.org -Lzip is available at http://www.nongnu.org/lzip/lzip.html +Gcc is available at http://gcc.gnu.org. The operating system must allow signal handlers read access to objects with static storage duration so that the cleanup handler for Control-C can delete @@ -75,7 +74,7 @@ After running 'configure', you can run 'make' and 'make install' as explained above. -Copyright (C) 2010-2025 Antonio Diaz Diaz. +Copyright (C) 2010-2023 Antonio Diaz Diaz. This file is free documentation: you have unlimited permission to copy, distribute, and modify it. diff --git a/LzmaDec.c b/LzmaDec.c index bd2a45a..1236bd3 100644 --- a/LzmaDec.c +++ b/LzmaDec.c @@ -716,8 +716,8 @@ static bool LzmaDec_DecodeToDic(CLzmaDec *p, uint32_t dicLimit, *status = LZMA_STATUS_NEEDS_MORE_INPUT; return true; } - /* check first byte of the LZMA stream */ - if (p->tempBuf[0] != 0) return false; + if (p->tempBuf[0] != 0) + return false; LzmaDec_InitRc(p, p->tempBuf); p->tempBufSize = 0; diff --git a/Makefile.in b/Makefile.in index fc59256..4b8c791 100644 --- a/Makefile.in +++ b/Makefile.in @@ -2,8 +2,8 @@ DISTNAME = $(pkgname)-$(pkgversion) INSTALL = install INSTALL_PROGRAM = $(INSTALL) -m 755 -INSTALL_DIR = $(INSTALL) -d -m 755 INSTALL_DATA = $(INSTALL) -m 644 +INSTALL_DIR = $(INSTALL) -d -m 755 SHELL = /bin/sh CAN_RUN_INSTALLINFO = $(SHELL) -c "install-info --version" > /dev/null 2>&1 @@ -30,8 +30,7 @@ main.o : main.c # prevent 'make' from trying to remake source files $(VPATH)/configure $(VPATH)/Makefile.in $(VPATH)/doc/$(pkgname).texi : ; -MAKEFLAGS += -r -.SUFFIXES : +%.h %.c : ; $(objs) : Makefile carg_parser.o : carg_parser.h @@ -126,7 +125,8 @@ dist : doc $(DISTNAME)/testsuite/fox.lz \ $(DISTNAME)/testsuite/fox_*.lz \ $(DISTNAME)/testsuite/test.txt.lz \ - $(DISTNAME)/testsuite/test.txt.lzma + $(DISTNAME)/testsuite/test.txt.lzma \ + $(DISTNAME)/testsuite/test_em.txt.lz rm -f $(DISTNAME) lzip -v -9 $(DISTNAME).tar diff --git a/NEWS b/NEWS index e715e5e..5415fd8 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,12 @@ -Changes in version 1.14: +Changes in version 1.13: -pdlzip now exits with error status 2 if any empty member is found in a -multimember file. +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 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' diff --git a/README b/README index 1e4ae50..14f73b7 100644 --- a/README +++ b/README @@ -1,31 +1,30 @@ -See the file INSTALL for compilation and installation instructions. - 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. +Pdlzip is written in C and is (hope)fully compatible with lzip 1.4 or newer. Lzip is a lossless data compressor with a user interface similar to the one -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. +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. The lzip file format is designed for data sharing and long-term archiving, taking into account both data integrity and decoder availability: - * The program lziprecover can repair bit flip errors (one of the most - common forms of data corruption) in lzip files, and provides data - recovery capabilities, including error-checked merging of damaged - copies of a file. + * The lzip format provides very safe integrity checking and some data + recovery means. The program lziprecover can repair bit flip errors + (one of the most common forms of data corruption) in lzip files, and + provides data recovery capabilities, including error-checked merging + of damaged copies of a file. * 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 @@ -51,14 +50,18 @@ without recompressing. Pdlzip includes public domain compression/decompression code from the LZMA SDK (Software Development Kit) written by Igor Pavlov. -Pdlzip uses Arg_parser for command-line argument parsing: -http://www.nongnu.org/arg-parser/arg_parser.html +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-2025 Antonio Diaz Diaz. +Copyright (C) 2010-2023 Antonio Diaz Diaz. This file is free documentation: you have unlimited permission to copy, distribute, and modify it. -The file Makefile.in is a data file used by configure to produce the Makefile. -It has the same copyright owner and permissions that configure itself. +The file Makefile.in is a data file used by configure to produce the +Makefile. It has the same copyright owner and permissions that configure +itself. diff --git a/carg_parser.c b/carg_parser.c index 20b8a16..8882b97 100644 --- a/carg_parser.c +++ b/carg_parser.c @@ -1,5 +1,5 @@ /* Arg_parser - POSIX/GNU command-line argument parser. (C version) - Copyright (C) 2006-2025 Antonio Diaz Diaz. + Copyright (C) 2006-2023 Antonio Diaz Diaz. This library is free software. Redistribution and use in source and binary forms, with or without modification, are permitted provided @@ -32,15 +32,15 @@ static void * ap_resize_buffer( void * buf, const int min_size ) } -static char push_back_record( Arg_parser * const ap, const int code, +static char push_back_record( struct Arg_parser * const ap, const int code, const char * const long_name, const char * const argument ) { - ap_Record * p; + struct ap_Record * p; void * tmp = ap_resize_buffer( ap->data, - ( ap->data_size + 1 ) * sizeof (ap_Record) ); + ( ap->data_size + 1 ) * sizeof (struct ap_Record) ); if( !tmp ) return 0; - ap->data = (ap_Record *)tmp; + ap->data = (struct ap_Record *)tmp; p = &(ap->data[ap->data_size]); p->code = code; if( long_name ) @@ -71,7 +71,7 @@ static char push_back_record( Arg_parser * const ap, const int code, } -static char add_error( Arg_parser * const ap, const char * const msg ) +static char add_error( struct Arg_parser * const ap, const char * const msg ) { const int len = strlen( msg ); void * tmp = ap_resize_buffer( ap->error, ap->error_size + len + 1 ); @@ -83,7 +83,7 @@ static char add_error( Arg_parser * const ap, const char * const msg ) } -static void free_data( Arg_parser * const ap ) +static void free_data( struct Arg_parser * const ap ) { int i; for( i = 0; i < ap->data_size; ++i ) @@ -94,9 +94,10 @@ static void free_data( Arg_parser * const ap ) /* Return 0 only if out of memory. */ -static char parse_long_option( Arg_parser * const ap, +static char parse_long_option( struct Arg_parser * const ap, const char * const opt, const char * const arg, - const ap_Option options[], int * const argindp ) + const struct ap_Option options[], + int * const argindp ) { unsigned len; int index = -1, i; @@ -147,21 +148,21 @@ static char parse_long_option( 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] ); /* argument may be empty */ + return push_back_record( ap, options[index].code, + options[index].long_name, &opt[len+3] ); } - if( options[index].has_arg == ap_yes || options[index].has_arg == ap_yme ) + if( options[index].has_arg == ap_yes ) { - if( !arg || ( options[index].has_arg == ap_yes && !arg[0] ) ) + if( !arg || !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 ); /* argument may be empty */ + return push_back_record( ap, options[index].code, + options[index].long_name, arg ); } return push_back_record( ap, options[index].code, @@ -170,9 +171,10 @@ static char parse_long_option( Arg_parser * const ap, /* Return 0 only if out of memory. */ -static char parse_short_option( Arg_parser * const ap, +static char parse_short_option( struct Arg_parser * const ap, const char * const opt, const char * const arg, - const ap_Option options[], int * const argindp ) + const struct ap_Option options[], + int * const argindp ) { int cind = 1; /* character index in opt */ @@ -202,15 +204,15 @@ static char parse_short_option( 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 || options[index].has_arg == ap_yme ) + else if( options[index].has_arg == ap_yes ) { - if( !arg || ( options[index].has_arg == ap_yes && !arg[0] ) ) + if( !arg || !arg[0] ) { add_error( ap, "option requires an argument -- '" ); add_error( ap, code_str ); add_error( ap, "'" ); return 1; } - ++*argindp; cind = 0; /* argument may be empty */ + ++*argindp; cind = 0; if( !push_back_record( ap, c, 0, arg ) ) return 0; } else if( !push_back_record( ap, c, 0, 0 ) ) return 0; @@ -219,9 +221,9 @@ static char parse_short_option( Arg_parser * const ap, } -char ap_init( Arg_parser * const ap, +char ap_init( struct Arg_parser * const ap, const int argc, const char * const argv[], - const ap_Option options[], const char in_order ) + const struct ap_Option options[], const char in_order ) { const char ** non_options = 0; /* skipped non-options */ int non_options_size = 0; /* number of skipped non-options */ @@ -280,7 +282,7 @@ out: if( non_options ) free( non_options ); } -void ap_free( Arg_parser * const ap ) +void ap_free( struct Arg_parser * const ap ) { free_data( ap ); if( ap->error ) { free( ap->error ); ap->error = 0; } @@ -288,25 +290,29 @@ void ap_free( Arg_parser * const ap ) } -const char * ap_error( const Arg_parser * const ap ) { return ap->error; } +const char * ap_error( const struct Arg_parser * const ap ) + { return ap->error; } -int ap_arguments( const Arg_parser * const ap ) { return ap->data_size; } -int ap_code( const Arg_parser * const ap, const int i ) +int ap_arguments( const struct Arg_parser * const ap ) + { return ap->data_size; } + + +int ap_code( const struct Arg_parser * const ap, const int i ) { if( i < 0 || i >= ap_arguments( ap ) ) return 0; return ap->data[i].code; } -const char * ap_parsed_name( const Arg_parser * const ap, const int i ) +const char * ap_parsed_name( const struct Arg_parser * const ap, const int i ) { if( i < 0 || i >= ap_arguments( ap ) || !ap->data[i].parsed_name ) return ""; return ap->data[i].parsed_name; } -const char * ap_argument( const Arg_parser * const ap, const int i ) +const char * ap_argument( const struct Arg_parser * const ap, const int i ) { if( i < 0 || i >= ap_arguments( ap ) || !ap->data[i].argument ) return ""; return ap->data[i].argument; diff --git a/carg_parser.h b/carg_parser.h index 28eabee..ec5d3d0 100644 --- a/carg_parser.h +++ b/carg_parser.h @@ -1,5 +1,5 @@ /* Arg_parser - POSIX/GNU command-line argument parser. (C version) - Copyright (C) 2006-2025 Antonio Diaz Diaz. + Copyright (C) 2006-2023 Antonio Diaz Diaz. This library is free software. Redistribution and use in source and binary forms, with or without modification, are permitted provided @@ -37,65 +37,60 @@ The argument '--' terminates all options; any following arguments are treated as non-option arguments, even if they begin with a hyphen. - The syntax of options with an optional argument is - '-' (without whitespace), or - '--='. - - The syntax of options with an empty argument is '- ""', - '-- ""', or '--=""'. + The syntax for optional option arguments is '-' + (without whitespace), or '--='. */ #ifdef __cplusplus extern "C" { #endif -/* ap_yme = yes but maybe empty */ -typedef enum ap_Has_arg { ap_no, ap_yes, ap_maybe, ap_yme } ap_Has_arg; +enum ap_Has_arg { ap_no, ap_yes, ap_maybe }; -typedef struct ap_Option +struct ap_Option { int code; /* Short option letter or code ( code != 0 ) */ const char * long_name; /* Long option name (maybe null) */ - ap_Has_arg has_arg; - } ap_Option; + enum ap_Has_arg has_arg; + }; -typedef struct ap_Record +struct ap_Record { int code; char * parsed_name; char * argument; - } ap_Record; + }; -typedef struct Arg_parser +struct Arg_parser { - ap_Record * data; + struct ap_Record * data; char * error; int data_size; int error_size; - } Arg_parser; + }; -char ap_init( Arg_parser * const ap, +char ap_init( struct Arg_parser * const ap, const int argc, const char * const argv[], - const ap_Option options[], const char in_order ); + const struct ap_Option options[], const char in_order ); -void ap_free( Arg_parser * const ap ); +void ap_free( struct Arg_parser * const ap ); -const char * ap_error( const Arg_parser * const ap ); +const char * ap_error( const struct Arg_parser * const ap ); /* The number of arguments parsed. May be different from argc. */ -int ap_arguments( const Arg_parser * const ap ); +int ap_arguments( const struct Arg_parser * const ap ); /* If ap_code( i ) is 0, ap_argument( i ) is a non-option. Else ap_argument( i ) is the option's argument (or empty). */ -int ap_code( const Arg_parser * const ap, const int i ); +int ap_code( const struct Arg_parser * const ap, const int i ); /* Full name of the option parsed (short or long). */ -const char * ap_parsed_name( const Arg_parser * const ap, const int i ); +const char * ap_parsed_name( const struct Arg_parser * const ap, const int i ); -const char * ap_argument( const Arg_parser * const ap, const int i ); +const char * ap_argument( const struct Arg_parser * const ap, const int i ); #ifdef __cplusplus } diff --git a/configure b/configure index 4f3fdd2..1f8c60f 100755 --- a/configure +++ b/configure @@ -1,12 +1,12 @@ #! /bin/sh # configure script for Pdlzip - LZMA lossless data compressor -# Copyright (C) 2010-2025 Antonio Diaz Diaz. +# Copyright (C) 2010-2023 Antonio Diaz Diaz. # # This configure script is free software: you have unlimited permission # to copy, distribute, and modify it. pkgname=pdlzip -pkgversion=1.14 +pkgversion=1.13-rc1 progname=pdlzip srctrigger=doc/${progname}.1 @@ -109,7 +109,7 @@ while [ $# != 0 ] ; do exit 1 ;; esac - # Check whether the option took a separate argument + # Check if 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 @@ -171,7 +171,7 @@ echo "MAKEINFO = ${MAKEINFO}" rm -f Makefile cat > Makefile << EOF # Makefile for Pdlzip - LZMA lossless data compressor -# Copyright (C) 2010-2025 Antonio Diaz Diaz. +# Copyright (C) 2010-2023 Antonio Diaz Diaz. # This file was generated automatically by configure. Don't edit. # # This Makefile is free software: you have unlimited permission diff --git a/debian/changelog b/debian/changelog index bf322b7..ea827f9 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,33 +1,3 @@ -pdlzip (1.14-1) sid; urgency=medium - - * Uploading to sid. - * Merging upstream version 1.14. - * Correcting public-domain identifier in copyright. - - -- Daniel Baumann Tue, 14 Jan 2025 11:06:12 +0100 - -pdlzip (1.14~rc1-1) sid; urgency=medium - - * Uploading to sid. - * Merging upstream version 1.14~rc1. - - -- Daniel Baumann Sun, 10 Nov 2024 09:40:36 +0100 - -pdlzip (1.13-2) sid; urgency=medium - - * Uploading to sid. - * Updating to standards-version 4.7.0. - - -- Daniel Baumann Thu, 25 Jul 2024 06:44:16 +0200 - -pdlzip (1.13-1) sid; urgency=medium - - * Uploading to sid. - * Merging upstream version 1.13. - * Updating years in copyright for 2024. - - -- Daniel Baumann Wed, 31 Jan 2024 06:33:48 +0100 - pdlzip (1.13~rc1-1) sid; urgency=medium * Uploading to sid. diff --git a/debian/control b/debian/control index cb4e339..3b7beea 100644 --- a/debian/control +++ b/debian/control @@ -5,7 +5,7 @@ Maintainer: Daniel Baumann Build-Depends: debhelper-compat (= 13), Rules-Requires-Root: no -Standards-Version: 4.7.0 +Standards-Version: 4.6.2 Homepage: http://www.nongnu.org/lzip/pdlzip.html Vcs-Browser: https://git.progress-linux.org/users/daniel.baumann/debian/packages/pdlzip Vcs-Git: https://git.progress-linux.org/users/daniel.baumann/debian/packages/pdlzip diff --git a/debian/copyright b/debian/copyright index e3a99c2..e433c95 100644 --- a/debian/copyright +++ b/debian/copyright @@ -4,12 +4,12 @@ Upstream-Contact: lzip-bug@nongnu.org Source: https://download.savannah.gnu.org/releases/lzip/ Files: * -Copyright: 2010-2024 Antonio Diaz Diaz +Copyright: 2010-2022 Antonio Diaz Diaz Igor Pavlov -License: public-domain +License: PD Files: debian/* -Copyright: 2009-2024 Daniel Baumann +Copyright: 2009-2022 Daniel Baumann License: BSD-2 License: BSD-2 diff --git a/doc/pdlzip.1 b/doc/pdlzip.1 index 81ab168..0e3e384 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 2025" "pdlzip 1.14" "User Commands" +.TH PDLZIP "1" "December 2023" "pdlzip 1.13-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. +Pdlzip is written in C and is (hope)fully compatible with lzip 1.4 or newer. .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 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. +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. .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. @@ -112,7 +112,7 @@ Report bugs to lzip\-bug@nongnu.org .br Pdlzip home page: http://www.nongnu.org/lzip/pdlzip.html .SH COPYRIGHT -Copyright \(co 2025 Antonio Diaz Diaz. +Copyright \(co 2023 Antonio Diaz Diaz. Public Domain 2009 Igor Pavlov. License 2\-clause BSD. .br diff --git a/lzip.h b/lzip.h index 7dc9ee3..7e7805a 100644 --- a/lzip.h +++ b/lzip.h @@ -1,5 +1,5 @@ /* Pdlzip - LZMA lossless data compressor - Copyright (C) 2010-2025 Antonio Diaz Diaz. + Copyright (C) 2010-2023 Antonio Diaz Diaz. This program is free software. Redistribution and use in source and binary forms, with or without modification, are permitted provided @@ -188,22 +188,11 @@ 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; } } -typedef struct Cl_options /* command-line options */ - { - bool ignore_trailing; - bool loose_trailing; - } Cl_options; - -static inline void Cl_options_init( 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 mem_msg = "Not enough memory."; static const char * const trailing_msg = "Trailing data not allowed."; +static const char * const mem_msg = "Not enough memory."; /* defined in main.c */ extern int verbosity; diff --git a/main.c b/main.c index f224942..0d3b659 100644 --- a/main.c +++ b/main.c @@ -1,6 +1,6 @@ /* Pdlzip - LZMA lossless data compressor 2009-08-14 : Igor Pavlov : Public domain - Copyright (C) 2010-2025 Antonio Diaz Diaz. + Copyright (C) 2010-2023 Antonio Diaz Diaz. This program is free software. Redistribution and use in source and binary forms, with or without modification, are permitted provided @@ -28,7 +28,7 @@ #include #include -#include /* CHAR_BIT, SSIZE_MAX */ +#include /* SSIZE_MAX */ #include #include #include /* SIZE_MAX */ @@ -85,7 +85,7 @@ static void show_file_error( const char * const filename, static void internal_error( const char * const msg ); static const char * const program_name = "pdlzip"; -static const char * const program_year = "2025"; +static const char * const program_year = "2023"; static const char * invocation_name = "pdlzip"; /* default value */ static const struct { const char * from; const char * to; } known_extensions[] = { @@ -94,13 +94,13 @@ static const struct { const char * from; const char * to; } known_extensions[] = { ".lzma", "" }, { 0, 0 } }; -typedef struct Lzma_options +struct Lzma_options { int dictionary_size; /* 4 KiB .. 512 MiB */ int match_len_limit; /* 5 .. 273 */ - } Lzma_options; + }; -typedef enum Mode { m_compress, m_decompress, m_test } Mode; +enum Mode { m_compress, m_decompress, m_test }; /* Variables used in signal handler context. They are not declared volatile because the handler never returns. */ @@ -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.\n" + "Pdlzip is written in C and is (hope)fully compatible with lzip 1.4 or newer.\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 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" + "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" "\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" @@ -196,16 +196,16 @@ static void * resize_buffer( void * buf, const unsigned min_size ) } -typedef struct Pretty_print +struct Pretty_print { const char * name; char * padded_name; const char * stdin_name; unsigned longest_name; bool first_post; - } Pretty_print; + }; -static void Pp_init( Pretty_print * const pp, +static void Pp_init( struct Pretty_print * const pp, const char * const filenames[], const int num_filenames ) { pp->name = 0; @@ -226,10 +226,8 @@ static void Pp_init( Pretty_print * const pp, if( pp->longest_name == 0 ) pp->longest_name = stdin_name_len; } -void Pp_free( Pretty_print * const pp ) - { if( pp->padded_name ) { free( pp->padded_name ); pp->padded_name = 0; } } - -static void Pp_set_name( Pretty_print * const pp, const char * const filename ) +static void Pp_set_name( struct Pretty_print * const pp, + const char * const filename ) { unsigned name_len, padded_name_len, i = 0; @@ -247,10 +245,10 @@ static void Pp_set_name( Pretty_print * const pp, const char * const filename ) pp->first_post = true; } -static void Pp_reset( Pretty_print * const pp ) +static void Pp_reset( struct Pretty_print * const pp ) { if( pp->name && pp->name[0] ) pp->first_post = true; } -static void Pp_show_msg( Pretty_print * const pp, const char * const msg ) +static void Pp_show_msg( struct Pretty_print * const pp, const char * const msg ) { if( verbosity < 0 ) return; if( pp->first_post ) @@ -270,7 +268,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; @@ -291,7 +289,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 > 9999 ) + if( num > 1024 ) { char prefix = 0; /* try binary first, then si */ for( i = 0; i < n && num != 0 && num % 1024 == 0; ++i ) @@ -337,7 +335,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] ) @@ -387,7 +385,7 @@ static int get_dict_size( const char * const arg, const char * const option_name } -static void set_mode( Mode * const program_modep, const Mode new_mode ) +static void set_mode( enum Mode * const program_modep, const enum Mode new_mode ) { if( *program_modep != m_compress && *program_modep != new_mode ) { @@ -454,13 +452,13 @@ static void set_d_outname( const char * const name, const int eindex ) static int open_instream( const char * const name, struct stat * const in_statsp, - const Mode program_mode, const int eindex, + const enum Mode program_mode, const int eindex, const bool one_to_one, const bool recompress ) { if( program_mode == m_compress && !recompress && eindex >= 0 ) { if( verbosity >= 0 ) - fprintf( stderr, "%s: %s: Input file already has '%s' suffix, ignored.\n", + fprintf( stderr, "%s: %s: Input file already has '%s' suffix.\n", program_name, name, known_extensions[eindex].from ); return -1; } @@ -471,9 +469,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 ) @@ -539,7 +537,7 @@ static void signal_handler( int sig ) static bool check_tty_in( const char * const input_filename, const int infd, - const Mode program_mode, int * const retval ) + const enum Mode program_mode, int * const retval ) { if( ( program_mode == m_decompress || program_mode == m_test ) && isatty( infd ) ) /* for example /dev/tty */ @@ -551,7 +549,7 @@ static bool check_tty_in( const char * const input_filename, const int infd, return true; } -static bool check_tty_out( const Mode program_mode ) +static bool check_tty_out( const enum Mode program_mode ) { if( program_mode == m_compress && isatty( outfd ) ) { show_file_error( output_filename[0] ? @@ -569,7 +567,7 @@ static void close_and_set_permissions( const struct stat * const in_statsp ) if( in_statsp ) { const mode_t mode = in_statsp->st_mode; - /* fchown in many cases returns with EPERM, which can be safely ignored. */ + /* fchown will in many cases return with EPERM, which can be safely ignored. */ if( fchown( outfd, in_statsp->st_uid, in_statsp->st_gid ) == 0 ) { if( fchmod( outfd, mode ) != 0 ) warning = true; } else @@ -595,9 +593,8 @@ static void close_and_set_permissions( const struct stat * const in_statsp ) } -static int compress( const int infd, - const Lzma_options * const encoder_options, - Pretty_print * const pp ) +static int compress( const int infd, const struct Lzma_options * const + encoder_options, struct Pretty_print * const pp ) { int retval = 0; CLzmaEncHandle encoder = 0; @@ -619,7 +616,7 @@ static int compress( const int infd, } if( writeblock( outfd, header, Lh_size ) != Lh_size ) - { show_error( "Write error", errno, false ); retval = 1; } + { show_error( "Can't write output file", errno, false ); retval = 1; } else if( LzmaEnc_Encode( encoder ) != 0 ) { Pp_show_msg( pp, "Encoder error." ); retval = 1; } @@ -687,7 +684,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 (;;) { @@ -714,7 +711,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( "Write error", errno, false ); return 1; } + { show_error( "Can't write output file", errno, false ); return 1; } data_size += outPos; outPos = 0; @@ -734,10 +731,10 @@ static int lzma_decode( uint64_t unpackSize, CLzmaDec *decoder, const int infd, } -static int lzip_decode( CLzmaDec * decoder, const int infd, - Pretty_print * const pp, uint8_t inBuf[], +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, bool * const data0p ) + const unsigned dictionary_size ) { unsigned long long member_size = Lh_size, data_size = 0; uint8_t outBuf[OUT_BUF_SIZE]; @@ -765,7 +762,7 @@ static int lzip_decode( CLzmaDec * decoder, const int infd, outPos += outProcessed; if( outfd >= 0 && writeblock( outfd, outBuf, outPos ) != outPos ) - { show_error( "Write error", errno, false ); return 1; } + { show_error( "Can't write output file", errno, false ); return 1; } CRC32_update_buf( &crc, outBuf, outPos ); data_size += outPos; @@ -833,16 +830,15 @@ 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, const Cl_options * const cl_opts, - Pretty_print * const pp, - const bool from_stdin, const bool testing ) +static int decompress( const int infd, struct Pretty_print * const pp, + const bool ignore_trailing, const bool loose_trailing, + const bool testing ) { uint64_t unpackSize = 0; CLzmaDec decoder; @@ -852,7 +848,6 @@ static int decompress( const int infd, const Cl_options * const cl_opts, 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 ) { @@ -872,7 +867,7 @@ static int decompress( const int infd, const Cl_options * const cl_opts, else if( Lh_check_prefix( header, size ) ) { Pp_show_msg( pp, "Truncated header in multimember file." ); retval = 2; } - else if( size > 0 && !cl_opts->ignore_trailing ) + else if( size > 0 && !ignore_trailing ) { Pp_show_msg( pp, trailing_msg ); retval = 2; } break; } @@ -880,10 +875,10 @@ static int decompress( const int infd, const Cl_options * const cl_opts, { if( !first_member ) { - if( !cl_opts->loose_trailing && Lh_check_corrupt( header ) ) + if( !loose_trailing && Lh_check_corrupt( header ) ) { Pp_show_msg( pp, "Corrupt header in multimember file." ); retval = 2; } - else if( !cl_opts->ignore_trailing ) + else if( !ignore_trailing ) { Pp_show_msg( pp, trailing_msg ); retval = 2; } break; } @@ -934,23 +929,19 @@ static int decompress( const int infd, const Cl_options * const cl_opts, 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, &data0 ); + dictionary_size ); 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; } @@ -1031,7 +1022,7 @@ int main( const int argc, const char * const argv[] ) { /* Mapping from gzip/bzip2 style 0..9 compression levels to the corresponding LZMA compression parameters. */ - const Lzma_options option_mapping[] = + const struct Lzma_options option_mapping[] = { { 1 << 16, 5 }, /* -0 */ { 1 << 20, 5 }, /* -1 */ @@ -1043,19 +1034,20 @@ int main( const int argc, const char * const argv[] ) { 1 << 24, 68 }, /* -7 */ { 3 << 23, 132 }, /* -8 */ { 1 << 25, 273 } }; /* -9 */ - Lzma_options encoder_options = option_mapping[6]; /* default = "-6" */ + struct Lzma_options encoder_options = option_mapping[6]; /* default = "-6" */ const char * default_output_filename = ""; - Mode program_mode = m_compress; - Cl_options cl_opts; /* command-line options */ - Cl_options_init( &cl_opts ); + enum Mode program_mode = m_compress; + int i; 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]; enum { opt_lt = 256 }; - const ap_Option options[] = + const struct ap_Option options[] = { { '0', "fast", ap_no }, { '1', 0, ap_no }, @@ -1085,12 +1077,12 @@ 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(); /* static because valgrind complains and memory management in C sucks */ - static Arg_parser parser; + static struct Arg_parser parser; if( !ap_init( &parser, argc, argv, options, 0 ) ) { show_error( mem_msg, 0, false ); return 1; } if( ap_error( &parser ) ) /* bad option */ @@ -1105,11 +1097,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': cl_opts.ignore_trailing = false; break; - case 'b': break; /* ignored */ + case 'a': ignore_trailing = false; break; + case 'b': break; case 'c': to_stdout = true; break; case 'd': set_mode( &program_mode, m_decompress ); break; case 'f': force = true; break; @@ -1118,17 +1110,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; /* ignored */ + case 'n': break; 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; /* ignored */ + case 'S': break; 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: cl_opts.loose_trailing = true; break; + case opt_lt: loose_trailing = true; break; default: internal_error( "uncaught option." ); } } /* end process options */ @@ -1143,7 +1135,6 @@ int main( const int argc, const char * const argv[] ) filenames = resize_buffer( filenames, num_filenames * sizeof filenames[0] ); filenames[0] = "-"; - int i; bool filenames_given = false; for( i = 0; argind + i < ap_arguments( &parser ); ++i ) { @@ -1165,22 +1156,21 @@ int main( const int argc, const char * const argv[] ) if( !to_stdout && program_mode != m_test && ( filenames_given || to_file ) ) set_signals( signal_handler ); - static Pretty_print pp; + static struct Pretty_print pp; Pp_init( &pp, filenames, num_filenames ); int failed_tests = 0; int retval = 0; const bool one_to_one = !to_stdout && program_mode != m_test && !to_file; bool stdin_used = false; - struct stat in_stats; for( i = 0; i < num_filenames; ++i ) { const char * input_filename = ""; int infd; - const bool from_stdin = strcmp( filenames[i], "-" ) == 0; + struct stat in_stats; Pp_set_name( &pp, filenames[i] ); - if( from_stdin ) + if( strcmp( filenames[i], "-" ) == 0 ) { if( stdin_used ) continue; else stdin_used = true; infd = STDIN_FILENO; @@ -1225,7 +1215,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, &cl_opts, &pp, from_stdin, + tmp = decompress( infd, &pp, ignore_trailing, loose_trailing, program_mode == m_test ); if( close( infd ) != 0 ) { show_file_error( pp.name, "Error closing input file", errno ); @@ -1240,9 +1230,7 @@ int main( const int argc, const char * const argv[] ) if( input_filename[0] && !keep_input_files && one_to_one ) remove( input_filename ); } - if( delete_output_on_interrupt ) /* -o */ - close_and_set_permissions( ( retval == 0 && !stdin_used && - filenames_given && num_filenames == 1 ) ? &in_stats : 0 ); + if( delete_output_on_interrupt ) close_and_set_permissions( 0 ); /* -o */ else if( outfd >= 0 && close( outfd ) != 0 ) /* -c */ { show_error( "Error closing stdout", errno, false ); @@ -1253,7 +1241,6 @@ 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 1760359..8c18a1c 100755 --- a/testsuite/check.sh +++ b/testsuite/check.sh @@ -1,6 +1,6 @@ #! /bin/sh # check script for Pdlzip - LZMA lossless data compressor -# Copyright (C) 2010-2025 Antonio Diaz Diaz. +# Copyright (C) 2010-2023 Antonio Diaz Diaz. # # This script is free software: you have unlimited permission # to copy, distribute, and modify it. @@ -28,10 +28,10 @@ if [ -d tmp ] ; then rm -rf tmp ; fi mkdir tmp cd "${objdir}"/tmp || framework_failure -cp "${testdir}"/test.txt in || framework_failure +cat "${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}" "${testdir}"/test.txt.lzma ; do +for i in "${in_lz}" "${in_em}" "${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,13 +108,16 @@ for i in "${in_lz}" "${testdir}"/test.txt.lzma ; do rm -f out || framework_failure done -cp "${in_lz}" out.lz || framework_failure +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 "${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 -cp fox copy || framework_failure -cp "${in_lz}" copy.lz || framework_failure +cat fox > copy || framework_failure +cat "${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 @@ -128,6 +131,7 @@ rm -f copy out || framework_failure printf "to be overwritten" > out || framework_failure "${LZIP}" -df -o out < "${in_lz}" || test_failed $LINENO cmp in out || test_failed $LINENO +rm -f out || framework_failure "${LZIP}" -d -o ./- "${in_lz}" || test_failed $LINENO cmp in ./- || test_failed $LINENO rm -f ./- || framework_failure @@ -135,12 +139,12 @@ rm -f ./- || framework_failure cmp in ./- || test_failed $LINENO rm -f ./- || framework_failure -cp "${in_lz}" anyothername || framework_failure +cat "${in_lz}" > anyothername || framework_failure "${LZIP}" -dv - anyothername - < "${in_lz}" > out 2> /dev/null || test_failed $LINENO cmp in out || test_failed $LINENO cmp in anyothername.out || test_failed $LINENO -rm -f anyothername.out || framework_failure +rm -f out anyothername.out || framework_failure "${LZIP}" -tq in "${in_lz}" [ $? = 2 ] || test_failed $LINENO @@ -153,7 +157,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 -cp "${in_lz}" out.lz || framework_failure +cat "${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 @@ -182,9 +186,6 @@ 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 @@ -202,20 +203,6 @@ 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 @@ -224,7 +211,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 copy2.lz || framework_failure +rm -f in2 out2 copy2.lz || framework_failure "${LZIP}" -cf "${in_lz}" > lzlz 2> /dev/null # /dev/null is a tty on OS/2 [ $? = 1 ] || test_failed $LINENO @@ -272,38 +259,11 @@ 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\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 +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 printf "LZIP${body}" >> int.lz || framework_failure -if "${LZIP}" -t int.lz ; then +if "${LZIP}" -tq int.lz ; then for header in ${headers} ; do printf "${header}${body}" > int.lz || framework_failure "${LZIP}" -tq int.lz # first member @@ -318,7 +278,7 @@ if "${LZIP}" -t int.lz ; then [ $? = 2 ] || test_failed $LINENO ${header} "${LZIP}" -cdq --loose-trailing int.lz > /dev/null [ $? = 2 ] || test_failed $LINENO ${header} - cp "${in_lz}" int.lz || framework_failure + cat "${in_lz}" > int.lz || framework_failure printf "${header}${body}" >> int.lz || framework_failure "${LZIP}" -tq int.lz # trailing data [ $? = 2 ] || test_failed $LINENO ${header} @@ -340,13 +300,10 @@ if "${LZIP}" -t int.lz ; then [ $? = 2 ] || test_failed $LINENO ${header} done else - printf "warning: skipping header test: 'printf' does not work on your system." + printf "\nwarning: 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 @@ -358,13 +315,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 || framework_failure +rm -f fox out || 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=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 +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 dd if=in3.lz of=trunc.lz bs=$i count=1 2> /dev/null "${LZIP}" -tq trunc.lz [ $? = 2 ] || test_failed $LINENO $i @@ -376,32 +333,28 @@ if dd if=in3.lz of=trunc.lz bs=14682 count=1 2> /dev/null && [ $? = 2 ] || test_failed $LINENO $i done else - printf "warning: skipping truncation test: 'dd' does not work on your system." + printf "\nwarning: skipping truncation test: 'dd' does not work on your system." fi rm -f in2.lz in3.lz trunc.lz || framework_failure -cp "${in_lz}" ingin.lz || framework_failure +cat "${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 > out +"${LZIP}" -acdq ingin.lz > /dev/null [ $? = 2 ] || test_failed $LINENO -cmp in out || test_failed $LINENO -"${LZIP}" -adq < ingin.lz > out +"${LZIP}" -adq < ingin.lz > /dev/null [ $? = 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 ingin.lz || framework_failure +rm -f out ingin.lz || framework_failure echo if [ ${fail} = 0 ] ; then diff --git a/testsuite/fox_nz.lz b/testsuite/fox_nz.lz deleted file mode 100644 index 44a4b58..0000000 Binary files a/testsuite/fox_nz.lz and /dev/null differ diff --git a/testsuite/test.txt b/testsuite/test.txt index 423f0c0..9196a3a 100644 --- a/testsuite/test.txt +++ b/testsuite/test.txt @@ -1,7 +1,8 @@ GNU GENERAL PUBLIC LICENSE Version 2, June 1991 - Copyright (C) 1989, 1991 Free Software Foundation, Inc. + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. @@ -338,7 +339,8 @@ Public License instead of this License. GNU GENERAL PUBLIC LICENSE Version 2, June 1991 - Copyright (C) 1989, 1991 Free Software Foundation, Inc. + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 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 index 5dc169f..22cea6e 100644 Binary files a/testsuite/test.txt.lz and b/testsuite/test.txt.lz differ diff --git a/testsuite/test.txt.lzma b/testsuite/test.txt.lzma index 091c023..53e54ea 100644 Binary files a/testsuite/test.txt.lzma and b/testsuite/test.txt.lzma differ diff --git a/testsuite/test_em.txt.lz b/testsuite/test_em.txt.lz new file mode 100644 index 0000000..7e96250 Binary files /dev/null and b/testsuite/test_em.txt.lz differ