Loading [MathJax]/extensions/tex2jax.js
Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ProgOptions.hpp
Go to the documentation of this file.
1 #ifndef MOAB_PROGRAM_OPTIONS_H 2 #define MOAB_PROGRAM_OPTIONS_H 3  4 #include <vector> 5 #include <map> 6 #include <string> 7 #include <iostream> 8  9 class ProgOpt; 10  11 /** A simple command-line option parser and help utility 12  * 13  * Utility class to specify a program's command-line options arguments, produce a help message 14  * explaining how they work, and parse user's command line input (producing useful errors messages 15  * if any problems arise). Loosely (okay, very loosely) inspired by boost program_options. 16  * 17  * Options are specified by a comma-separated namestring. An option named "foo,f" can be specified 18  * three ways on the command line: "-f val", "--foo val", or "--foo=val". The types of options 19  * and arguments are specified by function templates. Valid template values for positional argument 20  * and options are int, double, and std::string. void may also be used in options, and it indicates 21  * a command line option that does not take an argument. 22  * 23  * Example usage: 24  * ProgOptions po( "Example usage of ProgOptions" ); 25  * po.addOpt<void>( "verbose,v", "Turn on verbose messages" ); 26  * po.addOpt<std::string> ("foo", "Specify the foo string" ); 27  * int x = 0; 28  * po.addOpt<int>( ",x", "Specify the x number", &x ); // x will be automatically set when options 29  * parsed po.parseCommandLine( argc, argv ); bool verbose = po.numOptSet("verbose") > 0; std::string 30  * foo; if( !po.getOpt( "foo", &foo ) ) foo = "default"; 31  * ... 32  * 33  * See the file dagmc_preproc.cpp in the dagmc directory for a real-world example. 34  */ 35 class ProgOptions 36 { 37  38  public: 39  /** 40  * Flags for addOpt and addRequiredArg functions; may be combined with bitwise arithmetic 41  * (though not all combinations make sense!) 42  **/ 43  44  /// Set for a flag that, when detected, prints help text and halts program. 45  /// Constructor creates such a flag by default, so the user shouldn't need to use this directly. 46  static const int help_flag = 1 << 0; 47  48  /// Flag indicating that an option should be given a "cancel" flag. 49  /// This creates, for option --foo, an additional option --no-foo that 50  /// clears all previously read instances of the foo option 51  static const int add_cancel_opt = 1 << 1; 52  53  /// When applied to a flag argument (one with template type void), indicate that the 54  /// value 'false' should be stored into the pointer that was given at option creation time. 55  /// This overrides the default behavior, which is to store the value 'true'. 56  static const int store_false = 1 << 2; 57  58  /// Specify a numerical flag where any positive integer is an acceptable 59  /// value. E.g. --dimension=3 is equivalent to -3. Only values in the 60  /// range [0,9] are accepted and the flag type must be integer. 61  static const int int_flag = 1 << 3; 62  63  /** Substitue any occurance of the '%' symbol in a string with 64  * the the MPI rank of this process in MPI_COMM_WORLD. This 65  * option has no effect if not compiled with MPI. This flag 66  * has no effect for non-string options. 67  */ 68  static const int rank_subst = 1 << 4; 69  70  /// Set for a flag that, when detected, will call printVersion() and halt the program. 71  static const int version_flag = 1 << 5; 72  73  /// unimplemented flag for required arguments that may be given multiple times 74  // const static int accept_multiple; 75  76  /** 77  * @param helptext A brief summary of the program's function, to be printed 78  * when the help flag is detected 79  */ 80  ProgOptions( const std::string& helptext = "", const std::string& briefdesc = "" ); 81  ~ProgOptions(); 82  83  /** Specify the program version 84  * 85  * Set the program version to a given string. This will be printed when printVersion() 86  * is called. 87  * @param version_string The version string 88  * @param addflag If true, a default '--version' option will be added. If false, 89  * the version will be set, but no option will be added to the parser. 90  */ 91  void setVersion( const std::string& version_string, bool addFlag = true ); 92  93  /** Specify a new command-line option 94  * 95  * Instruct the parser to accept a new command-line argument, as well as specifying 96  * how the argument should be handled. The template parameter indicates the type of 97  * command-line option being specified: acceptable types are void (indicating a flag 98  * without an argument), int, double, and std::string. 99  * 100  * @param namestring The command-line options name(s). Format is longname,shortname. 101  * If the comma is omitted, or appears only at the end, this option will have 102  * no shortname; if the comma is the first letter of the namestring, the option 103  * has no longname. 104  * @param helpstring The help information displayed for the option when the program is 105  * invoked with --help 106  * @param value A pointer to memory in which to store the parsed value for this option. 107  * If NULL, then the value of the option must be queried using the getOpt function. 108  * If the template parameter is void and value is non-NULL, treat value as a bool* 109  * and store 'true' into it when the flag is encountered. (See also store_false, above) 110  * @param flags Option behavior flags, which should come from static vars in the ProgOptions 111  * class 112  */ 113  template < typename T > 114  void addOpt( const std::string& namestring, const std::string& helpstring, T* value, int flags = 0 ); 115  116  /** Specify a new command-line option 117  * 118  * This funtion is identical to the 4-arg version, but omits the value parameter, which 119  * is assumed to be NULL 120  */ 121  template < typename T > 122  void addOpt( const std::string& namestring, const std::string& helpstring, int flags = 0 ) 123  { 124  addOpt< T >( namestring, helpstring, NULL, flags ); 125  } 126  127  /** Add a new line of help text to the option help printout 128  * 129  * Add a line of text to the option-related help. Called between calls to addOpt(), 130  * this function can be used to divide the option list into groups of related options 131  * to make the help text more convenient. 132  */ 133  void addOptionHelpHeading( const std::string& ); 134  135  /** Add required positional argument 136  * 137  * Add a new required positional argument. The order in which arguments are specified 138  * is the order in which they will be expected on the command line. 139  * The template parameter may be int, double, or std::string (but not void) 140  * @param helpname The name to give the argument in the help text 141  * @param helpstring The help text for the argument 142  * @param value Pointer to where parsed value from command line should be stored. 143  * If NULL, the value must be queried using getReqArg() 144  */ 145  template < typename T > 146  void addRequiredArg( const std::string& helpname, const std::string& helpstring, T* value = NULL, int flags = 0 ); 147  148  /** Add optional positional arguments 149  * 150  * Specify location in ordered argument list at which optional arguments 151  * may occur. Optional arguments are allowed at only one location 152  * it argument list (this function may not be called more than once.). 153  * The template parameter may be int, double, or std::string (but not void) 154  * @param count The maximum number of optional arguments. Specify zero for unlimited. 155  * @param helpname The name to give the argument in the help text 156  * @param helpstring The help text for the arguments 157  */ 158  template < typename T > 159  void addOptionalArgs( unsigned max_count, 160  const std::string& helpname, 161  const std::string& helpstring, 162  int flags = 0 ); 163  164  /** 165  * Print the full help to the given stream 166  */ 167  void printHelp( std::ostream& str = std::cout ); 168  169  /** 170  * Print only the usage message to the given stream 171  */ 172  void printUsage( std::ostream& str = std::cout ); 173  174  /** 175  * Print the version string to the given stream 176  */ 177  void printVersion( std::ostream& str = std::cout ); 178  179  /** 180  * Parse command-line inputs as given to main() 181  */ 182  void parseCommandLine( int argc, char* argv[] ); 183  184  /** 185  * 186  * Get the value of the named option. 187  * @param namestring The name string given when the option was created. This need not be 188  * idential to the created name; only the longname, or the shortname (with comma prefix), 189  * will also work. 190  * @param value Pointer to location to store option argument, if any is found 191  * @return True if the option was set and its argument was stored into value; false otherwise. 192  */ 193  template < typename T > 194  bool getOpt( const std::string& namestring, T* value ); 195  196  /** 197  * Get a list of values for the named option-- one value for each time it was 198  * given on the command line. 199  * 200  * This function cannot be called with void as the template parameter; 201  * compilers will reject vector<void> as a type. This means it cannot be 202  * called for flag-type options. To count the number of times a given flag 203  * was specified, use numOptSet() 204  * @param namestring See similar argument to getOpt() 205  * @param values Reference to list to store values into. Will have as many entries 206  * as there were instances of this option on the command line 207  */ 208  template < typename T > 209  void getOptAllArgs( const std::string& namestring, std::vector< T >& values ); 210  211  /** 212  * @param namestring See similar argument to getOpt() 213  * @return The number of times the named option appeared on the command line. 214  */ 215  int numOptSet( const std::string& namestring ); 216  217  /** 218  * Retrieve the value of a required command-line argument by name 219  * @param namestring The helpname that was given to addRequiredArg when the 220  * desired argument was created 221  */ 222  template < typename T > 223  T getReqArg( const std::string& namestring ); 224  225  /** 226  * Append the values of any required or optional arguments 227  * @param namestring The helpname that was given to addRequiredArg or 228  * addOptionalArgs. 229  */ 230  template < typename T > 231  void getArgs( const std::string& namestring, std::vector< T >& values ); 232  233  /** 234  * Prints an error message to std::cerr, along with a brief usage message, 235  * then halts the program. Used throughout ProgramOptions implementation. 236  * Users may call this directly if they detect an incorrect usage of program 237  * options that the ProgramOptions wasn't able to detect itself. 238  * @param message The error message to print before program halt. 239  */ 240  void error( const std::string& message ); 241  242  /** 243  * Write help data formatted for use as a unix man page. 244  */ 245  void write_man_page( std::ostream& to_this_stream ); 246  247  protected: 248  std::string get_option_usage_prefix( const ProgOpt& option ); 249  250  void get_namestrings( const std::string& input, std::string* l, std::string* s ); 251  252  ProgOpt* lookup( const std::map< std::string, ProgOpt* >&, const std::string& ); 253  ProgOpt* lookup_option( const std::string& ); 254  255  bool evaluate( const ProgOpt& opt, void* target, const std::string& option, unsigned* arg_idx = NULL ); 256  bool process_option( ProgOpt* opt, std::string arg, const char* value = 0 ); 257  258  std::map< std::string, ProgOpt* > long_names; 259  std::map< std::string, ProgOpt* > short_names; 260  std::map< std::string, ProgOpt* > required_args; 261  262  typedef std::pair< ProgOpt*, std::string > help_line; 263  std::vector< help_line > option_help_strings; 264  std::vector< help_line > arg_help_strings; 265  std::vector< std::string > main_help; 266  std::string brief_help; 267  268  bool expect_optional_args; 269  unsigned optional_args_position, max_optional_args; 270  271  std::string progname; 272  std::string progversion; 273  274  // if an option was specified with the int_flag, this 275  // will contain the long name of the option 276  std::string number_option_name; 277 }; 278  279 #endif /* MOAB_PROGRAM_OPTIONS_H */