#include <ProgOptions.hpp>
Public Member Functions | |
ProgOptions (const std::string &helptext="", const std::string &briefdesc="") | |
unimplemented flag for required arguments that may be given multiple times More... | |
~ProgOptions () | |
void | setVersion (const std::string &version_string, bool addFlag=true) |
template<typename T > | |
void | addOpt (const std::string &namestring, const std::string &helpstring, T *value, int flags=0) |
template<typename T > | |
void | addOpt (const std::string &namestring, const std::string &helpstring, int flags=0) |
void | addOptionHelpHeading (const std::string &) |
template<typename T > | |
void | addRequiredArg (const std::string &helpname, const std::string &helpstring, T *value=NULL, int flags=0) |
template<typename T > | |
void | addOptionalArgs (unsigned max_count, const std::string &helpname, const std::string &helpstring, int flags=0) |
void | printHelp (std::ostream &str=std::cout) |
void | printUsage (std::ostream &str=std::cout) |
void | printVersion (std::ostream &str=std::cout) |
void | parseCommandLine (int argc, char *argv[]) |
template<typename T > | |
bool | getOpt (const std::string &namestring, T *value) |
template<typename T > | |
void | getOptAllArgs (const std::string &namestring, std::vector< T > &values) |
int | numOptSet (const std::string &namestring) |
template<typename T > | |
T | getReqArg (const std::string &namestring) |
template<typename T > | |
void | getArgs (const std::string &namestring, std::vector< T > &values) |
void | error (const std::string &message) |
void | write_man_page (std::ostream &to_this_stream) |
Static Public Attributes | |
static const int | help_flag = 1 << 0 |
Set for a flag that, when detected, prints help text and halts program. Constructor creates such a flag by default, so the user shouldn't need to use this directly. More... | |
static const int | add_cancel_opt = 1 << 1 |
Flag indicating that an option should be given a "cancel" flag. This creates, for option –foo, an additional option –no-foo that clears all previously read instances of the foo option. More... | |
static const int | store_false = 1 << 2 |
When applied to a flag argument (one with template type void), indicate that the value 'false' should be stored into the pointer that was given at option creation time. This overrides the default behavior, which is to store the value 'true'. More... | |
static const int | int_flag = 1 << 3 |
Specify a numerical flag where any positive integer is an acceptable value. E.g. –dimension=3 is equivalent to -3. Only values in the range [0,9] are accepted and the flag type must be integer. More... | |
static const int | rank_subst = 1 << 4 |
static const int | version_flag = 1 << 5 |
Set for a flag that, when detected, will call printVersion() and halt the program. More... | |
Protected Types | |
typedef std::pair< ProgOpt *, std::string > | help_line |
Protected Member Functions | |
std::string | get_option_usage_prefix (const ProgOpt &option) |
void | get_namestrings (const std::string &input, std::string *l, std::string *s) |
ProgOpt * | lookup (const std::map< std::string, ProgOpt * > &, const std::string &) |
ProgOpt * | lookup_option (const std::string &) |
bool | evaluate (const ProgOpt &opt, void *target, const std::string &option, unsigned *arg_idx=NULL) |
bool | process_option (ProgOpt *opt, std::string arg, const char *value=0) |
Protected Attributes | |
std::map< std::string, ProgOpt * > | long_names |
std::map< std::string, ProgOpt * > | short_names |
std::map< std::string, ProgOpt * > | required_args |
std::vector< help_line > | option_help_strings |
std::vector< help_line > | arg_help_strings |
std::vector< std::string > | main_help |
std::string | brief_help |
bool | expect_optional_args |
unsigned | optional_args_position |
unsigned | max_optional_args |
std::string | progname |
std::string | progversion |
std::string | number_option_name |
A simple command-line option parser and help utility
Utility class to specify a program's command-line options arguments, produce a help message explaining how they work, and parse user's command line input (producing useful errors messages if any problems arise). Loosely (okay, very loosely) inspired by boost program_options.
Options are specified by a comma-separated namestring. An option named "foo,f" can be specified three ways on the command line: "-f val", "--foo val", or "--foo=val". The types of options and arguments are specified by function templates. Valid template values for positional argument and options are int, double, and std::string. void may also be used in options, and it indicates a command line option that does not take an argument.
Example usage: ProgOptions po( "Example usage of ProgOptions" ); po.addOpt<void>( "verbose,v", "Turn on verbose messages" ); po.addOpt<std::string> ("foo", "Specify the foo string" ); int x = 0; po.addOpt<int>( ",x", "Specify the x number", &x ); // x will be automatically set when options parsed po.parseCommandLine( argc, argv ); bool verbose = po.numOptSet("verbose") > 0; std::string foo; if( !po.getOpt( "foo", &foo ) ) foo = "default"; ...
See the file dagmc_preproc.cpp in the dagmc directory for a real-world example.
Definition at line 35 of file ProgOptions.hpp.
|
protected |
Definition at line 262 of file ProgOptions.hpp.
ProgOptions::ProgOptions | ( | const std::string & | helptext = "" , |
const std::string & | briefdesc = "" |
||
) |
unimplemented flag for required arguments that may be given multiple times
helptext | A brief summary of the program's function, to be printed when the help flag is detected |
Definition at line 94 of file ProgOptions.cpp.
95 : expect_optional_args( false ), optional_args_position( 0 ), max_optional_args( 0 )
96 {
97 brief_help = briefhelp;
98 if( !helpstring.empty() ) main_help.push_back( helpstring );
99 addOpt< void >( "help,h", "Show full help text", help_flag );
100 }
References brief_help, help_flag, and main_help.
ProgOptions::~ProgOptions | ( | ) |
Definition at line 102 of file ProgOptions.cpp.
103 {
104 for( std::vector< help_line >::iterator i = option_help_strings.begin(); i != option_help_strings.end(); ++i )
105 {
106 if( ( *i ).first )
107 {
108 delete( *i ).first;
109 }
110 }
111
112 for( std::vector< help_line >::iterator i = arg_help_strings.begin(); i != arg_help_strings.end(); ++i )
113 {
114 delete( *i ).first;
115 }
116 }
References arg_help_strings, and option_help_strings.
|
inline |
Specify a new command-line option
This funtion is identical to the 4-arg version, but omits the value parameter, which is assumed to be NULL
Definition at line 122 of file ProgOptions.hpp.
123 {
124 addOpt< T >( namestring, helpstring, NULL, flags );
125 }
void ProgOptions::addOpt | ( | const std::string & | namestring, |
const std::string & | helpstring, | ||
T * | value, | ||
int | flags = 0 |
||
) |
Specify a new command-line option
Instruct the parser to accept a new command-line argument, as well as specifying how the argument should be handled. The template parameter indicates the type of command-line option being specified: acceptable types are void (indicating a flag without an argument), int, double, and std::string.
namestring | The command-line options name(s). Format is longname,shortname. If the comma is omitted, or appears only at the end, this option will have no shortname; if the comma is the first letter of the namestring, the option has no longname. |
helpstring | The help information displayed for the option when the program is invoked with –help |
value | A pointer to memory in which to store the parsed value for this option. If NULL, then the value of the option must be queried using the getOpt function. If the template parameter is void and value is non-NULL, treat value as a bool* and store 'true' into it when the flag is encountered. (See also store_false, above) |
flags | Option behavior flags, which should come from static vars in the ProgOptions class |
Definition at line 141 of file ProgOptions.cpp.
142 {
143
144 std::string shortname, longname;
145 get_namestrings( namestring, &longname, &shortname );
146
147 if( flags & int_flag )
148 { // short name is implicit for this flag
149 if( !shortname.empty() ) error( "Requested short name with int_flag option" );
150 if( get_opt_type< T >() != INT ) error( "Requested int_flag for non-integer option" );
151 if( !number_option_name.empty() ) error( "Requested int_flag for multiple options" );
152 number_option_name = longname;
153 }
154
155 ProgOpt* opt = new ProgOpt( longname, shortname, flags, get_opt_type< T >() );
156 if( value ) opt->storage = value;
157
158 if( longname.length() ) long_names[longname] = opt;
159 if( shortname.length() ) short_names[shortname] = opt;
160
161 help_line help = std::make_pair( opt, helpstring );
162 option_help_strings.push_back( help );
163
164 if( flags & add_cancel_opt )
165 {
166 std::string flag = "no-" + ( longname.length() ? longname : shortname );
167 ProgOpt* cancel_opt = new ProgOpt( flag, "", flags ^ ProgOptions::store_false, FLAG );
168 if( value ) cancel_opt->storage = value;
169
170 cancel_opt->cancel_opt = opt;
171 long_names[flag] = cancel_opt;
172 std::string clear_helpstring = "Clear previous " + flag.substr( 3, flag.npos ) + " flag";
173 help = std::make_pair( cancel_opt, clear_helpstring );
174 option_help_strings.push_back( help );
175 }
176 }
References add_cancel_opt, ProgOpt::cancel_opt, error(), FLAG, get_namestrings(), help(), INT, int_flag, long_names, number_option_name, option_help_strings, short_names, ProgOpt::storage, and store_false.
Referenced by main(), RuntimeContext::ParseCLOptions(), and ToolContext::ParseCLOptions().
void ProgOptions::addOptionalArgs | ( | unsigned | max_count, |
const std::string & | helpname, | ||
const std::string & | helpstring, | ||
int | flags = 0 |
||
) |
Add optional positional arguments
Specify location in ordered argument list at which optional arguments may occur. Optional arguments are allowed at only one location it argument list (this function may not be called more than once.). The template parameter may be int, double, or std::string (but not void)
count | The maximum number of optional arguments. Specify zero for unlimited. |
helpname | The name to give the argument in the help text |
helpstring | The help text for the arguments |
Definition at line 192 of file ProgOptions.cpp.
196 {
197 // If there was a previous one, we need to remove it
198 // because there can be only one. If we didn't remove
199 // the old one then it would be treated as a required arg.
200 if( expect_optional_args )
201 {
202 std::map< std::string, ProgOpt* >::iterator iter;
203 iter = required_args.find( arg_help_strings[optional_args_position].second );
204 assert( iter != required_args.end() );
205 delete iter->second;
206 required_args.erase( iter );
207 arg_help_strings.erase( arg_help_strings.begin() + optional_args_position );
208 }
209
210 expect_optional_args = true;
211 optional_args_position = arg_help_strings.size();
212 max_optional_args = max_count;
213 addRequiredArg< T >( helpname, helpstring, 0, flags );
214 }
References arg_help_strings, expect_optional_args, max_optional_args, optional_args_position, and required_args.
void ProgOptions::addOptionHelpHeading | ( | const std::string & | s | ) |
Add a new line of help text to the option help printout
Add a line of text to the option-related help. Called between calls to addOpt(), this function can be used to divide the option list into groups of related options to make the help text more convenient.
Definition at line 216 of file ProgOptions.cpp.
217 {
218 option_help_strings.push_back( std::make_pair( (ProgOpt*)NULL, s ) );
219 }
References option_help_strings.
Referenced by main().
void ProgOptions::addRequiredArg | ( | const std::string & | helpname, |
const std::string & | helpstring, | ||
T * | value = NULL , |
||
int | flags = 0 |
||
) |
Add required positional argument
Add a new required positional argument. The order in which arguments are specified is the order in which they will be expected on the command line. The template parameter may be int, double, or std::string (but not void)
helpname | The name to give the argument in the help text |
helpstring | The help text for the argument |
value | Pointer to where parsed value from command line should be stored. If NULL, the value must be queried using getReqArg() |
Definition at line 179 of file ProgOptions.cpp.
180 {
181
182 OptType type = get_opt_type< T >();
183
184 ProgOpt* opt = new ProgOpt( helpname, "", flags, type );
185 if( value ) opt->storage = value;
186 help_line help = std::make_pair( opt, helpstring );
187 arg_help_strings.push_back( help );
188 required_args[helpname] = opt;
189 }
References arg_help_strings, help(), required_args, and ProgOpt::storage.
Referenced by main().
void ProgOptions::error | ( | const std::string & | message | ) |
Prints an error message to std::cerr, along with a brief usage message, then halts the program. Used throughout ProgramOptions implementation. Users may call this directly if they detect an incorrect usage of program options that the ProgramOptions wasn't able to detect itself.
message | The error message to print before program halt. |
Definition at line 396 of file ProgOptions.cpp.
397 {
398 std::cerr << "Error: " << err << "\n" << std::endl;
399 ;
400 printUsage( std::cerr );
401 std::cerr << std::endl;
402 if( getenv( "MOAB_PROG_OPT_ABORT" ) ) abort();
403 std::exit( EXIT_FAILURE );
404 }
References printUsage().
Referenced by addOpt(), evaluate(), getArgs(), getOpt(), getOptAllArgs(), getReqArg(), lookup_option(), main(), numOptSet(), parseCommandLine(), and process_option().
|
protected |
Check the input to a given option for correctness, converting it to its expected type (e.g. int) and storing the result to target, if target is non-NULL.
option | Used only in error messages to state which option could not be successfully converted |
arg_idx | If non-NULL, evaluate the (*arg_idx)'th item in opt's args list |
Definition at line 501 of file ProgOptions.cpp.
502 {
503
504 unsigned idx = arg_idx ? *arg_idx : opt.args.size() - 1;
505
506 switch( opt.type )
507 {
508 case FLAG:
509 error( "Cannot evaluate a flag" );
510 break;
511 case INT: {
512 int temp;
513 int* i = target ? reinterpret_cast< int* >( target ) : &temp;
514 if( opt.args.size() < 1 )
515 {
516 error( "Missing argument to " + option + " option" );
517 }
518 const char* arg = opt.args.at( idx ).c_str();
519 char* p;
520 *i = std::strtol( arg, &p, 0 );
521 if( *p != '\0' )
522 {
523 error( "Bad integer argument '" + opt.args.at( idx ) + "' to " + option + " option." );
524 }
525 return true;
526 }
527 case REAL: {
528 double temp;
529 double* i = target ? reinterpret_cast< double* >( target ) : &temp;
530 if( opt.args.size() < 1 )
531 {
532 error( "Missing argument to " + option + " option" );
533 }
534 const char* arg = opt.args.at( idx ).c_str();
535 char* p;
536 *i = std::strtod( arg, &p );
537 if( *p != '\0' )
538 {
539 error( "Bad real argument '" + opt.args.at( idx ) + "' to " + option + " option." );
540 }
541 return true;
542 }
543
544 case STRING: {
545 std::string temp;
546 std::string* i = target ? reinterpret_cast< std::string* >( target ) : &temp;
547 if( opt.args.size() < 1 )
548 {
549 error( "Missing argument to " + option + " option" );
550 }
551 if( opt.flags & rank_subst )
552 *i = do_rank_subst( opt.args.at( idx ) );
553 else
554 *i = opt.args.at( idx );
555 return true;
556 }
557
558 case INT_VECT: {
559 std::vector< int > temp;
560 std::vector< int >* i = target ? reinterpret_cast< std::vector< int >* >( target ) : &temp;
561 if( !parse_int_list( opt.args.at( idx ).c_str(), *i ) )
562 error( "Bad integer list '" + opt.args.at( idx ) + "' to " + option + " option." );
563 return true;
564 }
565 }
566
567 return false;
568 }
References ProgOpt::args, do_rank_subst(), error(), FLAG, ProgOpt::flags, INT, INT_VECT, parse_int_list(), rank_subst, REAL, STRING, and ProgOpt::type.
Referenced by getArgs(), getOpt(), getOptAllArgs(), getReqArg(), parseCommandLine(), and process_option().
|
protected |
Definition at line 118 of file ProgOptions.cpp.
119 {
120 *shortname = "";
121 *longname = namestring;
122
123 size_t idx = namestring.find_first_of( ',' );
124 if( idx != namestring.npos )
125 {
126 *longname = namestring.substr( 0, idx );
127 *shortname = namestring.substr( idx + 1, namestring.npos );
128 }
129 }
Referenced by addOpt(), lookup_option(), and numOptSet().
|
protected |
Definition at line 309 of file ProgOptions.cpp.
310 {
311 bool has_shortname = option.shortname.length() > 0;
312 bool has_longname = option.longname.length() > 0;
313 std::string argstr = option.get_argstring();
314
315 std::stringstream s;
316 s << " ";
317 if( has_shortname )
318 {
319
320 s << "-" << option.shortname;
321 if( has_longname )
322 {
323 s << " ";
324 }
325 }
326 else if( option.flags & int_flag )
327 {
328
329 s << "-<n>";
330 if( has_longname )
331 {
332 s << " ";
333 }
334 }
335 if( has_longname )
336 {
337
338 if( has_shortname ) s << "[";
339 s << "--" << option.longname;
340 if( has_shortname ) s << "]";
341 }
342
343 if( argstr.length() ) s << " <" << argstr << ">";
344 return s.str();
345 }
References ProgOpt::flags, ProgOpt::get_argstring(), int_flag, ProgOpt::longname, and ProgOpt::shortname.
Referenced by printHelp().
void ProgOptions::getArgs | ( | const std::string & | namestring, |
std::vector< T > & | values | ||
) |
Append the values of any required or optional arguments
namestring | The helpname that was given to addRequiredArg or addOptionalArgs. |
Definition at line 655 of file ProgOptions.cpp.
656 {
657 ProgOpt* opt = lookup( required_args, namestring );
658
659 if( !opt )
660 {
661 error( "Could not look up required arg: " + namestring );
662 }
663
664 if( get_opt_type< T >() != opt->type )
665 {
666 error( "Option '" + namestring + "' looked up with incompatible type" );
667 }
668
669 values.resize( opt->args.size() );
670
671 // These calls to evaluate are inefficient, because the arguments were evaluated when they were
672 // parsed
673 for( unsigned i = 0; i < opt->args.size(); ++i )
674 {
675 evaluate( *opt, &( values[i] ), "", &i );
676 }
677 }
References ProgOpt::args, error(), evaluate(), lookup(), required_args, and ProgOpt::type.
bool ProgOptions::getOpt | ( | const std::string & | namestring, |
T * | value | ||
) |
Get the value of the named option.
namestring | The name string given when the option was created. This need not be idential to the created name; only the longname, or the shortname (with comma prefix), will also work. |
value | Pointer to location to store option argument, if any is found |
Definition at line 571 of file ProgOptions.cpp.
572 {
573
574 ProgOpt* opt = lookup_option( namestring );
575
576 if( get_opt_type< T >() != opt->type )
577 {
578 error( "Option '" + namestring + "' looked up with incompatible type" );
579 }
580
581 // This call to evaluate is inefficient, because opt was already evaluated when it was parsed.
582 if( opt->args.size() )
583 {
584 if( t ) evaluate( *opt, t, "" );
585 return true;
586 }
587 else
588 return false;
589 }
References ProgOpt::args, error(), evaluate(), lookup_option(), and ProgOpt::type.
Referenced by main().
void ProgOptions::getOptAllArgs | ( | const std::string & | namestring, |
std::vector< T > & | values | ||
) |
Get a list of values for the named option– one value for each time it was given on the command line.
This function cannot be called with void as the template parameter; compilers will reject vector<void> as a type. This means it cannot be called for flag-type options. To count the number of times a given flag was specified, use numOptSet()
namestring | See similar argument to getOpt() |
values | Reference to list to store values into. Will have as many entries as there were instances of this option on the command line |
Definition at line 592 of file ProgOptions.cpp.
593 {
594 ProgOpt* opt = lookup_option( namestring );
595
596 // special case: if user asks for list of int, but argument
597 // was INT_VECT, concatenate all lists
598 if( get_opt_type< T >() == INT && opt->type == INT_VECT )
599 {
600 for( unsigned i = 0; i < opt->args.size(); ++i )
601 evaluate( *opt, &values, "", &i );
602 return;
603 }
604
605 if( get_opt_type< T >() != opt->type )
606 {
607 error( "Option '" + namestring + "' looked up with incompatible type" );
608 }
609
610 values.resize( opt->args.size() );
611
612 // These calls to evaluate are inefficient, because the arguments were evaluated when they were
613 // parsed
614 for( unsigned i = 0; i < opt->args.size(); ++i )
615 {
616 evaluate( *opt, &( values[i] ), "", &i );
617 }
618 }
References ProgOpt::args, error(), evaluate(), INT, INT_VECT, lookup_option(), and ProgOpt::type.
Referenced by main(), and ToolContext::ParseCLOptions().
T ProgOptions::getReqArg | ( | const std::string & | namestring | ) |
Retrieve the value of a required command-line argument by name
namestring | The helpname that was given to addRequiredArg when the desired argument was created |
Definition at line 637 of file ProgOptions.cpp.
638 {
639
640 ProgOpt* opt = lookup( required_args, namestring );
641
642 if( !opt )
643 {
644 error( "Could not look up required arg: " + namestring );
645 }
646
647 // if parseProgramOptions succeeded, we can assume each required arg has a value,
648 // so calling evaluate is valid
649 T value;
650 evaluate( *opt, &value, "" );
651 return value;
652 }
References error(), evaluate(), lookup(), and required_args.
Referenced by main().
|
protected |
Definition at line 368 of file ProgOptions.cpp.
369 {
370 std::map< std::string, ProgOpt* >::const_iterator it = table.find( arg );
371 if( it != table.end() )
372 return it->second;
373 else if( &table == &short_names && arg.size() == 1 && isdigit( arg[0] ) && !number_option_name.empty() &&
374 ( it = long_names.find( number_option_name ) ) != long_names.end() )
375 return it->second;
376 else
377 return 0;
378 }
References long_names, number_option_name, and short_names.
Referenced by getArgs(), getReqArg(), lookup_option(), numOptSet(), and parseCommandLine().
|
protected |
Definition at line 380 of file ProgOptions.cpp.
381 {
382 std::string longname, shortname;
383 get_namestrings( namestring, &longname, &shortname );
384
385 ProgOpt* opt = lookup( long_names, longname );
386 if( !opt ) opt = lookup( short_names, shortname );
387
388 if( !opt )
389 {
390 error( "Invalid option: " + namestring );
391 }
392
393 return opt;
394 }
References error(), get_namestrings(), long_names, lookup(), and short_names.
Referenced by getOpt(), and getOptAllArgs().
int ProgOptions::numOptSet | ( | const std::string & | namestring | ) |
namestring | See similar argument to getOpt() |
Definition at line 620 of file ProgOptions.cpp.
621 {
622 std::string longname, shortname;
623 get_namestrings( namestring, &longname, &shortname );
624
625 ProgOpt* opt = lookup( long_names, longname );
626 if( !opt ) opt = lookup( short_names, shortname );
627
628 if( !opt )
629 {
630 error( "Could not look up option: " + namestring );
631 }
632
633 return opt->args.size();
634 }
References ProgOpt::args, error(), get_namestrings(), long_names, lookup(), and short_names.
Referenced by main(), and ToolContext::ParseCLOptions().
void ProgOptions::parseCommandLine | ( | int | argc, |
char * | argv[] | ||
) |
Parse command-line inputs as given to main()
Definition at line 737 of file ProgOptions.cpp.
738 {
739 const char* name = strrchr( argv[0], '/' );
740 if( name )
741 this->progname = ++name;
742 else
743 this->progname = argv[0];
744
745 std::vector< const char* > args;
746 std::list< ProgOpt* > expected_vals;
747 bool no_more_flags = false;
748
749 // Loop over all command line arguments
750 for( int i = 1; i < argc; ++i )
751 {
752 std::string arg( argv[i] );
753 if( arg.empty() ) continue;
754
755 if( !expected_vals.empty() )
756 {
757 ProgOpt* opt = expected_vals.front();
758 expected_vals.pop_front();
759 assert( opt->type != FLAG );
760 opt->args.push_back( arg );
761 evaluate( *opt, opt->storage, arg );
762 }
763 else if( !no_more_flags && arg[0] == '-' )
764 {
765 if( arg.length() > 2 && arg[1] == '-' )
766 { // long opt
767 size_t eq = arg.find_first_of( '=' );
768 if( eq != std::string::npos )
769 {
770 ProgOpt* opt = lookup( long_names, arg.substr( 2, eq - 2 ) );
771 process_option( opt, arg, arg.substr( eq + 1 ).c_str() );
772 }
773 else
774 {
775 ProgOpt* opt = lookup( long_names, arg.substr( 2 ) );
776 if( process_option( opt, arg ) ) expected_vals.push_back( opt );
777 }
778 }
779 else if( arg == "--" )
780 { // --
781 no_more_flags = true;
782 }
783 else
784 for( size_t f = 1; f < arg.length(); ++f )
785 { // for each short opt
786 ProgOpt* opt = lookup( short_names, std::string( 1, arg[f] ) );
787 if( opt && ( opt->flags & int_flag ) )
788 {
789 const char val[] = { arg[f], 0 };
790 process_option( opt, std::string( 1, arg[f] ), val );
791 }
792 else if( process_option( opt, std::string( 1, arg[f] ) ) )
793 expected_vals.push_back( opt );
794 }
795 }
796 else
797 {
798 /* arguments */
799 args.push_back( argv[i] );
800 }
801 } /* End loop over inputs */
802
803 // Print error if any missing values
804 if( !expected_vals.empty() )
805 {
806 error( "Missing value for option: -" + expected_vals.front()->shortname + ",--" +
807 expected_vals.front()->longname );
808 }
809
810 // Process non-option arguments
811 std::vector< help_line >::iterator arg_help_pos = arg_help_strings.begin();
812 std::vector< const char* >::iterator arg_val_pos = args.begin();
813 std::vector< help_line >::iterator opt_args_pos = arg_help_strings.end();
814 size_t min_required_args = required_args.size();
815 size_t max_required_args = required_args.size();
816 if( expect_optional_args )
817 {
818 min_required_args--;
819 if( max_optional_args )
820 max_required_args += max_optional_args;
821 else
822 max_required_args = std::numeric_limits< int >::max();
823 opt_args_pos = arg_help_pos + optional_args_position;
824 }
825 // check valid number of non-flag arguments
826 if( args.size() < min_required_args )
827 {
828 size_t missing_pos = args.size();
829 if( expect_optional_args && missing_pos >= optional_args_position ) ++missing_pos;
830
831 const std::string& missed_arg = arg_help_strings[missing_pos].first->longname;
832 error( "Did not find required positional argument: " + missed_arg );
833 }
834 else if( args.size() > max_required_args )
835 {
836 error( "Unexpected argument: " + std::string( args[max_required_args] ) );
837 }
838
839 // proccess arguments up to the first optional argument
840 // (or all arguments if no optional args)
841 while( arg_help_pos != opt_args_pos )
842 {
843 ProgOpt* opt = arg_help_pos->first;
844 ++arg_help_pos;
845 opt->args.push_back( *arg_val_pos );
846 evaluate( *opt, opt->storage, *arg_val_pos );
847 ++arg_val_pos;
848 }
849 // process any optional args
850 if( arg_help_pos != arg_help_strings.end() )
851 {
852 assert( arg_help_pos == opt_args_pos );
853 size_t num_opt_args = args.size() + 1 - required_args.size();
854 ProgOpt* opt = arg_help_pos->first;
855 ++arg_help_pos;
856 while( num_opt_args-- )
857 {
858 opt->args.push_back( *arg_val_pos );
859 evaluate( *opt, opt->storage, *arg_val_pos );
860 ++arg_val_pos;
861 }
862 }
863 // process any remaining args
864 while( arg_help_pos != arg_help_strings.end() )
865 {
866 assert( arg_val_pos != args.end() );
867 ProgOpt* opt = arg_help_pos->first;
868 ++arg_help_pos;
869 opt->args.push_back( *arg_val_pos );
870 evaluate( *opt, opt->storage, *arg_val_pos );
871 ++arg_val_pos;
872 }
873 assert( arg_val_pos == args.end() );
874 }
References arg_help_strings, ProgOpt::args, error(), evaluate(), expect_optional_args, FLAG, ProgOpt::flags, int_flag, long_names, lookup(), max_optional_args, optional_args_position, process_option(), progname, required_args, short_names, ProgOpt::storage, and ProgOpt::type.
Referenced by main(), RuntimeContext::ParseCLOptions(), and ToolContext::ParseCLOptions().
void ProgOptions::printHelp | ( | std::ostream & | str = std::cout | ) |
Print the full help to the given stream
Definition at line 226 of file ProgOptions.cpp.
227 {
228
229 /* Print introductory help text */
230 if( !brief_help.empty() ) out << brief_help << std::endl;
231 for( std::vector< std::string >::iterator i = main_help.begin(); i != main_help.end(); ++i )
232 {
233 if( ( *i ).length() )
234 {
235 out << std::endl << *i << std::endl;
236 }
237 }
238
239 printUsage( out );
240
241 // max number of characters to pad argument/option names with
242 // options with long names may exceed this, but will appear out of alignment in help text
243 const int max_padding = 20;
244
245 /* List required arguments, with help text */
246 if( arg_help_strings.size() > 0 )
247 {
248
249 int max_arg_namelen = 0;
250
251 for( std::vector< help_line >::iterator i = arg_help_strings.begin(); i != arg_help_strings.end(); ++i )
252 {
253 max_arg_namelen = std::max( max_arg_namelen, (int)( ( *i ).first->longname.length() ) );
254 }
255
256 max_arg_namelen = std::min( max_arg_namelen + 3, max_padding );
257
258 out << "Arguments: " << std::endl;
259
260 for( std::vector< help_line >::iterator i = arg_help_strings.begin(); i != arg_help_strings.end(); ++i )
261 {
262 ProgOpt* option = ( *i ).first;
263 std::string& info = ( *i ).second;
264
265 std::stringstream s;
266 s << " " << option->longname;
267 out << std::setw( max_arg_namelen ) << std::left << s.str();
268 out << ": " << info << std::endl;
269 }
270 }
271
272 /* List options, with help text */
273 out << "Options: " << std::endl;
274 int max_option_prefix_len = 0;
275
276 for( std::vector< help_line >::iterator i = option_help_strings.begin(); i != option_help_strings.end(); ++i )
277 {
278 ProgOpt* option = ( *i ).first;
279 std::string& info = ( *i ).second;
280
281 if( option )
282 {
283
284 if( max_option_prefix_len == 0 )
285 {
286 // iterate ahead in the option list to determine whitespace padding
287 // stop if (*j).first is NULL, which indicates a help header message
288 for( std::vector< help_line >::iterator j = i; j != option_help_strings.end() && ( *j ).first; ++j )
289 {
290 int len = get_option_usage_prefix( *( ( *j ).first ) ).length();
291 max_option_prefix_len = std::max( max_option_prefix_len, len );
292 }
293 }
294 max_option_prefix_len = std::min( max_option_prefix_len, max_padding );
295 std::string option_prefix = get_option_usage_prefix( *option );
296
297 out << std::setw( max_option_prefix_len ) << std::left << option_prefix;
298 out << ": ";
299 }
300 else
301 {
302 // no option: this is a help header. Reset max name length.
303 max_option_prefix_len = 0;
304 }
305 out << info << std::endl;
306 }
307 }
References arg_help_strings, brief_help, get_option_usage_prefix(), ProgOpt::longname, main_help, option_help_strings, and printUsage().
Referenced by main(), and process_option().
void ProgOptions::printUsage | ( | std::ostream & | str = std::cout | ) |
Print only the usage message to the given stream
Definition at line 347 of file ProgOptions.cpp.
348 {
349
350 out << "Usage: " << progname << " --help | [options] ";
351
352 for( size_t i = 0; i < arg_help_strings.size(); ++i )
353 {
354 if( !expect_optional_args || i != optional_args_position )
355 out << '<' << arg_help_strings[i].first->longname << "> ";
356 else if( 0 == max_optional_args || max_optional_args > 3 )
357 out << "[<" << arg_help_strings[i].first->longname << "> ...] ";
358 else if( 1 == max_optional_args )
359 out << "[" << arg_help_strings[i].first->longname << "] ";
360 else
361 for( unsigned j = 0; j < max_optional_args; ++j )
362 out << "[" << arg_help_strings[i].first->longname << ( j + 1 ) << "] ";
363 }
364
365 out << std::endl;
366 }
References arg_help_strings, expect_optional_args, moab::GeomUtil::first(), max_optional_args, optional_args_position, and progname.
Referenced by error(), and printHelp().
void ProgOptions::printVersion | ( | std::ostream & | str = std::cout | ) |
Print the version string to the given stream
Definition at line 221 of file ProgOptions.cpp.
222 {
223 out << progversion << std::endl;
224 }
References progversion.
Referenced by process_option().
|
protected |
Definition at line 683 of file ProgOptions.cpp.
684 {
685 if( !opt )
686 {
687 if( arg == "--manpage" )
688 {
689 write_man_page( std::cout );
690 exit( 0 );
691 }
692
693 error( "Unknown option: " + arg );
694 }
695
696 if( opt->flags & help_flag )
697 {
698 printHelp( std::cout );
699 exit( EXIT_SUCCESS );
700 }
701
702 if( opt->flags & version_flag )
703 {
704 printVersion( std::cout );
705 exit( EXIT_SUCCESS );
706 }
707
708 if( opt->type != FLAG )
709 {
710 if( !value ) return true;
711
712 opt->args.push_back( value );
713 evaluate( *opt, opt->storage, arg );
714 }
715 else
716 {
717 if( value )
718 {
719 error( "Unexpected value for flag: " + arg );
720 }
721
722 // do flag operations
723 if( opt->cancel_opt )
724 {
725 opt->cancel_opt->args.clear();
726 }
727 if( opt->storage )
728 {
729 *static_cast< bool* >( opt->storage ) = ( opt->flags & store_false ) ? false : true;
730 }
731 opt->args.push_back( "" );
732 }
733
734 return false;
735 }
References ProgOpt::args, ProgOpt::cancel_opt, error(), evaluate(), FLAG, ProgOpt::flags, help_flag, printHelp(), printVersion(), ProgOpt::storage, store_false, ProgOpt::type, version_flag, and write_man_page().
Referenced by parseCommandLine().
void ProgOptions::setVersion | ( | const std::string & | version_string, |
bool | addFlag = true |
||
) |
Specify the program version
Set the program version to a given string. This will be printed when printVersion() is called.
version_string | The version string |
addflag | If true, a default '–version' option will be added. If false, the version will be set, but no option will be added to the parser. |
Definition at line 131 of file ProgOptions.cpp.
132 {
133 progversion = version_string;
134 if( addFlag )
135 {
136 addOpt< void >( "version", "Print version number and exit", version_flag );
137 }
138 }
References progversion, and version_flag.
void ProgOptions::write_man_page | ( | std::ostream & | to_this_stream | ) |
Write help data formatted for use as a unix man page.
Definition at line 876 of file ProgOptions.cpp.
877 {
878 // a leading '.' is a control character. strip it if present.
879 std::string lprogname;
880 if( progname.empty() || progname[0] != '.' )
881 lprogname = progname;
882 else
883 {
884 lprogname = progname.substr( 1 );
885 }
886
887 // Manpage controls:
888 // .TH title
889 // .SH section
890 // .SS subsection
891 // .P paragraph
892 // .HP hanging paragraph
893 // .B bold
894 // .I italic
895 // .B bold
896 // .I italic
897 // .RS begin indent
898 // .RE end indent
899 // .RB alternating roman and blold
900 // .BR alternating bold and roman
901
902 std::vector< help_line >::iterator it;
903 std::set< ProgOpt* > skip_list;
904
905 // start man page
906 s << std::endl << ".TH " << lprogname << " 1" << std::endl;
907
908 // write NAME section
909 s << std::endl << ".SH NAME" << std::endl << ".P " << std::endl << lprogname << " \\- ";
910 if( brief_help.empty() && !main_help.empty() )
911 s << main_help.front();
912 else
913 s << brief_help;
914 s << std::endl << std::endl;
915
916 // write SYNOPSIS section
917 s << std::endl << ".SH SYNOPSIS" << std::endl << ".HP" << std::endl << ".B \"" << lprogname << '"' << std::endl;
918 for( it = option_help_strings.begin(); it != option_help_strings.end(); ++it )
919 {
920 if( !it->first || skip_list.find( it->first ) != skip_list.end() || it->first->longname == "help" ) continue;
921
922 if( it->first->type == FLAG )
923 {
924 char c = '[';
925 s << ".RB";
926 if( !it->first->shortname.empty() )
927 {
928 s << ' ' << c << " \"-" << it->first->shortname << '"';
929 c = '|';
930 }
931 if( !it->first->longname.empty() )
932 {
933 s << ' ' << c << " \"--" << it->first->longname << '"';
934 }
935 if( it->first->cancel_opt )
936 {
937 skip_list.insert( it->first->cancel_opt );
938 if( !it->first->cancel_opt->shortname.empty() )
939 s << " | \"-" << it->first->cancel_opt->shortname << '"';
940 if( !it->first->cancel_opt->longname.empty() ) s << " | \"--" << it->first->cancel_opt->longname << '"';
941 }
942 s << " ]" << std::endl;
943 }
944 else if( it->first->flags & int_flag )
945 {
946 s << ".RB [ - <n>| \"--" << it->first->longname << "\" \"=" << it->first->get_argstring() << "]\""
947 << std::endl;
948 }
949 else
950 {
951 s << ".RB [ ";
952 if( !it->first->shortname.empty() )
953 s << "\"-" << it->first->shortname << "\" \"\\ " << it->first->get_argstring();
954 if( !it->first->shortname.empty() && !it->first->longname.empty() ) s << "|\" ";
955 if( !it->first->longname.empty() )
956 s << "\"--" << it->first->longname << "\" \"=" << it->first->get_argstring();
957 s << "]\"" << std::endl;
958 }
959 }
960 for( it = arg_help_strings.begin(); it != arg_help_strings.end(); ++it )
961 {
962 if( !it->first ) continue;
963
964 if( !expect_optional_args || (unsigned)( it - arg_help_strings.begin() ) != optional_args_position )
965 s << it->first->longname << ' ';
966 else if( 1 == max_optional_args )
967 s << '[' << it->first->longname << "] ";
968 else
969 s << '[' << it->first->longname << " ...] ";
970 }
971 s << std::endl;
972 s << ".HP" << std::endl << ".B \"" << lprogname << " -h|--help\"" << std::endl;
973
974 // write DESCRIPTION section
975 s << std::endl << ".SH DESCRIPTION" << std::endl;
976 if( main_help.empty() ) s << brief_help << std::endl;
977 for( size_t i = 0; i < main_help.size(); ++i )
978 {
979 const std::string::size_type n = main_help[i].size();
980 std::string::size_type j = 0, k;
981 s << std::endl << ".P" << std::endl;
982 while( j != n )
983 {
984 if( main_help[i][j] == '\n' )
985 {
986 s << std::endl << ".P" << std::endl;
987 ++j;
988 continue;
989 }
990 k = main_help[i].find( "\n", j );
991 if( k == std::string::npos ) k = n;
992 if( main_help[i][j] == '.' ) s << '\\';
993 s << main_help[i].substr( j, k - j );
994 j = k;
995 }
996 }
997
998 // write OPTIONS section
999 s << std::endl << ".SH OPTIONS" << std::endl;
1000 for( it = arg_help_strings.begin(); it != arg_help_strings.end(); ++it )
1001 {
1002 if( it->first )
1003 s << ".IP \"" << it->first->longname << '"' << std::endl << it->second << std::endl;
1004 else
1005 s << ".SS " << it->first->longname << std::endl;
1006 }
1007 for( it = option_help_strings.begin(); it != option_help_strings.end(); ++it )
1008 {
1009 if( !it->first )
1010 {
1011 s << ".SS " << it->second << std::endl;
1012 continue;
1013 }
1014
1015 s << ".IP \"";
1016 if( it->first->longname.empty() )
1017 s << "-" << it->first->shortname;
1018 else if( it->first->shortname.empty() )
1019 s << "--" << it->first->longname;
1020 else
1021 s << "-" << it->first->shortname << ", --" << it->first->longname;
1022 s << '"' << std::endl << it->second << std::endl;
1023 }
1024 s << std::endl;
1025 }
References arg_help_strings, brief_help, expect_optional_args, FLAG, int_flag, main_help, max_optional_args, option_help_strings, optional_args_position, and progname.
Referenced by process_option().
|
static |
Flag indicating that an option should be given a "cancel" flag. This creates, for option –foo, an additional option –no-foo that clears all previously read instances of the foo option.
Definition at line 51 of file ProgOptions.hpp.
|
protected |
Definition at line 264 of file ProgOptions.hpp.
Referenced by addOptionalArgs(), addRequiredArg(), parseCommandLine(), printHelp(), printUsage(), write_man_page(), and ~ProgOptions().
|
protected |
Definition at line 266 of file ProgOptions.hpp.
Referenced by printHelp(), ProgOptions(), and write_man_page().
|
protected |
Definition at line 268 of file ProgOptions.hpp.
Referenced by addOptionalArgs(), parseCommandLine(), printUsage(), and write_man_page().
|
static |
Set for a flag that, when detected, prints help text and halts program. Constructor creates such a flag by default, so the user shouldn't need to use this directly.
Flags for addOpt and addRequiredArg functions; may be combined with bitwise arithmetic (though not all combinations make sense!)
Definition at line 46 of file ProgOptions.hpp.
Referenced by process_option(), and ProgOptions().
|
static |
Specify a numerical flag where any positive integer is an acceptable value. E.g. –dimension=3 is equivalent to -3. Only values in the range [0,9] are accepted and the flag type must be integer.
Definition at line 61 of file ProgOptions.hpp.
Referenced by addOpt(), get_option_usage_prefix(), main(), parseCommandLine(), and write_man_page().
|
protected |
Definition at line 258 of file ProgOptions.hpp.
Referenced by addOpt(), lookup(), lookup_option(), numOptSet(), and parseCommandLine().
|
protected |
Definition at line 265 of file ProgOptions.hpp.
Referenced by printHelp(), ProgOptions(), and write_man_page().
|
protected |
Definition at line 269 of file ProgOptions.hpp.
Referenced by addOptionalArgs(), parseCommandLine(), printUsage(), and write_man_page().
|
protected |
Definition at line 276 of file ProgOptions.hpp.
|
protected |
Definition at line 263 of file ProgOptions.hpp.
Referenced by addOpt(), addOptionHelpHeading(), printHelp(), write_man_page(), and ~ProgOptions().
|
protected |
Definition at line 269 of file ProgOptions.hpp.
Referenced by addOptionalArgs(), parseCommandLine(), printUsage(), and write_man_page().
|
protected |
Definition at line 271 of file ProgOptions.hpp.
Referenced by parseCommandLine(), printUsage(), and write_man_page().
|
protected |
Definition at line 272 of file ProgOptions.hpp.
Referenced by printVersion(), and setVersion().
|
static |
Substitue any occurance of the '' symbol in a string with the the MPI rank of this process in MPI_COMM_WORLD. This option has no effect if not compiled with MPI. This flag has no effect for non-string options.
Definition at line 68 of file ProgOptions.hpp.
Referenced by evaluate().
|
protected |
Definition at line 260 of file ProgOptions.hpp.
Referenced by addOptionalArgs(), addRequiredArg(), getArgs(), getReqArg(), and parseCommandLine().
|
protected |
Definition at line 259 of file ProgOptions.hpp.
Referenced by addOpt(), lookup(), lookup_option(), numOptSet(), and parseCommandLine().
|
static |
When applied to a flag argument (one with template type void), indicate that the value 'false' should be stored into the pointer that was given at option creation time. This overrides the default behavior, which is to store the value 'true'.
Definition at line 56 of file ProgOptions.hpp.
Referenced by addOpt(), and process_option().
|
static |
Set for a flag that, when detected, will call printVersion() and halt the program.
Definition at line 71 of file ProgOptions.hpp.
Referenced by process_option(), and setVersion().