diff options
author | Arne Juul <arnej@yahoo-inc.com> | 2019-06-12 14:41:07 +0000 |
---|---|---|
committer | Arne Juul <arnej@yahoo-inc.com> | 2019-06-12 14:41:07 +0000 |
commit | e38433e8cf5104bc3c3f4df1b9c5e5ec64b95cce (patch) | |
tree | 914e1e12f13b8702c2ddda1ffb2544e2573eabe1 /vespalib | |
parent | 67e0571b901e63dde4514a24d881d169abe463b1 (diff) |
make allow-underflow common code
Diffstat (limited to 'vespalib')
-rw-r--r-- | vespalib/src/vespa/vespalib/data/slime/json_format.cpp | 4 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/locale/c.cpp | 18 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/locale/c.h | 4 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/stllike/asciistream.cpp | 26 |
4 files changed, 28 insertions, 24 deletions
diff --git a/vespalib/src/vespa/vespalib/data/slime/json_format.cpp b/vespalib/src/vespa/vespalib/data/slime/json_format.cpp index e97786888e8..d2f953b38c8 100644 --- a/vespalib/src/vespa/vespalib/data/slime/json_format.cpp +++ b/vespalib/src/vespa/vespalib/data/slime/json_format.cpp @@ -434,7 +434,7 @@ JsonDecoder::decodeNumber(Inserter &inserter) default: char *endp; int errorCode = insertNumber(inserter, isLong, value, &endp); - if (endp == value.c_str()) { + if ((endp == value.c_str()) || (errorCode != 0)) { std::stringstream ss; ss << "error inserting number " << value << ". error code: " << errorCode << ". endp - value: " << (endp - value.c_str()); in.fail(ss.str()); @@ -454,7 +454,7 @@ insertNumber(Inserter &inserter, bool isLong, const vespalib::string & value, ch errorCode = errno; inserter.insertLong(val); } else { - double val = locale::c::strtod(value.c_str(), endp); + double val = locale::c::strtod_au(value.c_str(), endp); errorCode = errno; inserter.insertDouble(val); } diff --git a/vespalib/src/vespa/vespalib/locale/c.cpp b/vespalib/src/vespa/vespalib/locale/c.cpp index af228ce55c3..74e7485f158 100644 --- a/vespalib/src/vespa/vespalib/locale/c.cpp +++ b/vespalib/src/vespa/vespalib/locale/c.cpp @@ -3,6 +3,7 @@ #include "c.h" #include "locale.h" #include <cstdlib> +#include <errno.h> namespace vespalib::locale::c { @@ -20,5 +21,22 @@ float strtof(const char *startp, char **endp) { return strtof_l(startp, endp, _G_C_Locale.get()); } +double strtod_au(const char *startp, char **endp) { + int was = errno; + double v = strtod_l(startp, endp, _G_C_Locale.get()); + if (errno == ERANGE) { + if ((-1.0 < v) && (v < 1.0)) errno = was; + } + return v; } +float strtof_au(const char *startp, char **endp) { + int was = errno; + float v = strtof_l(startp, endp, _G_C_Locale.get()); + if (errno == ERANGE) { + if ((-1.0 < v) && (v < 1.0)) errno = was; + } + return v; +} + +} diff --git a/vespalib/src/vespa/vespalib/locale/c.h b/vespalib/src/vespa/vespalib/locale/c.h index ff7d0c18639..08cf6185e7f 100644 --- a/vespalib/src/vespa/vespalib/locale/c.h +++ b/vespalib/src/vespa/vespalib/locale/c.h @@ -7,6 +7,10 @@ namespace vespalib::locale::c { double strtod(const char *nptr, char **endptr); float strtof(const char *nptr, char **endptr); +// allow underflow variants +double strtod_au(const char *nptr, char **endptr); +float strtof_au(const char *nptr, char **endptr); + inline double atof(const char *nptr) { return strtod(nptr, nullptr); } } diff --git a/vespalib/src/vespa/vespalib/stllike/asciistream.cpp b/vespalib/src/vespa/vespalib/stllike/asciistream.cpp index 499171dc6e7..7d585cf1cf6 100644 --- a/vespalib/src/vespa/vespalib/stllike/asciistream.cpp +++ b/vespalib/src/vespa/vespalib/stllike/asciistream.cpp @@ -172,17 +172,8 @@ int getValue(double & val, const char *buf) { char *ebuf; errno = 0; - val = locale::c::strtod(buf, &ebuf); - bool failed = (buf == ebuf); - if (errno != 0) { - if (errno == ERANGE) { - if (val == HUGE_VAL) failed = true; - if (val == -HUGE_VAL) failed = true; - } else { - failed = true; - } - } - if (failed) { + val = locale::c::strtod_au(buf, &ebuf); + if ((errno != 0) || (buf == ebuf)) { throwInputError(errno, "double", buf); } return ebuf - buf; @@ -192,17 +183,8 @@ int getValue(float & val, const char *buf) { char *ebuf; errno = 0; - val = locale::c::strtof(buf, &ebuf); - bool failed = (buf == ebuf); - if (errno != 0) { - if (errno == ERANGE) { - if (val == HUGE_VALF) failed = true; - if (val == -HUGE_VALF) failed = true; - } else { - failed = true; - } - } - if (failed) { + val = locale::c::strtof_au(buf, &ebuf); + if ((errno != 0) || (buf == ebuf)) { throwInputError(errno, "float", buf); } return ebuf - buf; |