Adding upstream version 1.0~rc1.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
a92d8a2cdd
commit
d49eb8d954
24 changed files with 1438 additions and 882 deletions
92
main.cc
92
main.cc
|
@ -1,6 +1,6 @@
|
|||
/* Plzip - A parallel compressor compatible with lzip
|
||||
Copyright (C) 2009 Laszlo Ersek.
|
||||
Copyright (C) 2009, 2010, 2011, 2012 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009, 2010, 2011, 2012, 2013 Antonio Diaz Diaz.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -34,15 +34,30 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
#include <fcntl.h>
|
||||
#include <inttypes.h>
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <utime.h>
|
||||
#include <sys/stat.h>
|
||||
#include <lzlib.h>
|
||||
#if defined(__MSVCRT__)
|
||||
#include <io.h>
|
||||
#define fchmod(x,y) 0
|
||||
#define fchown(x,y,z) 0
|
||||
#define strtoull std::strtoul
|
||||
#define SIGHUP SIGTERM
|
||||
#define S_ISSOCK(x) 0
|
||||
#define S_IRGRP 0
|
||||
#define S_IWGRP 0
|
||||
#define S_IROTH 0
|
||||
#define S_IWOTH 0
|
||||
#endif
|
||||
#if defined(__OS2__)
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#include "arg_parser.h"
|
||||
#include "plzip.h"
|
||||
#include "lzip.h"
|
||||
|
||||
#if CHAR_BIT != 8
|
||||
#error "Environments where CHAR_BIT != 8 are not supported."
|
||||
|
@ -53,7 +68,7 @@ namespace {
|
|||
|
||||
const char * const Program_name = "Plzip";
|
||||
const char * const program_name = "plzip";
|
||||
const char * const program_year = "2012";
|
||||
const char * const program_year = "2013";
|
||||
const char * invocation_name = 0;
|
||||
|
||||
#ifdef O_BINARY
|
||||
|
@ -85,7 +100,7 @@ pthread_t main_thread;
|
|||
pid_t main_thread_pid;
|
||||
|
||||
|
||||
void show_help()
|
||||
void show_help( const long num_online )
|
||||
{
|
||||
std::printf( "%s - A parallel compressor compatible with lzip.\n", Program_name );
|
||||
std::printf( "\nUsage: %s [options] [files]\n", invocation_name );
|
||||
|
@ -99,7 +114,7 @@ void show_help()
|
|||
" -F, --recompress force recompression of compressed files\n"
|
||||
" -k, --keep keep (don't delete) input files\n"
|
||||
" -m, --match-length=<bytes> set match length limit in bytes [36]\n"
|
||||
" -n, --threads=<n> set the number of (de)compression threads\n"
|
||||
" -n, --threads=<n> set number of (de)compression threads [%ld]\n"
|
||||
" -o, --output=<file> if reading stdin, place the output into <file>\n"
|
||||
" -q, --quiet suppress all messages\n"
|
||||
" -s, --dictionary-size=<bytes> set dictionary size limit in bytes [8MiB]\n"
|
||||
|
@ -107,7 +122,7 @@ void show_help()
|
|||
" -v, --verbose be verbose (a 2nd -v gives more)\n"
|
||||
" -1 .. -9 set compression level [default 6]\n"
|
||||
" --fast alias for -1\n"
|
||||
" --best alias for -9\n" );
|
||||
" --best alias for -9\n", num_online );
|
||||
if( verbosity > 0 )
|
||||
{
|
||||
std::printf( " -D, --debug=<level> (0-1) print debug statistics to stderr\n" );
|
||||
|
@ -137,13 +152,13 @@ void show_version()
|
|||
}
|
||||
|
||||
|
||||
long long getnum( const char * const ptr,
|
||||
const long long llimit = LLONG_MIN + 1,
|
||||
const long long ulimit = LLONG_MAX )
|
||||
unsigned long long getnum( const char * const ptr,
|
||||
const unsigned long long llimit,
|
||||
const unsigned long long ulimit )
|
||||
{
|
||||
errno = 0;
|
||||
char *tail;
|
||||
long long result = strtoll( ptr, &tail, 0 );
|
||||
char * tail;
|
||||
unsigned long long result = strtoull( ptr, &tail, 0 );
|
||||
if( tail == ptr )
|
||||
{
|
||||
show_error( "Bad or missing numerical argument.", 0, true );
|
||||
|
@ -178,7 +193,7 @@ long long getnum( const char * const ptr,
|
|||
}
|
||||
for( int i = 0; i < exponent; ++i )
|
||||
{
|
||||
if( LLONG_MAX / factor >= llabs( result ) ) result *= factor;
|
||||
if( ulimit / factor >= result ) result *= factor;
|
||||
else { errno = ERANGE; break; }
|
||||
}
|
||||
}
|
||||
|
@ -194,7 +209,7 @@ long long getnum( const char * const ptr,
|
|||
|
||||
int get_dict_size( const char * const arg )
|
||||
{
|
||||
char *tail;
|
||||
char * tail;
|
||||
int bits = std::strtol( arg, &tail, 0 );
|
||||
if( bits >= LZ_min_dictionary_bits() &&
|
||||
bits <= LZ_max_dictionary_bits() && *tail == 0 )
|
||||
|
@ -240,7 +255,7 @@ int open_instream( const std::string & name, struct stat * const in_statsp,
|
|||
else
|
||||
{
|
||||
const int i = fstat( infd, in_statsp );
|
||||
const mode_t & mode = in_statsp->st_mode;
|
||||
const mode_t mode = in_statsp->st_mode;
|
||||
const bool can_read = ( i == 0 &&
|
||||
( S_ISBLK( mode ) || S_ISCHR( mode ) ||
|
||||
S_ISFIFO( mode ) || S_ISSOCK( mode ) ) );
|
||||
|
@ -368,9 +383,9 @@ extern "C" void signal_handler( int sig )
|
|||
{
|
||||
if( !pthread_equal( pthread_self(), main_thread ) )
|
||||
kill( main_thread_pid, sig );
|
||||
if( sig != SIGUSR1 )
|
||||
if( sig != SIGUSR1 && sig != SIGUSR2 )
|
||||
show_error( "Control-C or similar caught, quitting." );
|
||||
cleanup_and_fail( 1 );
|
||||
cleanup_and_fail( ( sig != SIGUSR2 ) ? 1 : 2 );
|
||||
}
|
||||
|
||||
|
||||
|
@ -391,7 +406,8 @@ int verbosity = 0;
|
|||
// since they all call common helper functions that call fatal() in case
|
||||
// of an error.
|
||||
//
|
||||
void fatal() { signal_handler( SIGUSR1 ); }
|
||||
void fatal( const int retval )
|
||||
{ signal_handler( ( retval != 2 ) ? SIGUSR1 : SIGUSR2 ); }
|
||||
|
||||
|
||||
void Pretty_print::operator()( const char * const msg ) const
|
||||
|
@ -402,7 +418,7 @@ void Pretty_print::operator()( const char * const msg ) const
|
|||
{
|
||||
first_post = false;
|
||||
std::fprintf( stderr, " %s: ", name_.c_str() );
|
||||
for( unsigned int i = 0; i < longest_name - name_.size(); ++i )
|
||||
for( unsigned i = 0; i < longest_name - name_.size(); ++i )
|
||||
std::fprintf( stderr, " " );
|
||||
if( !msg ) std::fflush( stderr );
|
||||
}
|
||||
|
@ -422,7 +438,7 @@ void show_error( const char * const msg, const int errcode, const bool help )
|
|||
std::fprintf( stderr, ": %s", std::strerror( errcode ) );
|
||||
std::fprintf( stderr, "\n" );
|
||||
}
|
||||
if( help && invocation_name && invocation_name[0] )
|
||||
if( help )
|
||||
std::fprintf( stderr, "Try '%s --help' for more information.\n",
|
||||
invocation_name );
|
||||
}
|
||||
|
@ -454,6 +470,9 @@ int main( const int argc, const char * const argv[] )
|
|||
{ 3 << 23, 132 }, // -8
|
||||
{ 1 << 25, 273 } }; // -9
|
||||
Lzma_options encoder_options = option_mapping[6]; // default = "-6"
|
||||
std::string input_filename;
|
||||
std::string default_output_filename;
|
||||
std::vector< std::string > filenames;
|
||||
int data_size = 0;
|
||||
int debug_level = 0;
|
||||
int infd = -1;
|
||||
|
@ -463,9 +482,6 @@ int main( const int argc, const char * const argv[] )
|
|||
bool keep_input_files = false;
|
||||
bool recompress = false;
|
||||
bool to_stdout = false;
|
||||
std::string input_filename;
|
||||
std::string default_output_filename;
|
||||
std::vector< std::string > filenames;
|
||||
invocation_name = argv[0];
|
||||
main_thread = pthread_self();
|
||||
main_thread_pid = getpid();
|
||||
|
@ -473,6 +489,7 @@ int main( const int argc, const char * const argv[] )
|
|||
if( LZ_version()[0] != LZ_version_string[0] )
|
||||
internal_error( "bad library version" );
|
||||
|
||||
const long num_online = std::max( 1L, sysconf( _SC_NPROCESSORS_ONLN ) );
|
||||
long max_workers = sysconf( _SC_THREAD_THREADS_MAX );
|
||||
if( max_workers < 1 || max_workers > INT_MAX / (int)sizeof (pthread_t) )
|
||||
max_workers = INT_MAX / sizeof (pthread_t);
|
||||
|
@ -521,7 +538,8 @@ int main( const int argc, const char * const argv[] )
|
|||
const char * const arg = parser.argument( argind ).c_str();
|
||||
switch( code )
|
||||
{
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '0':
|
||||
case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
encoder_options = option_mapping[code-'0']; break;
|
||||
case 'b': break;
|
||||
|
@ -532,7 +550,7 @@ int main( const int argc, const char * const argv[] )
|
|||
case 'D': debug_level = getnum( arg, 0, 3 ); break;
|
||||
case 'f': force = true; break;
|
||||
case 'F': recompress = true; break;
|
||||
case 'h': show_help(); return 0;
|
||||
case 'h': show_help( num_online ); return 0;
|
||||
case 'k': keep_input_files = true; break;
|
||||
case 'm': encoder_options.match_len_limit =
|
||||
getnum( arg, LZ_min_match_len_limit(),
|
||||
|
@ -550,9 +568,9 @@ int main( const int argc, const char * const argv[] )
|
|||
}
|
||||
} // end process options
|
||||
|
||||
#if defined(__OS2__)
|
||||
_fsetmode( stdin, "b" );
|
||||
_fsetmode( stdout, "b" );
|
||||
#if defined(__MSVCRT__) || defined(__OS2__)
|
||||
setmode( STDIN_FILENO, O_BINARY );
|
||||
setmode( STDOUT_FILENO, O_BINARY );
|
||||
#endif
|
||||
|
||||
if( program_mode == m_test )
|
||||
|
@ -564,17 +582,13 @@ int main( const int argc, const char * const argv[] )
|
|||
encoder_options.dictionary_size = std::max( data_size, LZ_min_dictionary_size() );
|
||||
|
||||
if( num_workers <= 0 )
|
||||
{
|
||||
long num_online = sysconf( _SC_NPROCESSORS_ONLN );
|
||||
if( num_online <= 0 ) num_online = 1;
|
||||
num_workers = std::min( num_online, max_workers );
|
||||
}
|
||||
|
||||
bool filenames_given = false;
|
||||
for( ; argind < parser.arguments(); ++argind )
|
||||
{
|
||||
if( parser.argument( argind ) != "-" ) filenames_given = true;
|
||||
filenames.push_back( parser.argument( argind ) );
|
||||
if( filenames.back() != "-" ) filenames_given = true;
|
||||
}
|
||||
|
||||
if( filenames.empty() ) filenames.push_back("-");
|
||||
|
@ -582,11 +596,12 @@ int main( const int argc, const char * const argv[] )
|
|||
( filenames_given || default_output_filename.size() ) )
|
||||
set_signals();
|
||||
std::signal( SIGUSR1, signal_handler );
|
||||
std::signal( SIGUSR2, signal_handler );
|
||||
|
||||
Pretty_print pp( filenames );
|
||||
|
||||
int retval = 0;
|
||||
for( unsigned int i = 0; i < filenames.size(); ++i )
|
||||
for( unsigned i = 0; i < filenames.size(); ++i )
|
||||
{
|
||||
struct stat in_stats;
|
||||
output_filename.clear();
|
||||
|
@ -607,7 +622,7 @@ int main( const int argc, const char * const argv[] )
|
|||
outfd_mode = all_rw;
|
||||
if( !open_outstream( force ) )
|
||||
{
|
||||
if( outfd == -1 && retval < 1 ) retval = 1;
|
||||
if( retval < 1 ) retval = 1;
|
||||
close( infd ); infd = -1;
|
||||
continue;
|
||||
}
|
||||
|
@ -632,7 +647,7 @@ int main( const int argc, const char * const argv[] )
|
|||
outfd_mode = usr_rw;
|
||||
if( !open_outstream( force ) )
|
||||
{
|
||||
if( outfd == -1 && retval < 1 ) retval = 1;
|
||||
if( retval < 1 ) retval = 1;
|
||||
close( infd ); infd = -1;
|
||||
continue;
|
||||
}
|
||||
|
@ -645,16 +660,17 @@ int main( const int argc, const char * const argv[] )
|
|||
if( output_filename.size() && !to_stdout && program_mode != m_test )
|
||||
delete_output_on_interrupt = true;
|
||||
const struct stat * const in_statsp = input_filename.size() ? &in_stats : 0;
|
||||
const bool infd_isreg = in_statsp && S_ISREG( in_statsp->st_mode );
|
||||
pp.set_name( input_filename );
|
||||
if( verbosity >= 1 ) pp();
|
||||
int tmp = 0;
|
||||
int tmp;
|
||||
if( program_mode == m_compress )
|
||||
tmp = compress( data_size, encoder_options.dictionary_size,
|
||||
encoder_options.match_len_limit,
|
||||
num_workers, infd, outfd, pp, debug_level );
|
||||
else
|
||||
tmp = decompress( num_workers, infd, outfd, pp, debug_level,
|
||||
program_mode == m_test );
|
||||
program_mode == m_test, infd_isreg );
|
||||
if( tmp > retval ) retval = tmp;
|
||||
if( tmp && program_mode != m_test ) cleanup_and_fail( retval );
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue