Add greedy-flag for argument parser
This is useful if one needs to pass subsequent arguments as-is to another nested argument parser.
This commit is contained in:
parent
08194f5d32
commit
3c769fa242
|
@ -206,7 +206,8 @@ bool ArgumentReader::read(ArgumentVector &args)
|
||||||
// iterate through all argument denotations; loop might exit earlier when an denotation is unknown
|
// iterate through all argument denotations; loop might exit earlier when an denotation is unknown
|
||||||
while (argv != end) {
|
while (argv != end) {
|
||||||
// check whether there are still values to read
|
// check whether there are still values to read
|
||||||
if (values && lastArgInLevel->requiredValueCount() != Argument::varValueCount && values->size() < lastArgInLevel->requiredValueCount()) {
|
if (values && ((lastArgInLevel->requiredValueCount() != Argument::varValueCount) || (lastArgInLevel->flags() & Argument::Flags::Greedy))
|
||||||
|
&& values->size() < lastArgInLevel->requiredValueCount()) {
|
||||||
// read arg as value and continue with next arg
|
// read arg as value and continue with next arg
|
||||||
values->emplace_back(argDenotation ? argDenotation : *argv);
|
values->emplace_back(argDenotation ? argDenotation : *argv);
|
||||||
++index;
|
++index;
|
||||||
|
@ -1092,7 +1093,7 @@ void ArgumentParser::verifyArgs(const ArgumentVector &args)
|
||||||
assert(!arg->abbreviation() || find(abbreviations.cbegin(), abbreviations.cend(), arg->abbreviation()) == abbreviations.cend());
|
assert(!arg->abbreviation() || find(abbreviations.cbegin(), abbreviations.cend(), arg->abbreviation()) == abbreviations.cend());
|
||||||
abbreviations.push_back(arg->abbreviation());
|
abbreviations.push_back(arg->abbreviation());
|
||||||
assert(!arg->name() || find_if(names.cbegin(), names.cend(), [arg](const char *name) { return !strcmp(arg->name(), name); }) == names.cend());
|
assert(!arg->name() || find_if(names.cbegin(), names.cend(), [arg](const char *name) { return !strcmp(arg->name(), name); }) == names.cend());
|
||||||
assert(arg->requiredValueCount() == 0 || arg->subArguments().size() == 0);
|
assert(arg->requiredValueCount() == 0 || arg->subArguments().size() == 0 || (arg->flags() & Argument::Flags::Greedy));
|
||||||
names.emplace_back(arg->name());
|
names.emplace_back(arg->name());
|
||||||
}
|
}
|
||||||
for (const Argument *arg : args) {
|
for (const Argument *arg : args) {
|
||||||
|
|
|
@ -273,6 +273,7 @@ public:
|
||||||
Implicit = 0x2,
|
Implicit = 0x2,
|
||||||
Operation = 0x4,
|
Operation = 0x4,
|
||||||
Deprecated = 0x8,
|
Deprecated = 0x8,
|
||||||
|
Greedy = 0x10,
|
||||||
};
|
};
|
||||||
|
|
||||||
Argument(const char *name, char abbreviation = '\0', const char *description = nullptr, const char *example = nullptr);
|
Argument(const char *name, char abbreviation = '\0', const char *description = nullptr, const char *example = nullptr);
|
||||||
|
|
|
@ -452,6 +452,27 @@ void ArgumentParserTests::testParsing()
|
||||||
CPPUNIT_ASSERT(fieldsArg.isPresent());
|
CPPUNIT_ASSERT(fieldsArg.isPresent());
|
||||||
CPPUNIT_ASSERT_EQUAL("fields"sv, std::string_view(fieldsArg.values().at(0)));
|
CPPUNIT_ASSERT_EQUAL("fields"sv, std::string_view(fieldsArg.values().at(0)));
|
||||||
CPPUNIT_ASSERT_EQUAL("album=test"sv, std::string_view(fieldsArg.values().at(1)));
|
CPPUNIT_ASSERT_EQUAL("album=test"sv, std::string_view(fieldsArg.values().at(1)));
|
||||||
|
|
||||||
|
// greedy-flag
|
||||||
|
const char *argv19[] = { "tageditor", "get", "--fields", "foo", "bar", "--help" };
|
||||||
|
parser.resetArgs();
|
||||||
|
try {
|
||||||
|
parser.parseArgs(6, argv19, ParseArgumentBehavior::CheckConstraints | ParseArgumentBehavior::InvokeCallbacks);
|
||||||
|
CPPUNIT_FAIL("Exception expected.");
|
||||||
|
} catch (const ParseError &e) {
|
||||||
|
CPPUNIT_ASSERT_EQUAL_MESSAGE("--help assumed to be an argument without greedy-flag (leading to error)",
|
||||||
|
"The argument \"help\" can not be combined with \"get\"."sv, std::string_view(e.what()));
|
||||||
|
}
|
||||||
|
parser.resetArgs();
|
||||||
|
fieldsArg.setFlags(Argument::Flags::Greedy, true);
|
||||||
|
parser.parseArgs(6, argv19, ParseArgumentBehavior::CheckConstraints | ParseArgumentBehavior::InvokeCallbacks);
|
||||||
|
CPPUNIT_ASSERT(displayTagInfoArg.isPresent());
|
||||||
|
CPPUNIT_ASSERT(fieldsArg.isPresent());
|
||||||
|
CPPUNIT_ASSERT_MESSAGE("--help not considered an argument with greedy-flag", !parser.helpArg().isPresent());
|
||||||
|
CPPUNIT_ASSERT_EQUAL("foo"sv, std::string_view(fieldsArg.values().at(0)));
|
||||||
|
CPPUNIT_ASSERT_EQUAL("bar"sv, std::string_view(fieldsArg.values().at(1)));
|
||||||
|
CPPUNIT_ASSERT_EQUAL("--help"sv, std::string_view(fieldsArg.values().at(2)));
|
||||||
|
CPPUNIT_ASSERT_THROW(fieldsArg.values().at(3), std::out_of_range);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
Loading…
Reference in New Issue