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.
This commit is contained in:
Jarryd Beck 2017-11-28 08:43:55 +11:00
parent 0a49b82072
commit abe9ebd6b4
3 changed files with 14 additions and 4 deletions

View File

@ -3,6 +3,16 @@
This is the changelog for `cxxopts`, a C++11 library for parsing command line
options. The project adheres to semantic versioning.
## 2.1
### Changed
* Options with implicit arguments now require the `--option=value` form if
they are to be specified with an option. This is to remove the ambiguity
when a positional argument could follow an option with an implicit value.
For example, `--foo value`, where `foo` has an implicit value, will be
parsed as `--foo=implicit` and a positional argument `value`.
## 2.0
### Changed

View File

@ -1522,7 +1522,7 @@ ParseResult::checked_parse_arg
}
else
{
if (argv[current + 1][0] == '-' && value->value().has_implicit())
if (value->value().has_implicit())
{
parse_option(value, name, value->value().get_implicit_value());
}
@ -1696,7 +1696,7 @@ ParseResult::parse(int& argc, char**& argv)
auto opt = iter->second;
//equals provided for long option?
if (result[3].length() != 0)
if (result[2].length() != 0)
{
//parse the option given

View File

@ -218,7 +218,7 @@ TEST_CASE("Empty with implicit value", "[implicit]")
("implicit", "Has implicit", cxxopts::value<std::string>()
->implicit_value("foo"));
Argv av({"implicit", "--implicit", ""});
Argv av({"implicit", "--implicit="});
char** argv = av.argv();
auto argc = av.argc();
@ -428,7 +428,7 @@ TEST_CASE("Booleans", "[boolean]") {
options.parse_positional("others");
Argv av({"booleans", "--bool=false", "--debug", "true", "--timing", "extra"});
Argv av({"booleans", "--bool=false", "--debug=true", "--timing", "extra"});
char** argv = av.argv();
auto argc = av.argc();