From db80a5f4bf4ecbbfe97e83ac6f816d99e9e0f35e Mon Sep 17 00:00:00 2001 From: Glen Fraser Date: Tue, 14 Mar 2017 11:19:54 +0100 Subject: [PATCH] Handle negative numbers in parse_num - fix issue #334, where negative numbers loaded from JSON were being parsed as 0. - add unit tests to cover these cases. --- include/chaiscript/chaiscript_defines.hpp | 33 ++++++++++++++--------- unittests/json_3.chai | 1 + unittests/json_4.chai | 1 + unittests/json_9.chai | 2 +- 4 files changed, 24 insertions(+), 13 deletions(-) diff --git a/include/chaiscript/chaiscript_defines.hpp b/include/chaiscript/chaiscript_defines.hpp index cc349a0b..faab56c2 100644 --- a/include/chaiscript/chaiscript_defines.hpp +++ b/include/chaiscript/chaiscript_defines.hpp @@ -145,14 +145,18 @@ namespace chaiscript { auto parse_num(const char *t_str) -> typename std::enable_if::value, T>::type { T t = 0; + bool is_negative = false; for (char c = *t_str; (c = *t_str) != 0; ++t_str) { - if (c < '0' || c > '9') { - return t; + if (c == '-') { + is_negative = true; + } else if (c < '0' || c > '9') { + return is_negative ? -t : t; + } else { + t *= 10; + t += c - '0'; } - t *= 10; - t += c - '0'; } - return t; + return is_negative ? -t : t; } @@ -164,12 +168,13 @@ namespace chaiscript { T decimal_place = 0; bool exponent = false; bool neg_exponent = false; + bool is_negative = false; - const auto final_value = [](const T val, const T baseval, const bool hasexp, const bool negexp) -> T { + const auto final_value = [](const T val, const bool neg, const T baseval, const bool hasexp, const bool negexp) -> T { if (!hasexp) { - return val; + return neg ? -val : val; } else { - return baseval * std::pow(T(10), val*T(negexp?-1:1)); + return (T(neg?-1:1)) * baseval * std::pow(T(10), val*T(negexp?-1:1)); } }; @@ -182,12 +187,16 @@ namespace chaiscript { decimal_place = 0; base = t; t = 0; - } else if (c == '-' && exponent) { - neg_exponent = true; + } else if (c == '-') { + if (exponent) { + neg_exponent = true; + } else { + is_negative = true; + } } else if (c == '+' && exponent) { neg_exponent = false; } else if (c < '0' || c > '9') { - return final_value(t, base, exponent, neg_exponent); + return final_value(t, is_negative, base, exponent, neg_exponent); } else if (decimal_place < T(10)) { t *= T(10); t += T(c - '0'); @@ -197,7 +206,7 @@ namespace chaiscript { } } - return final_value(t, base, exponent, neg_exponent); + return final_value(t, is_negative, base, exponent, neg_exponent); } template diff --git a/unittests/json_3.chai b/unittests/json_3.chai index d3f222e4..11ce7dcb 100644 --- a/unittests/json_3.chai +++ b/unittests/json_3.chai @@ -1 +1,2 @@ assert_equal(from_json("100"), 100) +assert_equal(from_json("-100"), -100) diff --git a/unittests/json_4.chai b/unittests/json_4.chai index 22d388c7..34ecfa9d 100644 --- a/unittests/json_4.chai +++ b/unittests/json_4.chai @@ -1 +1,2 @@ assert_equal(from_json("1.234"), 1.234) +assert_equal(from_json("-1.234"), -1.234) diff --git a/unittests/json_9.chai b/unittests/json_9.chai index 15127387..d8c64239 100644 --- a/unittests/json_9.chai +++ b/unittests/json_9.chai @@ -1,2 +1,2 @@ -assert_equal(from_json("[1,2,3]"), [1,2,3]) +assert_equal(from_json("[1,-2,3]"), [1,-2,3])