Commit b5283241076013b325a8cf881c19829ac1cbbdb5
1 parent
cd65c459
Fix option matching
Showing
3 changed files
with
33 additions
and
2 deletions
CHANGELOG.md
| @@ -19,6 +19,7 @@ options. The project adheres to semantic versioning. | @@ -19,6 +19,7 @@ options. The project adheres to semantic versioning. | ||
| 19 | * Fix a warning about possible loss of data. | 19 | * Fix a warning about possible loss of data. |
| 20 | * Fix version numbering in CMakeLists.txt | 20 | * Fix version numbering in CMakeLists.txt |
| 21 | * Remove unused declaration of the undefined `ParseResult::get_option`. | 21 | * Remove unused declaration of the undefined `ParseResult::get_option`. |
| 22 | +* Throw on invalid option syntax when beginning with a `-`. | ||
| 22 | 23 | ||
| 23 | ## 2.1.1 | 24 | ## 2.1.1 |
| 24 | 25 |
include/cxxopts.hpp
| @@ -368,6 +368,15 @@ namespace cxxopts | @@ -368,6 +368,15 @@ namespace cxxopts | ||
| 368 | } | 368 | } |
| 369 | }; | 369 | }; |
| 370 | 370 | ||
| 371 | + class option_syntax_exception : public OptionParseException { | ||
| 372 | + public: | ||
| 373 | + option_syntax_exception(const std::string& text) | ||
| 374 | + : OptionParseException(u8"Argument " + LQUOTE + text + RQUOTE + | ||
| 375 | + u8" starts with a - but has incorrect syntax") | ||
| 376 | + { | ||
| 377 | + } | ||
| 378 | + }; | ||
| 379 | + | ||
| 371 | class option_not_exists_exception : public OptionParseException | 380 | class option_not_exists_exception : public OptionParseException |
| 372 | { | 381 | { |
| 373 | public: | 382 | public: |
| @@ -1701,6 +1710,11 @@ ParseResult::parse(int& argc, char**& argv) | @@ -1701,6 +1710,11 @@ ParseResult::parse(int& argc, char**& argv) | ||
| 1701 | { | 1710 | { |
| 1702 | //not a flag | 1711 | //not a flag |
| 1703 | 1712 | ||
| 1713 | + // but if it starts with a `-`, then it's an error | ||
| 1714 | + if (argv[current][0] == '-') { | ||
| 1715 | + throw option_syntax_exception(argv[current]); | ||
| 1716 | + } | ||
| 1717 | + | ||
| 1704 | //if true is returned here then it was consumed, otherwise it is | 1718 | //if true is returned here then it was consumed, otherwise it is |
| 1705 | //ignored | 1719 | //ignored |
| 1706 | if (consume_positional(argv[current])) | 1720 | if (consume_positional(argv[current])) |
test/options.cpp
| @@ -111,7 +111,7 @@ TEST_CASE("Short options", "[options]") | @@ -111,7 +111,7 @@ TEST_CASE("Short options", "[options]") | ||
| 111 | CHECK(result.count("a") == 1); | 111 | CHECK(result.count("a") == 1); |
| 112 | CHECK(result["a"].as<std::string>() == "value"); | 112 | CHECK(result["a"].as<std::string>() == "value"); |
| 113 | 113 | ||
| 114 | - REQUIRE_THROWS_AS(options.add_options()("", "nothing option"), | 114 | + REQUIRE_THROWS_AS(options.add_options()("", "nothing option"), |
| 115 | cxxopts::invalid_option_format_error); | 115 | cxxopts::invalid_option_format_error); |
| 116 | } | 116 | } |
| 117 | 117 | ||
| @@ -513,7 +513,7 @@ TEST_CASE("Unrecognised options", "[options]") { | @@ -513,7 +513,7 @@ TEST_CASE("Unrecognised options", "[options]") { | ||
| 513 | "--long", | 513 | "--long", |
| 514 | "-su", | 514 | "-su", |
| 515 | "--another_unknown", | 515 | "--another_unknown", |
| 516 | - }); | 516 | + }); |
| 517 | 517 | ||
| 518 | char** argv = av.argv(); | 518 | char** argv = av.argv(); |
| 519 | auto argc = av.argc(); | 519 | auto argc = av.argc(); |
| @@ -529,3 +529,19 @@ TEST_CASE("Unrecognised options", "[options]") { | @@ -529,3 +529,19 @@ TEST_CASE("Unrecognised options", "[options]") { | ||
| 529 | CHECK_THAT(argv[1], Catch::Equals("--unknown")); | 529 | CHECK_THAT(argv[1], Catch::Equals("--unknown")); |
| 530 | } | 530 | } |
| 531 | } | 531 | } |
| 532 | + | ||
| 533 | +TEST_CASE("Invalid option syntax", "[options]") { | ||
| 534 | + cxxopts::Options options("invalid_syntax", " - test invalid syntax"); | ||
| 535 | + | ||
| 536 | + Argv av({ | ||
| 537 | + "invalid_syntax", | ||
| 538 | + "--a", | ||
| 539 | + }); | ||
| 540 | + | ||
| 541 | + char** argv = av.argv(); | ||
| 542 | + auto argc = av.argc(); | ||
| 543 | + | ||
| 544 | + SECTION("Default behaviour") { | ||
| 545 | + CHECK_THROWS_AS(options.parse(argc, argv), cxxopts::option_syntax_exception); | ||
| 546 | + } | ||
| 547 | +} |