diff --git a/include/cxxopts.hpp b/include/cxxopts.hpp index e0509e8..17bb590 100644 --- a/include/cxxopts.hpp +++ b/include/cxxopts.hpp @@ -431,7 +431,7 @@ namespace cxxopts namespace { std::basic_regex integer_pattern - ("(-)?(0x)?([1-9a-zA-Z][0-9a-zA-Z]*)|(0)"); + ("(-)?(0x)?([1-9a-zA-Z][0-9a-zA-Z]*)|((0x)?0)"); } namespace detail @@ -533,14 +533,18 @@ namespace cxxopts { digit = *iter - '0'; } - else if (*iter >= 'a' && *iter <= 'f') + else if (base == 16 && *iter >= 'a' && *iter <= 'f') { digit = *iter - 'a' + 10; } - else if (*iter >= 'A' && *iter <= 'F') + else if (base == 16 && *iter >= 'A' && *iter <= 'F') { digit = *iter - 'A' + 10; } + else + { + throw argument_incorrect_type(text); + } if (umax - digit < result * base) { diff --git a/test/options.cpp b/test/options.cpp index 1446929..d428f9a 100644 --- a/test/options.cpp +++ b/test/options.cpp @@ -246,7 +246,7 @@ TEST_CASE("Integers", "[options]") options.add_options() ("positional", "Integers", cxxopts::value>()); - Argv av({"ints", "--", "5", "6", "-6", "0", "0xab", "0xAf"}); + Argv av({"ints", "--", "5", "6", "-6", "0", "0xab", "0xAf", "0x0"}); char** argv = av.argv(); auto argc = av.argc(); @@ -254,7 +254,7 @@ TEST_CASE("Integers", "[options]") options.parse_positional("positional"); options.parse(argc, argv); - REQUIRE(options.count("positional") == 6); + REQUIRE(options.count("positional") == 7); auto& positional = options["positional"].as>(); CHECK(positional[0] == 5); @@ -263,6 +263,7 @@ TEST_CASE("Integers", "[options]") CHECK(positional[3] == 0); CHECK(positional[4] == 0xab); CHECK(positional[5] == 0xaf); + CHECK(positional[6] == 0x0); } TEST_CASE("Unsigned integers", "[options]") @@ -364,3 +365,16 @@ TEST_CASE("Floats", "[options]") CHECK(positional[3] == -1.5e6); } +TEST_CASE("Invalid integers", "[integer]") { + cxxopts::Options options("invalid_integers", "rejects invalid integers"); + options.add_options() + ("positional", "Integers", cxxopts::value>()); + + Argv av({"ints", "--", "Ae"}); + + char **argv = av.argv(); + auto argc = av.argc(); + + options.parse_positional("positional"); + CHECK_THROWS_AS(options.parse(argc, argv), cxxopts::argument_incorrect_type); +}