diff --git a/include/cxxopts.hpp b/include/cxxopts.hpp index 4ed4892..33851e1 100644 --- a/include/cxxopts.hpp +++ b/include/cxxopts.hpp @@ -678,7 +678,8 @@ inline OptionNames split_option_names(const std::string &text) "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789" - "_-"; + "_-.?"; + if (!std::isalnum(text[token_start_pos], std::locale::classic()) || text.find_first_not_of(option_name_valid_chars, token_start_pos) < next_delimiter_pos) { throw_or_mimic(text); @@ -752,9 +753,9 @@ std::basic_regex falsy_pattern ("(f|F)(alse)?|0"); std::basic_regex option_matcher - ("--([[:alnum:]][-_[:alnum:]]+)(=(.*))?|-([[:alnum:]].*)"); + ("--([[:alnum:]][-_[:alnum:]\\.]+)(=(.*))?|-([[:alnum:]].*)"); std::basic_regex option_specifier - ("([[:alnum:]][-_[:alnum:]]*)(,[ ]*[[:alnum:]][-_[:alnum:]]*)*"); + ("([[:alnum:]][-_[:alnum:]\\.]*)(,[ ]*[[:alnum:]][-_[:alnum:]]*)*"); std::basic_regex option_specifier_separator(", *"); } // namespace diff --git a/test/options.cpp b/test/options.cpp index 6da106e..288810d 100644 --- a/test/options.cpp +++ b/test/options.cpp @@ -56,6 +56,7 @@ TEST_CASE("Basic options", "[options]") ("a,av", "a short option with a value", cxxopts::value()) ("6,six", "a short number option") ("p, space", "an option with space between short and long") + ("period.delimited", "an option with a period in the long name") ("nothing", "won't exist", cxxopts::value()) ; @@ -77,7 +78,8 @@ TEST_CASE("Basic options", "[options]") "-z", "--over", "--dog", - "--lazy" + "--lazy", + "--period.delimited", }); auto** actual_argv = argv.argv(); @@ -97,9 +99,10 @@ TEST_CASE("Basic options", "[options]") CHECK(result.count("quick") == 2); CHECK(result.count("f") == 2); CHECK(result.count("z") == 4); + CHECK(result.count("period.delimited") == 1); auto& arguments = result.arguments(); - REQUIRE(arguments.size() == 15); + REQUIRE(arguments.size() == 16); CHECK(arguments[0].key() == "long"); CHECK(arguments[0].value() == "true"); CHECK(arguments[0].as() == true);