Commit 9d41ddef83ed8695b69707bb65a47772a9e57407
Committed by
Henry Schreiner
1 parent
b7c031cc
Better mixing of positionals and unlimited options (#102)
Showing
3 changed files
with
29 additions
and
7 deletions
README.md
| @@ -211,7 +211,7 @@ Extra positional arguments will cause the program to exit, so at least one posit | @@ -211,7 +211,7 @@ Extra positional arguments will cause the program to exit, so at least one posit | ||
| 211 | 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). | 211 | 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). |
| 212 | 212 | ||
| 213 | You can access a vector of pointers to the parsed options in the original order using `parse_order()`. | 213 | You can access a vector of pointers to the parsed options in the original order using `parse_order()`. |
| 214 | -If `--` is present in the command line, | 214 | +If `--` is present in the command line that does not end an unlimited option, then |
| 215 | everything after that is positional only. | 215 | everything after that is positional only. |
| 216 | 216 | ||
| 217 | 217 |
include/CLI/App.hpp
| @@ -1461,12 +1461,6 @@ class App { | @@ -1461,12 +1461,6 @@ class App { | ||
| 1461 | // If any positionals remain, don't keep eating | 1461 | // If any positionals remain, don't keep eating |
| 1462 | if(_count_remaining_positionals() > 0) | 1462 | if(_count_remaining_positionals() > 0) |
| 1463 | break; | 1463 | break; |
| 1464 | - | ||
| 1465 | - // If there are any unlimited positionals, those also take priority | ||
| 1466 | - if(std::any_of(std::begin(options_), std::end(options_), [](const Option_p &opt) { | ||
| 1467 | - return opt->get_positional() && opt->get_items_expected() < 0; | ||
| 1468 | - })) | ||
| 1469 | - break; | ||
| 1470 | } | 1464 | } |
| 1471 | op->add_result(args.back()); | 1465 | op->add_result(args.back()); |
| 1472 | parse_order_.push_back(op.get()); | 1466 | parse_order_.push_back(op.get()); |
tests/AppTest.cpp
| @@ -543,8 +543,22 @@ TEST_F(TApp, RequiredOptsUnlimited) { | @@ -543,8 +543,22 @@ TEST_F(TApp, RequiredOptsUnlimited) { | ||
| 543 | std::vector<std::string> remain; | 543 | std::vector<std::string> remain; |
| 544 | app.add_option("positional", remain); | 544 | app.add_option("positional", remain); |
| 545 | run(); | 545 | run(); |
| 546 | + EXPECT_EQ(strs, std::vector<std::string>({"one", "two"})); | ||
| 547 | + EXPECT_EQ(remain, std::vector<std::string>()); | ||
| 548 | + | ||
| 549 | + app.reset(); | ||
| 550 | + args = {"--str", "one", "--", "two"}; | ||
| 551 | + | ||
| 552 | + run(); | ||
| 546 | EXPECT_EQ(strs, std::vector<std::string>({"one"})); | 553 | EXPECT_EQ(strs, std::vector<std::string>({"one"})); |
| 547 | EXPECT_EQ(remain, std::vector<std::string>({"two"})); | 554 | EXPECT_EQ(remain, std::vector<std::string>({"two"})); |
| 555 | + | ||
| 556 | + app.reset(); | ||
| 557 | + args = {"one", "--str", "two"}; | ||
| 558 | + | ||
| 559 | + run(); | ||
| 560 | + EXPECT_EQ(strs, std::vector<std::string>({"two"})); | ||
| 561 | + EXPECT_EQ(remain, std::vector<std::string>({"one"})); | ||
| 548 | } | 562 | } |
| 549 | 563 | ||
| 550 | TEST_F(TApp, RequiredOptsUnlimitedShort) { | 564 | TEST_F(TApp, RequiredOptsUnlimitedShort) { |
| @@ -577,8 +591,22 @@ TEST_F(TApp, RequiredOptsUnlimitedShort) { | @@ -577,8 +591,22 @@ TEST_F(TApp, RequiredOptsUnlimitedShort) { | ||
| 577 | std::vector<std::string> remain; | 591 | std::vector<std::string> remain; |
| 578 | app.add_option("positional", remain); | 592 | app.add_option("positional", remain); |
| 579 | run(); | 593 | run(); |
| 594 | + EXPECT_EQ(strs, std::vector<std::string>({"one", "two"})); | ||
| 595 | + EXPECT_EQ(remain, std::vector<std::string>()); | ||
| 596 | + | ||
| 597 | + app.reset(); | ||
| 598 | + args = {"-s", "one", "--", "two"}; | ||
| 599 | + | ||
| 600 | + run(); | ||
| 580 | EXPECT_EQ(strs, std::vector<std::string>({"one"})); | 601 | EXPECT_EQ(strs, std::vector<std::string>({"one"})); |
| 581 | EXPECT_EQ(remain, std::vector<std::string>({"two"})); | 602 | EXPECT_EQ(remain, std::vector<std::string>({"two"})); |
| 603 | + | ||
| 604 | + app.reset(); | ||
| 605 | + args = {"one", "-s", "two"}; | ||
| 606 | + | ||
| 607 | + run(); | ||
| 608 | + EXPECT_EQ(strs, std::vector<std::string>({"two"})); | ||
| 609 | + EXPECT_EQ(remain, std::vector<std::string>({"one"})); | ||
| 582 | } | 610 | } |
| 583 | 611 | ||
| 584 | TEST_F(TApp, OptsUnlimitedEnd) { | 612 | TEST_F(TApp, OptsUnlimitedEnd) { |