From 9d41ddef83ed8695b69707bb65a47772a9e57407 Mon Sep 17 00:00:00 2001 From: Henry Fredrick Schreiner Date: Tue, 10 Apr 2018 13:49:36 +0200 Subject: [PATCH] Better mixing of positionals and unlimited options (#102) --- README.md | 2 +- include/CLI/App.hpp | 6 ------ tests/AppTest.cpp | 28 ++++++++++++++++++++++++++++ 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 67267dd0..4fd12b51 100644 --- a/README.md +++ b/README.md @@ -211,7 +211,7 @@ Extra positional arguments will cause the program to exit, so at least one posit If you set `.allow_extras()` on the main `App`, you will not get an error. You can access the missing options using `remaining` (if you have subcommands, `app.remaining(true)` will get all remaining options, subcommands included). You can access a vector of pointers to the parsed options in the original order using `parse_order()`. -If `--` is present in the command line, +If `--` is present in the command line that does not end an unlimited option, then everything after that is positional only. diff --git a/include/CLI/App.hpp b/include/CLI/App.hpp index 349a0d5d..e2c23919 100644 --- a/include/CLI/App.hpp +++ b/include/CLI/App.hpp @@ -1461,12 +1461,6 @@ class App { // If any positionals remain, don't keep eating if(_count_remaining_positionals() > 0) break; - - // If there are any unlimited positionals, those also take priority - if(std::any_of(std::begin(options_), std::end(options_), [](const Option_p &opt) { - return opt->get_positional() && opt->get_items_expected() < 0; - })) - break; } op->add_result(args.back()); parse_order_.push_back(op.get()); diff --git a/tests/AppTest.cpp b/tests/AppTest.cpp index b141cf63..5b1e0d92 100644 --- a/tests/AppTest.cpp +++ b/tests/AppTest.cpp @@ -542,9 +542,23 @@ TEST_F(TApp, RequiredOptsUnlimited) { app.allow_extras(false); std::vector remain; app.add_option("positional", remain); + run(); + EXPECT_EQ(strs, std::vector({"one", "two"})); + EXPECT_EQ(remain, std::vector()); + + app.reset(); + args = {"--str", "one", "--", "two"}; + run(); EXPECT_EQ(strs, std::vector({"one"})); EXPECT_EQ(remain, std::vector({"two"})); + + app.reset(); + args = {"one", "--str", "two"}; + + run(); + EXPECT_EQ(strs, std::vector({"two"})); + EXPECT_EQ(remain, std::vector({"one"})); } TEST_F(TApp, RequiredOptsUnlimitedShort) { @@ -576,9 +590,23 @@ TEST_F(TApp, RequiredOptsUnlimitedShort) { app.allow_extras(false); std::vector remain; app.add_option("positional", remain); + run(); + EXPECT_EQ(strs, std::vector({"one", "two"})); + EXPECT_EQ(remain, std::vector()); + + app.reset(); + args = {"-s", "one", "--", "two"}; + run(); EXPECT_EQ(strs, std::vector({"one"})); EXPECT_EQ(remain, std::vector({"two"})); + + app.reset(); + args = {"one", "-s", "two"}; + + run(); + EXPECT_EQ(strs, std::vector({"two"})); + EXPECT_EQ(remain, std::vector({"one"})); } TEST_F(TApp, OptsUnlimitedEnd) {