/** * $Id: getoptwrapper.h 2 2009-10-31 02:48:23Z l0728348 $ * * Copyright 2009 * * @author Manuel Mausz (0728348) * @brief Wraps around getopt_long() using two classes * class CommandOption represents a valid commandline option * class CommandOptionParse calls getopt_long * and generates usage message */ #ifndef GETOPTWRAPPER_H #define GETOPTWRAPPER_H #include #include #include #if !defined(_GNU_SOURCE) # define _GNU_SOURCE #endif #include /* forward declarations */ class CommandOption; class CommandOptionParse; /** default list containing commandline options */ extern std::list cmdoptionlist; /** * every instance of CommandOption represents a valid commandline option * use CommandOptionParse to parse them */ class CommandOption { /* be friend with CommandOptionParse so it can use our privates */ friend class CommandOptionParse; public: /** commandline option argument */ enum Type { noArg = 0, /* no argument */ needArg = 1, /* argument required */ optArg = 2, /* argument optional */ }; /** * @brief Default ctor. Adds commandline option to commandline list * @param longopt long commandline option. empty string to omit * @param shortopt short commandline option. 0 to omit * @param description description. will be printed in usage * @param type type of argument * @param cmdlist list to add this commandline option */ CommandOption(const std::string& longopt, const char shortopt, const std::string& description, const Type& type, std::list& cmdlist = cmdoptionlist) : m_longopt(longopt), m_shortopt(shortopt), m_description(description), m_type(type), m_count(0), m_value("") { if (!m_longopt.empty() || m_shortopt != 0) cmdlist.push_back(this); } /** * @brief Default dtor */ virtual ~CommandOption() {} /** * @brief generate a usage string/valid syntax * for this commandline option * @return usage string for this commandline option */ const std::string printParameters(); /** * @brief get number of commandline matches found * @return number of commandline matches found */ unsigned count() { return m_count; } /** * @brief get number of commandline matches found * @return number of commandline matches found */ operator unsigned() { return count(); } /** * @brief returns first valid commandline option argument * if the commandline option is found a second time, * the argument is omitted * @return first valid argument for this commandline option */ const std::string value() { return m_value; } /** * @brief returns first valid commandline option argument * if the commandline option is found a second time, * the argument is omitted * @return first valid argument for this commandline option */ operator std::string() { return value(); } private: /** * @brief gets called by CommandOptionParse if the commandline option * is found. Parses and stores the argument. Only the first call * will be stored. * @param value commandline option argument */ void foundOption(const char *value); std::string m_longopt; char m_shortopt; std::string m_description; Type m_type; unsigned m_count; std::string m_value; }; /*----------------------------------------------------------------------------*/ /** * parses argc/argv using getopt_long and a list of instances of CommandOption * also generates usage message */ class CommandOptionParse { public: /** list of pointers of CommandOption */ typedef std::list CommandOptionList; /** * @brief Default ctor. * @param argc argc of main * @param argv argv of main * @param description will be printed in usage before CommandOption list * @param cmdlist list to add this commandline option */ CommandOptionParse(int argc, char* argv[], const std::string& description, std::list& cmdlist = cmdoptionlist) : m_argc(argc), m_argv(argv), m_description(description), m_cmdlist(cmdlist), m_longopts(NULL) {} /** * @brief Default dtor. */ virtual ~CommandOptionParse() { if (m_longopts != NULL) delete[] m_longopts; } /** * @brief adds valid synopsis to usage message * @param synopsis synopsis */ void addSynopsis(const std::string& synopsis) { m_synopsis.push_back(synopsis); } /** * @brief starts parsing argc/argv * @return true on success. false otherwise */ bool parse(); /** * @brief generates usage message * @return usage message as string */ const std::string usage(); /** * @brief generates usage message and prints them on ostream * @return reference to ostream */ friend std::ostream& operator<<(std::ostream& os, CommandOptionParse& cmdoptions) { os << cmdoptions.usage(); return os; } /** * @brief directly access a valid/parsed commandline option * using its longopt parameter * @param longopt parameter "longopt" of commandline option * @return reference to commandline option * @throw std::out_of_range if the commandline option cannot be found */ CommandOption& operator[](const std::string& longopt); /** * @brief directly access a valid/parsed commandline option * using its shortopt parameter * @param shortopt parameter "shortopt" of commandline option * @return reference to commandline option * @throw std::out_of_range if the commandline option cannot be found */ CommandOption& operator[](const char shortopt); private: int m_argc; char **m_argv; std::string m_description; CommandOptionList m_cmdlist; std::vector m_synopsis; std::string m_optstring; struct option *m_longopts; }; #endif /* vim: set et sw=2 ts=2: */