Added mechanism to understand passed Option without value.
authorRafał Długołęcki <rafal@dlugolecki.net.pl>
Sun, 3 May 2015 09:54:44 +0000 (11:54 +0200)
committerRafał Długołęcki <rafal@dlugolecki.net.pl>
Sun, 3 May 2015 09:54:44 +0000 (11:54 +0200)
include/argument.h
include/callable.h
include/option.h
src/main.cpp

index 82954eb6fd3a5b8fa2b46841f110973d2def3f6b..53dea343344e8b3b1bf42ab301551135eb9d33c0 100644 (file)
@@ -16,6 +16,8 @@ namespace command {
      *
      * Example:
      *  ./myprog ARGUMENT
+     *  ./myprog /path/to/file
+     *  ./myprog "some argument"
      */
     template<typename ArgumentType>
     class Argument : public Parameter, public Callable<ArgumentType> {
index 7e6e503c436e23f086306d7c0dd33f1267795eff..bf74377de5ebe5e7823cefdaf873adfb9e2a3953 100644 (file)
@@ -36,6 +36,38 @@ namespace command {
             this->func(value);
         }
     };
+
+    /**
+     * Template specialization of Callable behaviour class.
+     * Allows passing functions with void argument
+     */
+    template<>
+    class Callable<void> {
+    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 */
index dba1c16818c4aa65ce05fecd9b79b048e68cac4c..a77d8f446d19f179b9799ae5f7393d23c4240042 100644 (file)
@@ -14,6 +14,8 @@ namespace command {
      *
      * Example:
      *  ./myprog OptionName=OptionValue
+     *  ./myprog -f=/some/file
+     *  ./myprog --level=15
      */
     template<typename OptionType>
     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<void>
+        : public Parameter, public Callable<void>  {
+    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<void>(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 */
index 017434559a71c9eca8c6e30f223d481c5d826f91..5a42e860c14eaad667c3ca656e93be3b23ca85e1 100644 (file)
@@ -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<std::string>("File path", [](std::string value)->void { std::cout << "Hello from lambda " << value << std::endl; }),
-        new command::Argument<bool>("File path", some_function),
-        new command::Option<std::string>("h", "Help", help_function)
+        new command::Argument<bool>("File path", argument_function),
+        new command::Option<std::string>("f", "Optional file", option_function),
+        new command::Option<void>("h", "Help", void_function)
     });
 
     return 0;