X-Git-Url: https://git.dlugolecki.net.pl/?a=blobdiff_plain;f=include%2Foption.h;h=935914e86112dca86c6e8bf5fad935785773c843;hb=395cd2099ecba699dcad270fa1fb42c1d8603ece;hp=dba1c16818c4aa65ce05fecd9b79b048e68cac4c;hpb=2900a7396aa582dcf622b968c286059b28d9c0a8;p=command.git diff --git a/include/option.h b/include/option.h index dba1c16..935914e 100644 --- a/include/option.h +++ b/include/option.h @@ -10,10 +10,12 @@ namespace command { /** * Class responsible for handling commandline options. - * Options are non-required, named parameters of program. + * Options are named parameters of program. * * Example: * ./myprog OptionName=OptionValue + * ./myprog -f=/some/file + * ./myprog --level=15 */ template class Option @@ -24,16 +26,13 @@ namespace command { /** * Current Option name */ - OptionName name; + const OptionName name; /** * Current Option value */ OptionType value; - /** Variable indicating if current Option was already used or not */ - bool used = false; - public: /** * Default constructor. @@ -42,7 +41,7 @@ namespace command { * @param description Description of current Option * @param function Function used to handle current Option. */ - Option(std::string name, const std::string & description, void (*function)(OptionType)) + Option(const std::string & name, const std::string & description, void (*function)(OptionType)) : Parameter(description), Callable(function), name(name) { } @@ -85,18 +84,21 @@ namespace command { * @throw std::invalid_argument when OptionValue part failed conversion * to OptionType */ - virtual bool understand(const std::string & argv) { - if ((!used) && - (argv.find(name) == 0)) { + virtual bool understand(const std::string & argv) + throw(std::invalid_argument) { + + if ((!isUsed()) && (argv.find(name) == 0)) { std::size_t pos = argv.find("="); + if (pos != name.size()) { throw std::invalid_argument("Option: " + name + " requires value but no one has been provided"); } std::stringstream ss; - ss << argv.substr(pos + 1); - ss >> value; + ss >> value;// memory leak? when uncommented and exception is + // thrown, valgrind shows e.g.: + // possibly lost: 380 bytes in 7 blocks if (ss.fail()) { throw std::invalid_argument("Value for option: " + name + " failed conversion to the required type"); @@ -108,6 +110,72 @@ namespace command { return false; } }; + + /** + * Template class responsible for handling commandline options. + * Options are non-required, named parameters of program. + * This template specialization allows Options to work like switches. + * It means that just named parameter is needed to invoke command. No value + * is used. + * + * Example: + * ./myprog OptionName + * ./myprog -h + * ./myprog --help + */ + template<> + class Option + : public Parameter, public Callable { + public: + typedef std::string OptionName; + protected: + /** + * Current Option name + */ + const OptionName name; + public: + /** + * Default constructor. + * + * @param name Name of the current Option + * @param description Description of current Option + * @param function Function used to handle current Option. + */ + Option(const std::string & name, const std::string & description, void (*function)(void)) + : Parameter(description), Callable(function), name(name) { + } + + /** + * + */ + virtual void handle() { + this->call(); + } + + /** + * Method used for checking if Option understands given user value. + * If so, current Option is flagged as used and no more checks against + * it will be done in future. + * + * Passed value should be in form of: + * OptionName + * + * @param argv command line value against which test will be made. + * User value should be in format: OptionName. + * + * @return If passed argv succesfully detected OptionName returns true + * and Option is set as used one. Otherwise returns false and can be + * used to check against next value. + */ + virtual bool understand(const std::string & argv) { + if ((!isUsed()) && + (argv == name)) { + used = true; + return true; + } + return false; + } + }; } #endif /* __COMMAND_OPTION_H */