diff options
Diffstat (limited to '')
-rw-r--r-- | rc.cc | 88 |
1 files changed, 56 insertions, 32 deletions
@@ -36,13 +36,13 @@ int verbosity = 0; namespace { -const char * const config_file_name = "zutilsrc"; +const char * const config_file_name = "zutils.conf"; const char * const program_year = "2022"; std::string compressor_names[num_formats] = { "bzip2", "gzip", "lzip", "xz", "zstd" }; // default compressor names -// args to compressors read from rc or from options like --lz, maybe empty +// args to compressors read from .conf or from options like --lz, maybe empty std::vector< std::string > compressor_args[num_formats]; // vector of enabled formats plus [num_formats] for uncompressed. @@ -189,7 +189,7 @@ bool parse_rc_line( const std::string & line, } - // Return 0 if success, 1 if file not found, 2 if syntax error. + // Return 0 if success, 1 if file not found, 2 if syntax or I/O error. int process_rcfile( const std::string & name ) { FILE * const f = std::fopen( name.c_str(), "r" ); @@ -205,24 +205,42 @@ int process_rcfile( const std::string & name ) if( !parse_rc_line( line, name.c_str(), linenum ) ) { retval = 2; break; } } - std::fclose( f ); + if( std::fclose( f ) != 0 && retval == 0 ) + { show_file_error( name.c_str(), "Error closing config file", errno ); + retval = 2; } return retval; } + +void show_using_version( const char * const command ) + { + FILE * const f = popen( command, "r" ); + if( f ) + { + char command_version[1024] = { 0 }; + const int rd = std::fread( command_version, 1, sizeof command_version, f ); + pclose( f ); + int i = 0; + while( i + 1 < rd && command_version[i] != '\n' ) ++i; + command_version[i] = 0; + if( command_version[0] ) std::printf( "Using %s\n", command_version ); + } + } + } // end namespace bool enabled_format( const int format_index ) { if( enabled_formats.size() <= num_formats ) return true; // all enabled - if( format_index < 0 ) return enabled_formats[num_formats]; // uncompressed + if( format_index < 0 || format_index >= num_formats ) + return enabled_formats[num_formats]; // uncompressed return enabled_formats[format_index]; } void parse_format_list( const std::string & arg, const char * const pn ) { - const std::string un( "uncompressed" ); bool error = arg.empty(); enabled_formats.assign( num_formats + 1, false ); @@ -235,26 +253,25 @@ void parse_format_list( const std::string & arg, const char * const pn ) for( int i = 0; i < num_formats; ++i ) if( s == format_names[i] ) { format_index = i; break; } - if( format_index == num_formats && un.find( s ) != 0 ) + if( format_index == num_formats && s != "un" ) // uncompressed { error = true; break; } enabled_formats[format_index] = true; } if( !error ) return; - if( verbosity >= 0 ) - std::fprintf( stderr, "%s: Bad argument in option '%s'.\n", - program_name, pn ); + show_option_error( arg.c_str(), "Invalid format in", pn ); std::exit( 1 ); } -int parse_format_type( const std::string & arg, const char * const pn ) +int parse_format_type( const std::string & arg, const char * const pn, + const bool allow_uncompressed ) { for( int i = 0; i < num_formats; ++i ) if( arg == format_names[i] ) return i; - if( verbosity >= 0 ) - std::fprintf( stderr, "%s: Bad argument in option '%s'.\n", - program_name, pn ); + if( allow_uncompressed && arg == "un" ) return num_formats; + show_option_error( arg.c_str(), ( arg.find( ',' ) < arg.size() ) ? + "Too many formats in" : "Invalid format in", pn ); std::exit( 1 ); } @@ -286,10 +303,11 @@ void maybe_process_config_file( const Arg_parser & parser ) for( int i = 0; i < parser.arguments(); ++i ) if( parser.code( i ) == 'N' ) return; std::string name; - const char * p = std::getenv( "HOME" ); if( p ) name = p; + const char * p = std::getenv( "XDG_CONFIG_HOME" ); if( p ) name = p; + else { p = std::getenv( "HOME" ); if( p ) { name = p; name += "/.config"; } } if( name.size() ) { - name += "/."; name += config_file_name; + name += '/'; name += config_file_name; const int retval = process_rcfile( name ); if( retval == 0 ) return; if( retval == 2 ) std::exit( 2 ); @@ -300,11 +318,12 @@ void maybe_process_config_file( const Arg_parser & parser ) } -void parse_compressor( const std::string & arg, const int format_index, - const int eretval ) +void parse_compressor( const std::string & arg, const char * const pn, + const int format_index, const int eretval ) { if( !parse_compressor_command( arg, 0, format_index ) ) - { show_error( "Missing compressor name." ); std::exit( eretval ); } + { show_option_error( arg.c_str(), "Invalid compressor command in", pn ); + std::exit( eretval ); } } @@ -313,7 +332,7 @@ const char * get_compressor_name( const int format_index ) if( format_index >= 0 && format_index < num_formats && compressor_names[format_index].size() ) return compressor_names[format_index].c_str(); - return 0; + return 0; // uncompressed/unknown } @@ -334,20 +353,16 @@ void show_version( const char * const command ) { std::printf( "%s (zutils) %s\n", program_name, PROGVERSION ); std::printf( "Copyright (C) %s Antonio Diaz Diaz.\n", program_year ); - if( command && verbosity >= 1 ) - { - FILE * const f = popen( command, "r" ); - if( f ) + if( command && verbosity >= 1 ) show_using_version( command ); + if( verbosity >= 1 + ( command != 0 ) ) + for( int format_index = 0; format_index < num_formats; ++format_index ) { - char command_version[1024] = { 0 }; - const int rd = std::fread( command_version, 1, sizeof command_version, f ); - pclose( f ); - int i = 0; - while( i + 1 < rd && command_version[i] != '\n' ) ++i; - command_version[i] = 0; - if( command_version[0] ) std::printf( "Using %s\n", command_version ); + if( !enabled_format( format_index ) ) continue; + std::string compressor_command( compressor_names[format_index] ); + if( compressor_command.empty() ) continue; + compressor_command += " -V 2> /dev/null"; + show_using_version( compressor_command.c_str() ); } - } std::printf( "License GPLv2+: GNU GPL version 2 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" ); @@ -385,6 +400,15 @@ void internal_error( const char * const msg ) } +void show_option_error( const char * const arg, const char * const msg, + const char * const option_name ) + { + if( verbosity >= 0 ) + std::fprintf( stderr, "%s: '%s': %s option '%s'.\n", + program_name, arg, msg, option_name ); + } + + void show_close_error( const char * const prog_name ) { if( verbosity >= 0 ) |