aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--args.hxx29
-rw-r--r--test.cxx19
2 files changed, 38 insertions, 10 deletions
diff --git a/args.hxx b/args.hxx
index 09c1919..da6eb54 100644
--- a/args.hxx
+++ b/args.hxx
@@ -1633,11 +1633,11 @@ namespace args
public:
Subparser(std::vector<std::string> args_, ArgumentParser &parser_, const Command &command_, const HelpParams &helpParams_)
- : args(std::move(args_)), parser(&parser_), helpParams(helpParams_), command(command_)
+ : Group({}, Validators::AllChildGroups), args(std::move(args_)), parser(&parser_), helpParams(helpParams_), command(command_)
{
}
- Subparser(const Command &command_, const HelpParams &helpParams_) : helpParams(helpParams_), command(command_)
+ Subparser(const Command &command_, const HelpParams &helpParams_) : Group({}, Validators::AllChildGroups), helpParams(helpParams_), command(command_)
{
}
@@ -2128,18 +2128,23 @@ namespace args
return;
}
- for (Base *child: Children())
+ auto onValidationError = [&]
{
- if (child->IsGroup() && !child->Matched())
- {
- std::ostringstream problem;
- problem << "Group validation failed somewhere!";
+ std::ostringstream problem;
+ problem << "Group validation failed somewhere!";
#ifdef ARGS_NOEXCEPT
- error = Error::Validation;
- errorMsg = problem.str();
+ error = Error::Validation;
+ errorMsg = problem.str();
#else
- throw ValidationError(problem.str());
+ throw ValidationError(problem.str());
#endif
+ };
+
+ for (Base *child: Children())
+ {
+ if (child->IsGroup() && !child->Matched())
+ {
+ onValidationError();
}
child->Validate(shortprefix, longprefix);
@@ -2148,6 +2153,10 @@ namespace args
if (subparser != nullptr)
{
subparser->Validate(shortprefix, longprefix);
+ if (!subparser->Matched())
+ {
+ onValidationError();
+ }
}
if (selectedCommand == nullptr && commandIsRequired && (Group::HasCommand() || subparserHasCommand))
diff --git a/test.cxx b/test.cxx
index b46007d..5e84398 100644
--- a/test.cxx
+++ b/test.cxx
@@ -936,6 +936,25 @@ TEST_CASE("Subparser validation works as expected", "[args]")
REQUIRE_THROWS_AS(p.ParseArgs(std::vector<std::string>{"unknown-command"}), args::ParseError);
}
+TEST_CASE("Subparser group validation works as expected", "[args]")
+{
+ int x = 0;
+ args::ArgumentParser p("parser");
+ args::Command a(p, "a", "command a", [&](args::Subparser &s)
+ {
+ args::Group required(s, "", args::Group::Validators::All);
+ args::ValueFlag<std::string> f(required, "", "", {'f'});
+ s.Parse();
+ ++x;
+ });
+
+ p.RequireCommand(false);
+ REQUIRE_NOTHROW(p.ParseArgs(std::vector<std::string>{}));
+ REQUIRE_NOTHROW(p.ParseArgs(std::vector<std::string>{"a", "-f", "F"}));
+ REQUIRE_THROWS_AS(p.ParseArgs(std::vector<std::string>{"a"}), args::ValidationError);
+ REQUIRE(x == 1);
+}
+
TEST_CASE("Global options work as expected", "[args]")
{
args::Group globals;