Commit b5283241076013b325a8cf881c19829ac1cbbdb5

Authored by Jarryd Beck
1 parent cd65c459

Fix option matching

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(&quot;Unrecognised options&quot;, &quot;[options]&quot;) {
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(&quot;Unrecognised options&quot;, &quot;[options]&quot;) {
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 +}
... ...