MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 #ifndef MOAB_PROGRAM_OPTIONS_H 00002 #define MOAB_PROGRAM_OPTIONS_H 00003 00004 #include <vector> 00005 #include <map> 00006 #include <string> 00007 #include <iostream> 00008 00009 class ProgOpt; 00010 00011 /** A simple command-line option parser and help utility 00012 * 00013 * Utility class to specify a program's command-line options arguments, produce a help message 00014 * explaining how they work, and parse user's command line input (producing useful errors messages 00015 * if any problems arise). Loosely (okay, very loosely) inspired by boost program_options. 00016 * 00017 * Options are specified by a comma-separated namestring. An option named "foo,f" can be specified 00018 * three ways on the command line: "-f val", "--foo val", or "--foo=val". The types of options 00019 * and arguments are specified by function templates. Valid template values for positional argument 00020 * and options are int, double, and std::string. void may also be used in options, and it indicates 00021 * a command line option that does not take an argument. 00022 * 00023 * Example usage: 00024 * ProgOptions po( "Example usage of ProgOptions" ); 00025 * po.addOpt<void>( "verbose,v", "Turn on verbose messages" ); 00026 * po.addOpt<std::string> ("foo", "Specify the foo string" ); 00027 * int x = 0; 00028 * po.addOpt<int>( ",x", "Specify the x number", &x ); // x will be automatically set when options 00029 * parsed po.parseCommandLine( argc, argv ); bool verbose = po.numOptSet("verbose") > 0; std::string 00030 * foo; if( !po.getOpt( "foo", &foo ) ) foo = "default"; 00031 * ... 00032 * 00033 * See the file dagmc_preproc.cpp in the dagmc directory for a real-world example. 00034 */ 00035 class ProgOptions 00036 { 00037 00038 public: 00039 /** 00040 * Flags for addOpt and addRequiredArg functions; may be combined with bitwise arithmetic 00041 * (though not all combinations make sense!) 00042 **/ 00043 00044 /// Set for a flag that, when detected, prints help text and halts program. 00045 /// Constructor creates such a flag by default, so the user shouldn't need to use this directly. 00046 static const int help_flag = 1 << 0; 00047 00048 /// Flag indicating that an option should be given a "cancel" flag. 00049 /// This creates, for option --foo, an additional option --no-foo that 00050 /// clears all previously read instances of the foo option 00051 static const int add_cancel_opt = 1 << 1; 00052 00053 /// When applied to a flag argument (one with template type void), indicate that the 00054 /// value 'false' should be stored into the pointer that was given at option creation time. 00055 /// This overrides the default behavior, which is to store the value 'true'. 00056 static const int store_false = 1 << 2; 00057 00058 /// Specify a numerical flag where any positive integer is an acceptable 00059 /// value. E.g. --dimension=3 is equivalent to -3. Only values in the 00060 /// range [0,9] are accepted and the flag type must be integer. 00061 static const int int_flag = 1 << 3; 00062 00063 /** Substitue any occurance of the '%' symbol in a string with 00064 * the the MPI rank of this process in MPI_COMM_WORLD. This 00065 * option has no effect if not compiled with MPI. This flag 00066 * has no effect for non-string options. 00067 */ 00068 static const int rank_subst = 1 << 4; 00069 00070 /// Set for a flag that, when detected, will call printVersion() and halt the program. 00071 static const int version_flag = 1 << 5; 00072 00073 /// unimplemented flag for required arguments that may be given multiple times 00074 // const static int accept_multiple; 00075 00076 /** 00077 * @param helptext A brief summary of the program's function, to be printed 00078 * when the help flag is detected 00079 */ 00080 ProgOptions( const std::string& helptext = "", const std::string& briefdesc = "" ); 00081 ~ProgOptions(); 00082 00083 /** Specify the program version 00084 * 00085 * Set the program version to a given string. This will be printed when printVersion() 00086 * is called. 00087 * @param version_string The version string 00088 * @param addflag If true, a default '--version' option will be added. If false, 00089 * the version will be set, but no option will be added to the parser. 00090 */ 00091 void setVersion( const std::string& version_string, bool addFlag = true ); 00092 00093 /** Specify a new command-line option 00094 * 00095 * Instruct the parser to accept a new command-line argument, as well as specifying 00096 * how the argument should be handled. The template parameter indicates the type of 00097 * command-line option being specified: acceptable types are void (indicating a flag 00098 * without an argument), int, double, and std::string. 00099 * 00100 * @param namestring The command-line options name(s). Format is longname,shortname. 00101 * If the comma is omitted, or appears only at the end, this option will have 00102 * no shortname; if the comma is the first letter of the namestring, the option 00103 * has no longname. 00104 * @param helpstring The help information displayed for the option when the program is 00105 * invoked with --help 00106 * @param value A pointer to memory in which to store the parsed value for this option. 00107 * If NULL, then the value of the option must be queried using the getOpt function. 00108 * If the template parameter is void and value is non-NULL, treat value as a bool* 00109 * and store 'true' into it when the flag is encountered. (See also store_false, above) 00110 * @param flags Option behavior flags, which should come from static vars in the ProgOptions 00111 * class 00112 */ 00113 template < typename T > 00114 void addOpt( const std::string& namestring, const std::string& helpstring, T* value, int flags = 0 ); 00115 00116 /** Specify a new command-line option 00117 * 00118 * This funtion is identical to the 4-arg version, but omits the value parameter, which 00119 * is assumed to be NULL 00120 */ 00121 template < typename T > 00122 void addOpt( const std::string& namestring, const std::string& helpstring, int flags = 0 ) 00123 { 00124 addOpt< T >( namestring, helpstring, NULL, flags ); 00125 } 00126 00127 /** Add a new line of help text to the option help printout 00128 * 00129 * Add a line of text to the option-related help. Called between calls to addOpt(), 00130 * this function can be used to divide the option list into groups of related options 00131 * to make the help text more convenient. 00132 */ 00133 void addOptionHelpHeading( const std::string& ); 00134 00135 /** Add required positional argument 00136 * 00137 * Add a new required positional argument. The order in which arguments are specified 00138 * is the order in which they will be expected on the command line. 00139 * The template parameter may be int, double, or std::string (but not void) 00140 * @param helpname The name to give the argument in the help text 00141 * @param helpstring The help text for the argument 00142 * @param value Pointer to where parsed value from command line should be stored. 00143 * If NULL, the value must be queried using getReqArg() 00144 */ 00145 template < typename T > 00146 void addRequiredArg( const std::string& helpname, const std::string& helpstring, T* value = NULL, int flags = 0 ); 00147 00148 /** Add optional positional arguments 00149 * 00150 * Specify location in ordered argument list at which optional arguments 00151 * may occur. Optional arguments are allowed at only one location 00152 * it argument list (this function may not be called more than once.). 00153 * The template parameter may be int, double, or std::string (but not void) 00154 * @param count The maximum number of optional arguments. Specify zero for unlimited. 00155 * @param helpname The name to give the argument in the help text 00156 * @param helpstring The help text for the arguments 00157 */ 00158 template < typename T > 00159 void addOptionalArgs( unsigned max_count, 00160 const std::string& helpname, 00161 const std::string& helpstring, 00162 int flags = 0 ); 00163 00164 /** 00165 * Print the full help to the given stream 00166 */ 00167 void printHelp( std::ostream& str = std::cout ); 00168 00169 /** 00170 * Print only the usage message to the given stream 00171 */ 00172 void printUsage( std::ostream& str = std::cout ); 00173 00174 /** 00175 * Print the version string to the given stream 00176 */ 00177 void printVersion( std::ostream& str = std::cout ); 00178 00179 /** 00180 * Parse command-line inputs as given to main() 00181 */ 00182 void parseCommandLine( int argc, char* argv[] ); 00183 00184 /** 00185 * 00186 * Get the value of the named option. 00187 * @param namestring The name string given when the option was created. This need not be 00188 * idential to the created name; only the longname, or the shortname (with comma prefix), 00189 * will also work. 00190 * @param value Pointer to location to store option argument, if any is found 00191 * @return True if the option was set and its argument was stored into value; false otherwise. 00192 */ 00193 template < typename T > 00194 bool getOpt( const std::string& namestring, T* value ); 00195 00196 /** 00197 * Get a list of values for the named option-- one value for each time it was 00198 * given on the command line. 00199 * 00200 * This function cannot be called with void as the template parameter; 00201 * compilers will reject vector<void> as a type. This means it cannot be 00202 * called for flag-type options. To count the number of times a given flag 00203 * was specified, use numOptSet() 00204 * @param namestring See similar argument to getOpt() 00205 * @param values Reference to list to store values into. Will have as many entries 00206 * as there were instances of this option on the command line 00207 */ 00208 template < typename T > 00209 void getOptAllArgs( const std::string& namestring, std::vector< T >& values ); 00210 00211 /** 00212 * @param namestring See similar argument to getOpt() 00213 * @return The number of times the named option appeared on the command line. 00214 */ 00215 int numOptSet( const std::string& namestring ); 00216 00217 /** 00218 * Retrieve the value of a required command-line argument by name 00219 * @param namestring The helpname that was given to addRequiredArg when the 00220 * desired argument was created 00221 */ 00222 template < typename T > 00223 T getReqArg( const std::string& namestring ); 00224 00225 /** 00226 * Append the values of any required or optional arguments 00227 * @param namestring The helpname that was given to addRequiredArg or 00228 * addOptionalArgs. 00229 */ 00230 template < typename T > 00231 void getArgs( const std::string& namestring, std::vector< T >& values ); 00232 00233 /** 00234 * Prints an error message to std::cerr, along with a brief usage message, 00235 * then halts the program. Used throughout ProgramOptions implementation. 00236 * Users may call this directly if they detect an incorrect usage of program 00237 * options that the ProgramOptions wasn't able to detect itself. 00238 * @param message The error message to print before program halt. 00239 */ 00240 void error( const std::string& message ); 00241 00242 /** 00243 * Write help data formatted for use as a unix man page. 00244 */ 00245 void write_man_page( std::ostream& to_this_stream ); 00246 00247 protected: 00248 std::string get_option_usage_prefix( const ProgOpt& option ); 00249 00250 void get_namestrings( const std::string& input, std::string* l, std::string* s ); 00251 00252 ProgOpt* lookup( const std::map< std::string, ProgOpt* >&, const std::string& ); 00253 ProgOpt* lookup_option( const std::string& ); 00254 00255 bool evaluate( const ProgOpt& opt, void* target, const std::string& option, unsigned* arg_idx = NULL ); 00256 bool process_option( ProgOpt* opt, std::string arg, const char* value = 0 ); 00257 00258 std::map< std::string, ProgOpt* > long_names; 00259 std::map< std::string, ProgOpt* > short_names; 00260 std::map< std::string, ProgOpt* > required_args; 00261 00262 typedef std::pair< ProgOpt*, std::string > help_line; 00263 std::vector< help_line > option_help_strings; 00264 std::vector< help_line > arg_help_strings; 00265 std::vector< std::string > main_help; 00266 std::string brief_help; 00267 00268 bool expect_optional_args; 00269 unsigned optional_args_position, max_optional_args; 00270 00271 std::string progname; 00272 std::string progversion; 00273 00274 // if an option was specified with the int_flag, this 00275 // will contain the long name of the option 00276 std::string number_option_name; 00277 }; 00278 00279 #endif /* MOAB_PROGRAM_OPTIONS_H */