diff options
Diffstat (limited to 'main.cc')
-rw-r--r-- | main.cc | 106 |
1 files changed, 65 insertions, 41 deletions
@@ -130,8 +130,7 @@ void show_help( const long num_online ) "The bidimensional parameter space of LZMA can't be mapped to a linear\n" "scale optimal for all files. If your files are large, very repetitive,\n" "etc, you may need to use the --match-length and --dictionary-size\n" - "options directly to achieve optimal performance. For example, -9m64\n" - "usually compresses executables more (and faster) than -9.\n" + "options directly to achieve optimal performance.\n" "\nExit status: 0 for a normal exit, 1 for environmental problems (file\n" "not found, invalid flags, I/O errors, etc), 2 to indicate a corrupt or\n" "invalid input file, 3 for an internal consistency error (eg, bug) which\n" @@ -152,6 +151,28 @@ void show_version() "There is NO WARRANTY, to the extent permitted by law.\n" ); } +} // end namespace + +void show_header( const unsigned dictionary_size ) + { + if( verbosity >= 3 ) + { + const char * const prefix[8] = + { "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi" }; + enum { factor = 1024 }; + const char * p = ""; + const char * np = " "; + unsigned num = dictionary_size; + bool exact = ( num % factor == 0 ); + + for( int i = 0; i < 8 && ( num > 9999 || ( exact && num >= factor ) ); ++i ) + { num /= factor; if( num % factor != 0 ) exact = false; + p = prefix[i]; np = ""; } + std::fprintf( stderr, "dictionary size %s%4u %sB. ", np, num, p ); + } + } + +namespace { unsigned long long getnum( const char * const ptr, const unsigned long long llimit, @@ -323,7 +344,7 @@ bool open_outstream( const bool force ) bool check_tty( const int infd, const Mode program_mode ) { - if( program_mode == m_compress && outfd >= 0 && isatty( outfd ) ) + if( program_mode == m_compress && isatty( outfd ) ) { show_error( "I won't write compressed data to a terminal.", 0, true ); return false; @@ -337,6 +358,32 @@ bool check_tty( const int infd, const Mode program_mode ) return true; } +} // end namespace + +// This can be called from any thread, main thread or sub-threads alike, +// since they all call common helper functions that call cleanup_and_fail() +// in case of an error. +// +void cleanup_and_fail( const int retval ) + { + // only one thread can delete and exit + static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + + pthread_mutex_lock( &mutex ); // ignore errors to avoid loop + if( delete_output_on_interrupt ) + { + delete_output_on_interrupt = false; + if( verbosity >= 0 ) + std::fprintf( stderr, "%s: Deleting output file '%s', if it exists.\n", + program_name, output_filename.c_str() ); + if( outfd >= 0 ) { close( outfd ); outfd = -1; } + if( std::remove( output_filename.c_str() ) != 0 && errno != ENOENT ) + show_error( "WARNING: deletion of output file (apparently) failed." ); + } + std::exit( retval ); + } + +namespace { // Set permissions, owner and times. void close_and_set_permissions( const struct stat * const in_statsp ) @@ -431,30 +478,6 @@ void internal_error( const char * const msg ) } -// This can be called from any thread, main thread or sub-threads alike, -// since they all call common helper functions that call cleanup_and_fail() -// in case of an error. -// -void cleanup_and_fail( const int retval ) - { - // only one thread can delete and exit - static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; - - pthread_mutex_lock( &mutex ); // ignore errors to avoid loop - if( delete_output_on_interrupt ) - { - delete_output_on_interrupt = false; - if( verbosity >= 0 ) - std::fprintf( stderr, "%s: Deleting output file '%s', if it exists.\n", - program_name, output_filename.c_str() ); - if( outfd >= 0 ) { close( outfd ); outfd = -1; } - if( std::remove( output_filename.c_str() ) != 0 && errno != ENOENT ) - show_error( "WARNING: deletion of output file (apparently) failed." ); - } - std::exit( retval ); - } - - void show_progress( const int packet_size, const Pretty_print * const p, const unsigned long long cfile_size ) @@ -464,17 +487,20 @@ void show_progress( const int packet_size, static const Pretty_print * pp = 0; static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; - if( p ) // initialize static vars - { csize = cfile_size; pos = 0; pp = p; } - if( pp ) + if( verbosity >= 2 ) { - xlock( &mutex ); - pos += packet_size; - if( csize > 0 ) - std::fprintf( stderr, "%4llu%%", pos / csize ); - std::fprintf( stderr, " %.1f MB\r", pos / 1000000.0 ); - pp->reset(); (*pp)(); // restore cursor position - xunlock( &mutex ); + if( p ) // initialize static vars + { csize = cfile_size; pos = 0; pp = p; } + if( pp ) + { + xlock( &mutex ); + pos += packet_size; + if( csize > 0 ) + std::fprintf( stderr, "%4llu%%", pos / csize ); + std::fprintf( stderr, " %.1f MB\r", pos / 1000000.0 ); + pp->reset(); (*pp)(); // restore cursor position + xunlock( &mutex ); + } } } @@ -688,15 +714,13 @@ int main( const int argc, const char * const argv[] ) int tmp; if( program_mode == m_compress ) { - if( verbosity >= 2 ) // init - show_progress( 0, &pp, infd_isreg ? in_statsp->st_size / 100 : 0 ); + show_progress( 0, &pp, infd_isreg ? in_statsp->st_size / 100 : 0 ); // init 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, infd_isreg ); + tmp = decompress( num_workers, infd, outfd, pp, debug_level, infd_isreg ); if( tmp > retval ) retval = tmp; if( tmp && program_mode != m_test ) cleanup_and_fail( retval ); |