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 | 19 | * Fix a warning about possible loss of data. |
| 20 | 20 | * Fix version numbering in CMakeLists.txt |
| 21 | 21 | * Remove unused declaration of the undefined `ParseResult::get_option`. |
| 22 | +* Throw on invalid option syntax when beginning with a `-`. | |
| 22 | 23 | |
| 23 | 24 | ## 2.1.1 |
| 24 | 25 | ... | ... |
include/cxxopts.hpp
| ... | ... | @@ -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 | 380 | class option_not_exists_exception : public OptionParseException |
| 372 | 381 | { |
| 373 | 382 | public: |
| ... | ... | @@ -1701,6 +1710,11 @@ ParseResult::parse(int& argc, char**& argv) |
| 1701 | 1710 | { |
| 1702 | 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 | 1718 | //if true is returned here then it was consumed, otherwise it is |
| 1705 | 1719 | //ignored |
| 1706 | 1720 | if (consume_positional(argv[current])) | ... | ... |
test/options.cpp
| ... | ... | @@ -111,7 +111,7 @@ TEST_CASE("Short options", "[options]") |
| 111 | 111 | CHECK(result.count("a") == 1); |
| 112 | 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 | 115 | cxxopts::invalid_option_format_error); |
| 116 | 116 | } |
| 117 | 117 | |
| ... | ... | @@ -513,7 +513,7 @@ TEST_CASE("Unrecognised options", "[options]") { |
| 513 | 513 | "--long", |
| 514 | 514 | "-su", |
| 515 | 515 | "--another_unknown", |
| 516 | - }); | |
| 516 | + }); | |
| 517 | 517 | |
| 518 | 518 | char** argv = av.argv(); |
| 519 | 519 | auto argc = av.argc(); |
| ... | ... | @@ -529,3 +529,19 @@ TEST_CASE("Unrecognised options", "[options]") { |
| 529 | 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 | +} | ... | ... |