diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..e08809c --- /dev/null +++ b/AUTHORS @@ -0,0 +1,7 @@ +Lzip was written by Antonio Diaz Diaz. + +The ideas embodied in lzip are due to (at least) the following people: +Abraham Lempel and Jacob Ziv (for the LZ algorithm), Andrei Markov (for the +definition of Markov chains), G.N.N. Martin (for the definition of range +encoding), Igor Pavlov (for putting all the above together in LZMA), and +Julian Seward (for bzip2's CLI). diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..4ed04db --- /dev/null +++ b/ChangeLog @@ -0,0 +1,345 @@ +2024-01-26 Antonio Diaz Diaz + + * Version 1.24 released. + * New options '--empty-error' and '--marking-error'. + * main.cc: Reformat file diagnostics as 'PROGRAM: FILE: MESSAGE'. + (show_option_error): New function showing argument and option name. + (main): Make -o preserve date/mode/owner if 1 input file. + (open_outstream): Create missing intermediate directories. + * lzip.h: Rename verify_* to check_*. + * configure, Makefile.in: New variable 'MAKEINFO'. + * testsuite: New test files fox6.lz, fox6_mark.lz. + +2022-01-24 Antonio Diaz Diaz + + * Version 1.23 released. + * Decompression time has been reduced by 5-12% depending on the file. + * main.cc (getnum): Show option name and valid range if error. + * Improve several descriptions in manual, '--help', and man page. + * lzip.texi: Change GNU Texinfo category to 'Compression'. + (Reported by Alfred M. Szmidt). + +2021-01-04 Antonio Diaz Diaz + + * Version 1.22 released. + * main.cc (main): Report an error if a file name is empty. + Make '-o' behave like '-c', but writing to file instead of stdout. + Make '-c' and '-o' check whether the output is a terminal only once. + Do not open output if input is a terminal. + * configure: Build, check, and install without 'make'. + * Replace 'decompressed', 'compressed' with 'out', 'in' in output. + * lzip_index.cc: Improve messages for corruption in last header. + * main.cc: Set a valid invocation_name even if argc == 0. + * Document extraction from tar.lz in manual, '--help', and man page. + * lzip.texi (Introduction): Mention plzip and tarlz as alternatives. + * lzip.texi: Several fixes and improvements. + * testsuite: Add 9 new test files. + +2019-01-03 Antonio Diaz Diaz + + * Version 1.21 released. + * Rename File_* to Lzip_*. + * lzip.h (Lzip_trailer): New function 'verify_consistency'. + * lzip_index.cc: Detect some kinds of corrupt trailers. + * main.cc (main): Check return value of close( infd ). + * main.cc: Compile on DOS with DJGPP. + * Fix a GCC warning about catching std::bad_alloc by value. + * lzip.texi: Improve description of '-0..-9', '-m', and '-s'. + * configure: Accept appending to CXXFLAGS; 'CXXFLAGS+=OPTIONS'. + * INSTALL: Document use of CXXFLAGS+='-D __USE_MINGW_ANSI_STDIO'. + +2018-02-11 Antonio Diaz Diaz + + * Version 1.20 released. + * New option '--loose-trailing'. + * Improve corrupt header detection to HD=3. + * main.cc: Show corrupt or truncated header in multimember file. + * main.cc (main): Option '-S, --volume-size' now keeps input files. + * encoder_base.*: Adjust dictionary size for each member. + * Replace 'bits/byte' with inverse compression ratio in output. + * Show progress of decompression at verbosity level 2 (-vv). + * Show progress of (de)compression only if stderr is a terminal. + * main.cc: Show final diagnostic when testing multiple files. + * main.cc: Do not add a second extension '.lz' to the arg of '-o'. + * decoder.cc (verify_trailer): Show stored sizes also in hex. + Show dictionary size at verbosity level 4 (-vvvv). + * lzip.texi: New chapter 'Meaning of lzip's output'. + +2017-04-13 Antonio Diaz Diaz + + * Version 1.19 released. + * The option '-l, --list' has been ported from lziprecover. + * Don't allow mixing different operations (-d, -l or -t). + * Compression time of option '-0' has been slightly reduced. + * Decompression time has been reduced by 2%. + * main.cc: Continue testing if any input file is a terminal. + * main.cc: Show trailing data in both hexadecimal and ASCII. + * encoder.cc (Matchfinder_base): Check the size passed to new. + * lzip_index.cc: Improve detection of bad dict and trailing data. + * lzip.h: Unify messages for bad magic, trailing data, etc. + +2016-05-14 Antonio Diaz Diaz + + * Version 1.18 released. + * New option '-a, --trailing-error'. + * Decompression time has been reduced by 2%. + * decoder.cc (verify_trailer): Remove test of final code. + * main.cc (main): Delete '--output' file if infd is a terminal. + * main.cc (main): Don't use stdin more than once. + * Remove decompression support for version 0 files. + * lzip.texi: New chapter 'Trailing data'. + * configure: Avoid warning on some shells when testing for g++. + * Makefile.in: Detect the existence of install-info. + * check.sh: A POSIX shell is required to run the tests. + * check.sh: Don't check error messages. + +2015-07-12 Antonio Diaz Diaz + + * Version 1.17 released. + * Reorganization of the compression code. + * lzip.texi: New chapter 'Quality assurance'. + * Makefile.in: New targets 'install*-compress'. + +2014-08-26 Antonio Diaz Diaz + + * Version 1.16 released. + * Compression ratio of option '-9' has been slightly increased. + * Compression time has been reduced by 4%. + * Compression time of option '-0' has been reduced by 2%. + * main.cc (close_and_set_permissions): Behave like 'cp -p'. + * Minor improvements. + * lzip.texinfo: Rename to lzip.texi. + * Change license to GPL version 2 or later. + +2013-09-20 Antonio Diaz Diaz + + * Version 1.15 released. + * Show progress of compression at verbosity level 2 (-vv). + * main.cc (show_header): Don't show header version. + * Ignore option '-n, --threads' for compatibility with plzip. + * configure: Options now accept a separate argument. + * lzip.texinfo: New chapter 'Stream format' and appendix + 'Reference source code'. + +2013-02-17 Antonio Diaz Diaz + + * Version 1.14 released. + * Multi-step trials have been implemented. + * Compression ratio has been slightly increased. + * Compression time has been reduced by 5%. + * Decompression time has been reduced by 12%. + * Makefile.in: New target 'install-bin'. + * main.cc: Use 'setmode' instead of '_setmode' on Windows and OS/2. + * main.cc: Define 'strtoull' to 'std::strtoul' on Windows. + +2012-02-24 Antonio Diaz Diaz + + * 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. + * Change quote characters in messages as advised by GNU Standards. + * configure: Rename 'datadir' to 'datarootdir'. + * 'unzcrash.cc' has been moved to package 'lziprecover'. + +2011-04-30 Antonio Diaz Diaz + + * Version 1.12 released. + * New option '-F, --recompress'. + * encoder.h (update_prices): Update high length symbol prices + independently of the value of 'pos_state'. This gives better + compression for large values of '--match-length' without being + slower. + * encoder.h, encoder.cc: Optimize pair price calculations, reducing + compression time for large values of '--match-length' by up to 6%. + * Compression time of option '-0' has been reduced by 2%. + * main.cc (decompress): Print only one status line for each + multimember file when only one '-v' is specified. + * main.cc (decompress): Print up to 6 bytes of trailing data when + '-vvvv' is specified. + * main.cc (open_instream): Don't show the message + " and '--stdout' was not specified" for directories, etc. + * lziprecover.cc: If '-v' is not specified show errors only. + * unzcrash.cc: Use Arg_parser. + * unzcrash.cc: New options '-b, --bits', '-p, --position', and + '-s, --size'. + +2010-09-16 Antonio Diaz Diaz + + * Version 1.11 released. + * New option '-0', which produces a compression speed and ratio + comparable to those of 'gzip -9'. + * fast_encoder.h, fast_encoder.cc: New files. + * main.cc: Match length limit set by options -1 to -8 has been + reduced to extend range of use towards gzip. Lower numbers now + compress less but faster. (-1 now takes 43% less time for only 20% + larger compressed size). + Exit with status 1 if any output file exists and is skipped. + * Compression ratio of option '-9' has been slightly increased. + * lziprecover.cc: New option '-m, --merge', which tries to produce a + correct file by merging the good parts of two or more damaged copies. + * lziprecover.cc: New option '-R, --repair' for repairing a + 1-byte error in single-member files. + * decoder.cc (decode_member): Detect file errors earlier to improve + efficiency of lziprecover's new repair capability. + This change also prevents (harmless) access to uninitialized + memory when decompressing a corrupt file. + * lziprecover.cc: New options '-f, --force' and '-o, --output'. + * lziprecover.cc: New option '-s, --split' to select the until now + only operation of splitting multimember files. + * lziprecover.cc: If no operation is specified, warn the user and do + nothing. + * main.cc: Fix warning about fchown's return value being ignored. + * decoder.cc: '-tvvvv' now also shows compression ratio. + * main.cc: Set stdin/stdout in binary mode on MSVC and OS2. + * lzip.texinfo: New examples. + * testsuite: Rename 'test1' to 'test.txt'. New tests. + * Matchfinder types HC4 (4 bytes hash-chain) and HT4 (4 bytes + hash-table) have been tested and found no better than the current + BT4. + +2010-04-05 Antonio Diaz Diaz + + * Version 1.10 released. + * decoder.h: Input_buffer integrated in Range_decoder. + * main.cc: File specified with option '-o' is now created with mode + 0666 if umask allows it, deleted if interrupted by user. + * main.cc: New constant 'o_binary'. + * main.cc: Dictionary size for options -2, -3, -4 and -8 has been + changed to improve linearity of compressed sizes. + * lzip.h: Fix warnings produced by over-optimization (-O3). + * Makefile.in: Add quotes to directory names. + +2010-01-17 Antonio Diaz Diaz + + * Version 1.9 released. + * main.cc (main): Return at least 1 if closing stdout fails. + * Makefile.in: Add option '--name' to help2man invocation. + * check.sh: Use 'test1' instead of 'COPYING' for testing. + +2009-09-02 Antonio Diaz Diaz + + * Version 1.8 released. + * Compression time has been reduced by 4%. + * Lzdiff and lzgrep have been moved to the new package zutils. + * Fix warnings on systems where uint32_t != unsigned int. + +2009-06-25 Antonio Diaz Diaz + + * Version 1.7 released. + * decoder.h (copy_block): Fix memcpy overlap introduced in 1.6. + +2009-06-22 Antonio Diaz Diaz + + * Version 1.6 released. + * Decompression time has been reduced by 17%. + * Add decompression support for Sync Flush marker. + * Add support for the extension '.tbz' to lzdiff and lzgrep. + * Add man pages for lzdiff, lzgrep and lziprecover. + * encoder.cc (Matchfinder): Reduce memory use to 9x if input file is + smaller than dictionary size limit. + * decoder.cc: Add extra flush calls to improve partial decompression + of corrupt files. + * '--test' no longer needs '/dev/null'. + * Remove some 'bashisms' from lzdiff and lzgrep. + * Dictionary size for options '-1' to '-4' has been changed. + * main.cc (signal_handler): Declare as 'extern "C"'. + * Makefile.in: Extra files are now installed by default. + * check.sh: Test lziprecover. + * Add 'export LC_ALL=C' to all scripts. + +2009-04-12 Antonio Diaz Diaz + + * Version 1.5 released. + * lzip.h: Implement coded dictionary size in Lzip_header. + * Fix some includes that prevented compilation with GCC 4.4. + * 'member_size' and 'volume_size' are now accurate limits. + * Compression speed has been improved. + * Implement bt4 type matchfinder. + * lzip.texinfo: New chapter 'Algorithm'. + * Lzdiff and lzgrep now accept '-h' for '--help' and + '-V' for '--version'. + * Makefile.in: Man page is now installed by default. + * check.sh: Check that files are opened in binary mode. + +2009-01-24 Antonio Diaz Diaz + + * Version 1.4 released. + * Implement compression of version 1 files. + * New options '-b, --member-size', '-S, --volume-size', and + '-o, --output'. + * main.cc: Read from non-regular files if '--stdout' is specified. + * Add 'lziprecover', a member recoverer program. + * unzcrash.cc: Test all 1-byte errors. + +2008-12-21 Antonio Diaz Diaz + + * Version 1.3 released. + * This version automatically chooses the smallest possible + dictionary size for each file during compression, saving memory + during decompression. + * Implement decompression of version 1 files. + * check.sh: Replace 'diff -q' with 'cmp'. + +2008-12-10 Antonio Diaz Diaz + + * Version 1.2 released. + * encoder.cc: A 1-byte read outside allocated memory has been fixed. + * lzip.h: Dictionary size limit has been reduced to 512 MiB because + setting it to 1 GiB causes overflow of a 32 bit integer. + * Add 'lzdiff', a diff/cmp wrapper for gzip, bzip2, lzip and + non-compressed files. + * Add 'lzgrep', a grep wrapper for gzip, bzip2, lzip and + non-compressed files. + * 'make install-info' should now work on Debian and OS X. + +2008-11-17 Antonio Diaz Diaz + + * Version 1.1 released. + * Change short name of option '--dictionary-size' to '-s'. + * Change short name of option '--match-length' to '-m'. + * Change LONG_LONG_MAX to LLONG_MAX. + +2008-10-14 Antonio Diaz Diaz + + * Version 1.0 released. + * '-tvv' shows file version and dictionary size. + +2008-09-30 Antonio Diaz Diaz + + * Version 0.5 released. + * Decompression is now 1% faster. + +2008-09-23 Antonio Diaz Diaz + + * Version 0.4 released. + * Code cleanup for global variable 'verbosity'. + * Regain the compression ratio of 0.2 with 5% faster speed. + * lzip.h: Fix compilation on systems where size_t != unsigned int. + +2008-09-15 Antonio Diaz Diaz + + * Version 0.3 released. + * encoder.cc: Compression is now 15% faster, 1% worse. + * main.cc (main): Make option '-t' override '-c'. + * main.cc (decompress): Show 'done' instead of 'ok' when not testing. + * encoder.h: Use trials[] to return the list of pairs. + +2008-09-09 Antonio Diaz Diaz + + * Version 0.2 released. + * encoder.cc: Small improvements in compression speed. + * Small documentation changes. + +2008-08-20 Antonio Diaz Diaz + + * Version 0.1 released. + + +Copyright (C) 2008-2024 Antonio Diaz Diaz. + +This file is a collection of facts, and thus it is not copyrightable, but just +in case, you have unlimited permission to copy, distribute, and modify it. diff --git a/arg_parser.cc b/arg_parser.cc new file mode 100644 index 0000000..0c04d8e --- /dev/null +++ b/arg_parser.cc @@ -0,0 +1,197 @@ +/* Arg_parser - POSIX/GNU command-line argument parser. (C++ version) + Copyright (C) 2006-2024 Antonio Diaz Diaz. + + This library is free software. Redistribution and use in source and + binary forms, with or without modification, are permitted provided + that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions, and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + This library 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. +*/ + +#include +#include +#include + +#include "arg_parser.h" + + +bool Arg_parser::parse_long_option( const char * const opt, const char * const arg, + const Option options[], int & argind ) + { + unsigned len; + int index = -1; + bool exact = false, ambig = false; + + for( len = 0; opt[len+2] && opt[len+2] != '='; ++len ) ; + + // Test all long options for either exact match or abbreviated matches. + for( int i = 0; options[i].code != 0; ++i ) + if( options[i].long_name && + std::strncmp( options[i].long_name, &opt[2], len ) == 0 ) + { + if( std::strlen( options[i].long_name ) == len ) // Exact match found + { index = i; exact = true; break; } + else if( index < 0 ) index = i; // First nonexact match found + else if( options[index].code != options[i].code || + options[index].has_arg != options[i].has_arg ) + ambig = true; // Second or later nonexact match found + } + + if( ambig && !exact ) + { + error_ = "option '"; error_ += opt; error_ += "' is ambiguous"; + return false; + } + + if( index < 0 ) // nothing found + { + error_ = "unrecognized option '"; error_ += opt; error_ += '\''; + return false; + } + + ++argind; + data.push_back( Record( options[index].code, options[index].long_name ) ); + + if( opt[len+2] ) // '--=' syntax + { + if( options[index].has_arg == no ) + { + error_ = "option '--"; error_ += options[index].long_name; + error_ += "' doesn't allow an argument"; + return false; + } + if( options[index].has_arg == yes && !opt[len+3] ) + { + error_ = "option '--"; error_ += options[index].long_name; + error_ += "' requires an argument"; + return false; + } + data.back().argument = &opt[len+3]; + return true; + } + + if( options[index].has_arg == yes ) + { + if( !arg || !arg[0] ) + { + error_ = "option '--"; error_ += options[index].long_name; + error_ += "' requires an argument"; + return false; + } + ++argind; data.back().argument = arg; + return true; + } + + return true; + } + + +bool Arg_parser::parse_short_option( const char * const opt, const char * const arg, + const Option options[], int & argind ) + { + int cind = 1; // character index in opt + + while( cind > 0 ) + { + int index = -1; + const unsigned char c = opt[cind]; + + if( c != 0 ) + for( int i = 0; options[i].code; ++i ) + if( c == options[i].code ) + { index = i; break; } + + if( index < 0 ) + { + error_ = "invalid option -- '"; error_ += c; error_ += '\''; + return false; + } + + data.push_back( Record( c ) ); + if( opt[++cind] == 0 ) { ++argind; cind = 0; } // opt finished + + if( options[index].has_arg != no && cind > 0 && opt[cind] ) + { + data.back().argument = &opt[cind]; ++argind; cind = 0; + } + else if( options[index].has_arg == yes ) + { + if( !arg || !arg[0] ) + { + error_ = "option requires an argument -- '"; error_ += c; + error_ += '\''; + return false; + } + data.back().argument = arg; ++argind; cind = 0; + } + } + return true; + } + + +Arg_parser::Arg_parser( const int argc, const char * const argv[], + const Option options[], const bool in_order ) + { + if( argc < 2 || !argv || !options ) return; + + std::vector< const char * > non_options; // skipped non-options + int argind = 1; // index in argv + + while( argind < argc ) + { + const unsigned char ch1 = argv[argind][0]; + const unsigned char ch2 = ch1 ? argv[argind][1] : 0; + + if( ch1 == '-' && ch2 ) // we found an option + { + const char * const opt = argv[argind]; + const char * const arg = ( argind + 1 < argc ) ? argv[argind+1] : 0; + if( ch2 == '-' ) + { + if( !argv[argind][2] ) { ++argind; break; } // we found "--" + else if( !parse_long_option( opt, arg, options, argind ) ) break; + } + else if( !parse_short_option( opt, arg, options, argind ) ) break; + } + else + { + if( in_order ) data.push_back( Record( argv[argind++] ) ); + else non_options.push_back( argv[argind++] ); + } + } + if( !error_.empty() ) data.clear(); + else + { + for( unsigned i = 0; i < non_options.size(); ++i ) + data.push_back( Record( non_options[i] ) ); + while( argind < argc ) + data.push_back( Record( argv[argind++] ) ); + } + } + + +Arg_parser::Arg_parser( const char * const opt, const char * const arg, + const Option options[] ) + { + if( !opt || !opt[0] || !options ) return; + + if( opt[0] == '-' && opt[1] ) // we found an option + { + int argind = 1; // dummy + if( opt[1] == '-' ) + { if( opt[2] ) parse_long_option( opt, arg, options, argind ); } + else + parse_short_option( opt, arg, options, argind ); + if( !error_.empty() ) data.clear(); + } + else data.push_back( Record( opt ) ); + } diff --git a/arg_parser.h b/arg_parser.h new file mode 100644 index 0000000..1eeec9a --- /dev/null +++ b/arg_parser.h @@ -0,0 +1,110 @@ +/* Arg_parser - POSIX/GNU command-line argument parser. (C++ version) + Copyright (C) 2006-2024 Antonio Diaz Diaz. + + This library is free software. Redistribution and use in source and + binary forms, with or without modification, are permitted provided + that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions, and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + This library 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. +*/ + +/* 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. + + 'options' is an array of 'struct Option' terminated by an element + containing a code which is zero. A null long_name means a short-only + option. A code value outside the unsigned char range means a long-only + option. + + Arg_parser normally makes it appear as if all the option arguments + 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 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 '-' + (without whitespace), or '--='. +*/ + +class Arg_parser + { +public: + enum Has_arg { no, yes, maybe }; + + struct Option + { + int code; // Short option letter or code ( code != 0 ) + const char * long_name; // Long option name (maybe null) + Has_arg has_arg; + }; + +private: + struct Record + { + int code; + std::string parsed_name; + std::string argument; + explicit Record( const unsigned char c ) + : code( c ), parsed_name( "-" ) { parsed_name += c; } + Record( const int c, const char * const long_name ) + : code( c ), parsed_name( "--" ) { parsed_name += long_name; } + explicit Record( const char * const arg ) : code( 0 ), argument( arg ) {} + }; + + const std::string empty_arg; + std::string error_; + std::vector< Record > data; + + bool parse_long_option( const char * const opt, const char * const arg, + const Option options[], int & argind ); + bool parse_short_option( const char * const opt, const char * const arg, + const Option options[], int & argind ); + +public: + Arg_parser( const int argc, const char * const argv[], + const Option options[], const bool in_order = false ); + + // Restricted constructor. Parses a single token and argument (if any). + Arg_parser( const char * const opt, const char * const arg, + const Option options[] ); + + const std::string & error() const { return error_; } + + // The number of arguments parsed. May be different from argc. + 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 + { + if( i >= 0 && i < arguments() ) return data[i].code; + else return 0; + } + + // Full name of the option parsed (short or long). + const std::string & parsed_name( const int i ) const + { + if( i >= 0 && i < arguments() ) return data[i].parsed_name; + else return empty_arg; + } + + const std::string & argument( const int i ) const + { + if( i >= 0 && i < arguments() ) return data[i].argument; + else return empty_arg; + } + }; diff --git a/configure b/configure new file mode 100644 index 0000000..012fb5c --- /dev/null +++ b/configure @@ -0,0 +1,231 @@ +#! /bin/sh +# configure script for Lzip - LZMA lossless data compressor +# Copyright (C) 2008-2024 Antonio Diaz Diaz. +# +# This configure script is free software: you have unlimited permission +# to copy, distribute, and modify it. + +pkgname=lzip +pkgversion=1.24 +progname=lzip +srctrigger=doc/${pkgname}.texi + +# clear some things potentially inherited from environment. +LC_ALL=C +export LC_ALL +srcdir= +prefix=/usr/local +exec_prefix='$(prefix)' +bindir='$(exec_prefix)/bin' +datarootdir='$(prefix)/share' +infodir='$(datarootdir)/info' +mandir='$(datarootdir)/man' +build=no +check=no +installdir= +CXX=g++ +CPPFLAGS= +CXXFLAGS='-Wall -W -O2' +LDFLAGS= +MAKEINFO=makeinfo + +# checking whether we are using GNU C++. +/bin/sh -c "${CXX} --version" > /dev/null 2>&1 || { CXX=c++ ; CXXFLAGS=-O2 ; } + +# Loop over all args +args= +no_create= +while [ $# != 0 ] ; do + + # Get the first arg, and shuffle + option=$1 ; arg2=no + shift + + # Add the argument quoted to args + if [ -z "${args}" ] ; then args="\"${option}\"" + else args="${args} \"${option}\"" ; fi + + # Split out the argument for options that take them + case ${option} in + *=*) optarg=`echo "${option}" | sed -e 's,^[^=]*=,,;s,/$,,'` ;; + esac + + # Process the options + case ${option} in + --help | -h) + echo "Usage: $0 [OPTION]... [VAR=VALUE]..." + echo + echo "To assign makefile variables (e.g., CXX, CXXFLAGS...), specify them as" + echo "arguments to configure in the form VAR=VALUE." + echo + echo "Options and variables: [defaults in brackets]" + echo " -h, --help display this help and exit" + echo " -V, --version output version information and exit" + echo " --srcdir=DIR find the source code in DIR [. or ..]" + 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 " --datarootdir=DIR base directory for doc and data [${datarootdir}]" + echo " --infodir=DIR info files directory [${infodir}]" + echo " --mandir=DIR man pages directory [${mandir}]" + echo " --build build in one step without using 'make'" + echo " --check check without using 'make', implies --build" + echo " --installdir=BINDIR install without using 'make', implies --build" + echo " CXX=COMPILER C++ compiler to use [${CXX}]" + echo " CPPFLAGS=OPTIONS command-line options for the preprocessor [${CPPFLAGS}]" + echo " CXXFLAGS=OPTIONS command-line options for the C++ compiler [${CXXFLAGS}]" + echo " CXXFLAGS+=OPTIONS append options to the current value of CXXFLAGS" + echo " LDFLAGS=OPTIONS command-line options for the linker [${LDFLAGS}]" + echo " MAKEINFO=NAME makeinfo program to use [${MAKEINFO}]" + echo + exit 0 ;; + --version | -V) + echo "Configure script for ${pkgname} version ${pkgversion}" + exit 0 ;; + --srcdir) srcdir=$1 ; arg2=yes ;; + --prefix) prefix=$1 ; arg2=yes ;; + --exec-prefix) exec_prefix=$1 ; arg2=yes ;; + --bindir) bindir=$1 ; arg2=yes ;; + --datarootdir) datarootdir=$1 ; arg2=yes ;; + --infodir) infodir=$1 ; arg2=yes ;; + --mandir) mandir=$1 ; arg2=yes ;; + --installdir) installdir=$1 ; arg2=yes ;; + + --srcdir=*) srcdir=${optarg} ;; + --prefix=*) prefix=${optarg} ;; + --exec-prefix=*) exec_prefix=${optarg} ;; + --bindir=*) bindir=${optarg} ;; + --datarootdir=*) datarootdir=${optarg} ;; + --infodir=*) infodir=${optarg} ;; + --mandir=*) mandir=${optarg} ;; + --build) build=yes ;; + --check) check=yes ; build=yes ;; + --installdir=*) installdir=${optarg} ; build=yes ;; + --no-create) no_create=yes ;; + + CXX=*) CXX=${optarg} ;; + CPPFLAGS=*) CPPFLAGS=${optarg} ;; + CXXFLAGS=*) CXXFLAGS=${optarg} ;; + CXXFLAGS+=*) CXXFLAGS="${CXXFLAGS} ${optarg}" ;; + LDFLAGS=*) LDFLAGS=${optarg} ;; + MAKEINFO=*) MAKEINFO=${optarg} ;; + + --*) + echo "configure: WARNING: unrecognized option: '${option}'" 1>&2 ;; + *=* | *-*-*) ;; + *) + echo "configure: unrecognized option: '${option}'" 1>&2 + echo "Try 'configure --help' for more information." 1>&2 + exit 1 ;; + esac + + # Check if the option took a separate argument + if [ "${arg2}" = yes ] ; then + if [ $# != 0 ] ; then args="${args} \"$1\"" ; shift + else echo "configure: Missing argument to '${option}'" 1>&2 + exit 1 + fi + fi +done + +# Find the source code, if location was not specified. +srcdirtext= +if [ -z "${srcdir}" ] ; then + srcdirtext="or . or .." ; srcdir=. + 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 + echo "configure: Can't find source code in ${srcdir} ${srcdirtext}" 1>&2 + echo "configure: (At least ${srctrigger} is missing)." 1>&2 + exit 1 +fi + +# Set srcdir to . if that's what it is. +if [ "`pwd`" = "`cd "${srcdir}" ; pwd`" ] ; then srcdir=. ; fi + +if [ "${build}" = yes ] ; then + objs=$(sed -e :a -e '/\\$/N; s/\\\n//; ta' "${srcdir}/Makefile.in" | \ + sed -n -e 's/^ *objs *= *//p' | sed -e 's/ \{2,\}/ /g') + for ofile in ${objs} ; do + file="${ofile%.o}.cc" ; pver= + [ "${ofile}" = main.o ] && pver=" -DPROGVERSION=\"${pkgversion}\"" + compile_command="${CXX} ${CPPFLAGS} ${CXXFLAGS}${pver} -c -o ${ofile}" + echo "${compile_command} ${srcdir}/${file}" + ${compile_command} "${srcdir}/${file}" || exit 1 + done + link_command="${CXX} ${LDFLAGS} ${CXXFLAGS} -o ${progname} ${objs}" + echo "${link_command}" ; ${link_command} || exit 1 + if [ "${check}" = yes ] ; then + "${srcdir}/testsuite/check.sh" "${srcdir}/testsuite" ${pkgversion} || exit 1 + fi + if [ -n "${installdir}" ] ; then + echo "installing ${progname} in ${installdir}" + [ -d "${installdir}" ] || mkdir -p "${installdir}" || exit 1 + cp -fp ${progname} "${installdir}/${progname}" || exit 1 + fi + exit 0 +fi + +echo +if [ -z "${no_create}" ] ; then + echo "creating config.status" + rm -f config.status + cat > config.status << EOF +#! /bin/sh +# This file was generated automatically by configure. Don't edit. +# Run this file to recreate the current configuration. +# +# This script is free software: you have unlimited permission +# to copy, distribute, and modify it. + +exec /bin/sh "$0" ${args} --no-create +EOF + chmod +x config.status +fi + +echo "creating Makefile" +echo "VPATH = ${srcdir}" +echo "prefix = ${prefix}" +echo "exec_prefix = ${exec_prefix}" +echo "bindir = ${bindir}" +echo "datarootdir = ${datarootdir}" +echo "infodir = ${infodir}" +echo "mandir = ${mandir}" +echo "CXX = ${CXX}" +echo "CPPFLAGS = ${CPPFLAGS}" +echo "CXXFLAGS = ${CXXFLAGS}" +echo "LDFLAGS = ${LDFLAGS}" +echo "MAKEINFO = ${MAKEINFO}" +rm -f Makefile +cat > Makefile << EOF +# Makefile for Lzip - LZMA lossless data compressor +# Copyright (C) 2008-2024 Antonio Diaz Diaz. +# This file was generated automatically by configure. Don't edit. +# +# This Makefile is free software: you have unlimited permission +# to copy, distribute, and modify it. + +pkgname = ${pkgname} +pkgversion = ${pkgversion} +progname = ${progname} +VPATH = ${srcdir} +prefix = ${prefix} +exec_prefix = ${exec_prefix} +bindir = ${bindir} +datarootdir = ${datarootdir} +infodir = ${infodir} +mandir = ${mandir} +CXX = ${CXX} +CPPFLAGS = ${CPPFLAGS} +CXXFLAGS = ${CXXFLAGS} +LDFLAGS = ${LDFLAGS} +MAKEINFO = ${MAKEINFO} +EOF +cat "${srcdir}/Makefile.in" >> Makefile + +echo "OK. Now you can run make."