1
0
mirror of https://github.com/CLIUtils/CLI11.git synced 2025-05-03 14:03:52 +00:00

allow the use of allow_extra_args(false) to specify only a single argument at a time with a container output. (#484)

This commit is contained in:
Philip Top 2020-07-23 21:02:33 -07:00 committed by GitHub
parent 73e94b22e7
commit 34bd80971b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 33 additions and 1 deletions

View File

@ -322,6 +322,7 @@ Before parsing, you can set the following options:
- `->ignore_case()`: Ignore the case on the command line (also works on subcommands, does not affect arguments). - `->ignore_case()`: Ignore the case on the command line (also works on subcommands, does not affect arguments).
- `->ignore_underscore()`: Ignore any underscores in the options names (also works on subcommands, does not affect arguments). For example "option_one" will match with "optionone". This does not apply to short form options since they only have one character - `->ignore_underscore()`: Ignore any underscores in the options names (also works on subcommands, does not affect arguments). For example "option_one" will match with "optionone". This does not apply to short form options since they only have one character
- `->disable_flag_override()`: From the command line long form flag options can be assigned a value on the command line using the `=` notation `--flag=value`. If this behavior is not desired, the `disable_flag_override()` disables it and will generate an exception if it is done on the command line. The `=` does not work with short form flag options. - `->disable_flag_override()`: From the command line long form flag options can be assigned a value on the command line using the `=` notation `--flag=value`. If this behavior is not desired, the `disable_flag_override()` disables it and will generate an exception if it is done on the command line. The `=` does not work with short form flag options.
- `->allow_extra_args(true/false)`: 🚧 If set to true the option will take an unlimited number of arguments like a vector, if false it will limit the number of arguments to the size of the type used in the option. Default value depends on the nature of the type use, containers default to true, others default to false.
- `->delimiter(char)`: Allows specification of a custom delimiter for separating single arguments into vector arguments, for example specifying `->delimiter(',')` on an option would result in `--opt=1,2,3` producing 3 elements of a vector and the equivalent of --opt 1 2 3 assuming opt is a vector value. - `->delimiter(char)`: Allows specification of a custom delimiter for separating single arguments into vector arguments, for example specifying `->delimiter(',')` on an option would result in `--opt=1,2,3` producing 3 elements of a vector and the equivalent of --opt 1 2 3 assuming opt is a vector value.
- `->description(str)`: Set/change the description. - `->description(str)`: Set/change the description.
- `->multi_option_policy(CLI::MultiOptionPolicy::Throw)`: Set the multi-option policy. Shortcuts available: `->take_last()`, `->take_first()`,`->take_all()`, and `->join()`. This will only affect options expecting 1 argument or bool flags (which do not inherit their default but always start with a specific policy). - `->multi_option_policy(CLI::MultiOptionPolicy::Throw)`: Set the multi-option policy. Shortcuts available: `->take_last()`, `->take_first()`,`->take_all()`, and `->join()`. This will only affect options expecting 1 argument or bool flags (which do not inherit their default but always start with a specific policy).

View File

@ -2761,7 +2761,12 @@ class App {
} }
int min_num = (std::min)(op->get_type_size_min(), op->get_items_expected_min()); int min_num = (std::min)(op->get_type_size_min(), op->get_items_expected_min());
int max_num = op->get_items_expected_max(); int max_num = op->get_items_expected_max();
// check container like options to limit the argument size to a single type if the allow_extra_flags argument is
// set. 16 is somewhat arbitrary (needs to be at least 4)
if(max_num >= detail::expected_max_vector_size / 16 && !op->get_allow_extra_args()) {
auto tmax = op->get_type_size_max();
max_num = detail::checked_multiply(tmax, op->get_expected_min()) ? tmax : detail::expected_max_vector_size;
}
// Make sure we always eat the minimum for unlimited vectors // Make sure we always eat the minimum for unlimited vectors
int collected = 0; // total number of arguments collected int collected = 0; // total number of arguments collected
int result_count = 0; // local variable for number of results in a single arg string int result_count = 0; // local variable for number of results in a single arg string

View File

@ -838,3 +838,29 @@ TEST_F(TApp, tupleTwoVectors) {
EXPECT_EQ(std::get<0>(cv).size(), 2U); EXPECT_EQ(std::get<0>(cv).size(), 2U);
EXPECT_EQ(std::get<1>(cv).size(), 3U); EXPECT_EQ(std::get<1>(cv).size(), 3U);
} }
TEST_F(TApp, vectorSingleArg) {
std::vector<int> cv;
app.add_option("-c", cv)->allow_extra_args(false);
std::string extra;
app.add_option("args", extra);
args = {"-c", "1", "-c", "2", "4"};
run();
EXPECT_EQ(cv.size(), 2U);
EXPECT_EQ(extra, "4");
}
TEST_F(TApp, vectorDoubleArg) {
std::vector<std::pair<int, std::string>> cv;
app.add_option("-c", cv)->allow_extra_args(false);
std::vector<std::string> extras;
app.add_option("args", extras);
args = {"-c", "1", "bob", "-c", "2", "apple", "4", "key"};
run();
EXPECT_EQ(cv.size(), 2U);
EXPECT_EQ(extras.size(), 2U);
}