Commit 4b7fccb5f2bca82041f6d71026c3133a873c6de5
Committed by
Jarryd Beck
1 parent
1ff0da64
Allow empty string to be valid positional arguments
Fixes #204.
Showing
2 changed files
with
31 additions
and
0 deletions
include/cxxopts.hpp
| ... | ... | @@ -974,6 +974,12 @@ namespace cxxopts |
| 974 | 974 | void |
| 975 | 975 | parse_value(const std::string& text, std::vector<T>& value) |
| 976 | 976 | { |
| 977 | + if (text.empty()) { | |
| 978 | + T v; | |
| 979 | + parse_value(text, v); | |
| 980 | + value.emplace_back(std::move(v)); | |
| 981 | + return; | |
| 982 | + } | |
| 977 | 983 | std::stringstream in(text); |
| 978 | 984 | std::string token; |
| 979 | 985 | while(!in.eof() && std::getline(in, token, CXXOPTS_VECTOR_DELIMITER)) { | ... | ... |
test/options.cpp
| ... | ... | @@ -231,6 +231,31 @@ TEST_CASE("Positional not valid", "[positional]") { |
| 231 | 231 | CHECK_THROWS_AS(options.parse(argc, argv), cxxopts::option_not_exists_exception&); |
| 232 | 232 | } |
| 233 | 233 | |
| 234 | +TEST_CASE("Positional with empty arguments", "[positional]") { | |
| 235 | + cxxopts::Options options("positional_with_empty_arguments", "positional with empty argument"); | |
| 236 | + options.add_options() | |
| 237 | + ("long", "a long option", cxxopts::value<std::string>()) | |
| 238 | + ("program", "program to run", cxxopts::value<std::string>()) | |
| 239 | + ("programArgs", "program arguments", cxxopts::value<std::vector<std::string>>()) | |
| 240 | + ; | |
| 241 | + | |
| 242 | + options.parse_positional("program", "programArgs"); | |
| 243 | + | |
| 244 | + Argv av({"foobar", "--long", "long_value", "--", "someProgram", "ab", "-c", "d", "--ef", "gh", "--ijk=lm", "n", "", "o", }); | |
| 245 | + std::vector<std::string> expected({"ab", "-c", "d", "--ef", "gh", "--ijk=lm", "n", "", "o", }); | |
| 246 | + | |
| 247 | + char** argv = av.argv(); | |
| 248 | + auto argc = av.argc(); | |
| 249 | + | |
| 250 | + auto result = options.parse(argc, argv); | |
| 251 | + auto actual = result["programArgs"].as<std::vector<std::string>>(); | |
| 252 | + | |
| 253 | + REQUIRE(result.count("program") == 1); | |
| 254 | + REQUIRE(result["program"].as<std::string>() == "someProgram"); | |
| 255 | + REQUIRE(result.count("programArgs") == expected.size()); | |
| 256 | + REQUIRE(actual == expected); | |
| 257 | +} | |
| 258 | + | |
| 234 | 259 | TEST_CASE("Empty with implicit value", "[implicit]") |
| 235 | 260 | { |
| 236 | 261 | cxxopts::Options options("empty_implicit", "doesn't handle empty"); | ... | ... |