diff options
Diffstat (limited to 'main.cc')
-rw-r--r-- | main.cc | 160 |
1 files changed, 85 insertions, 75 deletions
@@ -1,5 +1,5 @@ /* Zutils - Utilities dealing with compressed files - Copyright (C) 2009, 2010, 2011 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 @@ -54,27 +54,27 @@ const int o_binary = 0; enum Mode { m_none, m_zcat, m_zgrep, m_ztest }; -void show_help() throw() +void show_help() { - std::printf( "Zutils is a collection of utilities able to deal with any combination of\n" ); - std::printf( "compressed and non-compressed files transparently. If any given file,\n" ); - std::printf( "including standard input, is compressed, its uncompressed content is used.\n" ); - std::printf( "The supported compressors are bzip2, gzip, lzip and xz.\n" ); - std::printf( "\nUsage: %s <operation> [options] [files]\n", invocation_name ); - std::printf( "\nTry `%s <operation> --help' for more specific help.\n", invocation_name ); - std::printf( "\nOperations:\n" ); - std::printf( " -h, --help display this help and exit\n" ); - std::printf( " -V, --version output version information and exit\n" ); - std::printf( " --zcat zcat operation\n" ); - std::printf( " --zgrep zgrep operation\n" ); - std::printf( " --ztest ztest operation\n" ); + std::printf( "Zutils is a collection of utilities able to deal with any combination of\n" + "compressed and non-compressed files transparently. If any given file,\n" + "including standard input, is compressed, its uncompressed content is used.\n" + "\nThe supported formats are bzip2, gzip, lzip and xz.\n" + "\nUsage: %s <operation> [options] [files]\n", invocation_name ); + std::printf( "\nTry '%s <operation> --help' for more specific help.\n", invocation_name ); + std::printf( "\nOperations:\n" + " -h, --help display this help and exit\n" + " -V, --version output version information and exit\n" + " --zcat zcat operation\n" + " --zgrep zgrep operation\n" + " --ztest ztest operation\n" ); show_help_addr(); } -int simple_extension_index( const std::string & name ) throw() +int simple_extension_index( const std::string & name ) { - for( int i = 0; simple_extensions[i]; ++i ) + for( int i = 0; i < num_formats; ++i ) { const std::string ext( simple_extensions[i] ); if( name.size() > ext.size() && @@ -85,17 +85,19 @@ int simple_extension_index( const std::string & name ) throw() } -int open_instream( std::string & input_filename, const Mode program_mode ) throw() +int open_instream( std::string & input_filename, const Mode program_mode, + const bool search ) { int infd = open( input_filename.c_str(), O_RDONLY | o_binary ); if( infd < 0 ) { - if( ( program_mode == m_zcat || program_mode == m_zgrep ) - && simple_extension_index( input_filename ) < 0 ) + if( search && ( program_mode == m_zcat || program_mode == m_zgrep ) && + simple_extension_index( input_filename ) < 0 ) { - for( int i = 0; simple_extensions[i]; ++i ) + for( int i = 0; i < num_formats; ++i ) { - const std::string name( input_filename + simple_extensions[i] ); + const std::string name( input_filename + + simple_extensions[format_order[i]] ); infd = open( name.c_str(), O_RDONLY | o_binary ); if( infd >= 0 ) { input_filename = name; break; } } @@ -115,9 +117,11 @@ int open_instream( std::string & input_filename, const Mode program_mode ) throw int main( const int argc, const char * const argv[] ) { - enum { help_opt = 256, verbose_opt, zcat_opt, zgrep_opt, ztest_opt }; + enum { format_opt = 256, help_opt, verbose_opt, + zcat_opt, zgrep_opt, ztest_opt }; const Arg_parser::Option * options = 0; int infd = -1; + int format_type = -1; Mode program_mode = m_none; bool recursive = false; std::string input_filename; @@ -147,52 +151,55 @@ int main( const int argc, const char * const argv[] ) { 'T', "show-tabs", Arg_parser::no }, // cat { 'v', "show-nonprinting", Arg_parser::no }, // cat { 'V', "version", Arg_parser::no }, + { format_opt, "format", Arg_parser::yes }, { verbose_opt, "verbose", Arg_parser::no }, { zcat_opt, "zcat", Arg_parser::no }, { 0 , 0, Arg_parser::no } }; const Arg_parser::Option m_zgrep_options[] = { - { 'a', "text", Arg_parser::no }, // grep GNU - { 'A', "after-context", Arg_parser::yes }, // grep GNU - { 'b', "byte-offset", Arg_parser::no }, // grep GNU - { 'B', "before-context", Arg_parser::yes }, // grep GNU - { 'c', "count", Arg_parser::no }, // grep - { 'C', "context", Arg_parser::yes }, // grep GNU - { 'e', "regexp", Arg_parser::yes }, // grep - { 'E', "extended-regexp", Arg_parser::no }, // grep - { 'f', "file ", Arg_parser::yes }, // grep - { 'F', "fixed-strings", Arg_parser::no }, // grep - { 'h', "no-filename", Arg_parser::no }, // grep GNU - { 'H', "with-filename", Arg_parser::no }, // grep GNU - { 'i', "ignore-case", Arg_parser::no }, // grep - { 'I', 0, Arg_parser::no }, // grep GNU - { 'l', "files-with-matches", Arg_parser::no }, // grep - { 'L', "files-without-match", Arg_parser::no }, // grep GNU - { 'm', "max-count", Arg_parser::yes }, // grep GNU - { 'n', "line-number", Arg_parser::no }, // grep - { 'o', "only-matching", Arg_parser::no }, // grep - { 'q', "quiet", Arg_parser::no }, - { 'r', "recursive", Arg_parser::no }, - { 's', "no-messages", Arg_parser::no }, // grep - { 'v', "invert-match", Arg_parser::no }, // grep - { 'V', "version", Arg_parser::no }, - { 'w', "word-regexp", Arg_parser::no }, // grep GNU - { 'x', "line-regexp", Arg_parser::no }, // grep - { help_opt, "help", Arg_parser::no }, - { verbose_opt, "verbose", Arg_parser::no }, - { zgrep_opt, "zgrep", Arg_parser::no }, - { 0 , 0, Arg_parser::no } }; + { 'a', "text", Arg_parser::no }, // grep GNU + { 'A', "after-context", Arg_parser::yes }, // grep GNU + { 'b', "byte-offset", Arg_parser::no }, // grep GNU + { 'B', "before-context", Arg_parser::yes }, // grep GNU + { 'c', "count", Arg_parser::no }, // grep + { 'C', "context", Arg_parser::yes }, // grep GNU + { 'e', "regexp", Arg_parser::yes }, // grep + { 'E', "extended-regexp", Arg_parser::no }, // grep + { 'f', "file ", Arg_parser::yes }, // grep + { 'F', "fixed-strings", Arg_parser::no }, // grep + { 'h', "no-filename", Arg_parser::no }, // grep GNU + { 'H', "with-filename", Arg_parser::no }, // grep GNU + { 'i', "ignore-case", Arg_parser::no }, // grep + { 'I', 0, Arg_parser::no }, // grep GNU + { 'l', "files-with-matches", Arg_parser::no }, // grep + { 'L', "files-without-match", Arg_parser::no }, // grep GNU + { 'm', "max-count", Arg_parser::yes }, // grep GNU + { 'n', "line-number", Arg_parser::no }, // grep + { 'o', "only-matching", Arg_parser::no }, // grep + { 'q', "quiet", Arg_parser::no }, + { 'r', "recursive", Arg_parser::no }, + { 's', "no-messages", Arg_parser::no }, // grep + { 'v', "invert-match", Arg_parser::no }, // grep + { 'V', "version", Arg_parser::no }, + { 'w', "word-regexp", Arg_parser::no }, // grep GNU + { 'x', "line-regexp", Arg_parser::no }, // grep + { format_opt, "format", Arg_parser::yes }, + { help_opt, "help", Arg_parser::no }, + { verbose_opt, "verbose", Arg_parser::no }, + { zgrep_opt, "zgrep", Arg_parser::no }, + { 0 , 0, Arg_parser::no } }; const Arg_parser::Option m_ztest_options[] = { - { 'h', "help", Arg_parser::no }, - { 'q', "quiet", Arg_parser::no }, - { 'r', "recursive", Arg_parser::no }, - { 'v', "verbose", Arg_parser::no }, - { 'V', "version", Arg_parser::no }, - { ztest_opt, "ztest", Arg_parser::no }, - { 0 , 0, Arg_parser::no } }; + { 'h', "help", Arg_parser::no }, + { 'q', "quiet", Arg_parser::no }, + { 'r', "recursive", Arg_parser::no }, + { 'v', "verbose", Arg_parser::no }, + { 'V', "version", Arg_parser::no }, + { format_opt, "format", Arg_parser::yes }, + { ztest_opt, "ztest", Arg_parser::no }, + { 0 , 0, Arg_parser::no } }; { // parse operation const Arg_parser::Option operations[] = @@ -226,8 +233,8 @@ int main( const int argc, const char * const argv[] ) } #if defined(__MSVCRT__) || defined(__OS2__) - _setmode( STDIN_FILENO, O_BINARY ); - _setmode( STDOUT_FILENO, O_BINARY ); + setmode( STDIN_FILENO, O_BINARY ); + setmode( STDOUT_FILENO, O_BINARY ); #endif if( program_mode == m_none ) @@ -240,11 +247,11 @@ int main( const int argc, const char * const argv[] ) const Arg_parser parser( argc, argv, options ); if( parser.error().size() ) // bad option { show_error( parser.error().c_str(), 0, true ); - return ( program_mode == m_zcat ) ? 1 : 2; } + return ( program_mode == m_zcat || program_mode == m_ztest ) ? 1 : 2; } int argind = 0; + int grep_show_name = -1; bool grep_list = false; - bool grep_show_name = true; bool grep_pattern_found = false; for( ; argind < parser.arguments(); ++argind ) { @@ -256,9 +263,13 @@ int main( const int argc, const char * const argv[] ) { grep_args.push_back( arg ); grep_pattern_found = true; continue; } else break; // no more options } + if( code == format_opt ) + { + format_type = get_format_type( arg ); continue; + } switch( program_mode ) { - case m_none: internal_error( "invalid operation" ); + case m_none: internal_error( "invalid operation" ); break; case m_zcat: switch( code ) { @@ -339,17 +350,16 @@ int main( const int argc, const char * const argv[] ) } // end process options if( program_mode == m_zgrep && !grep_pattern_found ) - { show_error( "Pattern not found.", 0, true ); return 2; } + { show_error( "Pattern not found." ); return 2; } - bool filenames_given = false; for( ; argind < parser.arguments(); ++argind ) - { - if( parser.argument( argind ) != "-" ) filenames_given = true; filenames.push_back( parser.argument( argind ) ); - } if( filenames.empty() ) filenames.push_back("-"); + if( grep_show_name < 0 ) + grep_show_name = ( filenames.size() != 1 || recursive ); + int retval = ( ( program_mode == m_zgrep ) ? 1 : 0 ); while( !filenames.empty() ) { @@ -386,7 +396,7 @@ int main( const int argc, const char * const argv[] ) continue; } } - infd = open_instream( input_filename, program_mode ); + infd = open_instream( input_filename, program_mode, format_type < 0 ); if( infd < 0 ) { if( retval < 1 ) retval = 1; continue; } } @@ -396,18 +406,18 @@ int main( const int argc, const char * const argv[] ) case m_none: break; case m_zcat: - tmp = cat( infd, input_filename, cat_options ); + tmp = cat( infd, format_type, input_filename, cat_options ); break; case m_zgrep: if( infd == STDIN_FILENO ) - tmp = zgrep_stdin( infd, grep_args ); - else tmp = zgrep_file( infd, input_filename, grep_args, + tmp = zgrep_stdin( infd, format_type, grep_args ); + else tmp = zgrep_file( infd, format_type, input_filename, grep_args, grep_list, grep_show_name ); break; case m_ztest: if( infd == STDIN_FILENO ) - tmp = ztest_stdin( infd, ztest_args ); - else tmp = ztest_file( infd, input_filename, ztest_args ); + tmp = ztest_stdin( infd, format_type, ztest_args ); + else tmp = ztest_file( infd, format_type, input_filename, ztest_args ); break; } if( program_mode == m_zgrep ) |