Add possibility to set MultiValue Options.
authorRafał Długołęcki <rafal@dlugolecki.net.pl>
Tue, 12 May 2015 18:30:38 +0000 (20:30 +0200)
committerRafał Długołęcki <rafal@dlugolecki.net.pl>
Tue, 12 May 2015 18:30:38 +0000 (20:30 +0200)
include/argument.h
include/multiValue.h
include/option.h
include/parameter.h
include/required.h
tests/Makefile.am
tests/multiValue/should_extract_arguments_by_separator.cpp [moved from tests/multiValue/should_extract_values_by_separator.cpp with 100% similarity]
tests/multiValue/should_extract_options_by_separator.cpp [new file with mode: 0644]
tests/parameter/TestParameter.h

index a32cf82064893f9f78677aea1a9e3c4bb3d4a3f7..80deabb9c22f903aa4f518b89dc940342b179d23 100644 (file)
@@ -76,6 +76,13 @@ namespace command {
 
             return false;
         }
+
+        /**
+         * \inheritdoc
+         */
+        virtual unsigned int valuePosition(const std::string & ) {
+            return 0;
+        }
     };
 }
 
index e84b855628f035a0e89ea47b0f6223d2975063ec..90de29a9787d5f229de0935674dc0f9fb4a2e528 100644 (file)
@@ -67,13 +67,18 @@ namespace command {
          * \inheritdoc
          */
         virtual bool understand(const std::string & value) {
-            size_t start = 0;
+            size_t start = parameter->valuePosition(value);
             size_t pos = 0;
             bool _understand = true;
+            std::string prefix = "";
+
+            if (start > 0) {
+                prefix = value.substr(0, ++start);// always count: "="
+            }
 
             do {
                 pos = value.find(separator, start);
-                values.push_back(value.substr(start, pos-start));
+                values.push_back(prefix + value.substr(start, pos-start));
                 _understand &= parameter->understand(values.back());
                 start = pos + 1;
             } while ((pos != std::string::npos) && (start < value.size()));
@@ -99,6 +104,15 @@ namespace command {
         virtual bool isUsed() {
             return parameter->isUsed();
         };
+
+        /**
+         * Wrapper method around passed Parameter::valuePosition().
+         *
+         * \inheritdoc
+         */
+        virtual unsigned int valuePosition(const std::string & value) {
+            return parameter->valuePosition(value);
+        }
     };
 }
 
index 59de3957b9d9f97cdfb651b57b470ce03dc057b6..260659e6847efbe8466c7e3c4ab997ebfe48d477 100644 (file)
@@ -108,6 +108,13 @@ namespace command {
             }
             return false;
         }
+
+        /**
+         * \inheritdoc
+         */
+        virtual unsigned int valuePosition(const std::string & argv) {
+            return argv.find("=");
+        }
     };
 
     /**
@@ -173,6 +180,13 @@ namespace command {
             }
             return false;
         }
+
+        /**
+         * \inheritdoc
+         */
+        virtual unsigned int valuePosition(const std::string & ) {
+            throw new std::invalid_argument(this->describe() + "is void Option, so it does not have value part");
+        }
     };
 }
 
index 443111dbd4d0de120589ac9311a1d8d9008b57ff..1bbfa88739b55aa1c8445feef05ff9d36c7597a7 100644 (file)
@@ -63,6 +63,11 @@ namespace command {
         virtual bool isUsed() {
             return used;
         }
+
+        /**
+         * @return position where value starts in passed string
+         */
+        virtual unsigned int valuePosition(const std::string & ) = 0;
     };
 }
 
index a4e062201430dec369dc3b49bbc96273c8c12014..726f6ac983640e8e7cab7baf09a998de39039890 100644 (file)
@@ -69,7 +69,16 @@ namespace command {
          */
         virtual bool isUsed() {
             return parameter->isUsed();
-        };
+        }
+
+        /**
+         * Wrapper method around passed Parameter::valuePosition().
+         *
+         * \inheritdoc
+         */
+        virtual unsigned int valuePosition(const std::string & value) {
+            return parameter->valuePosition(value);
+        }
     };
 }
 
index d7b072a9b6a377bcc11e07a3af707c01f85b733c..214d6f2d9b94f2661b009ddfb0e4894c2b83cd03 100644 (file)
@@ -22,7 +22,8 @@ TESTS = \
        option_should_match_exact_name.test \
        option_should_throw_exception_on_missing_value.test \
        required_should_be_required.test \
-       multivalue_should_extract_values_by_separator.test
+       multivalue_should_extract_arguments_by_separator.test \
+       multivalue_should_extract_options_by_separator.test
 
 noinst_PROGRAMS = $(TESTS)
 
@@ -55,4 +56,5 @@ option_should_throw_exception_on_missing_value_test_SOURCES = option/should_thro
 
 required_should_be_required_test_SOURCES = required/should_be_required.cpp
 
-multivalue_should_extract_values_by_separator_test_SOURCES = multiValue/should_extract_values_by_separator.cpp
+multivalue_should_extract_arguments_by_separator_test_SOURCES = multiValue/should_extract_arguments_by_separator.cpp
+multivalue_should_extract_options_by_separator_test_SOURCES = multiValue/should_extract_options_by_separator.cpp
diff --git a/tests/multiValue/should_extract_options_by_separator.cpp b/tests/multiValue/should_extract_options_by_separator.cpp
new file mode 100644 (file)
index 0000000..1f19354
--- /dev/null
@@ -0,0 +1,57 @@
+#include <iostream>
+#include <vector>
+
+#include "option.h"
+#include "multiValue.h"
+
+using namespace std;
+using namespace command;
+
+#define NAME "test"
+#define VALUE "0,1,2,3,4,5,6,7,8,9"
+
+#define OPTION NAME "=" VALUE
+
+typedef int OptionType;
+
+std::vector<OptionType> input;
+
+void function(OptionType value) {
+    input.push_back(value);
+    cout << "Catched value: " << value << "\n";
+}
+
+int main() {
+    Parameter * option = new MultiValue(",", new Option<OptionType>(NAME, "Option as multiValue int", function));
+
+    try {
+        if (option->understand(OPTION)) {
+            option->handle();
+        }
+        else {
+            cout << option->describe() << " should understand multiple int values\n";
+            return 1;
+        }
+    }
+    catch (...) {
+        delete option;
+        cout << option->describe() << " thrown unknown exception\n";
+        return 1;
+    }
+
+    bool test = true;
+    for (int i = 0; i < 10; i++) {
+        test &= (input[i] == i);
+        cout << i << ") input: " << input[i] << "\n";
+    }
+
+    if (test) {
+        cout << option->describe() << " handles boolean (TRUE) values\n";
+        delete option;
+        return 0;
+    }
+
+    cout << option->describe() << " do not handle multiple int values\n";
+    delete option;
+    return 1;
+}
index 9e2874d8e3326d561ae3fca2a2bd1a63abc88281..cf985caf54680c72a15eacdedadf40def399fe08 100644 (file)
@@ -7,4 +7,8 @@ public:
 
     virtual void handle() { }
     virtual bool understand(const std::string & ) { return false; }
+
+    virtual unsigned int valuePosition(const std::string & value) {
+        return 0;
+    }
 };
\ No newline at end of file