From fa76077496ba086e603450f70bfb3007e14ea777 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 17 Feb 2025 22:03:07 +0100 Subject: [PATCH] Adding upstream version 1.2. Signed-off-by: Daniel Baumann --- ChangeLog | 10 ++- INSTALL | 11 ++- Makefile.in | 21 ++++-- NEWS | 14 +--- README | 2 +- carg_parser.c | 2 +- configure | 37 +++++---- decoder.c | 103 +++++++++++++++---------- decoder.h | 168 ++++++++++++++++++----------------------- doc/lunzip.1 | 4 +- lunzip.h | 87 ++++++++++----------- main.c | 161 ++++++++++++++++----------------------- testsuite/check.sh | 21 +----- testsuite/test.txt.lz | Bin 0 -> 11518 bytes testsuite/test_sync.lz | Bin 11658 -> 0 bytes testsuite/test_v0.lz | Bin 11540 -> 0 bytes testsuite/test_v1.lz | Bin 11548 -> 0 bytes 17 files changed, 302 insertions(+), 339 deletions(-) create mode 100644 testsuite/test.txt.lz delete mode 100644 testsuite/test_sync.lz delete mode 100644 testsuite/test_v0.lz delete mode 100644 testsuite/test_v1.lz diff --git a/ChangeLog b/ChangeLog index b9e41e1..b08eb00 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2013-02-18 Antonio Diaz Diaz + + * Version 1.2 released. + * Decompression time has been reduced by 12%. + * Makefile.in: Added new target 'install-as-lzip'. + * Makefile.in: Added new target 'install-bin'. + * main.c: Use 'setmode' instead of '_setmode' on Windows and OS/2. + 2012-02-26 Antonio Diaz Diaz * Version 1.1 released. @@ -15,7 +23,7 @@ * Created from the decompression code of clzip 1.1. -Copyright (C) 2010, 2011, 2012 Antonio Diaz Diaz. +Copyright (C) 2010, 2011, 2012, 2013 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 diff --git a/INSTALL b/INSTALL index a745cc1..53f1df3 100644 --- a/INSTALL +++ b/INSTALL @@ -1,7 +1,7 @@ Requirements ------------ You will need a C compiler. -I use gcc 4.3.5 and 3.3.6, but the code should compile with any +I use gcc 4.7.2 and 3.3.6, but the code should compile with any standards compliant compiler. Gcc is available at http://gcc.gnu.org. @@ -32,6 +32,13 @@ the main archive. 5. Type 'make install' to install the program and any data files and documentation. + You can install only the program, the info manual or the man page + typing 'make install-bin', 'make install-info' or 'make install-man' + respectively. + +5a. Type 'make install-as-lzip' to install the program and any data + files and documentation, and link the program to the name 'lzip'. + Another way ----------- @@ -50,7 +57,7 @@ After running 'configure', you can run 'make' and 'make install' as explained above. -Copyright (C) 2010, 2011, 2012 Antonio Diaz Diaz. +Copyright (C) 2010, 2011, 2012, 2013 Antonio Diaz Diaz. This file is free documentation: you have unlimited permission to copy, distribute and modify it. diff --git a/Makefile.in b/Makefile.in index cde25d8..378f626 100644 --- a/Makefile.in +++ b/Makefile.in @@ -9,8 +9,8 @@ SHELL = /bin/sh objs = carg_parser.o decoder.o main.o -.PHONY : all install install-info install-man install-strip \ - uninstall uninstall-info uninstall-man \ +.PHONY : all install install-bin install-info install-man install-strip \ + install-as-lzip uninstall uninstall-bin uninstall-info uninstall-man \ doc info man check dist clean distclean all : $(progname) @@ -52,14 +52,16 @@ Makefile : $(VPATH)/configure $(VPATH)/Makefile.in check : all @$(VPATH)/testsuite/check.sh $(VPATH)/testsuite $(pkgversion) -install : all install-man +install : install-bin install-man + +install-bin : all if [ ! -d "$(DESTDIR)$(bindir)" ] ; then $(INSTALL_DIR) "$(DESTDIR)$(bindir)" ; fi $(INSTALL_PROGRAM) ./$(progname) "$(DESTDIR)$(bindir)/$(progname)" install-info : if [ ! -d "$(DESTDIR)$(infodir)" ] ; then $(INSTALL_DIR) "$(DESTDIR)$(infodir)" ; fi $(INSTALL_DATA) $(VPATH)/doc/$(pkgname).info "$(DESTDIR)$(infodir)/$(pkgname).info" - -install-info --info-dir="$(DESTDIR)$(infodir)" $(DESTDIR)$(infodir)/$(pkgname).info + -install-info --info-dir="$(DESTDIR)$(infodir)" "$(DESTDIR)$(infodir)/$(pkgname).info" install-man : if [ ! -d "$(DESTDIR)$(mandir)/man1" ] ; then $(INSTALL_DIR) "$(DESTDIR)$(mandir)/man1" ; fi @@ -68,7 +70,13 @@ install-man : install-strip : all $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' install -uninstall : uninstall-man +install-as-lzip : install + -rm -f "$(DESTDIR)$(bindir)/lzip" + cd "$(DESTDIR)$(bindir)" && ln -s $(progname) lzip + +uninstall : uninstall-bin uninstall-man + +uninstall-bin : -rm -f "$(DESTDIR)$(bindir)/$(progname)" uninstall-info : @@ -92,8 +100,7 @@ dist : doc $(DISTNAME)/doc/$(progname).1 \ $(DISTNAME)/testsuite/check.sh \ $(DISTNAME)/testsuite/test.txt \ - $(DISTNAME)/testsuite/test_sync.lz \ - $(DISTNAME)/testsuite/test_v[01].lz \ + $(DISTNAME)/testsuite/test.txt.lz \ $(DISTNAME)/*.h \ $(DISTNAME)/*.c rm -f $(DISTNAME) diff --git a/NEWS b/NEWS index 3538962..b9ed0f4 100644 --- a/NEWS +++ b/NEWS @@ -1,13 +1,7 @@ -Changes in version 1.1: +Changes in version 1.2: -Print only one status line for each multimember file when only one "-v" -is specified. +Decompression time has been reduced by 12%. -Inability to change output file attributes has been downgraded from -error to warning. +The target "install-as-lzip" has been added to the Makefile. -Quote characters in messages have been changed as advised by GNU Coding -Standards. - -Configure option "--datadir" has been renamed to "--datarootdir" to -follow GNU Standards. +The target "install-bin" has been added to the Makefile. diff --git a/README b/README index 67192db..217fb0a 100644 --- a/README +++ b/README @@ -35,7 +35,7 @@ few tens of KiB larger than the dictionary size used to compress that file. -Copyright (C) 2010, 2011, 2012 Antonio Diaz Diaz. +Copyright (C) 2010, 2011, 2012, 2013 Antonio Diaz Diaz. This file is free documentation: you have unlimited permission to copy, distribute and modify it. diff --git a/carg_parser.c b/carg_parser.c index 326bd41..973bb7e 100644 --- a/carg_parser.c +++ b/carg_parser.c @@ -88,7 +88,7 @@ static char parse_long_option( struct Arg_parser * const ap, const struct ap_Option options[], int * const argindp ) { - unsigned int len; + unsigned len; int index = -1; int i; char exact = 0, ambig = 0; diff --git a/configure b/configure index 4990706..703fe5d 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # configure script for Lunzip - Decompressor for lzip files -# Copyright (C) 2010, 2011, 2012 Antonio Diaz Diaz. +# Copyright (C) 2010, 2011, 2012, 2013 Antonio Diaz Diaz. # # This configure script is free software: you have unlimited permission # to copy, distribute and modify it. @@ -8,7 +8,7 @@ args= no_create= pkgname=lunzip -pkgversion=1.1 +pkgversion=1.2 progname=lunzip srctrigger=lunzip.h @@ -22,11 +22,19 @@ bindir='$(exec_prefix)/bin' datarootdir='$(prefix)/share' infodir='$(datarootdir)/info' mandir='$(datarootdir)/man' -CC= +CC=gcc CPPFLAGS= CFLAGS='-Wall -W -O2' LDFLAGS= +# checking whether we are using GNU C. +if [ ! -x /bin/gcc ] && + [ ! -x /usr/bin/gcc ] && + [ ! -x /usr/local/bin/gcc ] ; then + CC=cc + CFLAGS='-W -O2' +fi + # Loop over all args while [ -n "$1" ] ; do @@ -91,14 +99,14 @@ done srcdirtext= if [ -z "${srcdir}" ] ; then srcdirtext="or . or .." ; srcdir=. - if [ ! -r ${srcdir}/${srctrigger} ] ; then srcdir=.. ; fi - if [ ! -r ${srcdir}/${srctrigger} ] ; then + if [ ! -r "${srcdir}/${srctrigger}" ] ; then srcdir=.. ; fi + if [ ! -r "${srcdir}/${srctrigger}" ] ; then ## the sed command below emulates the dirname command srcdir=`echo $0 | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` fi fi -if [ ! -r ${srcdir}/${srctrigger} ] ; then +if [ ! -r "${srcdir}/${srctrigger}" ] ; then exec 1>&2 echo echo "configure: Can't find sources in ${srcdir} ${srcdirtext}" @@ -107,18 +115,7 @@ if [ ! -r ${srcdir}/${srctrigger} ] ; then fi # Set srcdir to . if that's what it is. -if [ "`pwd`" = "`cd ${srcdir} ; pwd`" ] ; then srcdir=. ; fi - -# checking whether we are using GNU C. -if [ -z "${CC}" ] ; then # Let the user override the test. - if [ -x /bin/gcc ] || - [ -x /usr/bin/gcc ] || - [ -x /usr/local/bin/gcc ] ; then - CC="gcc" - else - CC="cc" - fi -fi +if [ "`pwd`" = "`cd "${srcdir}" ; pwd`" ] ; then srcdir=. ; fi echo if [ -z "${no_create}" ] ; then @@ -152,7 +149,7 @@ echo "LDFLAGS = ${LDFLAGS}" rm -f Makefile cat > Makefile << EOF # Makefile for Lunzip - Decompressor for lzip files -# Copyright (C) 2010, 2011, 2012 Antonio Diaz Diaz. +# Copyright (C) 2010, 2011, 2012, 2013 Antonio Diaz Diaz. # This file was generated automatically by configure. Do not edit. # # This Makefile is free software: you have unlimited permission @@ -173,6 +170,6 @@ CPPFLAGS = ${CPPFLAGS} CFLAGS = ${CFLAGS} LDFLAGS = ${LDFLAGS} EOF -cat ${srcdir}/Makefile.in >> Makefile +cat "${srcdir}/Makefile.in" >> Makefile echo "OK. Now you can run make." diff --git a/decoder.c b/decoder.c index d09a143..25f7c73 100644 --- a/decoder.c +++ b/decoder.c @@ -1,5 +1,5 @@ /* Lunzip - Decompressor for lzip files - Copyright (C) 2010, 2011, 2012 Antonio Diaz Diaz. + Copyright (C) 2010, 2011, 2012, 2013 Antonio Diaz Diaz. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -32,23 +32,40 @@ CRC32 crc32; +void Pp_show_msg( struct Pretty_print * const pp, const char * const msg ) + { + if( pp->verbosity >= 0 ) + { + if( pp->first_post ) + { + int i, len; + pp->first_post = false; + fprintf( stderr, " %s: ", pp->name ); + len = pp->longest_name - strlen( pp->name ); + for( i = 0; i < len; ++i ) fprintf( stderr, " " ); + if( !msg ) fflush( stderr ); + } + if( msg ) fprintf( stderr, "%s.\n", msg ); + } + } + + /* Returns the number of bytes really read. If (returned value < size) and (errno == 0), means EOF was reached. */ static int readblock( const int fd, uint8_t * const buf, const int size ) { int rest = size; - while( true ) + errno = 0; + while( rest > 0 ) { - int n; - errno = 0; - if( rest <= 0 ) break; - n = read( fd, buf + size - rest, rest ); + const int n = read( fd, buf + size - rest, rest ); if( n > 0 ) rest -= n; - else if( n == 0 ) break; + else if( n == 0 ) break; /* EOF */ else if( errno != EINTR && errno != EAGAIN ) break; + errno = 0; } - return ( rest > 0 ) ? size - rest : size; + return size - rest; } @@ -58,16 +75,15 @@ static int readblock( const int fd, uint8_t * const buf, const int size ) static int writeblock( const int fd, const uint8_t * const buf, const int size ) { int rest = size; - while( true ) + errno = 0; + while( rest > 0 ) { - int n; - errno = 0; - if( rest <= 0 ) break; - n = write( fd, buf + size - rest, rest ); + const int n = write( fd, buf + size - rest, rest ); if( n > 0 ) rest -= n; else if( n < 0 && errno != EINTR && errno != EAGAIN ) break; + errno = 0; } - return ( rest > 0 ) ? size - rest : size; + return size - rest; } @@ -107,7 +123,7 @@ bool LZd_verify_trailer( struct LZ_decoder * const decoder, { File_trailer trailer; const int trailer_size = Ft_versioned_size( decoder->member_version ); - const long long member_size = + const unsigned long long member_size = Rd_member_position( decoder->range_decoder ) + trailer_size; bool error = false; @@ -136,8 +152,7 @@ bool LZd_verify_trailer( struct LZ_decoder * const decoder, { Pp_show_msg( pp, 0 ); fprintf( stderr, "CRC mismatch; trailer says %08X, data CRC is %08X.\n", - (unsigned int)Ft_get_data_crc( trailer ), - (unsigned int)LZd_crc( decoder ) ); + Ft_get_data_crc( trailer ), LZd_crc( decoder ) ); } } if( Ft_get_data_size( trailer ) != LZd_data_position( decoder ) ) @@ -146,7 +161,7 @@ bool LZd_verify_trailer( struct LZ_decoder * const decoder, if( pp->verbosity >= 0 ) { Pp_show_msg( pp, 0 ); - fprintf( stderr, "Data size mismatch; trailer says %lld, data size is %lld (0x%llX).\n", + fprintf( stderr, "Data size mismatch; trailer says %llu, data size is %llu (0x%llX).\n", Ft_get_data_size( trailer ), LZd_data_position( decoder ), LZd_data_position( decoder ) ); } } @@ -156,7 +171,7 @@ bool LZd_verify_trailer( struct LZ_decoder * const decoder, if( pp->verbosity >= 0 ) { Pp_show_msg( pp, 0 ); - fprintf( stderr, "Member size mismatch; trailer says %lld, member size is %lld (0x%llX).\n", + fprintf( stderr, "Member size mismatch; trailer says %llu, member size is %llu (0x%llX).\n", Ft_get_member_size( trailer ), member_size, member_size ); } } @@ -166,8 +181,8 @@ bool LZd_verify_trailer( struct LZ_decoder * const decoder, ( 8.0 * member_size ) / LZd_data_position( decoder ), 100.0 * ( 1.0 - ( (double)member_size / LZd_data_position( decoder ) ) ) ); if( !error && pp->verbosity >= 4 ) - fprintf( stderr, "data CRC %08X, data size %9lld, member size %8lld. ", - (unsigned int)Ft_get_data_crc( trailer ), + fprintf( stderr, "data CRC %08X, data size %9llu, member size %8llu. ", + Ft_get_data_crc( trailer ), Ft_get_data_size( trailer ), Ft_get_member_size( trailer ) ); return !error; } @@ -178,10 +193,11 @@ bool LZd_verify_trailer( struct LZ_decoder * const decoder, int LZd_decode_member( struct LZ_decoder * const decoder, struct Pretty_print * const pp ) { - unsigned int rep0 = 0; /* rep[0-3] latest four distances */ - unsigned int rep1 = 0; /* used for efficient coding of */ - unsigned int rep2 = 0; /* repeated distances */ - unsigned int rep3 = 0; + unsigned rep0 = 0; /* rep[0-3] latest four distances */ + unsigned rep1 = 0; /* used for efficient coding of */ + unsigned rep2 = 0; /* repeated distances */ + unsigned rep3 = 0; + State state = 0; Rd_load( decoder->range_decoder ); @@ -192,12 +208,17 @@ int LZd_decode_member( struct LZ_decoder * const decoder, { const uint8_t prev_byte = LZd_get_prev_byte( decoder ); if( St_is_char( state ) ) - LZd_put_byte( decoder, Lid_decode( &decoder->literal_decoder, - decoder->range_decoder, prev_byte ) ); + { + state -= ( state < 4 ) ? state : 3; + LZd_put_byte( decoder, Rd_decode_tree( decoder->range_decoder, + decoder->bm_literal[get_lit_state(prev_byte)], 8 ) ); + } else - LZd_put_byte( decoder, Lid_decode_matched( &decoder->literal_decoder, - decoder->range_decoder, prev_byte, LZd_get_byte( decoder, rep0 ) ) ); - St_set_char( &state ); + { + state -= ( state < 10 ) ? 3 : 6; + LZd_put_byte( decoder, Rd_decode_matched( decoder->range_decoder, + decoder->bm_literal[get_lit_state(prev_byte)], LZd_get_byte( decoder, rep0 ) ) ); + } } else { @@ -207,7 +228,7 @@ int LZd_decode_member( struct LZ_decoder * const decoder, len = 0; if( Rd_decode_bit( decoder->range_decoder, &decoder->bm_rep0[state] ) == 1 ) { - unsigned int distance; + unsigned distance; if( Rd_decode_bit( decoder->range_decoder, &decoder->bm_rep1[state] ) == 0 ) distance = rep1; else @@ -223,31 +244,33 @@ int LZd_decode_member( struct LZ_decoder * const decoder, else { if( Rd_decode_bit( decoder->range_decoder, &decoder->bm_len[state][pos_state] ) == 0 ) - { St_set_short_rep( &state ); len = 1; } + { state = St_set_short_rep( state ); len = 1; } } if( len == 0 ) { - St_set_rep( &state ); + state = St_set_rep( state ); len = min_match_len + Led_decode( &decoder->rep_match_len_decoder, decoder->range_decoder, pos_state ); } } else { int dis_slot; - const unsigned int rep0_saved = rep0; + const unsigned rep0_saved = rep0; len = min_match_len + Led_decode( &decoder->len_decoder, decoder->range_decoder, pos_state ); - dis_slot = Rd_decode_tree( decoder->range_decoder, decoder->bm_dis_slot[get_dis_state(len)], dis_slot_bits ); + dis_slot = Rd_decode_tree6( decoder->range_decoder, decoder->bm_dis_slot[get_dis_state(len)] ); if( dis_slot < start_dis_model ) rep0 = dis_slot; else { const int direct_bits = ( dis_slot >> 1 ) - 1; rep0 = ( 2 | ( dis_slot & 1 ) ) << direct_bits; if( dis_slot < end_dis_model ) - rep0 += Rd_decode_tree_reversed( decoder->range_decoder, decoder->bm_dis + rep0 - dis_slot, direct_bits ); + rep0 += Rd_decode_tree_reversed( decoder->range_decoder, + decoder->bm_dis + rep0 - dis_slot - 1, + direct_bits ); else { rep0 += Rd_decode( decoder->range_decoder, direct_bits - dis_align_bits ) << dis_align_bits; - rep0 += Rd_decode_tree_reversed( decoder->range_decoder, decoder->bm_align, dis_align_bits ); + rep0 += Rd_decode_tree_reversed4( decoder->range_decoder, decoder->bm_align ); if( rep0 == 0xFFFFFFFFU ) /* Marker found */ { rep0 = rep0_saved; @@ -271,9 +294,9 @@ int LZd_decode_member( struct LZ_decoder * const decoder, } } rep3 = rep2; rep2 = rep1; rep1 = rep0_saved; - St_set_match( &state ); - if( rep0 >= (unsigned int)decoder->dictionary_size || - ( rep0 >= (unsigned int)decoder->pos && !decoder->partial_data_pos ) ) + state = St_set_match( state ); + if( rep0 >= (unsigned)decoder->dictionary_size || + ( rep0 >= (unsigned)decoder->pos && !decoder->partial_data_pos ) ) { LZd_flush_data( decoder ); return 1; } } LZd_copy_block( decoder, rep0, len ); diff --git a/decoder.h b/decoder.h index 65174b5..29b164a 100644 --- a/decoder.h +++ b/decoder.h @@ -1,5 +1,5 @@ /* Lunzip - Decompressor for lzip files - Copyright (C) 2010, 2011, 2012 Antonio Diaz Diaz. + Copyright (C) 2010, 2011, 2012, 2013 Antonio Diaz Diaz. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -19,7 +19,7 @@ enum { rd_buffer_size = 16384 }; struct Range_decoder { - long long partial_member_pos; + unsigned long long partial_member_pos; uint8_t * buffer; /* input buffer */ int pos; /* current pos in buffer */ int stream_pos; /* when reached, a new block must be read */ @@ -51,7 +51,8 @@ static inline void Rd_free( struct Range_decoder * const rdec ) static inline bool Rd_finished( struct Range_decoder * const rdec ) { return rdec->pos >= rdec->stream_pos && !Rd_read_block( rdec ); } -static inline long long Rd_member_position( const struct Range_decoder * const rdec ) +static inline unsigned long long +Rd_member_position( const struct Range_decoder * const rdec ) { return rdec->partial_member_pos + rdec->pos; } static inline void Rd_reset_member_position( struct Range_decoder * const rdec ) @@ -59,7 +60,7 @@ static inline void Rd_reset_member_position( struct Range_decoder * const rdec ) static inline uint8_t Rd_get_byte( struct Range_decoder * const rdec ) { - if( Rd_finished( rdec ) ) return 0x55; /* make code != 0 */ + if( Rd_finished( rdec ) ) return 0xAA; /* make code != 0 */ return rdec->buffer[rdec->pos++]; } @@ -74,16 +75,16 @@ static inline int Rd_read_data( struct Range_decoder * const rdec, rdec->pos += rd; rest -= rd; } - return ( rest > 0 ) ? size - rest : size; + return size - rest; } static inline void Rd_load( struct Range_decoder * const rdec ) { int i; rdec->code = 0; - rdec->range = 0xFFFFFFFFU; for( i = 0; i < 5; ++i ) rdec->code = (rdec->code << 8) | Rd_get_byte( rdec ); + rdec->range = 0xFFFFFFFFU; } static inline void Rd_normalize( struct Range_decoder * const rdec ) @@ -102,20 +103,15 @@ static inline int Rd_decode( struct Range_decoder * const rdec, int i; for( i = num_bits; i > 0; --i ) { - symbol <<= 1; - if( rdec->range <= 0x00FFFFFFU ) - { - rdec->range <<= 7; - rdec->code = (rdec->code << 8) | Rd_get_byte( rdec ); - if( rdec->code >= rdec->range ) - { rdec->code -= rdec->range; symbol |= 1; } - } - else - { - rdec->range >>= 1; - if( rdec->code >= rdec->range ) - { rdec->code -= rdec->range; symbol |= 1; } - } + uint32_t mask; + Rd_normalize( rdec ); + rdec->range >>= 1; +/* symbol <<= 1; */ +/* if( rdec->code >= rdec->range ) { rdec->code -= rdec->range; symbol |= 1; } */ + mask = 0U - (rdec->code < rdec->range); + rdec->code -= rdec->range; + rdec->code += rdec->range & mask; + symbol = (symbol << 1) + (mask + 1); } return symbol; } @@ -151,6 +147,19 @@ static inline int Rd_decode_tree( struct Range_decoder * const rdec, return model - (1 << num_bits); } +static inline int Rd_decode_tree6( struct Range_decoder * const rdec, + Bit_model bm[] ) + { + int model = 1; + model = ( model << 1 ) | Rd_decode_bit( rdec, &bm[model] ); + model = ( model << 1 ) | Rd_decode_bit( rdec, &bm[model] ); + model = ( model << 1 ) | Rd_decode_bit( rdec, &bm[model] ); + model = ( model << 1 ) | Rd_decode_bit( rdec, &bm[model] ); + model = ( model << 1 ) | Rd_decode_bit( rdec, &bm[model] ); + model = ( model << 1 ) | Rd_decode_bit( rdec, &bm[model] ); + return model - (1 << 6); + } + static inline int Rd_decode_tree_reversed( struct Range_decoder * const rdec, Bit_model bm[], const int num_bits ) { @@ -159,32 +168,49 @@ static inline int Rd_decode_tree_reversed( struct Range_decoder * const rdec, int i; for( i = 0; i < num_bits; ++i ) { - const int bit = Rd_decode_bit( rdec, &bm[model] ); + const bool bit = Rd_decode_bit( rdec, &bm[model] ); model <<= 1; - if( bit ) { model |= 1; symbol |= (1 << i); } + if( bit ) { ++model; symbol |= (1 << i); } } return symbol; } +static inline int Rd_decode_tree_reversed4( struct Range_decoder * const rdec, + Bit_model bm[] ) + { + int model = 1; + int symbol = 0; + int bit = Rd_decode_bit( rdec, &bm[model] ); + model = (model << 1) + bit; symbol |= bit; + bit = Rd_decode_bit( rdec, &bm[model] ); + model = (model << 1) + bit; symbol |= (bit << 1); + bit = Rd_decode_bit( rdec, &bm[model] ); + model = (model << 1) + bit; symbol |= (bit << 2); + if( Rd_decode_bit( rdec, &bm[model] ) ) symbol |= 8; + return symbol; + } + static inline int Rd_decode_matched( struct Range_decoder * const rdec, - Bit_model bm[], const int match_byte ) + Bit_model bm[], int match_byte ) { Bit_model * const bm1 = bm + 0x100; int symbol = 1; int i; for( i = 7; i >= 0; --i ) { - const int match_bit = ( match_byte >> i ) & 1; - const int bit = Rd_decode_bit( rdec, &bm1[(match_bit<<8)+symbol] ); + int match_bit, bit; + match_byte <<= 1; + match_bit = match_byte & 0x100; + bit = Rd_decode_bit( rdec, &bm1[match_bit+symbol] ); symbol = ( symbol << 1 ) | bit; - if( match_bit != bit ) + if( match_bit != bit << 8 ) { - while( --i >= 0 ) + while( symbol < 0x100 ) symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] ); break; } } - return symbol & 0xFF; + return symbol - 0x100; } @@ -199,17 +225,11 @@ struct Len_decoder static inline void Led_init( struct Len_decoder * const len_decoder ) { - int i, j; Bm_init( &len_decoder->choice1 ); Bm_init( &len_decoder->choice2 ); - for( i = 0; i < pos_states; ++i ) - for( j = 0; j < len_low_symbols; ++j ) - Bm_init( &len_decoder->bm_low[i][j] ); - for( i = 0; i < pos_states; ++i ) - for( j = 0; j < len_mid_symbols; ++j ) - Bm_init( &len_decoder->bm_mid[i][j] ); - for( i = 0; i < len_high_symbols; ++i ) - Bm_init( &len_decoder->bm_high[i] ); + Bm_array_init( len_decoder->bm_low[0], pos_states * len_low_symbols ); + Bm_array_init( len_decoder->bm_mid[0], pos_states * len_mid_symbols ); + Bm_array_init( len_decoder->bm_high, len_high_symbols ); } static inline int Led_decode( struct Len_decoder * const len_decoder, @@ -226,37 +246,9 @@ static inline int Led_decode( struct Len_decoder * const len_decoder, } -struct Literal_decoder - { - Bit_model bm_literal[1<bm_literal[i][j] ); - } - -static inline int Lid_state( const uint8_t prev_byte ) - { return ( prev_byte >> ( 8 - literal_context_bits ) ); } - -static inline uint8_t Lid_decode( struct Literal_decoder * const lidec, - struct Range_decoder * const rdec, - const uint8_t prev_byte ) - { return Rd_decode_tree( rdec, lidec->bm_literal[Lid_state(prev_byte)], 8 ); } - -static inline uint8_t Lid_decode_matched( struct Literal_decoder * const lidec, - struct Range_decoder * const rdec, - const uint8_t prev_byte, - const uint8_t match_byte ) - { return Rd_decode_matched( rdec, lidec->bm_literal[Lid_state(prev_byte)], match_byte ); } - - struct LZ_decoder { - long long partial_data_pos; + unsigned long long partial_data_pos; int dictionary_size; int buffer_size; uint8_t * buffer; /* output buffer */ @@ -266,6 +258,7 @@ struct LZ_decoder int outfd; /* output file descriptor */ int member_version; + Bit_model bm_literal[1<pos - distance - 1; if( i < 0 ) i += decoder->buffer_size; if( len < decoder->buffer_size - max( decoder->pos, i ) && - len <= abs( decoder->pos - i ) ) + len <= abs( decoder->pos - i ) ) /* no wrap, no overlap */ { memcpy( decoder->buffer + decoder->pos, decoder->buffer + i, len ); decoder->pos += len; } - else for( ; len > 0 ; --len ) + else for( ; len > 0; --len ) { decoder->buffer[decoder->pos] = decoder->buffer[i]; if( ++decoder->pos >= decoder->buffer_size ) LZd_flush_data( decoder ); @@ -332,7 +324,6 @@ static inline bool LZd_init( struct LZ_decoder * const decoder, const File_header header, struct Range_decoder * const rdec, const int ofd ) { - int i, j; decoder->partial_data_pos = 0; decoder->dictionary_size = Fh_get_dictionary_size( header ); decoder->buffer_size = max( 65536, decoder->dictionary_size ); @@ -344,30 +335,20 @@ static inline bool LZd_init( struct LZ_decoder * const decoder, decoder->outfd = ofd; decoder->member_version = Fh_version( header ); - for( i = 0; i < states; ++i ) - { - for( j = 0; j < pos_states; ++j ) - { - Bm_init( &decoder->bm_match[i][j] ); - Bm_init( &decoder->bm_len[i][j] ); - } - Bm_init( &decoder->bm_rep[i] ); - Bm_init( &decoder->bm_rep0[i] ); - Bm_init( &decoder->bm_rep1[i] ); - Bm_init( &decoder->bm_rep2[i] ); - } - for( i = 0; i < max_dis_states; ++i ) - for( j = 0; j < 1<bm_dis_slot[i][j] ); - for( i = 0; i < modeled_distances-end_dis_model+1; ++i ) - Bm_init( &decoder->bm_dis[i] ); - for( i = 0; i < dis_align_size; ++i ) - Bm_init( &decoder->bm_align[i] ); + Bm_array_init( decoder->bm_literal[0], (1 << literal_context_bits) * 0x300 ); + Bm_array_init( decoder->bm_match[0], states * pos_states ); + Bm_array_init( decoder->bm_rep, states ); + Bm_array_init( decoder->bm_rep0, states ); + Bm_array_init( decoder->bm_rep1, states ); + Bm_array_init( decoder->bm_rep2, states ); + Bm_array_init( decoder->bm_len[0], states * pos_states ); + Bm_array_init( decoder->bm_dis_slot[0], max_dis_states * (1 << dis_slot_bits) ); + Bm_array_init( decoder->bm_dis, modeled_distances - end_dis_model ); + Bm_array_init( decoder->bm_align, dis_align_size ); decoder->range_decoder = rdec; Led_init( &decoder->len_decoder ); Led_init( &decoder->rep_match_len_decoder ); - Lid_init( &decoder->literal_decoder ); decoder->buffer[decoder->buffer_size-1] = 0; /* prev_byte of first_byte */ return true; } @@ -375,10 +356,11 @@ static inline bool LZd_init( struct LZ_decoder * const decoder, static inline void LZd_free( struct LZ_decoder * const decoder ) { free( decoder->buffer ); } -static inline uint32_t LZd_crc( const struct LZ_decoder * const decoder ) +static inline unsigned LZd_crc( const struct LZ_decoder * const decoder ) { return decoder->crc ^ 0xFFFFFFFFU; } -static inline long long LZd_data_position( const struct LZ_decoder * const decoder ) +static inline unsigned long long +LZd_data_position( const struct LZ_decoder * const decoder ) { return decoder->partial_data_pos + decoder->pos; } int LZd_decode_member( struct LZ_decoder * const decoder, diff --git a/doc/lunzip.1 b/doc/lunzip.1 index ac3625d..820aa8b 100644 --- a/doc/lunzip.1 +++ b/doc/lunzip.1 @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1. -.TH LUNZIP "1" "February 2012" "Lunzip 1.1" "User Commands" +.TH LUNZIP "1" "February 2013" "Lunzip 1.2" "User Commands" .SH NAME Lunzip \- small decompressor for lzip files .SH SYNOPSIS @@ -46,7 +46,7 @@ Report bugs to lzip\-bug@nongnu.org .br Lunzip home page: http://www.nongnu.org/lzip/lunzip.html .SH COPYRIGHT -Copyright \(co 2012 Antonio Diaz Diaz. +Copyright \(co 2013 Antonio Diaz Diaz. License GPLv3+: GNU GPL version 3 or later .br This is free software: you are free to change and redistribute it. diff --git a/lunzip.h b/lunzip.h index e9a9ea2..4437ec6 100644 --- a/lunzip.h +++ b/lunzip.h @@ -1,5 +1,5 @@ /* Lunzip - Decompressor for lzip files - Copyright (C) 2010, 2011, 2012 Antonio Diaz Diaz. + Copyright (C) 2010, 2011, 2012, 2013 Antonio Diaz Diaz. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -22,39 +22,26 @@ #define min(x,y) ((x) <= (y) ? (x) : (y)) #endif -typedef unsigned char State; +typedef int State; enum { states = 12 }; static inline bool St_is_char( const State st ) { return st < 7; } -static inline void St_set_char( State * const st ) +static inline State St_set_char( const State st ) { - static const unsigned char next[states] = - { 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5 }; - *st = next[*st]; + static const State next[states] = { 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5 }; + return next[st]; } -static inline void St_set_match( State * const st ) - { - static const unsigned char next[states] = - { 7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10 }; - *st = next[*st]; - } +static inline State St_set_match( const State st ) + { return ( ( st < 7 ) ? 7 : 10 ); } -static inline void St_set_rep( State * const st ) - { - static const unsigned char next[states] = - { 8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11 }; - *st = next[*st]; - } +static inline State St_set_rep( const State st ) + { return ( ( st < 7 ) ? 8 : 11 ); } -static inline void St_set_short_rep( State * const st ) - { - static const unsigned char next[states] = - { 9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11 }; - *st = next[*st]; - } +static inline State St_set_short_rep( const State st ) + { return ( ( st < 7 ) ? 9 : 11 ); } enum { @@ -88,23 +75,25 @@ enum { max_dis_states = 4 }; -static inline int get_dis_state( int len ) - { - len -= min_match_len; - if( len >= max_dis_states ) len = max_dis_states - 1; - return len; - } +static inline int get_dis_state( const int len ) + { return min( len - min_match_len, max_dis_states - 1 ); } + +static inline int get_lit_state( const uint8_t prev_byte ) + { return ( prev_byte >> ( 8 - literal_context_bits ) ); } enum { bit_model_move_bits = 5, bit_model_total_bits = 11, bit_model_total = 1 << bit_model_total_bits }; -typedef unsigned int Bit_model; +typedef int Bit_model; static inline void Bm_init( Bit_model * const probability ) { *probability = bit_model_total / 2; } +static inline void Bm_array_init( Bit_model * const p, const int size ) + { int i = 0; while( i < size ) p[i++] = bit_model_total / 2; } + struct Pretty_print { @@ -121,7 +110,7 @@ void Pp_init( struct Pretty_print * const pp, const char * const filenames[], static inline void Pp_set_name( struct Pretty_print * const pp, const char * const filename ) { - if( filename && filename[0] && strcmp( filename, "-" ) ) + if( filename && filename[0] && strcmp( filename, "-" ) != 0 ) pp->name = filename; else pp->name = pp->stdin_name; pp->first_post = true; @@ -136,12 +125,12 @@ typedef uint32_t CRC32[256]; /* Table of CRCs of all 8-bit messages. */ extern CRC32 crc32; -static inline void CRC32_init() +static inline void CRC32_init( void ) { - unsigned int n; + unsigned n; for( n = 0; n < 256; ++n ) { - unsigned int c = n; + unsigned c = n; int k; for( k = 0; k < 8; ++k ) { if( c & 1 ) c = 0xEDB88320U ^ ( c >> 1 ); else c >>= 1; } @@ -151,6 +140,7 @@ static inline void CRC32_init() static inline void CRC32_update_byte( uint32_t * crc, const uint8_t byte ) { *crc = crc32[(*crc^byte)&0xFF] ^ ( *crc >> 8 ); } + static inline void CRC32_update_buf( uint32_t * crc, const uint8_t * const buffer, const int size ) { @@ -160,16 +150,15 @@ static inline void CRC32_update_buf( uint32_t * crc, const uint8_t * const buffe } -static inline int real_bits( const unsigned int value ) +static inline int real_bits( unsigned value ) { - int bits = 0, i = 1; - unsigned int mask = 1; - for( ; mask > 0; ++i, mask <<= 1 ) if( value & mask ) bits = i; + int bits = 0; + while( value > 0 ) { value >>= 1; ++bits; } return bits; } -static const uint8_t magic_string[4] = { 'L', 'Z', 'I', 'P' }; +static const uint8_t magic_string[4] = { 0x4C, 0x5A, 0x49, 0x50 }; /* "LZIP" */ typedef uint8_t File_header[6]; /* 0-3 magic bytes */ /* 4 version */ @@ -226,43 +215,43 @@ enum { Ft_size = 20 }; static inline int Ft_versioned_size( const int version ) { return ( ( version >= 1 ) ? 20 : 12 ); } -static inline uint32_t Ft_get_data_crc( const File_trailer data ) +static inline unsigned Ft_get_data_crc( const File_trailer data ) { - uint32_t tmp = 0; + unsigned tmp = 0; int i; for( i = 3; i >= 0; --i ) { tmp <<= 8; tmp += data[i]; } return tmp; } -static inline void Ft_set_data_crc( File_trailer data, uint32_t crc ) +static inline void Ft_set_data_crc( File_trailer data, unsigned crc ) { int i; for( i = 0; i <= 3; ++i ) { data[i] = (uint8_t)crc; crc >>= 8; } } -static inline long long Ft_get_data_size( const File_trailer data ) +static inline unsigned long long Ft_get_data_size( const File_trailer data ) { - long long tmp = 0; + unsigned long long tmp = 0; int i; for( i = 11; i >= 4; --i ) { tmp <<= 8; tmp += data[i]; } return tmp; } -static inline void Ft_set_data_size( File_trailer data, long long sz ) +static inline void Ft_set_data_size( File_trailer data, unsigned long long sz ) { int i; for( i = 4; i <= 11; ++i ) { data[i] = (uint8_t)sz; sz >>= 8; } } -static inline long long Ft_get_member_size( const File_trailer data ) +static inline unsigned long long Ft_get_member_size( const File_trailer data ) { - long long tmp = 0; + unsigned long long tmp = 0; int i; for( i = 19; i >= 12; --i ) { tmp <<= 8; tmp += data[i]; } return tmp; } -static inline void Ft_set_member_size( File_trailer data, long long sz ) +static inline void Ft_set_member_size( File_trailer data, unsigned long long sz ) { int i; for( i = 12; i <= 19; ++i ) { data[i] = (uint8_t)sz; sz >>= 8; } diff --git a/main.c b/main.c index 97218de..9ba2280 100644 --- a/main.c +++ b/main.c @@ -1,5 +1,5 @@ /* Lunzip - Decompressor for lzip files - Copyright (C) 2010, 2011, 2012 Antonio Diaz Diaz. + Copyright (C) 2010, 2011, 2012, 2013 Antonio Diaz Diaz. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -58,12 +58,10 @@ #error "Environments where CHAR_BIT != 8 are not supported." #endif -long long int llabs( long long int number ); - const char * const Program_name = "Lunzip"; const char * const program_name = "lunzip"; -const char * const program_year = "2012"; +const char * const program_year = "2013"; const char * invocation_name = 0; #ifdef O_BINARY @@ -86,21 +84,7 @@ mode_t outfd_mode = S_IRUSR | S_IWUSR; bool delete_output_on_interrupt = false; -/* assure at least a minimum size for buffer 'buf' */ -static void * resize_buffer( void * buf, const int min_size ) - { - if( buf ) buf = realloc( buf, min_size ); - else buf = malloc( min_size ); - if( !buf ) - { - show_error( "Not enough memory.", 0, false ); - cleanup_and_fail( 1 ); - } - return buf; - } - - -static void show_help() +static void show_help( void ) { printf( "%s - Decompressor for lzip files.\n", Program_name ); printf( "\nUsage: %s [options] [files]\n", invocation_name ); @@ -122,7 +106,7 @@ static void show_help() } -static void show_version() +static void show_version( void ) { printf( "%s %s\n", Program_name, PROGVERSION ); printf( "Copyright (C) %s Antonio Diaz Diaz.\n", program_year ); @@ -132,21 +116,35 @@ static void show_version() } -static const char * format_num( long long num ) +void show_header( const File_header header ) { const char * const prefix[8] = { "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi" }; - enum { buf_size = 16, factor = 1024 }; - static char buf[buf_size]; - const char *p = ""; + enum { factor = 1024 }; + const char * p = ""; + const char * np = " "; + unsigned num = Fh_get_dictionary_size( header ), i; bool exact = ( num % factor == 0 ); - int i; - for( i = 0; i < 8 && ( llabs( num ) > 9999 || - ( exact && llabs( num ) >= factor ) ); ++i ) - { num /= factor; if( num % factor != 0 ) exact = false; p = prefix[i]; } - snprintf( buf, buf_size, "%lld %s", num, p ); - return buf; + for( i = 0; i < 8 && ( num > 9999 || ( exact && num >= factor ) ); ++i ) + { num /= factor; if( num % factor != 0 ) exact = false; + p = prefix[i]; np = ""; } + fprintf( stderr, "version %d, dictionary size %s%4u %sB. ", + Fh_version( header ), np, num, p ); + } + + +static int extension_index( const char * const name ) + { + int i; + for( i = 0; known_extensions[i].from; ++i ) + { + const char * const ext = known_extensions[i].from; + if( strlen( name ) > strlen( ext ) && + strncmp( name + strlen( name ) - strlen( ext ), ext, strlen( ext ) ) == 0 ) + return i; + } + return -1; } @@ -183,23 +181,22 @@ static int open_instream( const char * const name, } -static int extension_index( const char * const name ) +/* assure at least a minimum size for buffer 'buf' */ +static void * resize_buffer( void * buf, const int min_size ) { - int i; - for( i = 0; known_extensions[i].from; ++i ) + if( buf ) buf = realloc( buf, min_size ); + else buf = malloc( min_size ); + if( !buf ) { - const char * const ext = known_extensions[i].from; - if( strlen( name ) > strlen( ext ) && - strncmp( name + strlen( name ) - strlen( ext ), ext, strlen( ext ) ) == 0 ) - return i; + show_error( "Not enough memory.", 0, false ); + cleanup_and_fail( 1 ); } - return -1; + return buf; } -static void set_d_outname( const char * const name ) +static void set_d_outname( const char * const name, const int i ) { - const int i = extension_index( name ); if( i >= 0 ) { const char * const from = known_extensions[i].from; @@ -286,9 +283,9 @@ static void close_and_set_permissions( const struct stat * const in_statsp ) static int decompress( const int infd, struct Pretty_print * const pp, const bool testing ) { - long long partial_file_pos = 0; + unsigned long long partial_file_pos = 0; struct Range_decoder rdec; - int retval = 0, result; + int retval = 0; bool first_member; if( !Rd_init( &rdec, infd ) ) { @@ -296,13 +293,14 @@ static int decompress( const int infd, struct Pretty_print * const pp, cleanup_and_fail( 1 ); } - for( first_member = true; ; first_member = false, Pp_reset( pp ) ) + for( first_member = true; ; first_member = false ) { + int result; File_header header; struct LZ_decoder decoder; Rd_reset_member_position( &rdec ); Rd_read_data( &rdec, header, Fh_size ); - if( Rd_finished( &rdec ) ) /* End Of File */ + if( Rd_finished( &rdec ) ) /* End Of File */ { if( first_member ) { Pp_show_msg( pp, "Error reading member header" ); retval = 1; } @@ -328,13 +326,7 @@ static int decompress( const int infd, struct Pretty_print * const pp, retval = 2; break; } if( verbosity >= 2 || ( verbosity == 1 && first_member ) ) - { - Pp_show_msg( pp, 0 ); - if( verbosity >= 2 ) - fprintf( stderr, "version %d, dictionary size %7sB. ", - Fh_version( header ), - format_num( Fh_get_dictionary_size( header ) ) ); - } + { Pp_show_msg( pp, 0 ); if( verbosity >= 2 ) show_header( header ); } if( !LZd_init( &decoder, header, &rdec, outfd ) ) { @@ -350,16 +342,16 @@ static int decompress( const int infd, struct Pretty_print * const pp, { Pp_show_msg( pp, 0 ); if( result == 2 ) - fprintf( stderr, "File ends unexpectedly at pos %lld\n", + fprintf( stderr, "File ends unexpectedly at pos %llu\n", partial_file_pos ); else - fprintf( stderr, "Decoder error at pos %lld\n", partial_file_pos ); + fprintf( stderr, "Decoder error at pos %llu\n", partial_file_pos ); } retval = 2; break; } if( verbosity >= 2 ) { if( testing ) fprintf( stderr, "ok\n" ); - else fprintf( stderr, "done\n" ); } + else fprintf( stderr, "done\n" ); Pp_reset( pp ); } } Rd_free( &rdec ); if( verbosity == 1 && retval == 0 ) @@ -371,13 +363,13 @@ static int decompress( const int infd, struct Pretty_print * const pp, void signal_handler( int sig ) { - sig = 0; /* keep compiler happy */ + if( sig ) {} /* keep compiler happy */ show_error( "Control-C or similar caught, quitting.", 0, false ); cleanup_and_fail( 1 ); } -static void set_signals() +static void set_signals( void ) { signal( SIGHUP, signal_handler ); signal( SIGINT, signal_handler ); @@ -388,7 +380,7 @@ static void set_signals() void Pp_init( struct Pretty_print * const pp, const char * const filenames[], const int num_filenames, const int v ) { - unsigned int stdin_name_len; + unsigned stdin_name_len; int i; pp->name = 0; pp->stdin_name = "(stdin)"; @@ -400,31 +392,13 @@ void Pp_init( struct Pretty_print * const pp, const char * const filenames[], for( i = 0; i < num_filenames; ++i ) { const char * const s = filenames[i]; - const int len = ( !strcmp( s, "-" ) ? stdin_name_len : strlen( s ) ); + const int len = ( (strcmp( s, "-" ) == 0) ? stdin_name_len : strlen( s ) ); if( len > pp->longest_name ) pp->longest_name = len; } if( pp->longest_name == 0 ) pp->longest_name = stdin_name_len; } -void Pp_show_msg( struct Pretty_print * const pp, const char * const msg ) - { - if( verbosity >= 0 ) - { - if( pp->first_post ) - { - int i, len; - pp->first_post = false; - fprintf( stderr, " %s: ", pp->name ); - len = pp->longest_name - strlen( pp->name ); - for( i = 0; i < len; ++i ) fprintf( stderr, " " ); - if( !msg ) fflush( stderr ); - } - if( msg ) fprintf( stderr, "%s.\n", msg ); - } - } - - void show_error( const char * const msg, const int errcode, const bool help ) { if( verbosity >= 0 ) @@ -435,7 +409,7 @@ void show_error( const char * const msg, const int errcode, const bool help ) if( errcode > 0 ) fprintf( stderr, ": %s", strerror( errcode ) ); fprintf( stderr, "\n" ); } - if( help && invocation_name && invocation_name[0] ) + if( help ) fprintf( stderr, "Try '%s --help' for more information.\n", invocation_name ); } @@ -495,7 +469,7 @@ int main( const int argc, const char * const argv[] ) { const int code = ap_code( &parser, argind ); const char * const arg = ap_argument( &parser, argind ); - if( !code ) break; /* no more options */ + if( !code ) break; /* no more options */ switch( code ) { case 'c': to_stdout = true; break; @@ -513,28 +487,23 @@ int main( const int argc, const char * const argv[] ) } /* end process options */ #if defined(__MSVCRT__) || defined(__OS2__) - _fsetmode( stdin, "b" ); - _fsetmode( stdout, "b" ); + setmode( STDIN_FILENO, O_BINARY ); + setmode( STDOUT_FILENO, O_BINARY ); #endif if( testing ) outfd = -1; - for( ; argind < ap_arguments( &parser ); ++argind ) + num_filenames = max( 1, ap_arguments( &parser ) - argind ); + filenames = resize_buffer( filenames, num_filenames * sizeof filenames[0] ); + filenames[0] = "-"; + + for( i = 0; argind + i < ap_arguments( &parser ); ++i ) { - if( strcmp( ap_argument( &parser, argind ), "-" ) ) - filenames_given = true; - ++num_filenames; - filenames = resize_buffer( filenames, num_filenames * sizeof (char *) ); - filenames[num_filenames-1] = ap_argument( &parser, argind ); + filenames[i] = ap_argument( &parser, argind + i ); + if( strcmp( filenames[i], "-" ) != 0 ) filenames_given = true; } - if( num_filenames == 0 ) - { - ++num_filenames; - filenames = resize_buffer( filenames, sizeof (char *) ); - filenames[num_filenames-1] = "-"; - } if( !to_stdout && !testing && ( filenames_given || default_output_filename[0] ) ) set_signals(); @@ -549,7 +518,7 @@ int main( const int argc, const char * const argv[] ) const struct stat * in_statsp; output_filename[0] = 0; - if( !filenames[i][0] || !strcmp( filenames[i], "-" ) ) + if( !filenames[i][0] || strcmp( filenames[i], "-" ) == 0 ) { input_filename = ""; infd = STDIN_FILENO; @@ -565,7 +534,7 @@ int main( const int argc, const char * const argv[] ) outfd_mode = all_rw; if( !open_outstream( force ) ) { - if( outfd == -1 && retval < 1 ) retval = 1; + if( retval < 1 ) retval = 1; close( infd ); infd = -1; continue; } @@ -582,11 +551,11 @@ int main( const int argc, const char * const argv[] ) if( to_stdout ) outfd = STDOUT_FILENO; else { - set_d_outname( input_filename ); + set_d_outname( input_filename, extension_index( input_filename ) ); outfd_mode = usr_rw; if( !open_outstream( force ) ) { - if( outfd == -1 && retval < 1 ) retval = 1; + if( retval < 1 ) retval = 1; close( infd ); infd = -1; continue; } diff --git a/testsuite/check.sh b/testsuite/check.sh index fea9d0a..8408109 100755 --- a/testsuite/check.sh +++ b/testsuite/check.sh @@ -1,6 +1,6 @@ #! /bin/sh # check script for Lunzip - Decompressor for lzip files -# Copyright (C) 2010, 2011, 2012 Antonio Diaz Diaz. +# Copyright (C) 2010, 2011, 2012, 2013 Antonio Diaz Diaz. # # This script is free software: you have unlimited permission # to copy, distribute and modify it. @@ -23,27 +23,14 @@ cd "${objdir}"/tmp cat "${testdir}"/test.txt > in || framework_failure cat in in > in2 || framework_failure -cat "${testdir}"/test_v1.lz > in.lz || framework_failure +cat "${testdir}"/test.txt.lz > in.lz || framework_failure cat in.lz in.lz > in2.lz || framework_failure fail=0 printf "testing lunzip-%s..." "$2" -"${LZIP}" -t "${testdir}"/test_v0.lz || fail=1 -printf . -"${LZIP}" -cd "${testdir}"/test_v0.lz > copy || fail=1 -cmp in copy || fail=1 -printf . - -"${LZIP}" -t "${testdir}"/test_v1.lz || fail=1 -printf . -"${LZIP}" -cd "${testdir}"/test_v1.lz > copy || fail=1 -cmp in copy || fail=1 -printf . - -"${LZIP}" -t "${testdir}"/test_sync.lz || fail=1 -printf . -"${LZIP}" -cd "${testdir}"/test_sync.lz > copy || fail=1 +"${LZIP}" -t "${testdir}"/test.txt.lz || fail=1 +"${LZIP}" -cd "${testdir}"/test.txt.lz > copy || fail=1 cmp in copy || fail=1 printf . diff --git a/testsuite/test.txt.lz b/testsuite/test.txt.lz new file mode 100644 index 0000000000000000000000000000000000000000..4db881aa68489345e86b677d05091a773f26bbb5 GIT binary patch literal 11518 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 literal 0 HcmV?d00001 diff --git a/testsuite/test_sync.lz b/testsuite/test_sync.lz deleted file mode 100644 index 419fa97e5ba15fcdc367ab305a0a87079b80bfd1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11658 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 UwV;at000000E#UD000000B*;s6aWAK diff --git a/testsuite/test_v0.lz b/testsuite/test_v0.lz deleted file mode 100644 index a09b1e885e665afac43958644069691715aae0db..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11540 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