Commit abe9ebd6b4084d576ceb79904c94ef8c9c0e6c56

Authored by Jarryd Beck
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.
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(&quot;Booleans&quot;, &quot;[boolean]&quot;) {
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();
... ...