--- /dev/null
+#ifndef __COMMAND_MULTIVALUE_H
+#define __COMMAND_MULTIVALUE_H
+
+#include <iostream>
+
+#include "parameter.h"
+
+namespace command {
+ /**
+ * Multiple Value Parameter decorator. Allows Parameters to understand
+ * many values.
+ *
+ * Example:
+ * - separator: ","
+ * - multiValue: "0,1,2,3,4,5,6,7,8,9"
+ *
+ * Example usage:
+ * - ./myprog ARGUMENT,ARGUMENT,ARGUMENT,ARGUMENT
+ * - ./myprog OPTION_NAME=VALUE,VALUE,VALUE,VALUE
+ */
+ class MultiValue : public Parameter {
+ protected:
+ /**
+ * Parameter which will be treated as containing multiple values
+ */
+ Parameter * parameter;
+
+ std::vector<std::string> values;
+
+ std::string separator;
+
+ public:
+ /**
+ * Default constructor.
+ *
+ * @param parameter Parameter which will be treated as containing multiple values
+ */
+ MultiValue(std::string separator, Parameter * parameter)
+ : Parameter(parameter->describe()), parameter(parameter),
+ separator(separator) {
+ }
+
+ /**
+ * Default destructor. Releases allocated memory
+ */
+ virtual ~MultiValue() {
+ delete parameter;
+ }
+
+ /**
+ * Wrapper method around passed Parameter::handle().
+ *
+ * \inheritdoc
+ */
+ virtual void handle() {
+ for (std::string value : values) {
+ parameter->understand(value);
+ parameter->handle();
+ }
+ }
+
+ /**
+ * Wrapper method around passed Parameter::understand()
+ *
+ * @param argv command line value against which test will be made
+ *
+ * \inheritdoc
+ */
+ virtual bool understand(const std::string & value) {
+ size_t start = 0;
+ size_t pos = 0;
+ bool _understand = true;
+
+ do {
+ pos = value.find(separator, start);
+ values.push_back(value.substr(start, pos-start));
+ _understand &= parameter->understand(values.back());
+ start = pos + 1;
+ } while ((pos != std::string::npos) && (start < value.size()));
+
+ return _understand;
+ }
+
+ /**
+ * Wrapper method around passed Parameter::isRequired().
+ * Indicates if current Parameter is required.
+ *
+ * @return true if Parameter is required, false otherwise
+ */
+ virtual bool isRequired() {
+ return parameter->isRequired();
+ };
+
+ /**
+ * Wrapper method around passed Parameter::isUsed().
+ *
+ * \inheritdoc
+ */
+ virtual bool isUsed() {
+ return parameter->isUsed();
+ };
+ };
+}
+
+#endif /* __COMMAND_PARAMETER_H */
*/
virtual void handle() {
this->call(value);
+ used = true;
}
/**
*/
virtual bool understand(const std::string & argv) {
- if ((!isUsed()) && (argv.find(name) == 0)) {
+ if (argv.find(name) == 0) {
std::size_t pos = argv.find("=");
if (pos != name.size()) {
throw OptionFailedConversion("Value for option: " + name + " failed conversion to the required type");
}
- used = true;
return true;
}
return false;
*/
virtual void handle() {
this->call();
+ used = true;
}
/**
* used to check against next value.
*/
virtual bool understand(const std::string & argv) {
- if ((!isUsed()) &&
- (argv == name)) {
- used = true;
+ if (argv == name) {
return true;
}
return false;
option_handles_void_value.test \
option_should_match_exact_name.test \
option_should_throw_exception_on_missing_value.test \
- required_should_be_required.test
+ required_should_be_required.test \
+ multivalue_should_extract_values_by_separator.test
noinst_PROGRAMS = $(TESTS)
option_should_throw_exception_on_missing_value_test_SOURCES = option/should_throw_exception_on_missing_value.cpp
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
--- /dev/null
+#include <iostream>
+#include <vector>
+
+#include "argument.h"
+#include "multiValue.h"
+
+using namespace std;
+using namespace command;
+
+#define VALUE "0,1,2,3,4,5,6,7,8,9"
+
+typedef int ArgumentType;
+
+std::vector<ArgumentType> input;
+
+void function(ArgumentType value) {
+ input.push_back(value);
+ cout << "Catched value: " << value << "\n";
+}
+
+int main() {
+ Parameter * argument = new MultiValue(",", new Argument<ArgumentType>("Argument as multiValue int", function));
+
+ try {
+ if (argument->understand(VALUE)) {
+ argument->handle();
+ }
+ else {
+ cout << argument->describe() << " should understand multiple int values\n";
+ return 1;
+ }
+ }
+ catch (...) {
+ delete argument;
+ cout << argument->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 << argument->describe() << " handles boolean (TRUE) values\n";
+ delete argument;
+ return 0;
+ }
+
+ cout << argument->describe() << " do not handle multiple int values\n";
+ delete argument;
+ return 1;
+}