From: Rafał Długołęcki Date: Tue, 5 May 2015 23:43:12 +0000 (+0200) Subject: Add possibility to set Required Parameters. X-Git-Tag: v0.2~15 X-Git-Url: https://git.dlugolecki.net.pl/?p=command.git;a=commitdiff_plain;h=0d52a8d02278592356f94ac17b1ccc5fcea388a5 Add possibility to set Required Parameters. --- diff --git a/include/argument.h b/include/argument.h index b07ae67..1dae06f 100644 --- a/include/argument.h +++ b/include/argument.h @@ -11,8 +11,7 @@ namespace command { /** * Class responsible for handling commandline arguments. - * Arguments are required, non-named parameters of program. - * Accepts + * Arguments are non-named parameters of program. * * Example: * ./myprog ARGUMENT @@ -22,9 +21,6 @@ namespace command { template class Argument : public Parameter, public Callable { protected: - /** Variable indicating if current Argument was already used or not */ - bool used = false; - ArgumentType value; public: typedef class Argument Type; @@ -68,14 +64,14 @@ namespace command { * against next value. */ virtual bool understand(const std::string & argv) { - if (!used) { + if (!isUsed()) { std::stringstream ss; ss << argv; ss >> value; if (!ss.fail()) { - used = true; + this->used = true; return true; } } diff --git a/include/command.h b/include/command.h index 8ecb280..6e8ecf6 100644 --- a/include/command.h +++ b/include/command.h @@ -3,6 +3,7 @@ #include #include +#include #include "parameter.h" @@ -32,6 +33,10 @@ namespace command { releaseMemory(); throw; } + catch(std::logic_error exception) { + releaseMemory(); + throw; + } } /** @@ -53,6 +58,11 @@ namespace command { } } } + for(Parameter *param : parameters) { + if (param->isRequired() && !param->isUsed()) { + throw std::logic_error(param->describe() + " is required but it was not handled"); + } + } } /** diff --git a/include/option.h b/include/option.h index 426942b..935914e 100644 --- a/include/option.h +++ b/include/option.h @@ -10,7 +10,7 @@ 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 @@ -33,9 +33,6 @@ namespace command { */ OptionType value; - /** Variable indicating if current Option was already used or not */ - bool used = false; - public: /** * Default constructor. @@ -90,7 +87,7 @@ namespace command { virtual bool understand(const std::string & argv) throw(std::invalid_argument) { - if ((!used) && (argv.find(name) == 0)) { + if ((!isUsed()) && (argv.find(name) == 0)) { std::size_t pos = argv.find("="); if (pos != name.size()) { @@ -136,10 +133,6 @@ namespace command { * Current Option name */ const OptionName name; - - /** Variable indicating if current Option was already used or not */ - bool used = false; - public: /** * Default constructor. @@ -175,7 +168,7 @@ namespace command { * used to check against next value. */ virtual bool understand(const std::string & argv) { - if ((!used) && + if ((!isUsed()) && (argv == name)) { used = true; return true; diff --git a/include/parameter.h b/include/parameter.h index 1396f83..a54a967 100644 --- a/include/parameter.h +++ b/include/parameter.h @@ -14,6 +14,10 @@ namespace command { * ./myprog ARGUMENT */ class Parameter : public Descriptive { + protected: + /** Variable indicating if current Parameter was already used or not */ + bool used = false; + public: typedef class Parameter Type; /** @@ -37,6 +41,17 @@ namespace command { * parameter. */ virtual bool understand(const std::string & ) = 0; + + /** + * Indicates if current Parameter is required + */ + virtual bool isRequired() { + return false; + }; + + virtual bool isUsed() { + return used; + } }; } diff --git a/include/required.h b/include/required.h new file mode 100644 index 0000000..bdb6299 --- /dev/null +++ b/include/required.h @@ -0,0 +1,67 @@ +#ifndef __COMMAND_REQUIRED_H +#define __COMMAND_REQUIRED_H + +#include "parameter.h" + +namespace command { + /** + * Required Parameter decorator. Makes passed Parameters treated as required + */ + class Required : public Parameter { + protected: + /** + * Parameter which will be treated as required + */ + Parameter * parameter; + + public: + /** + * Default constructor. + * + * @param parameter Parameter which will be treated as required + */ + Required(Parameter * parameter) + : Parameter(parameter->describe()), parameter(parameter) { + } + + /** + * Default destructor. Releases allocated memory + */ + virtual ~Required() { + delete parameter; + } + + /** + * Method used for handling method calls to linked Parameter + */ + virtual void handle() { + parameter->handle(); + } + + /** + * Method used for checking if the given user value is understandable by + * parameter. + * + * @param value value from argv to check against + */ + virtual bool understand(const std::string & value) { + return parameter->understand(value); + } + + /** + * Indicates if current Parameter is required + */ + virtual bool isRequired() { + return true; + }; + + /** + * Indicates if current Parameter is already used + */ + virtual bool isUsed() { + return parameter->isUsed(); + }; + }; +} + +#endif /* __COMMAND_PARAMETER_H */ diff --git a/src/main.cpp b/src/main.cpp index 5a42e86..5cf4e83 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,8 +3,11 @@ #include "option.h" #include "argument.h" +#include "required.h" #include "command.h" +using namespace command; + void argument_function(bool a) { std::cout << "Argument: " << a << std::endl; } @@ -18,11 +21,11 @@ void void_function(void) { } int main(int argc, char *argv[]) { - command::Command command(argc, argv, { -// new command::Argument("File path", [](std::string value)->void { std::cout << "Hello from lambda " << value << std::endl; }), - new command::Argument("File path", argument_function), - new command::Option("f", "Optional file", option_function), - new command::Option("h", "Help", void_function) + Command command(argc, argv, { +// new Argument("File path", [](std::string value)->void { std::cout << "Hello from lambda " << value << std::endl; }), + new Required(new Argument("File path", argument_function)), + new Option("f", "Optional file", option_function), + new Option("h", "Help", void_function) }); return 0;