Skip to content

Commit

Permalink
Allow -- to end unlimited options
Browse files Browse the repository at this point in the history
  • Loading branch information
henryiii committed Apr 9, 2018
1 parent af19b92 commit 801e0ad
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 4 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ On a compiler that supports C++17's `__has_include`, you can also use `std::opti
The add commands return a pointer to an internally stored `Option`. If you set the final argument to true, the default value is captured and printed on the command line with the help flag. This option can be used directly to check for the count (`->count()`) after parsing to avoid a string based lookup. Before parsing, you can set the following options:

* `->required()`: The program will quit if this option is not present. This is `mandatory` in Plumbum, but required options seems to be a more standard term. For compatibility, `->mandatory()` also works.
* `->expected(N)`: Take `N` values instead of as many as possible, only for vector args. If negative, require at least `-N`.
* `->expected(N)`: Take `N` values instead of as many as possible, only for vector args. If negative, require at least `-N`; end with `--` or another recognized option.
* `->needs(opt)`: This option requires another option to also be present, opt is an `Option` pointer.
* `->excludes(opt)`: This option cannot be given with `opt` present, opt is an `Option` pointer.
* `->envname(name)`: Gets the value from the environment if present and not passed on the command line.
Expand Down
2 changes: 1 addition & 1 deletion examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ add_cli_exe(prefix_command prefix_command.cpp)
add_test(NAME prefix_command COMMAND prefix_command -v 3 2 1 -- other one two 3)
set_property(TEST prefix_command PROPERTY PASS_REGULAR_EXPRESSION
"Prefix: 3 : 2 : 1"
"Remaining commands: -- other one two 3")
"Remaining commands: other one two 3")

add_cli_exe(enum enum.cpp)
add_test(NAME enum_pass COMMAND enum -l 1)
Expand Down
8 changes: 7 additions & 1 deletion include/CLI/App.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1035,12 +1035,14 @@ class App {
/// This gets a vector of pointers with the original parse order
const std::vector<Option *> &parse_order() const { return parse_order_; }

/// This retuns the missing options from the current subcommand
/// This returns the missing options from the current subcommand
std::vector<std::string> remaining(bool recurse = false) const {
std::vector<std::string> miss_list;
for(const std::pair<detail::Classifer, std::string> &miss : missing_) {
miss_list.push_back(std::get<1>(miss));
}

// Recurse into subcommands
if(recurse) {
for(const App *sub : parsed_subcommands_) {
std::vector<std::string> output = sub->remaining(recurse);
Expand Down Expand Up @@ -1472,6 +1474,10 @@ class App {
collected++;
}

// Allow -- to end an unlimited list and "eat" it
if(args.size() > 0 && _recognize(args.back()) == detail::Classifer::POSITIONAL_MARK)
args.pop_back();

} else {
while(num > 0 && !args.empty()) {
num--;
Expand Down
13 changes: 13 additions & 0 deletions tests/AppTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -581,6 +581,19 @@ TEST_F(TApp, RequiredOptsUnlimitedShort) {
EXPECT_EQ(remain, std::vector<std::string>({"two"}));
}

TEST_F(TApp, OptsUnlimitedEnd) {
std::vector<std::string> strs;
app.add_option("-s,--str", strs);
app.allow_extras();

args = {"one", "-s", "two", "three", "--", "four"};

run();

EXPECT_EQ(strs, std::vector<std::string>({"two", "three"}));
EXPECT_EQ(app.remaining(), std::vector<std::string>({"one", "four"}));
}

TEST_F(TApp, RequireOptPriority) {

std::vector<std::string> strs;
Expand Down
2 changes: 1 addition & 1 deletion tests/SubcommandTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ TEST_F(TApp, PrefixSeparation) {

run();

EXPECT_EQ(app.remaining(), std::vector<std::string>({"--", "other"}));
EXPECT_EQ(app.remaining(), std::vector<std::string>({"other"}));
EXPECT_EQ(vals, std::vector<int>({1, 2, 3}));
}

Expand Down

0 comments on commit 801e0ad

Please sign in to comment.