From 609c48c2a2181ac83ec4bd24549a6caec55e9da5 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Wed, 21 Oct 2020 16:56:44 -0400 Subject: [PATCH] Another tweak. --- tests/exhaustive32_midpoint.cpp | 26 +++++++++++++++++++++++++- tests/random_string.cpp | 26 +++++++++++++++++++++++++- tests/string_test.cpp | 27 +++++++++++++++++++++++++-- 3 files changed, 75 insertions(+), 4 deletions(-) diff --git a/tests/exhaustive32_midpoint.cpp b/tests/exhaustive32_midpoint.cpp index 42afff3..377d456 100644 --- a/tests/exhaustive32_midpoint.cpp +++ b/tests/exhaustive32_midpoint.cpp @@ -4,6 +4,25 @@ #include #include +#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) +// Anything at all that is related to cygwin, msys and so forth will +// always use this fallback because we cannot rely on it behaving as normal +// gcc. +#include +#include +// workaround for CYGWIN +double cygwin_strtod_l(const char* start, char** end) { + double d; + std::stringstream ss; + ss.imbue(std::locale::classic()); + ss << start; + ss >> d; + size_t nread = ss.tellg(); + *end = const_cast(start) + nread; + return d; +} +#endif + template char *to_string(T d, char *buffer) { auto written = std::snprintf(buffer, 64, "%.*e", std::numeric_limits::max_digits10 - 1, d); @@ -12,7 +31,9 @@ template char *to_string(T d, char *buffer) { void strtod_from_string(const char * st, float& d) { char *pr = (char *)st; -#ifdef _WIN32 +#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) + d = cygwin_strtod_l(st, &pr, c_locale); +#elif defined(_WIN32) static _locale_t c_locale = _create_locale(LC_ALL, "C"); d = _strtof_l(st, &pr, c_locale); #else @@ -73,6 +94,9 @@ void allvalues() { } int main() { +#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) + std::cout << "Warning: msys/cygwin detected. This particular test is likely to generate false failures due to our reliance on the underlying runtime library." << std::endl; +#endif allvalues(); std::cout << std::endl; std::cout << "all ok" << std::endl; diff --git a/tests/random_string.cpp b/tests/random_string.cpp index b40eb07..88a8673 100644 --- a/tests/random_string.cpp +++ b/tests/random_string.cpp @@ -2,6 +2,25 @@ #include #include +#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) +// Anything at all that is related to cygwin, msys and so forth will +// always use this fallback because we cannot rely on it behaving as normal +// gcc. +#include +#include +// workaround for CYGWIN +double cygwin_strtod_l(const char* start, char** end) { + double d; + std::stringstream ss; + ss.imbue(std::locale::classic()); + ss << start; + ss >> d; + size_t nread = ss.tellg(); + *end = const_cast(start) + nread; + return d; +} +#endif + class RandomEngine { public: RandomEngine() = delete; @@ -103,7 +122,9 @@ std::pair strtod_from_string(char *st) { std::pair strtof_from_string(char *st) { float d; char *pr; -#ifdef _WIN32 +#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) + d = cygwin_strtod_l(st, &pr, c_locale); +#elif defined(_WIN32) static _locale_t c_locale = _create_locale(LC_ALL, "C"); d = _strtof_l(st, &pr, c_locale); #else @@ -178,6 +199,9 @@ bool tester(int seed, size_t volume) { } int main() { +#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) + std::cout << "Warning: msys/cygwin detected. This particular test is likely to generate false failures due to our reliance on the underlying runtime library." << std::endl; +#endif if (tester(1234344, 100000000)) { std::cout << "All tests ok." << std::endl; return EXIT_SUCCESS; diff --git a/tests/string_test.cpp b/tests/string_test.cpp index a7f9c54..3686def 100644 --- a/tests/string_test.cpp +++ b/tests/string_test.cpp @@ -2,6 +2,25 @@ #include +#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) +// Anything at all that is related to cygwin, msys and so forth will +// always use this fallback because we cannot rely on it behaving as normal +// gcc. +#include +#include +// workaround for CYGWIN +double cygwin_strtod_l(const char* start, char** end) { + double d; + std::stringstream ss; + ss.imbue(std::locale::classic()); + ss << start; + ss >> d; + size_t nread = ss.tellg(); + *end = const_cast(start) + nread; + return d; +} +#endif + inline void Assert(bool Assertion) { if (!Assertion) throw std::runtime_error("bug"); @@ -66,7 +85,9 @@ void strtod_from_string(const std::string &st, double& d) { template <> void strtod_from_string(const std::string &st, float& d) { char *pr = (char *)st.data(); -#ifdef _WIN32 +#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) + d = cygwin_strtod_l(st, &pr, c_locale); +#elif defined(_WIN32) static _locale_t c_locale = _create_locale(LC_ALL, "C"); d = _strtof_l(st.data(), &pr, c_locale); #else @@ -215,7 +236,9 @@ bool partow_test() { int main() { - +#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) + std::cout << "Warning: msys/cygwin detected. This particular test is likely to generate false failures due to our reliance on the underlying runtime library." << std::endl; +#endif std::cout << "32 bits checks" << std::endl; Assert(partow_test()); Assert(test());