From f871b625ee94fe721c60e3200785310d653393f8 Mon Sep 17 00:00:00 2001 From: Philip Top Date: Tue, 11 Mar 2025 07:08:38 -0700 Subject: [PATCH] Float parsing negative (#1140) Fixes #1139 Fix a bug relating to parsing negative floating point values with no zero before decimal point in a context where an option could be possible. --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- include/CLI/impl/App_inl.hpp | 4 +++- tests/OptionTypeTest.cpp | 25 +++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/include/CLI/impl/App_inl.hpp b/include/CLI/impl/App_inl.hpp index 69eccf72..10e0a568 100644 --- a/include/CLI/impl/App_inl.hpp +++ b/include/CLI/impl/App_inl.hpp @@ -1090,7 +1090,9 @@ CLI11_NODISCARD CLI11_INLINE detail::Classifier App::_recognize(const std::strin if(detail::split_long(current, dummy1, dummy2)) return detail::Classifier::LONG; if(detail::split_short(current, dummy1, dummy2)) { - if(dummy1[0] >= '0' && dummy1[0] <= '9') { + if((dummy1[0] >= '0' && dummy1[0] <= '9') || + (dummy1[0] == '.' && !dummy2.empty() && (dummy2[0] >= '0' && dummy2[0] <= '9'))) { + // it looks like a number but check if it could be an option if(get_option_no_throw(std::string{'-', dummy1[0]}) == nullptr) { return detail::Classifier::NONE; } diff --git a/tests/OptionTypeTest.cpp b/tests/OptionTypeTest.cpp index c1193bdf..d89a1357 100644 --- a/tests/OptionTypeTest.cpp +++ b/tests/OptionTypeTest.cpp @@ -232,6 +232,9 @@ static const std::map testValuesDouble{ {"-3.14159 ", -3.14159}, {"+1.0", 1.0}, {"-0.01", -0.01}, + {"-.01", -0.01}, + {"-.3251", -0.3251}, + {"+.3251", 0.3251}, {"5e22", 5e22}, {" 5e22", 5e22}, {" 5e22 ", 5e22}, @@ -822,6 +825,28 @@ TEST_CASE_METHOD(TApp, "floatPair", "[optiontype]") { CHECK(2.7f == Approx(custom_opt.second)); } +// now with tuple support this is possible +TEST_CASE_METHOD(TApp, "doubleVector", "[optiontype]") { + + std::vector custom_opt; + + app.add_option("--fp", custom_opt); + + args = {"--fp", "12.7", "1.5"}; + run(); + CHECK(12.7 == Approx(custom_opt[0])); + CHECK(1.5 == Approx(custom_opt[1])); + args = {"--fp", "12.7", "-.5"}; + run(); + CHECK(12.7 == Approx(custom_opt[0])); + CHECK(-0.5 == Approx(custom_opt[1])); + + args = {"--fp", "-.7", "+.5"}; + run(); + CHECK(-0.7 == Approx(custom_opt[0])); + CHECK(0.5 == Approx(custom_opt[1])); +} + // now with independent type sizes and expected this is possible TEST_CASE_METHOD(TApp, "vectorPair", "[optiontype]") {