From c85d60a873e21052a470c172df4ba56a1c0d59c6 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Rafa=C5=82=20D=C5=82ugo=C5=82=C4=99cki?= Date: Sun, 3 May 2015 11:54:44 +0200 Subject: [PATCH] Added mechanism to understand passed Option without value. --- include/argument.h | 2 ++ include/callable.h | 32 +++++++++++++++++++ include/option.h | 77 ++++++++++++++++++++++++++++++++++++++++++++++ src/main.cpp | 17 ++++++---- 4 files changed, 122 insertions(+), 6 deletions(-) diff --git a/include/argument.h b/include/argument.h index 82954eb..53dea34 100644 --- a/include/argument.h +++ b/include/argument.h @@ -16,6 +16,8 @@ namespace command { * * Example: * ./myprog ARGUMENT + * ./myprog /path/to/file + * ./myprog "some argument" */ template class Argument : public Parameter, public Callable { diff --git a/include/callable.h b/include/callable.h index 7e6e503..bf74377 100644 --- a/include/callable.h +++ b/include/callable.h @@ -36,6 +36,38 @@ namespace command { this->func(value); } }; + + /** + * Template specialization of Callable behaviour class. + * Allows passing functions with void argument + */ + template<> + class Callable { + protected: + /** + * Function handling user Arguments + */ + void (*func)(void); + + public: + /** + * Default constructor. + * + * @param function Function that will be invoked + */ + Callable(void (*function)(void)) + : func(function) { + } + virtual ~Callable() { } + + protected: + /** + * Executes command + */ + void call() { + this->func(); + } + }; } #endif /* __COMMAND_DESCRIPTIVE_H */ diff --git a/include/option.h b/include/option.h index dba1c16..a77d8f4 100644 --- a/include/option.h +++ b/include/option.h @@ -14,6 +14,8 @@ namespace command { * * Example: * ./myprog OptionName=OptionValue + * ./myprog -f=/some/file + * ./myprog --level=15 */ template class Option @@ -108,6 +110,81 @@ 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 + */ + OptionName name; + + /** Variable indicating if current Option was already used or not */ + bool used = false; + + 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(std::string name, const std::string & description, void (*function)(void)) + : Parameter(description), Callable(function), name(name) { + } + + /** + * + */ + virtual ~Option() { } + + /** + * + */ + 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 ((!used) && + (argv == name)) { + used = true; + return true; + } + return false; + } + }; } #endif /* __COMMAND_OPTION_H */ diff --git a/src/main.cpp b/src/main.cpp index 0174345..5a42e86 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,19 +5,24 @@ #include "argument.h" #include "command.h" -void some_function(bool a) { - std::cout << "Some function " << a << std::endl; +void argument_function(bool a) { + std::cout << "Argument: " << a << std::endl; } -void help_function(std::string a) { - std::cout << "Some function " << a << std::endl; +void option_function(std::string a) { + std::cout << "Help function " << a << std::endl; +} + +void void_function(void) { + std::cout << "Void function " << std::endl; } 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", some_function), - new command::Option("h", "Help", help_function) + new command::Argument("File path", argument_function), + new command::Option("f", "Optional file", option_function), + new command::Option("h", "Help", void_function) }); return 0; -- 2.30.2