diff --git a/src/cxxopts.hpp b/src/cxxopts.hpp index 6f0dcbe..f1999d4 100644 --- a/src/cxxopts.hpp +++ b/src/cxxopts.hpp @@ -1031,20 +1031,35 @@ Options::add_to_option(const std::string& option, const std::string& arg) bool Options::consume_positional(std::string a) { - if (m_next_positional != m_positional.end()) + while (m_next_positional != m_positional.end()) { - add_to_option(*m_next_positional, a); - auto iter = m_options.find(*m_next_positional); - if (iter != m_options.end() && !iter->second->value().is_container()) { - ++m_next_positional; + if (iter != m_options.end()) + { + if (!iter->second->value().is_container()) + { + if (iter->second->count() == 0) + { + add_to_option(*m_next_positional, a); + ++m_next_positional; + return true; + } + else + { + ++m_next_positional; + continue; + } + } + else + { + add_to_option(*m_next_positional, a); + return true; + } } - return true; - } - else - { - return false; + ++m_next_positional; } + + return false; } void diff --git a/test/options.cpp b/test/options.cpp index c707eaf..e957009 100644 --- a/test/options.cpp +++ b/test/options.cpp @@ -78,11 +78,47 @@ TEST_CASE("Basic options", "[options]") TEST_CASE("No positional", "[positional]") { - cxxopts::Options options("test_positional", " - test no positional options"); + cxxopts::Options options("test_no_positional", + " - test no positional options"); - Argv argv({"tester", "a", "b", "def"}); + Argv av({"tester", "a", "b", "def"}); - char** passed_argv = argv.argv(); - auto argc = argv.argc(); - options.parse(argc, passed_argv); + char** argv = av.argv(); + auto argc = av.argc(); + options.parse(argc, argv); + + REQUIRE(argc == 4); + CHECK(strcmp(argv[1], "a") == 0); +} + +TEST_CASE("Some positional explicit", "[positional]") +{ + cxxopts::Options options("positional_explicit", " - test positional"); + + options.add_options() + ("input", "Input file", cxxopts::value()) + ("output", "Output file", cxxopts::value()) + ("positional", "Positional parameters", + cxxopts::value>()) + ; + + options.parse_positional({"input", "output", "positional"}); + + Argv av({"tester", "--output", "a", "b", "c", "d"}); + + char** argv = av.argv(); + auto argc = av.argc(); + + options.parse(argc, argv); + + CHECK(argc == 1); + CHECK(options.count("output")); + CHECK(options["input"].as() == "b"); + CHECK(options["output"].as() == "a"); + + auto& positional = options["positional"].as>(); + + REQUIRE(positional.size() == 2); + CHECK(positional[0] == "c"); + CHECK(positional[1] == "d"); }