summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Baumann <mail@daniel-baumann.ch>2015-11-07 09:32:03 +0000
committerDaniel Baumann <mail@daniel-baumann.ch>2015-11-07 09:32:03 +0000
commit415e3e6d437f5cadbf4d7c3727e0bb1d0106b437 (patch)
treeafb6be0c266301843a8ff7e0ac10c452394de3c0
parentAdding upstream version 1.13~rc2. (diff)
downloadlzip-415e3e6d437f5cadbf4d7c3727e0bb1d0106b437.tar.xz
lzip-415e3e6d437f5cadbf4d7c3727e0bb1d0106b437.zip
Adding upstream version 1.13.upstream/1.13
Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch>
-rw-r--r--ChangeLog16
-rw-r--r--Makefile.in14
-rw-r--r--NEWS3
-rw-r--r--README10
-rw-r--r--arg_parser.cc12
-rw-r--r--arg_parser.h22
-rwxr-xr-xconfigure56
-rw-r--r--decoder.cc8
-rw-r--r--decoder.h38
-rw-r--r--doc/lzip.12
-rw-r--r--doc/lzip.info24
-rw-r--r--doc/lzip.texinfo18
-rw-r--r--encoder.cc33
-rw-r--r--encoder.h111
-rw-r--r--fast_encoder.cc4
-rw-r--r--fast_encoder.h4
-rw-r--r--lzip.h78
-rw-r--r--main.cc44
-rwxr-xr-xtestsuite/check.sh9
-rw-r--r--testsuite/unzcrash.cc354
20 files changed, 239 insertions, 621 deletions
diff --git a/ChangeLog b/ChangeLog
index 3a3eccb..8e3aa1e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,17 +1,15 @@
-2012-01-05 Antonio Diaz Diaz <ant_diaz@teleline.es>
+2012-02-24 Antonio Diaz Diaz <ant_diaz@teleline.es>
- * Version 1.13-rc2 released.
+ * Version 1.13 released.
+ * Lziprecover has been moved to its own package.
+ * main.cc (close_and_set_permissions): Inability to change output
+ file attributes has been downgraded from error to warning.
* Compression time of option '-0' has been reduced by 2%.
* Reorganization of the compression code.
* Small change in '--help' output and man page.
* Changed quote characters in messages as advised by GNU Standards.
-
-2011-11-12 Antonio Diaz Diaz <ant_diaz@teleline.es>
-
- * Version 1.13-rc1 released.
- * Lziprecover has been moved to its own package.
- * main.cc (close_and_set_permissions): Inability to change output
- file attributes has been downgraded from error to warning.
+ * configure: 'datadir' renamed to 'datarootdir'.
+ * 'testsuite/unzcrash.cc' has been moved to package 'lziprecover'.
2011-04-30 Antonio Diaz Diaz <ant_diaz@teleline.es>
diff --git a/Makefile.in b/Makefile.in
index 83991ef..d64b06c 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -7,7 +7,6 @@ INSTALL_DIR = $(INSTALL) -d -m 755
SHELL = /bin/sh
objs = arg_parser.o decoder.o encoder.o fast_encoder.o main.o
-unzobjs = arg_parser.o unzcrash.o
.PHONY : all install install-info install-man install-strip \
@@ -17,20 +16,14 @@ unzobjs = arg_parser.o unzcrash.o
all : $(progname)
$(progname) : $(objs)
- $(CXX) $(LDFLAGS) -o $@ $^
+ $(CXX) $(LDFLAGS) -o $@ $(objs)
$(progname)_profiled : $(objs)
- $(CXX) $(LDFLAGS) -pg -o $@ $^
-
-unzcrash : $(unzobjs)
- $(CXX) $(LDFLAGS) -o $@ $^
+ $(CXX) $(LDFLAGS) -pg -o $@ $(objs)
main.o : main.cc
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -DPROGVERSION=\"$(pkgversion)\" -c -o $@ $<
-unzcrash.o : testsuite/unzcrash.cc
- $(CXX) $(CPPFLAGS) $(CXXFLAGS) -DPROGVERSION=\"$(pkgversion)\" -c -o $@ $<
-
%.o : %.cc
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $<
@@ -40,7 +33,6 @@ decoder.o : lzip.h decoder.h
encoder.o : lzip.h encoder.h
fast_encoder.o : lzip.h encoder.h fast_encoder.h
main.o : arg_parser.h lzip.h decoder.h encoder.h fast_encoder.h
-unzcrash.o : arg_parser.h Makefile
doc : info man
@@ -106,7 +98,6 @@ dist : doc
$(DISTNAME)/testsuite/test.txt \
$(DISTNAME)/testsuite/test_sync.lz \
$(DISTNAME)/testsuite/test_v[01].lz \
- $(DISTNAME)/testsuite/unzcrash.cc \
$(DISTNAME)/*.h \
$(DISTNAME)/*.cc
rm -f $(DISTNAME)
@@ -114,7 +105,6 @@ dist : doc
clean :
-rm -f $(progname) $(progname)_profiled $(objs)
- -rm -f unzcrash unzcrash.o
distclean : clean
-rm -f Makefile config.status *.tar *.tar.lz
diff --git a/NEWS b/NEWS
index df56781..41cf2d4 100644
--- a/NEWS
+++ b/NEWS
@@ -13,3 +13,6 @@ A small change has been made in the "--help" output and man page.
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.
diff --git a/README b/README
index 75674e1..6ff4771 100644
--- a/README
+++ b/README
@@ -26,11 +26,11 @@ or more compressed files. The result is the concatenation of the
corresponding uncompressed files. Integrity testing of concatenated
compressed files is also supported.
-Lzip can produce multi-member files and safely recover, with lziprecover,
-the undamaged members in case of file damage. Lzip can also split the
-compressed output in volumes of a given size, even when reading from
-standard input. This allows the direct creation of multivolume
-compressed tar archives.
+Lzip can produce multi-member files and safely recover, with
+lziprecover, the undamaged members in case of file damage. Lzip can also
+split the compressed output in volumes of a given size, even when
+reading from standard input. This allows the direct creation of
+multivolume compressed tar archives.
Lzip will automatically use the smallest possible dictionary size
without exceeding the given limit. Keep in mind that the decompression
diff --git a/arg_parser.cc b/arg_parser.cc
index 27137a1..b3fd48d 100644
--- a/arg_parser.cc
+++ b/arg_parser.cc
@@ -56,30 +56,30 @@ bool Arg_parser::parse_long_option( const char * const opt, const char * const a
if( ambig && !exact )
{
- error_ = "option `"; error_ += opt; error_ += "' is ambiguous";
+ error_ = "option '"; error_ += opt; error_ += "' is ambiguous";
return false;
}
if( index < 0 ) // nothing found
{
- error_ = "unrecognized option `"; error_ += opt; error_ += '\'';
+ error_ = "unrecognized option '"; error_ += opt; error_ += '\'';
return false;
}
++argind;
data.push_back( Record( options[index].code ) );
- if( opt[len+2] ) // `--<long_option>=<argument>' syntax
+ if( opt[len+2] ) // '--<long_option>=<argument>' syntax
{
if( options[index].has_arg == no )
{
- error_ = "option `--"; error_ += options[index].name;
+ error_ = "option '--"; error_ += options[index].name;
error_ += "' doesn't allow an argument";
return false;
}
if( options[index].has_arg == yes && !opt[len+3] )
{
- error_ = "option `--"; error_ += options[index].name;
+ error_ = "option '--"; error_ += options[index].name;
error_ += "' requires an argument";
return false;
}
@@ -91,7 +91,7 @@ bool Arg_parser::parse_long_option( const char * const opt, const char * const a
{
if( !arg || !arg[0] )
{
- error_ = "option `--"; error_ += options[index].name;
+ error_ = "option '--"; error_ += options[index].name;
error_ += "' requires an argument";
return false;
}
diff --git a/arg_parser.h b/arg_parser.h
index 5d036ab..4fbd1af 100644
--- a/arg_parser.h
+++ b/arg_parser.h
@@ -26,12 +26,12 @@
Public License.
*/
-/* Arg_parser reads the arguments in `argv' and creates a number of
+/* Arg_parser reads the arguments in 'argv' and creates a number of
option codes, option arguments and non-option arguments.
- In case of error, `error' returns a non-empty error message.
+ In case of error, 'error' returns a non-empty error message.
- `options' is an array of `struct Option' terminated by an element
+ 'options' is an array of 'struct Option' terminated by an element
containing a code which is zero. A null name means a short-only
option. A code value outside the unsigned char range means a
long-only option.
@@ -40,13 +40,13 @@
were specified before all the non-option arguments for the purposes
of parsing, even if the user of your program intermixed option and
non-option arguments. If you want the arguments in the exact order
- the user typed them, call `Arg_parser' with `in_order' = true.
+ the user typed them, call 'Arg_parser' with 'in_order' = true.
- The argument `--' terminates all options; any following arguments are
+ The argument '--' terminates all options; any following arguments are
treated as non-option arguments, even if they begin with a hyphen.
- The syntax for optional option arguments is `-<short_option><argument>'
- (without whitespace), or `--<long_option>=<argument>'.
+ The syntax for optional option arguments is '-<short_option><argument>'
+ (without whitespace), or '--<long_option>=<argument>'.
*/
class Arg_parser
@@ -85,20 +85,20 @@ public:
Arg_parser( const char * const opt, const char * const arg,
const Option options[] );
- const std::string & error() const throw() { return error_; }
+ const std::string & error() const { return error_; }
// The number of arguments parsed (may be different from argc)
- int arguments() const throw() { return data.size(); }
+ int arguments() const { return data.size(); }
// If code( i ) is 0, argument( i ) is a non-option.
// Else argument( i ) is the option's argument (or empty).
- int code( const int i ) const throw()
+ int code( const int i ) const
{
if( i >= 0 && i < arguments() ) return data[i].code;
else return 0;
}
- const std::string & argument( const int i ) const throw()
+ const std::string & argument( const int i ) const
{
if( i >= 0 && i < arguments() ) return data[i].argument;
else return error_;
diff --git a/configure b/configure
index 633f4d3..f96530e 100755
--- a/configure
+++ b/configure
@@ -8,7 +8,7 @@
args=
no_create=
pkgname=lzip
-pkgversion=1.13-rc2
+pkgversion=1.13
progname=lzip
srctrigger=lzip.h
@@ -19,10 +19,9 @@ srcdir=
prefix=/usr/local
exec_prefix='$(prefix)'
bindir='$(exec_prefix)/bin'
-datadir='$(prefix)/share'
-infodir='$(datadir)/info'
-mandir='$(datadir)/man'
-sysconfdir='$(prefix)/etc'
+datarootdir='$(prefix)/share'
+infodir='$(datarootdir)/info'
+mandir='$(datarootdir)/man'
CXX=
CPPFLAGS=
CXXFLAGS='-Wall -W -O2'
@@ -40,12 +39,12 @@ while [ -n "$1" ] ; do
# Split out the argument for options that take them
case ${option} in
- *=*) optarg=`echo ${option} | sed -e 's,^[^=]*=,,'` ;;
+ *=*) optarg=`echo ${option} | sed -e 's,^[^=]*=,,;s,/$,,'` ;;
esac
# Process the options
case ${option} in
- --help | --he* | -h)
+ --help | -h)
echo "Usage: configure [options]"
echo
echo "Options: [defaults in brackets]"
@@ -55,42 +54,31 @@ while [ -n "$1" ] ; do
echo " --prefix=DIR install into DIR [${prefix}]"
echo " --exec-prefix=DIR base directory for arch-dependent files [${exec_prefix}]"
echo " --bindir=DIR user executables directory [${bindir}]"
- echo " --datadir=DIR base directory for doc and data [${datadir}]"
+ echo " --datarootdir=DIR base directory for doc and data [${datarootdir}]"
echo " --infodir=DIR info files directory [${infodir}]"
echo " --mandir=DIR man pages directory [${mandir}]"
- echo " --sysconfdir=DIR read-only single-machine data directory [${sysconfdir}]"
echo " CXX=COMPILER C++ compiler to use [g++]"
echo " CPPFLAGS=OPTIONS command line options for the preprocessor [${CPPFLAGS}]"
echo " CXXFLAGS=OPTIONS command line options for the C++ compiler [${CXXFLAGS}]"
echo " LDFLAGS=OPTIONS command line options for the linker [${LDFLAGS}]"
echo
exit 0 ;;
- --version | --ve* | -V)
+ --version | -V)
echo "Configure script for ${pkgname} version ${pkgversion}"
exit 0 ;;
- --srcdir* | --sr*)
- srcdir=`echo ${optarg} | sed -e 's,/$,,'` ;;
- --prefix* | --pr*)
- prefix=`echo ${optarg} | sed -e 's,/$,,'` ;;
- --exec-prefix* | --ex*)
- exec_prefix=`echo ${optarg} | sed -e 's,/$,,'` ;;
- --bindir* | --bi*)
- bindir=`echo ${optarg} | sed -e 's,/$,,'` ;;
- --datadir* | --da*)
- datadir=`echo ${optarg} | sed -e 's,/$,,'` ;;
- --infodir* | --inf*)
- infodir=`echo ${optarg} | sed -e 's,/$,,'` ;;
- --mandir* | --ma*)
- mandir=`echo ${optarg} | sed -e 's,/$,,'` ;;
- --sysconfdir* | --sy*)
- sysconfdir=`echo ${optarg} | sed -e 's,/$,,'` ;;
- --no-create | --no-c*)
- no_create=yes ;;
-
- CXX=*) CXX=${optarg} ;;
+ --srcdir=*) srcdir=${optarg} ;;
+ --prefix=*) prefix=${optarg} ;;
+ --exec-prefix=*) exec_prefix=${optarg} ;;
+ --bindir=*) bindir=${optarg} ;;
+ --datarootdir=*) datarootdir=${optarg} ;;
+ --infodir=*) infodir=${optarg} ;;
+ --mandir=*) mandir=${optarg} ;;
+ --no-create) no_create=yes ;;
+
+ CXX=*) CXX=${optarg} ;;
CPPFLAGS=*) CPPFLAGS=${optarg} ;;
CXXFLAGS=*) CXXFLAGS=${optarg} ;;
- LDFLAGS=*) LDFLAGS=${optarg} ;;
+ LDFLAGS=*) LDFLAGS=${optarg} ;;
--* | *=* | *-*-*) ;;
*)
@@ -154,10 +142,9 @@ echo "VPATH = ${srcdir}"
echo "prefix = ${prefix}"
echo "exec_prefix = ${exec_prefix}"
echo "bindir = ${bindir}"
-echo "datadir = ${datadir}"
+echo "datarootdir = ${datarootdir}"
echo "infodir = ${infodir}"
echo "mandir = ${mandir}"
-echo "sysconfdir = ${sysconfdir}"
echo "CXX = ${CXX}"
echo "CPPFLAGS = ${CPPFLAGS}"
echo "CXXFLAGS = ${CXXFLAGS}"
@@ -178,10 +165,9 @@ VPATH = ${srcdir}
prefix = ${prefix}
exec_prefix = ${exec_prefix}
bindir = ${bindir}
-datadir = ${datadir}
+datarootdir = ${datarootdir}
infodir = ${infodir}
mandir = ${mandir}
-sysconfdir = ${sysconfdir}
CXX = ${CXX}
CPPFLAGS = ${CPPFLAGS}
CXXFLAGS = ${CXXFLAGS}
diff --git a/decoder.cc b/decoder.cc
index a060797..ae37563 100644
--- a/decoder.cc
+++ b/decoder.cc
@@ -34,7 +34,7 @@
const CRC32 crc32;
-void Pretty_print::operator()( const char * const msg ) const throw()
+void Pretty_print::operator()( const char * const msg ) const
{
if( verbosity_ >= 0 )
{
@@ -54,7 +54,7 @@ void Pretty_print::operator()( const char * const msg ) const throw()
// Returns the number of bytes really read.
// If (returned value < size) and (errno == 0), means EOF was reached.
//
-int readblock( const int fd, uint8_t * const buf, const int size ) throw()
+int readblock( const int fd, uint8_t * const buf, const int size )
{
int rest = size;
errno = 0;
@@ -73,7 +73,7 @@ int readblock( const int fd, uint8_t * const buf, const int size ) throw()
// Returns the number of bytes really written.
// If (returned value < size), it is always an error.
//
-int writeblock( const int fd, const uint8_t * const buf, const int size ) throw()
+int writeblock( const int fd, const uint8_t * const buf, const int size )
{
int rest = size;
errno = 0;
@@ -124,7 +124,7 @@ bool LZ_decoder::verify_trailer( const Pretty_print & pp ) const
const long long member_size = range_decoder.member_position() + trailer_size;
bool error = false;
- const int size = range_decoder.read( trailer.data, trailer_size );
+ const int size = range_decoder.read_data( trailer.data, trailer_size );
if( size < trailer_size )
{
error = true;
diff --git a/decoder.h b/decoder.h
index ad3ff7c..d583c65 100644
--- a/decoder.h
+++ b/decoder.h
@@ -29,8 +29,8 @@ class Range_decoder
bool read_block();
- Range_decoder( const Range_decoder & );
- void operator=( const Range_decoder & );
+ Range_decoder( const Range_decoder & ); // declared as private
+ void operator=( const Range_decoder & ); // declared as private
public:
explicit Range_decoder( const int ifd )
@@ -42,16 +42,15 @@ public:
code( 0 ),
range( 0xFFFFFFFFU ),
infd( ifd ),
- at_stream_end( false ) {}
+ at_stream_end( false )
+ {}
~Range_decoder() { delete[] buffer; }
- bool code_is_zero() const throw() { return ( code == 0 ); }
+ bool code_is_zero() const { return ( code == 0 ); }
bool finished() { return pos >= stream_pos && !read_block(); }
- long long member_position() const throw()
- { return partial_member_pos + pos; }
- void reset_member_position() throw()
- { partial_member_pos = -pos; }
+ long long member_position() const { return partial_member_pos + pos; }
+ void reset_member_position() { partial_member_pos = -pos; }
uint8_t get_byte()
{
@@ -59,7 +58,7 @@ public:
return buffer[pos++];
}
- int read( uint8_t * const outbuf, const int size )
+ int read_data( uint8_t * const outbuf, const int size )
{
int rest = size;
while( rest > 0 && !finished() )
@@ -192,7 +191,7 @@ class Literal_decoder
{
Bit_model bm_literal[1<<literal_context_bits][0x300];
- int lstate( const int prev_byte ) const throw()
+ int lstate( const uint8_t prev_byte ) const
{ return ( prev_byte >> ( 8 - literal_context_bits ) ); }
public:
@@ -209,6 +208,7 @@ public:
class LZ_decoder
{
long long partial_data_pos;
+ Range_decoder & range_decoder;
const int dictionary_size;
const int buffer_size;
uint8_t * const buffer; // output buffer
@@ -217,18 +217,17 @@ class LZ_decoder
uint32_t crc_;
const int outfd; // output file descriptor
const int member_version;
- Range_decoder & range_decoder;
void flush_data();
bool verify_trailer( const Pretty_print & pp ) const;
- uint8_t get_prev_byte() const throw()
+ uint8_t get_prev_byte() const
{
const int i = ( ( pos > 0 ) ? pos : buffer_size ) - 1;
return buffer[i];
}
- uint8_t get_byte( const int distance ) const throw()
+ uint8_t get_byte( const int distance ) const
{
int i = pos - distance - 1;
if( i < 0 ) i += buffer_size;
@@ -258,13 +257,14 @@ class LZ_decoder
}
}
- LZ_decoder( const LZ_decoder & );
- void operator=( const LZ_decoder & );
+ LZ_decoder( const LZ_decoder & ); // declared as private
+ void operator=( const LZ_decoder & ); // declared as private
public:
LZ_decoder( const File_header & header, Range_decoder & rdec, const int ofd )
:
partial_data_pos( 0 ),
+ range_decoder( rdec ),
dictionary_size( header.dictionary_size() ),
buffer_size( std::max( 65536, dictionary_size ) ),
buffer( new uint8_t[buffer_size] ),
@@ -272,16 +272,14 @@ public:
stream_pos( 0 ),
crc_( 0xFFFFFFFFU ),
outfd( ofd ),
- member_version( header.version() ),
- range_decoder( rdec )
+ member_version( header.version() )
{ buffer[buffer_size-1] = 0; } // prev_byte of first_byte
~LZ_decoder() { delete[] buffer; }
- uint32_t crc() const throw() { return crc_ ^ 0xFFFFFFFFU; }
+ uint32_t crc() const { return crc_ ^ 0xFFFFFFFFU; }
- long long data_position() const throw()
- { return partial_data_pos + pos; }
+ long long data_position() const { return partial_data_pos + pos; }
int decode_member( const Pretty_print & pp );
};
diff --git a/doc/lzip.1 b/doc/lzip.1
index 60df32e..f83c444 100644
--- a/doc/lzip.1
+++ b/doc/lzip.1
@@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1.
-.TH LZIP "1" "January 2012" "Lzip 1.13-rc2" "User Commands"
+.TH LZIP "1" "February 2012" "Lzip 1.13" "User Commands"
.SH NAME
Lzip \- reduces the size of files
.SH SYNOPSIS
diff --git a/doc/lzip.info b/doc/lzip.info
index 5d2c6ec..9379eb3 100644
--- a/doc/lzip.info
+++ b/doc/lzip.info
@@ -11,7 +11,7 @@ File: lzip.info, Node: Top, Next: Introduction, Up: (dir)
Lzip Manual
***********
-This manual is for Lzip (version 1.13-rc2, 5 January 2012).
+This manual is for Lzip (version 1.13, 24 February 2012).
* Menu:
@@ -62,8 +62,8 @@ corresponding uncompressed files. Integrity testing of concatenated
compressed files is also supported.
Lzip can produce multi-member files and safely recover, with
-lziprecover, the undamaged members in case of file damage. Lzip can
-also split the compressed output in volumes of a given size, even when
+lziprecover, the undamaged members in case of file damage. Lzip can also
+split the compressed output in volumes of a given size, even when
reading from standard input. This allows the direct creation of
multivolume compressed tar archives.
@@ -389,7 +389,7 @@ File: lzip.info, Node: Examples, Next: Problems, Prev: File Format, Up: Top
WARNING! Even if lzip is bug-free, other causes may result in a corrupt
compressed file (bugs in the system libraries, memory errors, etc).
-Therefore, if the data you are going to compress is important give the
+Therefore, if the data you are going to compress is important, give the
`--keep' option to lzip and do not remove the original file until you
verify the compressed file with a command like
`lzip -cd file.lz | cmp file -'.
@@ -484,7 +484,7 @@ Concept Index
* file format: File Format. (line 6)
* getting help: Problems. (line 6)
* introduction: Introduction. (line 6)
-* invoking lzip: Invoking Lzip. (line 6)
+* invoking: Invoking Lzip. (line 6)
* options: Invoking Lzip. (line 6)
* usage: Invoking Lzip. (line 6)
* version: Invoking Lzip. (line 6)
@@ -493,13 +493,13 @@ Concept Index

Tag Table:
Node: Top224
-Node: Introduction921
-Node: Algorithm4422
-Node: Invoking Lzip6940
-Node: File Format12292
-Node: Examples14285
-Node: Problems16231
-Node: Concept Index16753
+Node: Introduction919
+Node: Algorithm4420
+Node: Invoking Lzip6938
+Node: File Format12290
+Node: Examples14283
+Node: Problems16230
+Node: Concept Index16752

End Tag Table
diff --git a/doc/lzip.texinfo b/doc/lzip.texinfo
index cf7b21e..0ebc9ca 100644
--- a/doc/lzip.texinfo
+++ b/doc/lzip.texinfo
@@ -6,8 +6,8 @@
@finalout
@c %**end of header
-@set UPDATED 5 January 2012
-@set VERSION 1.13-rc2
+@set UPDATED 24 February 2012
+@set VERSION 1.13
@dircategory Data Compression
@direntry
@@ -81,11 +81,11 @@ or more compressed files. The result is the concatenation of the
corresponding uncompressed files. Integrity testing of concatenated
compressed files is also supported.
-Lzip can produce multi-member files and safely recover, with lziprecover,
-the undamaged members in case of file damage. Lzip can also split the
-compressed output in volumes of a given size, even when reading from
-standard input. This allows the direct creation of multivolume
-compressed tar archives.
+Lzip can produce multi-member files and safely recover, with
+lziprecover, the undamaged members in case of file damage. Lzip can also
+split the compressed output in volumes of a given size, even when
+reading from standard input. This allows the direct creation of
+multivolume compressed tar archives.
The amount of memory required for compression is about 5 MiB plus 1 or 2
times the dictionary size limit (1 if input file size is less than
@@ -188,7 +188,7 @@ LZMA), and Julian Seward (for bzip2's CLI and the idea of unzcrash).
@node Invoking Lzip
@chapter Invoking Lzip
-@cindex invoking lzip
+@cindex invoking
@cindex options
@cindex usage
@cindex version
@@ -417,7 +417,7 @@ safe recovery of undamaged members from multi-member files.
WARNING! Even if lzip is bug-free, other causes may result in a corrupt
compressed file (bugs in the system libraries, memory errors, etc).
-Therefore, if the data you are going to compress is important give the
+Therefore, if the data you are going to compress is important, give the
@samp{--keep} option to lzip and do not remove the original file until
you verify the compressed file with a command like @w{@samp{lzip -cd
file.lz | cmp file -}}.
diff --git a/encoder.cc b/encoder.cc
index 67e9d95..56820b5 100644
--- a/encoder.cc
+++ b/encoder.cc
@@ -84,6 +84,7 @@ Matchfinder_base::Matchfinder_base( const int before, const int dict_size,
stream_pos( 0 ),
at_stream_end( false )
{
+ for( int i = 0; i < num_prev_positions; ++i ) prev_positions[i] = -1;
const int buffer_size_limit =
( dict_size * dict_factor ) + before_size + after_size;
buffer_size = std::max( 65536, dict_size );
@@ -103,7 +104,6 @@ Matchfinder_base::Matchfinder_base( const int before, const int dict_size,
else dictionary_size_ = dict_size;
pos_limit = buffer_size;
if( !at_stream_end ) pos_limit -= after_size;
- for( int i = 0; i < num_prev_positions; ++i ) prev_positions[i] = -1;
pos_array_size = pos_array_factor * dictionary_size_;
pos_array = new( std::nothrow ) int32_t[pos_array_size];
if( !pos_array )
@@ -124,17 +124,7 @@ void Matchfinder_base::reset()
}
-bool Matchfinder::dec_pos( const int ahead ) throw()
- {
- if( ahead < 0 || pos < ahead ) return false;
- pos -= ahead;
- cyclic_pos -= ahead;
- if( cyclic_pos < 0 ) cyclic_pos += dictionary_size_;
- return true;
- }
-
-
-int Matchfinder::longest_match_len( int * const distances ) throw()
+int Matchfinder::longest_match_len( int * const distances )
{
int len_limit = match_len_limit_;
if( len_limit > available_bytes() )
@@ -264,7 +254,7 @@ void Len_encoder::encode( Range_encoder & range_encoder, int symbol,
// End Of Stream mark => (dis == 0xFFFFFFFFU, len == min_match_len)
void LZ_encoder_base::full_flush( const long long data_position,
- const State & state )
+ const State state )
{
const int pos_state = data_position & pos_state_mask;
range_encoder.encode_bit( bm_match[state()][pos_state], 1 );
@@ -281,7 +271,7 @@ void LZ_encoder_base::full_flush( const long long data_position,
}
-void LZ_encoder::fill_align_prices() throw()
+void LZ_encoder::fill_align_prices()
{
for( int i = 0; i < dis_align_size; ++i )
align_prices[i] = price_symbol_reversed( bm_align, i, dis_align_bits );
@@ -289,7 +279,7 @@ void LZ_encoder::fill_align_prices() throw()
}
-void LZ_encoder::fill_distance_prices() throw()
+void LZ_encoder::fill_distance_prices()
{
for( int dis = start_dis_model; dis < modeled_distances; ++dis )
{
@@ -327,7 +317,7 @@ void LZ_encoder::fill_distance_prices() throw()
// trials[0]..trials[retval-1] contain the steps to encode.
// ( trials[0].dis == -1 && trials[0].price == 1 ) means literal.
int LZ_encoder::sequence_optimizer( const int reps[num_rep_distances],
- const State & state )
+ const State state )
{
int main_len;
if( longest_match_found > 0 ) // from previous call
@@ -381,7 +371,7 @@ int LZ_encoder::sequence_optimizer( const int reps[num_rep_distances],
const int rep_match_price = match_price + price1( bm_rep[state()] );
if( match_byte == cur_byte )
- trials[1].update( 0, 0, rep_match_price + price_rep_len1( state, pos_state ) );
+ trials[1].update( 0, 0, rep_match_price + price_rep_len1( pos_state, state ) );
if( main_len < min_match_len )
{
@@ -411,11 +401,10 @@ int LZ_encoder::sequence_optimizer( const int reps[num_rep_distances],
for( int rep = 0; rep < num_rep_distances; ++rep )
{
- const int price = rep_match_price +
- price_rep( rep, state, pos_state );
+ const int price = rep_match_price + price_rep( rep, pos_state, state );
for( int len = min_match_len; len <= replens[rep]; ++len )
trials[len].update( rep, 0, price +
- rep_match_len_encoder.price( len, pos_state ) );
+ rep_match_len_encoder.price( len, pos_state ) );
}
}
@@ -480,7 +469,7 @@ int LZ_encoder::sequence_optimizer( const int reps[num_rep_distances],
if( match_byte == cur_byte && next_trial.dis != 0 )
next_trial.update( 0, cur, rep_match_price +
- price_rep_len1( cur_trial.state, pos_state ) );
+ price_rep_len1( pos_state, cur_trial.state ) );
const int len_limit = std::min( std::min( max_num_trials - 1 - cur,
matchfinder.available_bytes() ), matchfinder.match_len_limit() );
@@ -495,7 +484,7 @@ int LZ_encoder::sequence_optimizer( const int reps[num_rep_distances],
if( len >= min_match_len )
{
const int price = rep_match_price +
- price_rep( rep, cur_trial.state, pos_state );
+ price_rep( rep, pos_state, cur_trial.state );
while( num_trials < cur + len )
trials[++num_trials].price = infinite_price;
for( ; len >= min_match_len; --len )
diff --git a/encoder.h b/encoder.h
index 21c683d..75250ca 100644
--- a/encoder.h
+++ b/encoder.h
@@ -23,7 +23,7 @@ class Dis_slots
unsigned char data[1<<12];
public:
- void init() throw()
+ void init()
{
for( int slot = 0; slot < 4; ++slot ) data[slot] = slot;
for( int i = 4, size = 2, slot = 4; slot < 24; slot += 2 )
@@ -35,9 +35,9 @@ public:
}
}
- unsigned char table( const int dis ) const throw() { return data[dis]; }
+ unsigned char table( const int dis ) const { return data[dis]; }
- int operator[]( const uint32_t dis ) const throw()
+ int operator[]( const uint32_t dis ) const
{
if( dis < (1 << 12) ) return data[dis];
if( dis < (1 << 23) ) return data[dis>>11] + 22;
@@ -53,7 +53,7 @@ class Prob_prices
int data[bit_model_total >> 2];
public:
- void init() throw()
+ void init()
{
const int num_bits = ( bit_model_total_bits - 2 );
int j = 1, end = 2;
@@ -66,24 +66,24 @@ public:
}
}
- int operator[]( const int probability ) const throw()
+ int operator[]( const int probability ) const
{ return data[probability >> 2]; }
};
extern Prob_prices prob_prices;
-inline int price0( const Bit_model & bm ) throw()
+inline int price0( const Bit_model & bm )
{ return prob_prices[bm.probability]; }
-inline int price1( const Bit_model & bm ) throw()
+inline int price1( const Bit_model & bm )
{ return prob_prices[bit_model_total-bm.probability]; }
-inline int price_bit( const Bit_model & bm, const int bit ) throw()
+inline int price_bit( const Bit_model & bm, const int bit )
{ if( bit ) return price1( bm ); else return price0( bm ); }
-inline int price_symbol( const Bit_model bm[], int symbol, const int num_bits ) throw()
+inline int price_symbol( const Bit_model bm[], int symbol, const int num_bits )
{
int price = 0;
symbol |= ( 1 << num_bits );
@@ -98,7 +98,7 @@ inline int price_symbol( const Bit_model bm[], int symbol, const int num_bits )
inline int price_symbol_reversed( const Bit_model bm[], int symbol,
- const int num_bits ) throw()
+ const int num_bits )
{
int price = 0;
int model = 1;
@@ -114,7 +114,7 @@ inline int price_symbol_reversed( const Bit_model bm[], int symbol,
inline int price_matched( const Bit_model bm[], const int symbol,
- const int match_byte ) throw()
+ const int match_byte )
{
int price = 0;
int model = 1;
@@ -142,12 +142,12 @@ inline int price_matched( const Bit_model bm[], const int symbol,
class Matchfinder_base
{
- Matchfinder_base( const Matchfinder_base & ); // declared as private
- void operator=( const Matchfinder_base & ); // declared as private
-
bool read_block();
void normalize_pos();
+ Matchfinder_base( const Matchfinder_base & ); // declared as private
+ void operator=( const Matchfinder_base & ); // declared as private
+
protected:
enum { after_size = max_match_len }; // bytes to keep in buffer after pos
@@ -177,15 +177,15 @@ protected:
{ delete[] pos_array; std::free( buffer ); delete[] prev_positions; }
public:
- uint8_t operator[]( const int i ) const throw() { return buffer[pos+i]; }
- int available_bytes() const throw() { return stream_pos - pos; }
- long long data_position() const throw() { return partial_data_pos + pos; }
- int dictionary_size() const throw() { return dictionary_size_; }
- bool finished() const throw() { return at_stream_end && pos >= stream_pos; }
- int match_len_limit() const throw() { return match_len_limit_; }
- const uint8_t * ptr_to_current_pos() const throw() { return buffer + pos; }
-
- int true_match_len( const int index, const int distance, int len_limit ) const throw()
+ uint8_t operator[]( const int i ) const { return buffer[pos+i]; }
+ int available_bytes() const { return stream_pos - pos; }
+ long long data_position() const { return partial_data_pos + pos; }
+ int dictionary_size() const { return dictionary_size_; }
+ bool finished() const { return at_stream_end && pos >= stream_pos; }
+ int match_len_limit() const { return match_len_limit_; }
+ const uint8_t * ptr_to_current_pos() const { return buffer + pos; }
+
+ int true_match_len( const int index, const int distance, int len_limit ) const
{
if( index + len_limit > available_bytes() )
len_limit = available_bytes() - index;
@@ -225,8 +225,16 @@ public:
cycles( ( len_limit < max_match_len ) ? 16 + ( len_limit / 2 ) : 256 )
{}
- bool dec_pos( const int ahead ) throw();
- int longest_match_len( int * const distances = 0 ) throw();
+ bool dec_pos( const int ahead )
+ {
+ if( ahead < 0 || pos < ahead ) return false;
+ pos -= ahead;
+ cyclic_pos -= ahead;
+ if( cyclic_pos < 0 ) cyclic_pos += dictionary_size_;
+ return true;
+ }
+
+ int longest_match_len( int * const distances = 0 );
};
@@ -244,8 +252,8 @@ class Range_encoder
void shift_low()
{
- const uint32_t carry = low >> 32;
- if( low < 0xFF000000U || carry == 1 )
+ const bool carry = ( low > 0xFFFFFFFFU );
+ if( carry || low < 0xFF000000U )
{
put_byte( cache + carry );
for( ; ff_count > 0; --ff_count ) put_byte( 0xFF + carry );
@@ -255,8 +263,8 @@ class Range_encoder
low = ( low & 0x00FFFFFFU ) << 8;
}
- Range_encoder( const Range_encoder & );
- void operator=( const Range_encoder & );
+ Range_encoder( const Range_encoder & ); // declared as private
+ void operator=( const Range_encoder & ); // declared as private
public:
explicit Range_encoder( const int ofd )
@@ -268,11 +276,12 @@ public:
range( 0xFFFFFFFFU ),
ff_count( 0 ),
outfd( ofd ),
- cache( 0 ) {}
+ cache( 0 )
+ {}
~Range_encoder() { delete[] buffer; }
- long long member_position() const throw()
+ long long member_position() const
{ return partial_member_pos + pos + ff_count; }
void flush() { for( int i = 0; i < 5; ++i ) shift_low(); }
@@ -371,7 +380,7 @@ class Len_encoder
const int len_symbols;
int counters[pos_states];
- void update_prices( const int pos_state ) throw()
+ void update_prices( const int pos_state )
{
int * const pps = prices[pos_state];
int tmp = price0( choice1 );
@@ -401,7 +410,7 @@ public:
void encode( Range_encoder & range_encoder, int symbol,
const int pos_state );
- int price( const int symbol, const int pos_state ) const throw()
+ int price( const int symbol, const int pos_state ) const
{ return prices[pos_state][symbol - min_match_len]; }
};
@@ -410,7 +419,7 @@ class Literal_encoder
{
Bit_model bm_literal[1<<literal_context_bits][0x300];
- int lstate( const uint8_t prev_byte ) const throw()
+ int lstate( const uint8_t prev_byte ) const
{ return ( prev_byte >> ( 8 - literal_context_bits ) ); }
public:
@@ -423,11 +432,11 @@ public:
{ range_encoder.encode_matched( bm_literal[lstate(prev_byte)],
symbol, match_byte ); }
- int price_symbol( uint8_t prev_byte, uint8_t symbol ) const throw()
+ int price_symbol( uint8_t prev_byte, uint8_t symbol ) const
{ return ::price_symbol( bm_literal[lstate(prev_byte)], symbol, 8 ); }
int price_matched( uint8_t prev_byte, uint8_t symbol,
- uint8_t match_byte ) const throw()
+ uint8_t match_byte ) const
{ return ::price_matched( bm_literal[lstate(prev_byte)],
symbol, match_byte ); }
};
@@ -458,7 +467,7 @@ protected:
const int num_dis_slots;
- uint32_t crc() const throw() { return crc_ ^ 0xFFFFFFFFU; }
+ uint32_t crc() const { return crc_ ^ 0xFFFFFFFFU; }
LZ_encoder_base( const File_header & header, const int dictionary_size,
const int match_len_limit, const int outfd )
@@ -474,7 +483,7 @@ protected:
}
// move-to-front dis in/into reps
- void mtf_reps( const int dis, int reps[num_rep_distances] ) throw()
+ void mtf_reps( const int dis, int reps[num_rep_distances] )
{
if( dis >= num_rep_distances )
{
@@ -489,7 +498,7 @@ protected:
}
}
- void encode_pair( const uint32_t dis, const int len, const int pos_state ) throw()
+ void encode_pair( const uint32_t dis, const int len, const int pos_state )
{
len_encoder.encode( range_encoder, len, pos_state );
const int dis_slot = dis_slots[dis];
@@ -512,11 +521,10 @@ protected:
}
}
- void full_flush( const long long data_position, const State & state );
+ void full_flush( const long long data_position, const State state );
public:
- long long member_position() const throw()
- { return range_encoder.member_position(); }
+ long long member_position() const { return range_encoder.member_position(); }
};
@@ -531,7 +539,7 @@ class LZ_encoder : public LZ_encoder_base
int prev_index; // index of prev trial in trials[]
int price; // dual use var; cumulative price, match length
int reps[num_rep_distances];
- void update( const int d, const int p_i, const int pr ) throw()
+ void update( const int d, const int p_i, const int pr )
{ if( pr < price ) { dis = d; prev_index = p_i; price = pr; } }
};
@@ -545,16 +553,15 @@ class LZ_encoder : public LZ_encoder_base
int align_prices[dis_align_size];
int align_price_count;
- void fill_align_prices() throw();
- void fill_distance_prices() throw();
+ void fill_align_prices();
+ void fill_distance_prices();
- int price_rep_len1( const State & state, const int pos_state ) const throw()
+ int price_rep_len1( const int pos_state, const State state ) const
{
return price0( bm_rep0[state()] ) + price0( bm_len[state()][pos_state] );
}
- int price_rep( const int rep, const State & state,
- const int pos_state ) const throw()
+ int price_rep( const int rep, const int pos_state, const State state ) const
{
if( rep == 0 ) return price0( bm_rep0[state()] ) +
price1( bm_len[state()][pos_state] );
@@ -569,7 +576,7 @@ class LZ_encoder : public LZ_encoder_base
return price;
}
- int price_dis( const int dis, const int dis_state ) const throw()
+ int price_dis( const int dis, const int dis_state ) const
{
if( dis < modeled_distances )
return dis_prices[dis_state][dis];
@@ -578,7 +585,7 @@ class LZ_encoder : public LZ_encoder_base
align_prices[dis & (dis_align_size - 1)];
}
- int price_pair( const int dis, const int len, const int pos_state ) const throw()
+ int price_pair( const int dis, const int len, const int pos_state ) const
{
if( len <= min_match_len && dis >= modeled_distances )
return infinite_price;
@@ -586,7 +593,7 @@ class LZ_encoder : public LZ_encoder_base
price_dis( dis, get_dis_state( len ) );
}
- int read_match_distances() throw()
+ int read_match_distances()
{
int len = matchfinder.longest_match_len( match_distances );
if( len == matchfinder.match_len_limit() && len < max_match_len )
@@ -619,7 +626,7 @@ class LZ_encoder : public LZ_encoder_base
}
int sequence_optimizer( const int reps[num_rep_distances],
- const State & state );
+ const State state );
public:
LZ_encoder( Matchfinder & mf, const File_header & header, const int outfd )
diff --git a/fast_encoder.cc b/fast_encoder.cc
index 319250a..2d99b04 100644
--- a/fast_encoder.cc
+++ b/fast_encoder.cc
@@ -30,7 +30,7 @@
#include "fast_encoder.h"
-int Fmatchfinder::longest_match_len( int * const distance ) throw()
+int Fmatchfinder::longest_match_len( int * const distance )
{
int len_limit = match_len_limit_;
if( len_limit > available_bytes() )
@@ -80,7 +80,7 @@ int Fmatchfinder::longest_match_len( int * const distance ) throw()
}
-void Fmatchfinder::longest_match_len() throw()
+void Fmatchfinder::longest_match_len()
{
int len_limit = match_len_limit_;
if( len_limit > available_bytes() )
diff --git a/fast_encoder.h b/fast_encoder.h
index ce5bae5..05c3ca8 100644
--- a/fast_encoder.h
+++ b/fast_encoder.h
@@ -35,8 +35,8 @@ public:
{}
void reset() { Matchfinder_base::reset(); key4 = 0; }
- int longest_match_len( int * const distance ) throw();
- void longest_match_len() throw();
+ int longest_match_len( int * const distance );
+ void longest_match_len();
};
diff --git a/lzip.h b/lzip.h
index 9776710..1e61400 100644
--- a/lzip.h
+++ b/lzip.h
@@ -21,32 +21,32 @@ class State
public:
enum { states = 12 };
- State() throw() : st( 0 ) {}
- unsigned char operator()() const throw() { return st; }
- bool is_char() const throw() { return st < 7; }
+ State() : st( 0 ) {}
+ unsigned char operator()() const { return st; }
+ bool is_char() const { return st < 7; }
- void set_char() throw()
+ void set_char()
{
static const unsigned char next[states] =
{ 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5 };
st = next[st];
}
- void set_match() throw()
+ void set_match()
{
static const unsigned char next[states] =
{ 7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10 };
st = next[st];
}
- void set_rep() throw()
+ void set_rep()
{
static const unsigned char next[states] =
{ 8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11 };
st = next[st];
}
- void set_short_rep() throw()
+ void set_short_rep()
{
static const unsigned char next[states] =
{ 9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11 };
@@ -86,7 +86,7 @@ enum {
max_dis_states = 4 };
-inline int get_dis_state( int len ) throw()
+inline int get_dis_state( int len )
{
len -= min_match_len;
if( len >= max_dis_states ) len = max_dis_states - 1;
@@ -101,7 +101,7 @@ enum { bit_model_move_bits = 5,
struct Bit_model
{
unsigned int probability;
- Bit_model() throw() : probability( bit_model_total / 2 ) {}
+ Bit_model() : probability( bit_model_total / 2 ) {}
};
@@ -135,10 +135,10 @@ public:
first_post = true;
}
- void reset() const throw() { if( name_.size() ) first_post = true; }
- const char * name() const throw() { return name_.c_str(); }
- int verbosity() const throw() { return verbosity_; }
- void operator()( const char * const msg = 0 ) const throw();
+ void reset() const { if( name_.size() ) first_post = true; }
+ const char * name() const { return name_.c_str(); }
+ int verbosity() const { return verbosity_; }
+ void operator()( const char * const msg = 0 ) const;
};
@@ -158,10 +158,10 @@ public:
}
}
- uint32_t operator[]( const uint8_t byte ) const throw() { return data[byte]; }
- void update( uint32_t & crc, const uint8_t byte ) const throw()
+ uint32_t operator[]( const uint8_t byte ) const { return data[byte]; }
+ void update( uint32_t & crc, const uint8_t byte ) const
{ crc = data[(crc^byte)&0xFF] ^ ( crc >> 8 ); }
- void update( uint32_t & crc, const uint8_t * const buffer, const int size ) const throw()
+ void update( uint32_t & crc, const uint8_t * const buffer, const int size ) const
{
for( int i = 0; i < size; ++i )
crc = data[(crc^buffer[i])&0xFF] ^ ( crc >> 8 );
@@ -171,11 +171,11 @@ public:
extern const CRC32 crc32;
-inline int real_bits( const int value ) throw()
+inline int real_bits( const unsigned int value )
{
- int bits = 0;
- for( int i = 1, mask = 1; mask > 0; ++i, mask <<= 1 )
- if( value & mask ) bits = i;
+ int bits = 0, i = 1;
+ unsigned int mask = 1;
+ for( ; mask > 0; ++i, mask <<= 1 ) if( value & mask ) bits = i;
return bits;
}
@@ -189,24 +189,22 @@ struct File_header
// 5 coded_dict_size
enum { size = 6 };
- void set_magic() throw()
- { std::memcpy( data, magic_string, 4 ); data[4] = 1; }
-
- bool verify_magic() const throw()
+ void set_magic() { std::memcpy( data, magic_string, 4 ); data[4] = 1; }
+ bool verify_magic() const
{ return ( std::memcmp( data, magic_string, 4 ) == 0 ); }
- uint8_t version() const throw() { return data[4]; }
- bool verify_version() const throw() { return ( data[4] <= 1 ); }
+ uint8_t version() const { return data[4]; }
+ bool verify_version() const { return ( data[4] <= 1 ); }
- int dictionary_size() const throw()
+ int dictionary_size() const
{
int sz = ( 1 << ( data[5] & 0x1F ) );
if( sz > min_dictionary_size && sz <= max_dictionary_size )
- sz -= ( sz / 16 ) * ( ( data[5] >> 5 ) & 0x07 );
+ sz -= ( sz / 16 ) * ( ( data[5] >> 5 ) & 7 );
return sz;
}
- bool dictionary_size( const int sz ) throw()
+ bool dictionary_size( const int sz )
{
if( sz >= min_dictionary_size && sz <= max_dictionary_size )
{
@@ -235,36 +233,36 @@ struct File_trailer
static int size( const int version = 1 )
{ return ( ( version >= 1 ) ? 20 : 12 ); }
- uint32_t data_crc() const throw()
+ uint32_t data_crc() const
{
uint32_t tmp = 0;
for( int i = 3; i >= 0; --i ) { tmp <<= 8; tmp += data[i]; }
return tmp;
}
- void data_crc( uint32_t crc ) throw()
+ void data_crc( uint32_t crc )
{ for( int i = 0; i <= 3; ++i ) { data[i] = (uint8_t)crc; crc >>= 8; } }
- long long data_size() const throw()
+ long long data_size() const
{
long long tmp = 0;
for( int i = 11; i >= 4; --i ) { tmp <<= 8; tmp += data[i]; }
return tmp;
}
- void data_size( long long sz ) throw()
+ void data_size( long long sz )
{
for( int i = 4; i <= 11; ++i ) { data[i] = (uint8_t)sz; sz >>= 8; }
}
- long long member_size() const throw()
+ long long member_size() const
{
long long tmp = 0;
for( int i = 19; i >= 12; --i ) { tmp <<= 8; tmp += data[i]; }
return tmp;
}
- void member_size( long long sz ) throw()
+ void member_size( long long sz )
{
for( int i = 12; i <= 19; ++i ) { data[i] = (uint8_t)sz; sz >>= 8; }
}
@@ -274,15 +272,15 @@ struct File_trailer
struct Error
{
const char * const msg;
- explicit Error( const char * const s ) throw() : msg( s ) {}
+ explicit Error( const char * const s ) : msg( s ) {}
};
// defined in main.cc
void show_error( const char * const msg, const int errcode = 0,
- const bool help = false ) throw();
-void internal_error( const char * const msg ) throw();
+ const bool help = false );
+void internal_error( const char * const msg );
// defined in decoder.cc
-int readblock( const int fd, uint8_t * const buf, const int size ) throw();
-int writeblock( const int fd, const uint8_t * const buf, const int size ) throw();
+int readblock( const int fd, uint8_t * const buf, const int size );
+int writeblock( const int fd, const uint8_t * const buf, const int size );
diff --git a/main.cc b/main.cc
index 3e95eb9..276fe30 100644
--- a/main.cc
+++ b/main.cc
@@ -108,7 +108,7 @@ mode_t outfd_mode = usr_rw;
bool delete_output_on_interrupt = false;
-void show_help() throw()
+void show_help()
{
std::printf( "%s - Data compressor based on the LZMA algorithm.\n", Program_name );
std::printf( "\nUsage: %s [options] [files]\n", invocation_name );
@@ -144,7 +144,7 @@ void show_help() throw()
}
-void show_version() throw()
+void show_version()
{
std::printf( "%s %s\n", Program_name, PROGVERSION );
std::printf( "Copyright (C) %s Antonio Diaz Diaz.\n", program_year );
@@ -154,7 +154,7 @@ void show_version() throw()
}
-const char * format_num( long long num ) throw()
+const char * format_num( long long num )
{
const char * const prefix[8] =
{ "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi" };
@@ -173,7 +173,7 @@ const char * format_num( long long num ) throw()
long long getnum( const char * const ptr,
const long long llimit = LLONG_MIN + 1,
- const long long ulimit = LLONG_MAX ) throw()
+ const long long ulimit = LLONG_MAX )
{
errno = 0;
char *tail;
@@ -226,7 +226,7 @@ long long getnum( const char * const ptr,
}
-int get_dict_size( const char * const arg ) throw()
+int get_dict_size( const char * const arg )
{
char *tail;
int bits = std::strtol( arg, &tail, 0 );
@@ -237,7 +237,7 @@ int get_dict_size( const char * const arg ) throw()
}
-int extension_index( const std::string & name ) throw()
+int extension_index( const std::string & name )
{
for( int i = 0; known_extensions[i].from; ++i )
{
@@ -252,7 +252,7 @@ int extension_index( const std::string & name ) throw()
int open_instream( const std::string & name, struct stat * const in_statsp,
const Mode program_mode, const int eindex,
- const bool recompress, const bool to_stdout ) throw()
+ const bool recompress, const bool to_stdout )
{
int infd = -1;
if( program_mode == m_compress && !recompress && eindex >= 0 )
@@ -294,7 +294,7 @@ int open_instream( const std::string & name, struct stat * const in_statsp,
}
-void set_c_outname( const std::string & name, const bool multifile ) throw()
+void set_c_outname( const std::string & name, const bool multifile )
{
output_filename = name;
if( multifile ) output_filename += "00001";
@@ -302,7 +302,7 @@ void set_c_outname( const std::string & name, const bool multifile ) throw()
}
-void set_d_outname( const std::string & name, const int i ) throw()
+void set_d_outname( const std::string & name, const int i )
{
if( i >= 0 )
{
@@ -321,7 +321,7 @@ void set_d_outname( const std::string & name, const int i ) throw()
}
-bool open_outstream( const bool force ) throw()
+bool open_outstream( const bool force )
{
int flags = O_CREAT | O_WRONLY | o_binary;
if( force ) flags |= O_TRUNC; else flags |= O_EXCL;
@@ -340,7 +340,7 @@ bool open_outstream( const bool force ) throw()
}
-bool check_tty( const int infd, const Mode program_mode ) throw()
+bool check_tty( const int infd, const Mode program_mode )
{
if( program_mode == m_compress && outfd >= 0 && isatty( outfd ) )
{
@@ -357,7 +357,7 @@ bool check_tty( const int infd, const Mode program_mode ) throw()
}
-void cleanup_and_fail( const int retval ) throw()
+void cleanup_and_fail( const int retval )
{
if( delete_output_on_interrupt )
{
@@ -460,7 +460,7 @@ int compress( const long long member_size, const long long volume_size,
if( retval == 0 && verbosity >= 1 )
{
if( in_size <= 0 || out_size <= 0 )
- std::fprintf( stderr, "No data compressed.\n" );
+ std::fprintf( stderr, " no data compressed.\n" );
else
std::fprintf( stderr, "%6.3f:1, %6.3f bits/byte, "
"%5.2f%% saved, %lld in, %lld out.\n",
@@ -523,7 +523,7 @@ int fcompress( const long long member_size, const long long volume_size,
if( retval == 0 && verbosity >= 1 )
{
if( in_size <= 0 || out_size <= 0 )
- std::fprintf( stderr, "No data compressed.\n" );
+ std::fprintf( stderr, " no data compressed.\n" );
else
std::fprintf( stderr, "%6.3f:1, %6.3f bits/byte, "
"%5.2f%% saved, %lld in, %lld out.\n",
@@ -543,7 +543,7 @@ int fcompress( const long long member_size, const long long volume_size,
}
-unsigned char xdigit( const int value ) throw()
+unsigned char xdigit( const int value )
{
if( value >= 0 && value <= 9 ) return '0' + value;
if( value >= 10 && value <= 15 ) return 'A' + value - 10;
@@ -552,7 +552,7 @@ unsigned char xdigit( const int value ) throw()
void show_trailing_garbage( const uint8_t * const data, const int size,
- const Pretty_print & pp, const bool all ) throw()
+ const Pretty_print & pp, const bool all )
{
std::string garbage_msg;
if( !all ) garbage_msg = "first bytes of ";
@@ -566,7 +566,7 @@ void show_trailing_garbage( const uint8_t * const data, const int size,
garbage_msg.append( (const char *)data, size );
garbage_msg += '\'';
}
- else
+ else
{
for( int i = 0; i < size; ++i )
{
@@ -590,7 +590,7 @@ int decompress( const int infd, const Pretty_print & pp, const bool testing )
{
File_header header;
rdec.reset_member_position();
- const int size = rdec.read( header.data, File_header::size );
+ const int size = rdec.read_data( header.data, File_header::size );
if( rdec.finished() ) // End Of File
{
if( first_member )
@@ -663,14 +663,14 @@ int decompress( const int infd, const Pretty_print & pp, const bool testing )
}
-extern "C" void signal_handler( int ) throw()
+extern "C" void signal_handler( int )
{
show_error( "Control-C or similar caught, quitting." );
cleanup_and_fail( 1 );
}
-void set_signals() throw()
+void set_signals()
{
std::signal( SIGHUP, signal_handler );
std::signal( SIGINT, signal_handler );
@@ -680,7 +680,7 @@ void set_signals() throw()
} // end namespace
-void show_error( const char * const msg, const int errcode, const bool help ) throw()
+void show_error( const char * const msg, const int errcode, const bool help )
{
if( verbosity >= 0 )
{
@@ -698,7 +698,7 @@ void show_error( const char * const msg, const int errcode, const bool help ) th
}
-void internal_error( const char * const msg ) throw()
+void internal_error( const char * const msg )
{
if( verbosity >= 0 )
std::fprintf( stderr, "%s: internal error: %s.\n", program_name, msg );
diff --git a/testsuite/check.sh b/testsuite/check.sh
index a82d0de..116345c 100755
--- a/testsuite/check.sh
+++ b/testsuite/check.sh
@@ -22,24 +22,22 @@ mkdir tmp
cd "${objdir}"/tmp
cat "${testdir}"/test.txt > in || framework_failure
+cat in in > in2 || framework_failure
fail=0
printf "testing lzip-%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
cmp in copy || fail=1
printf .
@@ -82,6 +80,11 @@ for i in s4Ki 0 1 2 3 4 5 6 7 8 9 ; do
printf .
done
+"${LZIP}" < in2 > out2 || fail=1
+"${LZIP}" -d < out2 > copy2 || fail=1
+cmp in2 copy2 || fail=1
+printf .
+
"${LZIP}" < in > anyothername || fail=1
"${LZIP}" -d anyothername || fail=1
cmp in anyothername.out || fail=1
diff --git a/testsuite/unzcrash.cc b/testsuite/unzcrash.cc
deleted file mode 100644
index 65d160d..0000000
--- a/testsuite/unzcrash.cc
+++ /dev/null
@@ -1,354 +0,0 @@
-/* Unzcrash - A test program written to test robustness to
- decompression of corrupted data.
- Inspired by unzcrash.c from Julian Seward's bzip2.
- Copyright (C) 2008, 2009, 2010, 2011 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
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <cerrno>
-#include <climits>
-#include <csignal>
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
-#include <string>
-#include <vector>
-#include <stdint.h>
-#include <unistd.h>
-
-#include "../arg_parser.h"
-
-#if CHAR_BIT != 8
-#error "Environments where CHAR_BIT != 8 are not supported."
-#endif
-
-#ifndef LLONG_MAX
-#define LLONG_MAX 0x7FFFFFFFFFFFFFFFLL
-#endif
-#ifndef LLONG_MIN
-#define LLONG_MIN (-LLONG_MAX - 1LL)
-#endif
-#ifndef ULLONG_MAX
-#define ULLONG_MAX 0xFFFFFFFFFFFFFFFFULL
-#endif
-
-
-namespace {
-
-const char * const Program_name = "Unzcrash";
-const char * const program_name = "unzcrash";
-const char * const program_year = "2011";
-const char * invocation_name = 0;
-
-int verbosity = 0;
-
-
-void show_help() throw()
- {
- std::printf( "%s - A test program written to test robustness to\n", Program_name );
- std::printf( "decompression of corrupted data.\n"
- "\nUsage: %s [options] \"lzip -tv\" filename.lz\n", invocation_name );
- std::printf( "\nThis program reads the specified file and then repeatedly decompresses\n"
- "it, increasing 256 times each byte of the compressed data, so as to test\n"
- "all possible one-byte errors. This should not cause any invalid memory\n"
- "accesses. If it does, please, report it as a bug.\n"
- "\nOptions:\n"
- " -h, --help display this help and exit\n"
- " -V, --version output version information and exit\n"
- " -b, --bits=<n>[,<n>]... test <n>-bit errors instead of full byte\n"
- " -p, --position=<bytes> first byte position to test\n"
- " -q, --quiet suppress all messages\n"
- " -s, --size=<bytes> number of byte positions to test\n"
- " -v, --verbose be verbose (a 2nd -v gives more)\n"
- "\nReport bugs to lzip-bug@nongnu.org\n"
- "Lzip home page: http://www.nongnu.org/lzip/lzip.html\n" );
- }
-
-
-void show_version() throw()
- {
- std::printf( "%s %s\n", Program_name, PROGVERSION );
- std::printf( "Copyright (C) %s Antonio Diaz Diaz.\n", program_year );
- std::printf( "License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\n"
- "This is free software: you are free to change and redistribute it.\n"
- "There is NO WARRANTY, to the extent permitted by law.\n" );
- }
-
-
-void show_error( const char * const msg, const int errcode = 0,
- const bool help = false ) throw()
- {
- if( verbosity >= 0 )
- {
- if( msg && msg[0] )
- {
- std::fprintf( stderr, "%s: %s", program_name, msg );
- if( errcode > 0 )
- std::fprintf( stderr, ": %s", std::strerror( errcode ) );
- std::fprintf( stderr, "\n" );
- }
- if( help && invocation_name && invocation_name[0] )
- std::fprintf( stderr, "Try `%s --help' for more information.\n",
- invocation_name );
- }
- }
-
-
-void internal_error( const char * const msg ) throw() __attribute__ ((noreturn));
-void internal_error( const char * const msg ) throw()
- {
- if( verbosity >= 0 )
- std::fprintf( stderr, "%s: internal error: %s.\n", program_name, msg );
- std::exit( 3 );
- }
-
-
-long long getnum( const char * const ptr,
- const long long llimit = LLONG_MIN + 1,
- const long long ulimit = LLONG_MAX ) throw()
- {
- errno = 0;
- char *tail;
- long long result = strtoll( ptr, &tail, 0 );
- if( tail == ptr )
- {
- show_error( "Bad or missing numerical argument.", 0, true );
- std::exit( 1 );
- }
-
- if( !errno && tail[0] )
- {
- int factor = ( tail[1] == 'i' ) ? 1024 : 1000;
- int exponent = 0;
- bool bad_multiplier = false;
- switch( tail[0] )
- {
- case ' ': break;
- case 'Y': exponent = 8; break;
- case 'Z': exponent = 7; break;
- case 'E': exponent = 6; break;
- case 'P': exponent = 5; break;
- case 'T': exponent = 4; break;
- case 'G': exponent = 3; break;
- case 'M': exponent = 2; break;
- case 'K': if( factor == 1024 ) exponent = 1; else bad_multiplier = true;
- break;
- case 'k': if( factor == 1000 ) exponent = 1; else bad_multiplier = true;
- break;
- default : bad_multiplier = true;
- }
- if( bad_multiplier )
- {
- show_error( "Bad multiplier in numerical argument.", 0, true );
- std::exit( 1 );
- }
- for( int i = 0; i < exponent; ++i )
- {
- if( LLONG_MAX / factor >= llabs( result ) ) result *= factor;
- else { errno = ERANGE; break; }
- }
- }
- if( !errno && ( result < llimit || result > ulimit ) ) errno = ERANGE;
- if( errno )
- {
- show_error( "Numerical argument out of limits." );
- std::exit( 1 );
- }
- return result;
- }
-
-
-class Bitset8 // 8 value bitset (1..8)
- {
- bool data[8];
- static bool valid_digit( const unsigned char ch ) throw()
- { return ( ch >= '1' && ch <= '8' ); }
-
-public:
- Bitset8() throw() { for( int i = 0; i < 8; ++i ) data[i] = true; }
-
- bool includes( const int i ) const throw()
- { return ( i >= 1 && i <= 8 && data[i-1] ); }
-
- // Recognized formats: 1 1,2,3 1-4 1,3-5,8
- bool parse( const char * p ) throw()
- {
- for( int i = 0; i < 8; ++i ) data[i] = false;
- while( true )
- {
- const unsigned char ch1 = *p++;
- if( !valid_digit( ch1 ) ) break;
- if( *p != '-' ) data[ch1-'1'] = true;
- else
- {
- ++p;
- if( !valid_digit( *p ) || ch1 > *p ) break;
- for( int c = ch1; c <= *p; ++c ) data[c-'1'] = true;
- ++p;
- }
- if( *p == 0 ) return true;
- if( *p == ',' ) ++p; else break;
- }
- show_error( "Invalid value or range." );
- return false;
- }
-
- // number of n-bit errors per byte (n=0..8): 1 8 28 56 70 56 28 8 1
- void print() const throw()
- {
- std::fflush( stderr );
- int c = 0;
- for( int i = 0; i < 8; ++i ) if( data[i] ) ++c;
- if( c == 8 ) std::printf( "Testing full byte.\n" );
- else if( c == 0 ) std::printf( "Nothing to test.\n" );
- else
- {
- std::printf( "Testing " );
- for( int i = 0; i < 8; ++i )
- if( data[i] )
- {
- std::printf( "%d", i + 1 );
- if( --c ) std::printf( "," );
- }
- std::printf( " bit errors.\n" );
- }
- std::fflush( stdout );
- }
- };
-
-
-int differing_bits( const uint8_t byte1, const uint8_t byte2 )
- {
- int count = 0;
- uint8_t dif = byte1 ^ byte2;
- while( dif )
- { count += ( dif & 1 ); dif >>= 1; }
- return count;
- }
-
-} // end namespace
-
-
-int main( const int argc, const char * const argv[] )
- {
- enum { buffer_size = 3 << 20 };
- Bitset8 bits; // if Bitset8::parse not called test full byte
- int pos = 0;
- int max_size = buffer_size;
- invocation_name = argv[0];
-
- const Arg_parser::Option options[] =
- {
- { 'h', "help", Arg_parser::no },
- { 'b', "bits", Arg_parser::yes },
- { 'p', "position", Arg_parser::yes },
- { 'q', "quiet", Arg_parser::no },
- { 's', "size", Arg_parser::yes },
- { 'v', "verbose", Arg_parser::no },
- { 'V', "version", Arg_parser::no },
- { 0 , 0, Arg_parser::no } };
-
- const Arg_parser parser( argc, argv, options );
- if( parser.error().size() ) // bad option
- { show_error( parser.error().c_str(), 0, true ); return 1; }
-
- int argind = 0;
- for( ; argind < parser.arguments(); ++argind )
- {
- const int code = parser.code( argind );
- if( !code ) break; // no more options
- const char * const arg = parser.argument( argind ).c_str();
- switch( code )
- {
- case 'h': show_help(); return 0;
- case 'b': if( !bits.parse( arg ) ) return 1; break;
- case 'p': pos = getnum( arg, 0, buffer_size - 1 ); break;
- case 'q': verbosity = -1; break;
- case 's': max_size = getnum( arg, 1, buffer_size ); break;
- case 'v': if( verbosity < 4 ) ++verbosity; break;
- case 'V': show_version(); return 0;
- default : internal_error( "uncaught option" );
- }
- } // end process options
-
- if( argind + 2 != parser.arguments() )
- {
- if( verbosity >= 0 )
- std::fprintf( stderr, "Usage: %s \"lzip -tv\" filename.lz\n",
- invocation_name );
- return 1;
- }
-
- FILE *f = std::fopen( parser.argument( argind + 1 ).c_str(), "rb" );
- if( !f )
- {
- if( verbosity >= 0 )
- std::fprintf( stderr, "Can't open file `%s' for reading\n",
- parser.argument( argind + 1 ).c_str() );
- return 1;
- }
-
- uint8_t * const buffer = new uint8_t[buffer_size];
- const int size = std::fread( buffer, 1, buffer_size, f );
- if( size >= buffer_size )
- {
- if( verbosity >= 0 )
- std::fprintf( stderr, "input file `%s' is too big.\n",
- parser.argument( argind + 1 ).c_str() );
- return 1;
- }
- std::fclose( f );
-
- f = popen( parser.argument( argind ).c_str(), "w" );
- if( !f )
- { show_error( "Can't open pipe", errno ); return 1; }
- const int wr = std::fwrite( buffer, 1, size, f );
- if( wr != size || pclose( f ) != 0 )
- {
- if( verbosity >= 0 )
- std::fprintf( stderr, "Could not run `%s' : %s.\n",
- parser.argument( argind ).c_str(), std::strerror( errno ) );
- return 1;
- }
-
- std::signal( SIGPIPE, SIG_IGN );
- if( verbosity >= 1 ) bits.print();
-
- const int end = ( ( pos + max_size < size ) ? pos + max_size : size );
- for( int i = pos; i < end; ++i )
- {
- if( verbosity >= 0 )
- std::fprintf( stderr, "byte %d\n", i );
- const uint8_t byte = buffer[i];
- for( int j = 0; j < 255; ++j )
- {
- ++buffer[i];
- if( bits.includes( differing_bits( byte, buffer[i] ) ) )
- {
- f = popen( parser.argument( argind ).c_str(), "w" );
- if( !f )
- { show_error( "Can't open pipe", errno ); return 1; }
- std::fwrite( buffer, 1, size, f );
- if( pclose( f ) == 0 && verbosity >= 0 )
- std::fprintf( stderr, "0x%02X (0x%02X+0x%02X) passed the test\n",
- buffer[i], byte, j + 1 );
- }
- }
- buffer[i] = byte;
- }
-
- delete[] buffer;
- return 0;
- }