1
0
mirror of https://github.com/CLIUtils/CLI11.git synced 2025-04-29 12:13:52 +00:00

Allow -- to end unlimited options

This commit is contained in:
Henry Fredrick Schreiner 2018-04-09 13:17:55 +02:00 committed by Henry Schreiner
parent 0303929552
commit 8f1215873c
6 changed files with 28 additions and 6 deletions

View File

@ -1,5 +1,4 @@
## Version 1.5: Optional
## Version 1.5: Optionals
This version introduced support for optionals, along with clarification and examples of custom conversion overloads. Enums now have been dropped from the automatic conversion system, allowing explicit protection for out-of-range ints (or a completely custom conversion). This version has some internal cleanup and improved support for the newest compilers. Several bugs were fixed, as well.
@ -11,6 +10,7 @@ Note: This is the final release with `requires`, please switch to `needs`.
* All macros/CMake variables now start with `CLI11_` instead of just `CLI_` [#95]
* The internal stream was not being cleared before use in some cases. Fixed. [#95]
* Using an emum now requires explicit conversion overload [#97]
* The separator `--` now is removed when it ends unlimited arguments [#100]
Other, non-user facing changes:
@ -21,12 +21,15 @@ Other, non-user facing changes:
* Better single file generation [#95]
* Added support for GTest on MSVC 2017 (but not in C++17 mode, will need next version of GTest)
* Types now have a specific size, separate from the expected number - cleaner and more powerful internally [#92]
* Examples now run as part of testing [#99]
[#64]: https://github.com/CLIUtils/CLI11/issues/64
[#90]: https://github.com/CLIUtils/CLI11/issues/90
[#92]: https://github.com/CLIUtils/CLI11/issues/92
[#95]: https://github.com/CLIUtils/CLI11/pull/95
[#97]: https://github.com/CLIUtils/CLI11/pull/97
[#99]: https://github.com/CLIUtils/CLI11/pull/99
[#100]: https://github.com/CLIUtils/CLI11/pull/100
## Version 1.4: More feedback

View File

@ -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.

View File

@ -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)

View File

@ -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);
@ -1472,6 +1474,10 @@ class App {
collected++;
}
// Allow -- to end an unlimited list and "eat" it
if(!args.empty() && _recognize(args.back()) == detail::Classifer::POSITIONAL_MARK)
args.pop_back();
} else {
while(num > 0 && !args.empty()) {
num--;

View File

@ -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;

View File

@ -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}));
}