Skip to content

Commit

Permalink
Merge pull request #344 from rouault/At_least_one_followed_by_exactly…
Browse files Browse the repository at this point in the history
…_one

Fix parsing of a program that accepts a positional argument with 1:* cardinality followed by another positional argument with 1:1
  • Loading branch information
p-ranav authored Apr 2, 2024
2 parents 1c48205 + 2c245a2 commit 9550b0a
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 0 deletions.
16 changes: 16 additions & 0 deletions include/argparse/argparse.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2336,6 +2336,22 @@ class ArgumentParser {
}
}
auto argument = positional_argument_it++;

// Deal with the situation of <positional_arg1>... <positional_arg2>
if (argument->m_num_args_range.get_min() == 1 &&
argument->m_num_args_range.get_max() == (std::numeric_limits<std::size_t>::max)() &&
positional_argument_it != std::end(m_positional_arguments) &&
std::next(positional_argument_it) == std::end(m_positional_arguments) &&
positional_argument_it->m_num_args_range.get_min() == 1 &&
positional_argument_it->m_num_args_range.get_max() == 1 ) {
if (std::next(it) != end) {
positional_argument_it->consume(std::prev(end), end);
end = std::prev(end);
} else {
throw std::runtime_error("Missing " + positional_argument_it->m_names.front());
}
}

it = argument->consume(it, end);
continue;
}
Expand Down
37 changes: 37 additions & 0 deletions test/test_positional_arguments.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -264,3 +264,40 @@ TEST_CASE("Square a number" * test_suite("positional_arguments")) {
program.parse_args({"./main", "15"});
REQUIRE(program.get<double>("square") == 225);
}

TEST_CASE("At_least_one_followed_by_exactly_one" * test_suite("positional_arguments")) {
GIVEN("a program that accepts a positional argument with at_least_one cardinality followed by another positional argument with 1:1") {
argparse::ArgumentParser program;

std::vector<std::string> at_least_one;
program.add_argument("at_least_one")
.nargs(argparse::nargs_pattern::at_least_one)
.store_into(at_least_one);

std::string exactly_one;
program.add_argument("exactly_one")
.store_into(exactly_one);

WHEN("provided one, two") {
THEN("parse_args works") {
program.parse_args({"./main", "one", "two"});
REQUIRE(at_least_one == std::vector<std::string>{"one"});
REQUIRE(exactly_one == "two");
}
}

WHEN("provided one, two, three") {
THEN("parse_args works") {
program.parse_args({"./main", "one", "two", "three"});
REQUIRE(at_least_one == std::vector<std::string>{"one", "two"});
REQUIRE(exactly_one == "three");
}
}

WHEN("provided one, two") {
THEN("parse_args throws") {
REQUIRE_THROWS(program.parse_args({"./main", "one"}));
}
}
}
}

0 comments on commit 9550b0a

Please sign in to comment.