From abe9ebd6b4084d576ceb79904c94ef8c9c0e6c56 Mon Sep 17 00:00:00 2001 From: Jarryd Beck Date: Tue, 28 Nov 2017 08:43:55 +1100 Subject: [PATCH] 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 | 10 ++++++++++ include/cxxopts.hpp | 4 ++-- test/options.cpp | 4 ++-- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b4ba45..11af807 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/include/cxxopts.hpp b/include/cxxopts.hpp index 3117e9d..bb486c5 100644 --- a/include/cxxopts.hpp +++ b/include/cxxopts.hpp @@ -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 diff --git a/test/options.cpp b/test/options.cpp index 387f956..3879660 100644 --- a/test/options.cpp +++ b/test/options.cpp @@ -218,7 +218,7 @@ TEST_CASE("Empty with implicit value", "[implicit]") ("implicit", "Has implicit", cxxopts::value() ->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();