/* * optparse.h * * An option parser for C++ modeled after the optparse Python * module. Create an instance of OptionParser in your program * and you can add options to it then call the method * parse_args with argc and argv and it will parse them. The * '-h' and '--help' options are built in, they print the * usage message. * * W. Evan Sheehan * */ #ifndef OPTPARSE_H #define OPTPARSE_H #include #include #include #include #include namespace optparse { /** * Action type. * Use this type to determine what we're storing, naming * convention is the same as the optparse python module. * Even with STORE_FALSE and STORE_TRUE the values are * going to be stored as strings, false is "0" true is "1" * so you can just atoi() the value and use that for tests. */ typedef enum {STORE_FALSE=0, STORE_TRUE, STORE} action_t; /** * Option argument type. * Defines expected option argument type. */ typedef enum {STRING=0, BOOL, INT, DOUBLE} type_t; /** Option for OptionParser */ class Option { public: Option (std::string shrt, std::string lng, std::string dest, std::string hlp, action_t act, std::string dfault, type_t type, std::string allowed_args); ~Option (); /** * Validate option argument. * Test if argument is valid for the option. The argument must be valid w.r.t. * to type_ and allowed_values_. * @param argument Argument to be tested. * @return true if argument is valid. */ bool is_allowed(std::string argument); action_t action; // define what we store std::string shrt_flag; // short flag, something like -o std::string lng_flag; // long flag, something like --outfile std::string help; // help message about the option std::string destination; // the key used to store this option in the parser. /** * Default value. An empty string means no default value exist. */ std::string dfault_; /** * Expected type the argument of this option should have. * Only relevant for STORE action. * Used for generating the usage string. */ type_t type_; std::string allowed_args_; //!< Comma-separated list of allowed option arguments. }; class OptionError : public std::runtime_error { public: OptionError(std::string option, std::string error_msg) : std::runtime_error("") { std::ostringstream str; str << "OptionParser error: option: " << option << ", cause: " << error_msg; msg_ = str.str(); } virtual ~OptionError() throw() {} /** * Human-readable error message. * @return Pointer to error message. */ virtual const char* what() const throw() { return msg_.c_str(); } protected: std::string msg_; }; /** Option parser. */ class OptionParser { public: OptionParser (std::string usage=""); virtual ~OptionParser (); /** * Add an option to the parser. * @param shrt_flag Short option name, like e.g. "-q". * @param lng_flag Long option name, like e.g. "--quiet" * @param destination Key under which the option argument is stored in the dictionary. * @param help Help string for generating the usage info. * @param act Action, one of STORE, STORE_TRUE, STORE_FALSE. * @param type Type info of the expected option argument. One of INT, DOUBLE, STRING, BOOL. * @param dfault Default value. Value stored in the dictionary if the option is not given. * @param allowed_values List of possible option values. * A string of comma-separated allowed values. An empty string means * that any value is allowed. */ void add_option (std::string shrt_flag, std::string lng_flag, std::string destination, std::string help="", action_t act=STORE, type_t type=STRING, std::string dfault="", std::string allowed_values=""); /** * Get option argument. * @param option_name Name of option, as given in "destination" parameter of "add_option". * @return Option argument with type appendix removed. */ std::string get_option(std::string option_name); template T get(std::string option_name); /* Parse the commandline args. */ void parse_args (int argc, char **argv); /** * Write usage info to stream. * The usage info includes a formatted list of all options the parser knows about, * including the help string, expected argument type and default value. * @param os Output stream the usage info is written to. */ void help (std::ostream& os); /** * Convert type_t type to human-readable string. * This is used for generating the usage string and also in * TypeOptionParser to encode the argument type in the options dictionary. * @see help * @param type Type. * @return Converted string. */ std::string type2string(type_t type); /** * Type of "options" dictionary. */ typedef std::map options_type; options_type options; //!< Dictionary of options. Use options[key] to access. std::vector arguments; //!< List of positional arguments. protected: /** * Set option in dictionary. * Function the parser uses to store an option argument or a default value in * options dictionary. Can be overridden in a subclass to store additional info. * @param option Option object. * @param argument Option argument to store. */ virtual void set_option(Option& option, std::string argument); private: std::string use_msg; //!< Usage message. std::vector