From 95af563cb577e8eedc95c0664a6529d12ea050ed Mon Sep 17 00:00:00 2001 From: =?utf8?q?Rafa=C5=82=20D=C5=82ugo=C5=82=C4=99cki?= Date: Tue, 12 May 2015 20:30:38 +0200 Subject: [PATCH] Add possibility to set MultiValue Options. --- include/argument.h | 7 +++ include/multiValue.h | 18 +++++- include/option.h | 14 +++++ include/parameter.h | 5 ++ include/required.h | 11 +++- tests/Makefile.am | 6 +- ...should_extract_arguments_by_separator.cpp} | 0 .../should_extract_options_by_separator.cpp | 57 +++++++++++++++++++ tests/parameter/TestParameter.h | 4 ++ 9 files changed, 117 insertions(+), 5 deletions(-) rename tests/multiValue/{should_extract_values_by_separator.cpp => should_extract_arguments_by_separator.cpp} (100%) create mode 100644 tests/multiValue/should_extract_options_by_separator.cpp diff --git a/include/argument.h b/include/argument.h index a32cf82..80deabb 100644 --- a/include/argument.h +++ b/include/argument.h @@ -76,6 +76,13 @@ namespace command { return false; } + + /** + * \inheritdoc + */ + virtual unsigned int valuePosition(const std::string & ) { + return 0; + } }; } diff --git a/include/multiValue.h b/include/multiValue.h index e84b855..90de29a 100644 --- a/include/multiValue.h +++ b/include/multiValue.h @@ -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); + } }; } diff --git a/include/option.h b/include/option.h index 59de395..260659e 100644 --- a/include/option.h +++ b/include/option.h @@ -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"); + } }; } diff --git a/include/parameter.h b/include/parameter.h index 443111d..1bbfa88 100644 --- a/include/parameter.h +++ b/include/parameter.h @@ -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; }; } diff --git a/include/required.h b/include/required.h index a4e0622..726f6ac 100644 --- a/include/required.h +++ b/include/required.h @@ -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); + } }; } diff --git a/tests/Makefile.am b/tests/Makefile.am index d7b072a..214d6f2 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -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_values_by_separator.cpp b/tests/multiValue/should_extract_arguments_by_separator.cpp similarity index 100% rename from tests/multiValue/should_extract_values_by_separator.cpp rename to tests/multiValue/should_extract_arguments_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 index 0000000..1f19354 --- /dev/null +++ b/tests/multiValue/should_extract_options_by_separator.cpp @@ -0,0 +1,57 @@ +#include +#include + +#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 input; + +void function(OptionType value) { + input.push_back(value); + cout << "Catched value: " << value << "\n"; +} + +int main() { + Parameter * option = new MultiValue(",", new Option(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; +} diff --git a/tests/parameter/TestParameter.h b/tests/parameter/TestParameter.h index 9e2874d..cf985ca 100644 --- a/tests/parameter/TestParameter.h +++ b/tests/parameter/TestParameter.h @@ -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 -- 2.30.2