diff --git a/app/ModulesHandleOptDialog.cpp b/app/ModulesHandleOptDialog.cpp index 2cac1b6..c6f992a 100644 --- a/app/ModulesHandleOptDialog.cpp +++ b/app/ModulesHandleOptDialog.cpp @@ -39,33 +39,35 @@ public: OpionConfiguration( QWidget *parent, OptionBase* option ) : QWidget( parent ) { - m_cName = QString::fromStdString( option->opt_string ); + m_cName = option->opt_string; m_pcDescription = new QLabel( this ); m_pcDescription->setText( QString::fromStdString( option->opt_desc ) ); m_pcValue = new QLineEdit( this ); + m_pcValue->setMinimumWidth( 40 ); + m_pcValue->setMaximumWidth( 65 ); QHBoxLayout* layout = new QHBoxLayout( this ); - layout->addWidget( m_pcDescription ); - layout->addWidget( m_pcValue ); + layout->addWidget( m_pcDescription, Qt::AlignLeft ); + layout->addWidget( m_pcValue, Qt::AlignRight ); } - QString getValue() + const QString getValue() const { return m_pcValue->text(); } - QString& getName() + const std::string& getName() { return m_cName; } private: QLineEdit* m_pcValue; QLabel* m_pcDescription; - QString m_cName; + std::string m_cName; }; ModulesHandleOptDialog::ModulesHandleOptDialog( QWidget *parent, PlaYUVerAppModuleIf *pcCurrModuleIf ) : QDialog( parent ), m_pcCurrModuleIf( pcCurrModuleIf ) { - resize( 300, 10 ); + resize( 400, 10 ); setWindowTitle( "Select module parameters" ); setWindowIcon( QIcon( ":/images/configureformat.png" ) ); @@ -98,23 +100,26 @@ Int ModulesHandleOptDialog::runConfiguration() { return QDialog::Rejected; } - QString optionString( "" ); + + std::vector argsArray; + std::string optionString; QString valueString( "" ); - Int argsCount = 0; + for( Int i = 0; i < m_apcOptionList.size(); i++ ) { valueString = m_apcOptionList.at( i )->getValue(); if( !valueString.isEmpty() ) { - optionString.append( QString( "--%1=%2" ).arg( m_apcOptionList.at( i )->getName() ).arg( valueString ) ); - argsCount++; + optionString.append( "--" ); + optionString.append( m_apcOptionList.at( i )->getName() ); + optionString.append( "=" ); + optionString.append( valueString.toStdString() ); + argsArray.push_back( optionString ); } } - if( argsCount > 0 ) + if( argsArray.size() > 0 ) { - std::string optionStdString = optionString.toStdString(); - scanLine( m_pcCurrModuleIf->m_pcModule->m_cModuleOptions, optionStdString ); - qDebug( ) << optionString; + m_pcCurrModuleIf->m_pcModule->m_cModuleOptions.scanArgs( argsArray ); } return QDialog::Accepted; } diff --git a/app/PlaYUVerApp.cpp b/app/PlaYUVerApp.cpp index 40276f4..c2ce416 100644 --- a/app/PlaYUVerApp.cpp +++ b/app/PlaYUVerApp.cpp @@ -106,7 +106,7 @@ Bool plaYUVerApp::parseArgs( Int argc, Char *argv[] ) if( m_pcCmdParser->Opts()["help"]->count() ) { printf( "Usage: %s [options] input_file[s]\n", argv[0] ); - doHelp( std::cout, m_pcCmdParser->Opts() ); + m_pcCmdParser->Opts().doHelp( std::cout ); bRet |= true; } if( m_pcCmdParser->Opts()["input"]->count() ) diff --git a/lib/PlaYUVerCmdParser.cpp b/lib/PlaYUVerCmdParser.cpp index 3030734..bee40bc 100644 --- a/lib/PlaYUVerCmdParser.cpp +++ b/lib/PlaYUVerCmdParser.cpp @@ -65,7 +65,7 @@ Bool PlaYUVerCmdParser::parse() try { // m_cParserOptions.setDefaults(); - m_aUnhandledArgs = scanArgv( m_cParserOptions, m_iArgc, ( const Char** )m_ppArgv ); + m_aUnhandledArgs = m_cParserOptions.scanArgv( m_iArgc, ( const Char** )m_ppArgv ); // for( std::list::const_iterator it = argv_unhandled.begin(); it != argv_unhandled.end(); it++ ) // { @@ -96,7 +96,7 @@ Bool PlaYUVerCmdParser::parse( Options& opts, Int argc, Char *argv[] ) try { // m_cParserOptions.setDefaults(); - m_aUnhandledArgs = scanArgv( opts, argc, ( const Char** )argv ); + m_aUnhandledArgs = opts.scanArgv( argc, ( const Char** )argv ); } catch( std::exception& e ) diff --git a/lib/ProgramOptions.cpp b/lib/ProgramOptions.cpp index 233ae41..4288944 100644 --- a/lib/ProgramOptions.cpp +++ b/lib/ProgramOptions.cpp @@ -53,8 +53,8 @@ namespace plaYUVer Options::Options( const std::string& name ) { - opt_name = name; - allow_unknow = false; + m_cOptionGroupName = name; + m_bAllowUnkonw = true; } Options::~Options() @@ -152,6 +152,207 @@ static void setOptions( Options::OptionsList& opt_list, const string& value ) } } +Bool Options::storePair( Bool allow_long, Bool allow_short, const string& name, const string& value ) +{ + bool found = false; + Options::OptionMap::iterator opt_it; + if( allow_long ) + { + opt_it = opt_long_map.find( name ); + if( opt_it != opt_long_map.end() ) + { + found = true; + } + } + + /* check for the short list */ + if( allow_short && !( found && allow_long ) ) + { + opt_it = opt_short_map.find( name ); + if( opt_it != opt_short_map.end() ) + { + found = true; + } + } + + if( !found ) + { + if( !m_bAllowUnkonw ) + { + /* not found */ + cerr << "Unknown option: `" + << name + << "' (value:`" + << value + << "')" + << endl; + } + return false; + } + + setOptions( ( *opt_it ).second, value ); + return true; +} + +Bool Options::storePair( const string& name, const string& value ) +{ + return storePair( true, true, name, value ); +} + +/** + * returns number of extra arguments consumed + */ +UInt Options::parseLONG( unsigned argc, const char* argv[] ) +{ + /* gnu style long options can take the forms: + * --option=arg + * --option arg + */ + string arg( argv[0] ); + size_t arg_opt_start = arg.find_first_not_of( '-' ); + size_t arg_opt_sep = arg.find_first_of( '=' ); + string option = arg.substr( arg_opt_start, arg_opt_sep - arg_opt_start ); + + unsigned extra_argc_consumed = 0; + if( arg_opt_sep == string::npos ) + { + /* no argument found => argument in argv[1] (maybe) */ + /* xxx, need to handle case where option isn't required */ +#if 0 + /* commented out, to return to true GNU style processing + * where longopts have to include an =, otherwise they are + * booleans */ + if (argc == 1) + return 0; /* run out of argv for argument */ + extra_argc_consumed = 1; +#endif + if( !storePair( true, false, option, "1" ) ) + { + return 0; + } + } + else + { + /* argument occurs after option_sep */ + string val = arg.substr( arg_opt_sep + 1 ); + storePair( true, false, option, val ); + } + return extra_argc_consumed; +} + +/** + * returns number of extra arguments consumed + */ +UInt Options::parseLONG( string arg ) +{ + /* gnu style long options can take the forms: + * --option=arg + * --option arg + */ + size_t arg_opt_start = arg.find_first_not_of( '-' ); + size_t arg_opt_sep = arg.find_first_of( '=' ); + string option = arg.substr( arg_opt_start, arg_opt_sep - arg_opt_start ); + + unsigned extra_argc_consumed = 0; + if( arg_opt_sep == string::npos ) + { + /* no argument found => argument in argv[1] (maybe) */ + /* xxx, need to handle case where option isn't required */ + if( !storePair( true, false, option, "1" ) ) + { + return 0; + } + } + else + { + /* argument occurs after option_sep */ + string val = arg.substr( arg_opt_sep + 1 ); + storePair( true, false, option, val ); + } + return extra_argc_consumed; +} + +unsigned Options::parseSHORT( unsigned argc, const char* argv[] ) +{ + /* short options can take the forms: + * --option arg + * -option arg + */ + string arg( argv[0] ); + size_t arg_opt_start = arg.find_first_not_of( '-' ); + string option = arg.substr( arg_opt_start ); + /* lookup option */ + + /* argument in argv[1] */ + /* xxx, need to handle case where option isn't required */ + if( argc == 1 ) + { + cerr << "Not processing option without argument `" + << option + << "'" + << endl; + return 0; /* run out of argv for argument */ + } + storePair( false, true, option, string( argv[1] ) ); + + return 1; +} + +list Options::scanArgv( unsigned argc, const char* argv[] ) +{ + /* a list for anything that didn't get handled as an option */ + list non_option_arguments; + + for( unsigned i = 1; i < argc; i++ ) + { + if( argv[i][0] != '-' ) + { + non_option_arguments.push_back( argv[i] ); + continue; + } + + if( argv[i][1] == 0 ) + { + /* a lone single dash is an argument (usually signifying stdin) */ + non_option_arguments.push_back( argv[i] ); + continue; + } + + if( argv[i][1] != '-' ) + { + /* handle short (single dash) options */ +#if 0 + i += parsePOSIX(opts, argc - i, &argv[i]); +#else + i += parseSHORT( argc - i, &argv[i] ); +#endif + continue; + } + + if( argv[i][2] == 0 ) + { + /* a lone double dash ends option processing */ + while( ++i < argc ) + non_option_arguments.push_back( argv[i] ); + break; + } + + /* handle long (double dash) options */ + i += parseLONG( argc - i, &argv[i] ); + } + + return non_option_arguments; +} + +Void Options::scanArgs( std::vector args_array) +{ + for( unsigned i = 0; i < args_array.size(); i++ ) + { + i += parseLONG( args_array[0] ); + } + return; +} + static const char spaces[41] = " "; /* format help text for a single option: @@ -187,12 +388,12 @@ static void doHelpOpt( ostream& out, const Options::Option& entry, unsigned pad_ } /* format the help text */ -void doHelp( ostream& out, Options& opts, unsigned columns ) +Void Options::doHelp( ostream& out, unsigned columns ) { const unsigned pad_short = 3; /* first pass: work out the longest option name */ unsigned max_width = 0; - for( Options::OptionsList::iterator it = opts.opt_list.begin(); it != opts.opt_list.end(); it++ ) + for( Options::OptionsList::iterator it = opt_list.begin(); it != opt_list.end(); it++ ) { ostringstream line( ios_base::out ); doHelpOpt( line, **it, pad_short ); @@ -207,7 +408,7 @@ void doHelp( ostream& out, Options& opts, unsigned columns ) * - if the option text is longer than opt_width, place the help * text at opt_width on the next line. */ - for( Options::OptionsList::iterator it = opts.opt_list.begin(); it != opts.opt_list.end(); it++ ) + for( Options::OptionsList::iterator it = opt_list.begin(); it != opt_list.end(); it++ ) { ostringstream line( ios_base::out ); line << " "; @@ -285,275 +486,5 @@ void doHelp( ostream& out, Options& opts, unsigned columns ) } } -bool storePair( Options& opts, bool allow_long, bool allow_short, const string& name, const string& value ) -{ - bool found = false; - Options::OptionMap::iterator opt_it; - if( allow_long ) - { - opt_it = opts.opt_long_map.find( name ); - if( opt_it != opts.opt_long_map.end() ) - { - found = true; - } - } - - /* check for the short list */ - if( allow_short && !( found && allow_long ) ) - { - opt_it = opts.opt_short_map.find( name ); - if( opt_it != opts.opt_short_map.end() ) - { - found = true; - } - } - - if( !found ) - { -// if( !opts.allow_unknow ) -// { -// /* not found */ -// cerr << "Unknown option: `" -// << name -// << "' (value:`" -// << value -// << "')" -// << endl; -// } - return false; - } - - setOptions( ( *opt_it ).second, value ); - return true; -} - -bool storePair( Options& opts, const string& name, const string& value ) -{ - return storePair( opts, true, true, name, value ); -} - -/** - * returns number of extra arguments consumed - */ -unsigned parseGNU( Options& opts, unsigned argc, const char* argv[] ) -{ - /* gnu style long options can take the forms: - * --option=arg - * --option arg - */ - string arg( argv[0] ); - size_t arg_opt_start = arg.find_first_not_of( '-' ); - size_t arg_opt_sep = arg.find_first_of( '=' ); - string option = arg.substr( arg_opt_start, arg_opt_sep - arg_opt_start ); - - unsigned extra_argc_consumed = 0; - if( arg_opt_sep == string::npos ) - { - /* no argument found => argument in argv[1] (maybe) */ - /* xxx, need to handle case where option isn't required */ -#if 0 - /* commented out, to return to true GNU style processing - * where longopts have to include an =, otherwise they are - * booleans */ - if (argc == 1) - return 0; /* run out of argv for argument */ - extra_argc_consumed = 1; -#endif - if( !storePair( opts, true, false, option, "1" ) ) - { - return 0; - } - } - else - { - /* argument occurs after option_sep */ - string val = arg.substr( arg_opt_sep + 1 ); - storePair( opts, true, false, option, val ); - } - - return extra_argc_consumed; -} - -unsigned parseSHORT( Options& opts, unsigned argc, const char* argv[] ) -{ - /* short options can take the forms: - * --option arg - * -option arg - */ - string arg( argv[0] ); - size_t arg_opt_start = arg.find_first_not_of( '-' ); - string option = arg.substr( arg_opt_start ); - /* lookup option */ - - /* argument in argv[1] */ - /* xxx, need to handle case where option isn't required */ - if( argc == 1 ) - { - cerr << "Not processing option without argument `" - << option - << "'" - << endl; - return 0; /* run out of argv for argument */ - } - storePair( opts, false, true, option, string( argv[1] ) ); - - return 1; -} - -list scanArgv( Options& opts, unsigned argc, const char* argv[] ) -{ - /* a list for anything that didn't get handled as an option */ - list non_option_arguments; - - for( unsigned i = 1; i < argc; i++ ) - { - if( argv[i][0] != '-' ) - { - non_option_arguments.push_back( argv[i] ); - continue; - } - - if( argv[i][1] == 0 ) - { - /* a lone single dash is an argument (usually signifying stdin) */ - non_option_arguments.push_back( argv[i] ); - continue; - } - - if( argv[i][1] != '-' ) - { - /* handle short (single dash) options */ -#if 0 - i += parsePOSIX(opts, argc - i, &argv[i]); -#else - i += parseSHORT( opts, argc - i, &argv[i] ); -#endif - continue; - } - - if( argv[i][2] == 0 ) - { - /* a lone double dash ends option processing */ - while( ++i < argc ) - non_option_arguments.push_back( argv[i] ); - break; - } - - /* handle long (double dash) options */ - i += parseGNU( opts, argc - i, &argv[i] ); - } - - return non_option_arguments; -} - -void scanLine( Options& opts, string& line ) -{ - /* strip any leading whitespace */ - size_t start = line.find_first_not_of( " \t\n\r" ); - if( start == string::npos ) - { - /* blank line */ - return; - } - if( line[start] == '#' ) - { - /* comment line */ - return; - } - /* look for first whitespace or ':' after the option end */ - size_t option_end = line.find_first_of( ": \t\n\r", start ); - string option = line.substr( start, option_end - start ); - - /* look for ':', eat up any whitespace first */ - start = line.find_first_not_of( " \t\n\r", option_end ); - if( start == string::npos ) - { - /* error: badly formatted line */ - return; - } - if( line[start] != ':' ) - { - /* error: badly formatted line */ - return; - } - - /* look for start of value string -- eat up any leading whitespace */ - start = line.find_first_not_of( " \t\n\r", ++start ); - if( start == string::npos ) - { - /* error: badly formatted line */ - return; - } - - /* extract the value part, which may contain embedded spaces - * by searching for a word at a time, until we hit a comment or end of line */ - size_t value_end = start; - do - { - if( line[value_end] == '#' ) - { - /* rest of line is a comment */ - value_end--; - break; - } - value_end = line.find_first_of( " \t\n\r", value_end ); - /* consume any white space, incase there is another word. - * any trailing whitespace will be removed shortly */ - value_end = line.find_first_not_of( " \t\n\r", value_end ); - } - while( value_end != string::npos ); - /* strip any trailing space from value*/ - value_end = line.find_last_not_of( " \t\n\r", value_end ); - - string value; - if( value_end >= start ) - { - value = line.substr( start, value_end + 1 - start ); - } - else - { - /* error: no value */ - return; - } - - /* store the value in option */ - storePair( opts, true, false, option, value ); -} - -void scanFile( Options& opts, istream& in ) -{ - do - { - string line; - getline( in, line ); - scanLine( opts, line ); - } - while( !!in ); -} - -/* for all options in opts, set their storage to their specified - * default value */ -void setDefaults( Options& opts ) -{ -// for( Options::OptionsList::iterator it = opts.opt_list.begin(); it != opts.opt_list.end(); it++ ) -// { -// ( *it )->opt->setDefault(); -// } -} - -void parseConfigFile( Options& opts, const string& filename ) -{ - ifstream cfgstream( filename.c_str(), ifstream::in ); - if( !cfgstream ) - { - cerr << "Failed to open config file: `" - << filename - << "'" - << endl; - exit( EXIT_FAILURE ); - } - scanFile( opts, cfgstream ); -} - } // NAMESPACE diff --git a/lib/ProgramOptions.h b/lib/ProgramOptions.h index dc6fd20..b27ae47 100644 --- a/lib/ProgramOptions.h +++ b/lib/ProgramOptions.h @@ -74,17 +74,6 @@ struct ParseFailure: public std::exception } }; -void doHelp( std::ostream& out, Options& opts, unsigned columns = 80 ); -unsigned parseGNU( Options& opts, unsigned argc, const char* argv[] ); -unsigned parseSHORT( Options& opts, unsigned argc, const char* argv[] ); -std::list scanArgv( Options& opts, unsigned argc, const char* argv[] ); -void scanLine( Options& opts, std::string& line ); -void scanFile( Options& opts, std::istream& in ); -void setDefaults( Options& opts ); -void setDefaults( Options* opts ); -void parseConfigFile( Options& opts, const std::string& filename ); -bool storePair( Options& opts, const std::string& name, const std::string& value ); - /** OptionBase: Virtual base class for storing information relating to a * specific option This base class describes common elements. Type specific * information should be stored in a derived class. */ @@ -245,11 +234,14 @@ public: OptionBase* opt; }; typedef std::list OptionsList; - OptionsList opt_list; Options( const std::string& name = "" ); ~Options(); + std::list scanArgv( unsigned argc, const char* argv[] ); + Void scanArgs( std::vector args_array); + Void doHelp( std::ostream& out, unsigned columns = 80 ); + OptionSpecific addOptions(); Void setDefaults(); @@ -263,13 +255,22 @@ public: void addOption( OptionBase *opt ); +private: + typedef std::map OptionMap; OptionMap opt_long_map; OptionMap opt_short_map; - std::string opt_name; + OptionsList opt_list; - Bool allow_unknow; + std::string m_cOptionGroupName; + Bool m_bAllowUnkonw; + + Bool storePair( Bool allow_long, Bool allow_short, const std::string& name, const std::string& value ); + Bool storePair( const std::string& name, const std::string& value ); + UInt parseLONG( unsigned argc, const char* argv[] ); + UInt parseLONG( std::string arg ); + unsigned parseSHORT( unsigned argc, const char* argv[] ); }; /* Class with templated overloaded operator(), for use by Options::addOptions() */ diff --git a/tools/CommandLineHandle.cpp b/tools/CommandLineHandle.cpp index 74b569e..75fb37c 100644 --- a/tools/CommandLineHandle.cpp +++ b/tools/CommandLineHandle.cpp @@ -95,7 +95,7 @@ Int CommandLineHandle::parseToolsArgs( Int argc, Char *argv[] ) else if( Opts()["help"]->count() ) { printf( "Usage: %s modules/quality [options] -input=input_file [--output=output_file]\n", argv[0] ); - doHelp( std::cout, Opts() ); + Opts().doHelp( std::cout ); iRet = 1; } @@ -181,7 +181,7 @@ Void CommandLineHandle::listModuleHelp() if( pcCurrModuleIf ) { printf( "Usage: playuverTools --module=%s options:\n", it->first ); - doHelp( std::cout, pcCurrModuleIf->m_cModuleOptions ); + pcCurrModuleIf->m_cModuleOptions.doHelp( std::cout ); } } diff --git a/tools/PlaYUVerTools.cpp b/tools/PlaYUVerTools.cpp index e1b52e6..d9a9c3b 100644 --- a/tools/PlaYUVerTools.cpp +++ b/tools/PlaYUVerTools.cpp @@ -180,8 +180,7 @@ Int PlaYUVerTools::Open( Int argc, Char *argv[] ) m_pcCurrModuleIf->create( m_apcInputStreams[0]->getCurrFrame() ); - m_pcCurrModuleIf->m_cModuleOptions.allow_unknow = true; - scanArgv( m_pcCurrModuleIf->m_cModuleOptions, argc, ( const Char** )argv ); + m_pcCurrModuleIf->m_cModuleOptions.scanArgv( argc, ( const Char** )argv ); if( m_pcCurrModuleIf->m_iModuleType == FRAME_PROCESSING_MODULE ) {