Commit abe9ebd6b4084d576ceb79904c94ef8c9c0e6c56
1 parent
0a49b820
Fix handling of implicit values
Fixes #84. Implicit values are not handled very well. For example:
--foo false true
--foo --bar
In the first, `false` is an argument to `--foo`, and then `true` is a
positional argument. In the second, because of the hyphen in `--bar`, `--foo`
is parsed with its implicit value. This seems inconsistent and unintuitive.
Better is that implicit values *never* consume the next parameter to be
completely consistent. This means that values with an implicit parameter
*must* be specified using the `--option=value` form.
Showing
3 changed files
with
14 additions
and
4 deletions
CHANGELOG.md
| ... | ... | @@ -3,6 +3,16 @@ |
| 3 | 3 | This is the changelog for `cxxopts`, a C++11 library for parsing command line |
| 4 | 4 | options. The project adheres to semantic versioning. |
| 5 | 5 | |
| 6 | +## 2.1 | |
| 7 | + | |
| 8 | +### Changed | |
| 9 | + | |
| 10 | +* Options with implicit arguments now require the `--option=value` form if | |
| 11 | + they are to be specified with an option. This is to remove the ambiguity | |
| 12 | + when a positional argument could follow an option with an implicit value. | |
| 13 | + For example, `--foo value`, where `foo` has an implicit value, will be | |
| 14 | + parsed as `--foo=implicit` and a positional argument `value`. | |
| 15 | + | |
| 6 | 16 | ## 2.0 |
| 7 | 17 | |
| 8 | 18 | ### Changed | ... | ... |
include/cxxopts.hpp
| ... | ... | @@ -1522,7 +1522,7 @@ ParseResult::checked_parse_arg |
| 1522 | 1522 | } |
| 1523 | 1523 | else |
| 1524 | 1524 | { |
| 1525 | - if (argv[current + 1][0] == '-' && value->value().has_implicit()) | |
| 1525 | + if (value->value().has_implicit()) | |
| 1526 | 1526 | { |
| 1527 | 1527 | parse_option(value, name, value->value().get_implicit_value()); |
| 1528 | 1528 | } |
| ... | ... | @@ -1696,7 +1696,7 @@ ParseResult::parse(int& argc, char**& argv) |
| 1696 | 1696 | auto opt = iter->second; |
| 1697 | 1697 | |
| 1698 | 1698 | //equals provided for long option? |
| 1699 | - if (result[3].length() != 0) | |
| 1699 | + if (result[2].length() != 0) | |
| 1700 | 1700 | { |
| 1701 | 1701 | //parse the option given |
| 1702 | 1702 | ... | ... |
test/options.cpp
| ... | ... | @@ -218,7 +218,7 @@ TEST_CASE("Empty with implicit value", "[implicit]") |
| 218 | 218 | ("implicit", "Has implicit", cxxopts::value<std::string>() |
| 219 | 219 | ->implicit_value("foo")); |
| 220 | 220 | |
| 221 | - Argv av({"implicit", "--implicit", ""}); | |
| 221 | + Argv av({"implicit", "--implicit="}); | |
| 222 | 222 | |
| 223 | 223 | char** argv = av.argv(); |
| 224 | 224 | auto argc = av.argc(); |
| ... | ... | @@ -428,7 +428,7 @@ TEST_CASE("Booleans", "[boolean]") { |
| 428 | 428 | |
| 429 | 429 | options.parse_positional("others"); |
| 430 | 430 | |
| 431 | - Argv av({"booleans", "--bool=false", "--debug", "true", "--timing", "extra"}); | |
| 431 | + Argv av({"booleans", "--bool=false", "--debug=true", "--timing", "extra"}); | |
| 432 | 432 | |
| 433 | 433 | char** argv = av.argv(); |
| 434 | 434 | auto argc = av.argc(); | ... | ... |