From 8727767816ce8fa59d4078e19aa53b51fd2cd942 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Tue, 22 Dec 2020 08:44:47 -0500 Subject: [PATCH 1/9] Adding more CI tests. --- .github/workflows/mingw-ci.yml | 49 +++++++++++++++++++++++ .github/workflows/mingw64-ci.yml | 49 +++++++++++++++++++++++ .github/workflows/vs16-clang-ninja-ci.yml | 25 ++++++++++++ 3 files changed, 123 insertions(+) create mode 100644 .github/workflows/mingw-ci.yml create mode 100644 .github/workflows/mingw64-ci.yml create mode 100644 .github/workflows/vs16-clang-ninja-ci.yml diff --git a/.github/workflows/mingw-ci.yml b/.github/workflows/mingw-ci.yml new file mode 100644 index 00000000..288d13ca --- /dev/null +++ b/.github/workflows/mingw-ci.yml @@ -0,0 +1,49 @@ +name: MinGW32-CI + +on: [push, pull_request] + +# Important: scoop will either install 32-bit GCC or 64-bit GCC, not both. + +# It is important to build static libraries because cmake is not smart enough under Windows/mingw to take care of the path. So +# with a dynamic library, you could get failures due to the fact that the EXE can't find its DLL. + +jobs: + ci: + name: windows-gcc + runs-on: windows-2016 + + env: + CMAKE_GENERATOR: Ninja + CC: gcc + CXX: g++ + + steps: # To reproduce what is below, start a powershell with administrative rights, using scoop *is* a good idea + - uses: actions/checkout@v2 + + - uses: actions/cache@v2 # we cache the scoop setup with 32-bit GCC + id: cache + with: + path: | + C:\ProgramData\scoop + key: scoop32 # static key: should be good forever + - name: Setup Windows # This should almost never run if the cache works. + if: steps.cache.outputs.cache-hit != 'true' + shell: powershell + run: | + Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://get.scoop.sh') + scoop install sudo --global + sudo scoop install git --global + sudo scoop install ninja --global + sudo scoop install cmake --global + sudo scoop install gcc --arch 32bit --global + $env:path + Write-Host 'Everything has been installed, you are good!' + - name: Build and Test 32-bit x86 + shell: powershell + run: | + $ENV:PATH="C:\ProgramData\scoop\shims;C:\ProgramData\scoop\apps\gcc\current\bin;C:\ProgramData\scoop\apps\ninja\current;$ENV:PATH" + mkdir build32 + cd build32 + cmake -DFASTFLOAT_TEST=ON .. + cmake --build . --verbose + ctest -j4 --output-on-failure \ No newline at end of file diff --git a/.github/workflows/mingw64-ci.yml b/.github/workflows/mingw64-ci.yml new file mode 100644 index 00000000..5795bee6 --- /dev/null +++ b/.github/workflows/mingw64-ci.yml @@ -0,0 +1,49 @@ +name: MinGW64-CI + +on: [push, pull_request] + +# Important: scoop will either install 32-bit GCC or 64-bit GCC, not both. + +# It is important to build static libraries because cmake is not smart enough under Windows/mingw to take care of the path. So +# with a dynamic library, you could get failures due to the fact that the EXE can't find its DLL. + +jobs: + ci: + name: windows-gcc + runs-on: windows-2016 + + env: + CMAKE_GENERATOR: Ninja + CC: gcc + CXX: g++ + + steps: # To reproduce what is below, start a powershell with administrative rights, using scoop *is* a good idea + - uses: actions/checkout@v2 + + - uses: actions/cache@v2 # we cache the scoop setup with 64-bit GCC + id: cache + with: + path: | + C:\ProgramData\scoop + key: scoop64 # static key: should be good forever + - name: Setup Windows # This should almost never run if the cache works. + if: steps.cache.outputs.cache-hit != 'true' + shell: powershell + run: | + Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://get.scoop.sh') + scoop install sudo --global + sudo scoop install git --global + sudo scoop install ninja --global + sudo scoop install cmake --global + sudo scoop install gcc --arch 64bit --global + $env:path + Write-Host 'Everything has been installed, you are good!' + - name: Build and Test 64-bit x64 + shell: powershell + run: | + $ENV:PATH="C:\ProgramData\scoop\shims;C:\ProgramData\scoop\apps\gcc\current\bin;C:\ProgramData\scoop\apps\ninja\current;$ENV:PATH" + mkdir build64 + cd build64 + cmake -DFASTFLOAT_TEST=ON .. + cmake --build . --verbose + ctest -j4 --output-on-failure \ No newline at end of file diff --git a/.github/workflows/vs16-clang-ninja-ci.yml b/.github/workflows/vs16-clang-ninja-ci.yml new file mode 100644 index 00000000..e35b3faa --- /dev/null +++ b/.github/workflows/vs16-clang-ninja-ci.yml @@ -0,0 +1,25 @@ +name: VS16-Ninja-CI + +on: [push, pull_request] + +jobs: + ci: + name: windows-vs16 + runs-on: windows-latest + steps: + - uses: actions/checkout@v2 + - name: 'Run CMake with VS16' + uses: lukka/run-cmake@v2 + with: + cmakeListsOrSettingsJson: CMakeListsTxtAdvanced + cmakeListsTxtPath: '${{ github.workspace }}/CMakeLists.txt' + buildDirectory: "${{ github.workspace }}/../../_temp/windows" + cmakeBuildType: Release + buildWithCMake: true + cmakeGenerator: VS16Win64 + cmakeAppendedArgs: -G Ninja -DFASTFLOAT_TEST=ON + buildWithCMakeArgs: --config Release + + - name: 'Run CTest' + run: ctest -C Release --output-on-failure + working-directory: "${{ github.workspace }}/../../_temp/windows" \ No newline at end of file From 0da898d5aa25df27a451d9b3df8b70d56139ce55 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Tue, 22 Dec 2020 08:47:44 -0500 Subject: [PATCH 2/9] Updating cmake requirement. --- .github/workflows/ubuntu18.yml | 2 +- .github/workflows/ubuntu20.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ubuntu18.yml b/.github/workflows/ubuntu18.yml index ab292b66..a029f308 100644 --- a/.github/workflows/ubuntu18.yml +++ b/.github/workflows/ubuntu18.yml @@ -18,7 +18,7 @@ jobs: - name: Setup cmake uses: jwlawson/actions-setup-cmake@v1.4 with: - cmake-version: '3.9.x' + cmake-version: '3.11.x' - name: Install older compilers run: | sudo -E dpkg --add-architecture i386 diff --git a/.github/workflows/ubuntu20.yml b/.github/workflows/ubuntu20.yml index 6b8c6342..f026366b 100644 --- a/.github/workflows/ubuntu20.yml +++ b/.github/workflows/ubuntu20.yml @@ -17,7 +17,7 @@ jobs: - name: Setup cmake uses: jwlawson/actions-setup-cmake@v1.4 with: - cmake-version: '3.9.x' + cmake-version: '3.11.x' - name: install older compilers run: | sudo -E dpkg --add-architecture i386 From 87bba4436f64bbc1e3dda9ab85c907a5a51157e0 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Tue, 22 Dec 2020 09:43:20 -0500 Subject: [PATCH 3/9] Targeting the test. --- .github/workflows/mingw-ci.yml | 2 +- .github/workflows/mingw64-ci.yml | 2 +- .github/workflows/vs16-clang-ninja-ci.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/mingw-ci.yml b/.github/workflows/mingw-ci.yml index 288d13ca..f886c93e 100644 --- a/.github/workflows/mingw-ci.yml +++ b/.github/workflows/mingw-ci.yml @@ -46,4 +46,4 @@ jobs: cd build32 cmake -DFASTFLOAT_TEST=ON .. cmake --build . --verbose - ctest -j4 --output-on-failure \ No newline at end of file + ctest -j4 --output-on-failure -R basictest \ No newline at end of file diff --git a/.github/workflows/mingw64-ci.yml b/.github/workflows/mingw64-ci.yml index 5795bee6..f476f2b7 100644 --- a/.github/workflows/mingw64-ci.yml +++ b/.github/workflows/mingw64-ci.yml @@ -46,4 +46,4 @@ jobs: cd build64 cmake -DFASTFLOAT_TEST=ON .. cmake --build . --verbose - ctest -j4 --output-on-failure \ No newline at end of file + ctest -j4 --output-on-failure -R basictest \ No newline at end of file diff --git a/.github/workflows/vs16-clang-ninja-ci.yml b/.github/workflows/vs16-clang-ninja-ci.yml index e35b3faa..b557ddb1 100644 --- a/.github/workflows/vs16-clang-ninja-ci.yml +++ b/.github/workflows/vs16-clang-ninja-ci.yml @@ -21,5 +21,5 @@ jobs: buildWithCMakeArgs: --config Release - name: 'Run CTest' - run: ctest -C Release --output-on-failure + run: ctest -C Release --output-on-failure -R basictest working-directory: "${{ github.workspace }}/../../_temp/windows" \ No newline at end of file From cc5cb1f94fbd0de1f247fee58b7eeeeac9a85cbd Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Tue, 22 Dec 2020 09:53:23 -0500 Subject: [PATCH 4/9] Adding msys-clang tests. --- .github/workflows/msys2-clang.yml | 45 +++++++++++++++++++++++ .github/workflows/vs16-clang-ninja-ci.yml | 2 +- 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/msys2-clang.yml diff --git a/.github/workflows/msys2-clang.yml b/.github/workflows/msys2-clang.yml new file mode 100644 index 00000000..a9aee0c9 --- /dev/null +++ b/.github/workflows/msys2-clang.yml @@ -0,0 +1,45 @@ +name: MSYS2-CLANG-CI + +on: [push, pull_request] + +jobs: + windows-mingw: + name: ${{ matrix.msystem }} + runs-on: windows-latest + defaults: + run: + shell: msys2 {0} + strategy: + fail-fast: false + matrix: + include: + - msystem: "MINGW64" + install: mingw-w64-x86_64-cmake mingw-w64-x86_64-ninja mingw-w64-x86_64-clang + type: Release + - msystem: "MINGW32" + install: mingw-w64-i686-cmake mingw-w64-i686-ninja mingw-w64-i686-clang + type: Release + - msystem: "MINGW64" + install: mingw-w64-x86_64-cmake mingw-w64-x86_64-ninja mingw-w64-x86_64-gcc + type: Debug + - msystem: "MINGW32" + install: mingw-w64-i686-cmake mingw-w64-i686-ninja mingw-w64-i686-gcc + type: Debug + env: + CMAKE_GENERATOR: Ninja + + steps: + - uses: actions/checkout@v2 + - uses: msys2/setup-msys2@v2 + with: + update: true + msystem: ${{ matrix.msystem }} + install: ${{ matrix.install }} + - name: Prepare build dir + run: mkdir build + - name: Configure + run: cd build && cmake -DCMAKE_BUILD_TYPE=${{ matrix.type }} -DFASTFLOAT_TEST=ON .. + - name: Build + run: cmake --build build + - name: Run basic tests + run: cd build && ctest --output-on-failure -R basictest diff --git a/.github/workflows/vs16-clang-ninja-ci.yml b/.github/workflows/vs16-clang-ninja-ci.yml index b557ddb1..04e8e37c 100644 --- a/.github/workflows/vs16-clang-ninja-ci.yml +++ b/.github/workflows/vs16-clang-ninja-ci.yml @@ -21,5 +21,5 @@ jobs: buildWithCMakeArgs: --config Release - name: 'Run CTest' - run: ctest -C Release --output-on-failure -R basictest + run: ctest -C Release --verbose --output-on-failure -R basictest working-directory: "${{ github.workspace }}/../../_temp/windows" \ No newline at end of file From df11f6119696e85475d875ac5fc105e008d6a6f9 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Tue, 22 Dec 2020 10:02:00 -0500 Subject: [PATCH 5/9] Specify the compiler. --- .github/workflows/msys2-clang.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/msys2-clang.yml b/.github/workflows/msys2-clang.yml index a9aee0c9..53701650 100644 --- a/.github/workflows/msys2-clang.yml +++ b/.github/workflows/msys2-clang.yml @@ -38,7 +38,7 @@ jobs: - name: Prepare build dir run: mkdir build - name: Configure - run: cd build && cmake -DCMAKE_BUILD_TYPE=${{ matrix.type }} -DFASTFLOAT_TEST=ON .. + run: cd build && cmake -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=${{ matrix.type }} -DFASTFLOAT_TEST=ON .. - name: Build run: cmake --build build - name: Run basic tests From b0e417cdde6f1dc920eac7a07015c12f33cf0de5 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Tue, 22 Dec 2020 15:10:23 -0500 Subject: [PATCH 6/9] Simplifying. --- .github/workflows/vs16-clang-ninja-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/vs16-clang-ninja-ci.yml b/.github/workflows/vs16-clang-ninja-ci.yml index 04e8e37c..e6aceb93 100644 --- a/.github/workflows/vs16-clang-ninja-ci.yml +++ b/.github/workflows/vs16-clang-ninja-ci.yml @@ -18,8 +18,8 @@ jobs: buildWithCMake: true cmakeGenerator: VS16Win64 cmakeAppendedArgs: -G Ninja -DFASTFLOAT_TEST=ON - buildWithCMakeArgs: --config Release + buildWithCMakeArgs: - name: 'Run CTest' - run: ctest -C Release --verbose --output-on-failure -R basictest + run: ctest --verbose --output-on-failure -R basictest working-directory: "${{ github.workspace }}/../../_temp/windows" \ No newline at end of file From a1a734746445fe669962a85fc413a311183fb025 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Tue, 22 Dec 2020 15:55:48 -0500 Subject: [PATCH 7/9] Minor tweaks to better handle cygwin/clang. --- include/fast_float/float_common.h | 14 +++---- tests/exhaustive32.cpp | 10 ++--- tests/exhaustive32_64.cpp | 12 +++--- tests/exhaustive32_midpoint.cpp | 62 +++++++++++++++++++++---------- tests/long_exhaustive32.cpp | 12 +++--- tests/long_random64.cpp | 12 +++--- tests/long_test.cpp | 3 +- tests/powersoffive_hardround.cpp | 22 +++++++++-- tests/random64.cpp | 12 +++--- tests/random_string.cpp | 30 ++++++++++++--- tests/short_random_string.cpp | 28 +++++++++++--- tests/string_test.cpp | 31 +++++++++++++--- 12 files changed, 171 insertions(+), 77 deletions(-) diff --git a/include/fast_float/float_common.h b/include/fast_float/float_common.h index 90a111a5..69001006 100644 --- a/include/fast_float/float_common.h +++ b/include/fast_float/float_common.h @@ -5,18 +5,18 @@ #include #include -#if (defined(__i386) || defined(__i386__) || defined(_M_IX86) \ - || defined(__arm__) \ - || defined(__MINGW32__)) -#define FASTFLOAT_32BIT -#elif (defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) \ +#if (defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) \ || defined(__amd64) || defined(__aarch64__) || defined(_M_ARM64) \ || defined(__MINGW64__) \ || defined(__s390x__) \ || (defined(__ppc64__) || defined(__PPC64__) || defined(__ppc64le__) || defined(__PPC64LE__))) #define FASTFLOAT_64BIT +#elif (defined(__i386) || defined(__i386__) || defined(_M_IX86) \ + || defined(__arm__) \ + || defined(__MINGW32__)) +#define FASTFLOAT_32BIT #else -#error Unknown platform +#error Unknown platform (not 32-bit, not 64-bit?) #endif #if ((defined(_WIN32) || defined(_WIN64)) && !defined(__clang__)) @@ -164,7 +164,7 @@ fastfloat_really_inline value128 full_multiplication(uint64_t a, // ARM64 has native support for 64-bit multiplications, no need to emulate answer.high = __umulh(a, b); answer.low = a * b; -#elif defined(FASTFLOAT_32BIT) || (defined(_WIN64)) +#elif defined(FASTFLOAT_32BIT) || (defined(_WIN64) && !defined(__clang__)) answer.low = _umul128(a, b, &answer.high); // _umul128 not available on ARM64 #elif defined(FASTFLOAT_64BIT) __uint128_t r = ((__uint128_t)a) * b; diff --git a/tests/exhaustive32.cpp b/tests/exhaustive32.cpp index bcbce791..879d1e22 100644 --- a/tests/exhaustive32.cpp +++ b/tests/exhaustive32.cpp @@ -30,15 +30,15 @@ void allvalues() { std::cerr << "parsing error ? " << buffer << std::endl; abort(); } - if(copysign(1,result_value) != copysign(1,v)) { - std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << v - << std::endl; - abort(); - } else if (std::isnan(v)) { + if (std::isnan(v)) { if (!std::isnan(result_value)) { std::cerr << "not nan" << buffer << std::endl; abort(); } + } else if(copysign(1,result_value) != copysign(1,v)) { + std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << v + << std::endl; + abort(); } else if (result_value != v) { std::cerr << "no match ? " << buffer << std::endl; std::cout << "started with " << std::hexfloat << v << std::endl; diff --git a/tests/exhaustive32_64.cpp b/tests/exhaustive32_64.cpp index 46a35b03..50aebd7e 100644 --- a/tests/exhaustive32_64.cpp +++ b/tests/exhaustive32_64.cpp @@ -20,16 +20,16 @@ bool basic_test_64bit(std::string vals, double val) { std::cerr << " I could not parse " << vals << std::endl; return false; } - if(copysign(1,result_value) != copysign(1,val)) { - std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << val - << std::endl; - return false; - } else if (std::isnan(val)) { + if (std::isnan(val)) { if (!std::isnan(result_value)) { std::cerr << vals << std::endl; std::cerr << "not nan" << result_value << std::endl; return false; - } + } + } else if(copysign(1,result_value) != copysign(1,val)) { + std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << val + << std::endl; + return false; } else if (result_value != val) { std::cerr << vals << std::endl; std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << val diff --git a/tests/exhaustive32_midpoint.cpp b/tests/exhaustive32_midpoint.cpp index 828655f8..cfcb5415 100644 --- a/tests/exhaustive32_midpoint.cpp +++ b/tests/exhaustive32_midpoint.cpp @@ -17,7 +17,21 @@ double cygwin_strtod_l(const char* start, char** end) { ss.imbue(std::locale::classic()); ss << start; ss >> d; - size_t nread = ss.tellg(); + if(ss.fail()) { *end = nullptr; } + if(ss.eof()) { ss.clear(); } + auto nread = ss.tellg(); + *end = const_cast(start) + nread; + return d; +} +float cygwin_strtof_l(const char* start, char** end) { + float d; + std::stringstream ss; + ss.imbue(std::locale::classic()); + ss << start; + ss >> d; + if(ss.fail()) { *end = nullptr; } + if(ss.eof()) { ss.clear(); } + auto nread = ss.tellg(); *end = const_cast(start) + nread; return d; } @@ -29,10 +43,10 @@ template char *to_string(T d, char *buffer) { return buffer + written; } -void strtod_from_string(const char * st, float& d) { +void strtof_from_string(const char * st, float& d) { char *pr = (char *)st; #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun) - d = cygwin_strtod_l(st, &pr); + d = cygwin_strtof_l(st, &pr); #elif defined(_WIN32) static _locale_t c_locale = _create_locale(LC_ALL, "C"); d = _strtof_l(st, &pr, c_locale); @@ -45,7 +59,7 @@ void strtod_from_string(const char * st, float& d) { } } -void allvalues() { +bool allvalues() { char buffer[64]; for (uint64_t w = 0; w <= 0xFFFFFFFF; w++) { float v; @@ -68,32 +82,32 @@ void allvalues() { const char *string_end = to_string(midv, buffer); float str_answer; - strtod_from_string(buffer, str_answer); + strtof_from_string(buffer, str_answer); float result_value; auto result = fast_float::from_chars(buffer, string_end, result_value); if (result.ec != std::errc()) { std::cerr << "parsing error ? " << buffer << std::endl; - abort(); + return false; } - if(copysign(1,result_value) != copysign(1,v)) { - std::cerr << buffer << std::endl; - std::cerr << "v " << std::hexfloat << v << std::endl; - std::cerr << "v2 " << std::hexfloat << v2 << std::endl; - std::cerr << "midv " << std::hexfloat << midv << std::endl; - std::cerr << "expected_midv " << std::hexfloat << expected_midv << std::endl; - std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << v - << std::endl; - abort(); - } else if (std::isnan(v)) { + if (std::isnan(v)) { if (!std::isnan(result_value)) { std::cerr << "not nan" << buffer << std::endl; std::cerr << "v " << std::hexfloat << v << std::endl; std::cerr << "v2 " << std::hexfloat << v2 << std::endl; std::cerr << "midv " << std::hexfloat << midv << std::endl; std::cerr << "expected_midv " << std::hexfloat << expected_midv << std::endl; - abort(); + return false; } + } else if(copysign(1,result_value) != copysign(1,v)) { + std::cerr << buffer << std::endl; + std::cerr << "v " << std::hexfloat << v << std::endl; + std::cerr << "v2 " << std::hexfloat << v2 << std::endl; + std::cerr << "midv " << std::hexfloat << midv << std::endl; + std::cerr << "expected_midv " << std::hexfloat << expected_midv << std::endl; + std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << v + << std::endl; + return false; } else if (result_value != str_answer) { std::cerr << "no match ? " << buffer << std::endl; std::cerr << "v " << std::hexfloat << v << std::endl; @@ -104,18 +118,26 @@ void allvalues() { std::cout << "round down to " << std::hexfloat << str_answer << std::endl; std::cout << "got back " << std::hexfloat << result_value << std::endl; std::cout << std::dec; - abort(); + return false; } } } std::cout << std::endl; + return true; } +inline void Assert(bool Assertion) { +#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun) + if (!Assertion) { std::cerr << "Omitting hard falure on msys/cygwin/sun systems."; } +#else + if (!Assertion) { throw std::runtime_error("bug"); } +#endif +} int main() { #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun) - std::cout << "Warning: msys/cygwin or solaris detected. This particular test is likely to generate false failures due to our reliance on the underlying runtime library." << std::endl; + std::cout << "Warning: msys/cygwin or solaris detected. This particular test is likely to generate false failures due to our reliance on the underlying runtime library as a gold standard." << std::endl; #endif - allvalues(); + Assert(allvalues()); std::cout << std::endl; std::cout << "all ok" << std::endl; return EXIT_SUCCESS; diff --git a/tests/long_exhaustive32.cpp b/tests/long_exhaustive32.cpp index 19ea3f37..683200ca 100644 --- a/tests/long_exhaustive32.cpp +++ b/tests/long_exhaustive32.cpp @@ -30,16 +30,16 @@ void allvalues() { std::cerr << "parsing error ? " << buffer << std::endl; abort(); } - if(copysign(1,result_value) != copysign(1,v)) { - std::cerr << buffer << std::endl; - std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << v - << std::endl; - abort(); - } else if (std::isnan(v)) { + if (std::isnan(v)) { if (!std::isnan(result_value)) { std::cerr << "not nan" << buffer << std::endl; abort(); } + } else if(copysign(1,result_value) != copysign(1,v)) { + std::cerr << buffer << std::endl; + std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << v + << std::endl; + abort(); } else if (result_value != v) { std::cerr << "no match ? " << buffer << " got " << result_value << " expected " << v << std::endl; std::cout << "started with " << std::hexfloat << v << std::endl; diff --git a/tests/long_random64.cpp b/tests/long_random64.cpp index 38dce21d..e5abe8f8 100644 --- a/tests/long_random64.cpp +++ b/tests/long_random64.cpp @@ -60,12 +60,7 @@ void random_values(size_t N) { abort(); } } - if(copysign(1,result_value) != copysign(1,v)) { - std::cerr << buffer << std::endl; - std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << v - << std::endl; - abort(); - } else if (std::isnan(v)) { + if (std::isnan(v)) { if (!std::isnan(result_value)) { std::cerr << "not nan" << buffer << std::endl; errors++; @@ -73,6 +68,11 @@ void random_values(size_t N) { abort(); } } + } else if(copysign(1,result_value) != copysign(1,v)) { + std::cerr << buffer << std::endl; + std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << v + << std::endl; + abort(); } else if (result_value != v) { std::cerr << "no match ? '" << buffer << "'" << std::endl; std::cout << "started with " << std::hexfloat << v << std::endl; diff --git a/tests/long_test.cpp b/tests/long_test.cpp index 301c606b..1ab370ad 100644 --- a/tests/long_test.cpp +++ b/tests/long_test.cpp @@ -3,8 +3,7 @@ #include inline void Assert(bool Assertion) { - if (!Assertion) - throw std::runtime_error("bug"); + if (!Assertion) { throw std::runtime_error("bug"); } } template diff --git a/tests/powersoffive_hardround.cpp b/tests/powersoffive_hardround.cpp index 9288beb3..6258be5e 100644 --- a/tests/powersoffive_hardround.cpp +++ b/tests/powersoffive_hardround.cpp @@ -19,7 +19,21 @@ double cygwin_strtod_l(const char* start, char** end) { ss.imbue(std::locale::classic()); ss << start; ss >> d; - size_t nread = ss.tellg(); + if(ss.fail()) { *end = nullptr; } + if(ss.eof()) { ss.clear(); } + auto nread = ss.tellg(); + *end = const_cast(start) + nread; + return d; +} +float cygwin_strtof_l(const char* start, char** end) { + float d; + std::stringstream ss; + ss.imbue(std::locale::classic()); + ss << start; + ss >> d; + if(ss.fail()) { *end = nullptr; } + if(ss.eof()) { ss.clear(); } + auto nread = ss.tellg(); *end = const_cast(start) + nread; return d; } @@ -29,7 +43,9 @@ double cygwin_strtod_l(const char* start, char** end) { std::pair strtod_from_string(const char *st) { double d; char *pr; -#ifdef _WIN32 +#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun) + d = cygwin_strtod_l(st, &pr); +#elif defined(_WIN32) static _locale_t c_locale = _create_locale(LC_ALL, "C"); d = _strtod_l(st, &pr, c_locale); #else @@ -47,7 +63,7 @@ std::pair strtof_from_string(char *st) { float d; char *pr; #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun) - d = cygwin_strtod_l(st, &pr); + d = cygwin_strtof_l(st, &pr); #elif defined(_WIN32) static _locale_t c_locale = _create_locale(LC_ALL, "C"); d = _strtof_l(st, &pr, c_locale); diff --git a/tests/random64.cpp b/tests/random64.cpp index 8d5c59df..5abc4f89 100644 --- a/tests/random64.cpp +++ b/tests/random64.cpp @@ -62,12 +62,7 @@ void random_values(size_t N) { abort(); } } - if(copysign(1,result_value) != copysign(1,v)) { - std::cerr << buffer << std::endl; - std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << v - << std::endl; - abort(); - } else if (std::isnan(v)) { + if (std::isnan(v)) { if (!std::isnan(result_value)) { std::cerr << "not nan" << buffer << std::endl; errors++; @@ -75,6 +70,11 @@ void random_values(size_t N) { abort(); } } + } else if(copysign(1,result_value) != copysign(1,v)) { + std::cerr << buffer << std::endl; + std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << v + << std::endl; + abort(); } else if (result_value != v) { std::cerr << "no match ? " << buffer << std::endl; std::cout << "started with " << std::hexfloat << v << std::endl; diff --git a/tests/random_string.cpp b/tests/random_string.cpp index ed9fb6b3..8f367e06 100644 --- a/tests/random_string.cpp +++ b/tests/random_string.cpp @@ -17,7 +17,21 @@ double cygwin_strtod_l(const char* start, char** end) { ss.imbue(std::locale::classic()); ss << start; ss >> d; - size_t nread = ss.tellg(); + if(ss.fail()) { *end = nullptr; } + if(ss.eof()) { ss.clear(); } + auto nread = ss.tellg(); + *end = const_cast(start) + nread; + return d; +} +float cygwin_strtof_l(const char* start, char** end) { + float d; + std::stringstream ss; + ss.imbue(std::locale::classic()); + ss << start; + ss >> d; + if(ss.fail()) { *end = nullptr; } + if(ss.eof()) { ss.clear(); } + auto nread = ss.tellg(); *end = const_cast(start) + nread; return d; } @@ -111,7 +125,9 @@ size_t build_random_string(RandomEngine &rand, char *buffer) { std::pair strtod_from_string(char *st) { double d; char *pr; -#ifdef _WIN32 +#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun) + d = cygwin_strtod_l(st, &pr); +#elif defined(_WIN32) static _locale_t c_locale = _create_locale(LC_ALL, "C"); d = _strtod_l(st, &pr, c_locale); #else @@ -129,7 +145,7 @@ std::pair strtof_from_string(char *st) { float d; char *pr; #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun) - d = cygwin_strtod_l(st, &pr); + d = cygwin_strtof_l(st, &pr); #elif defined(_WIN32) static _locale_t c_locale = _create_locale(LC_ALL, "C"); d = _strtof_l(st, &pr, c_locale); @@ -205,13 +221,17 @@ bool tester(uint64_t seed, size_t volume) { } int main() { + #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun) - std::cout << "Warning: msys/cygwin or solaris detected. This particular test is likely to generate false failures due to our reliance on the underlying runtime library." << std::endl; -#endif + std::cout << "Warning: msys/cygwin or solaris detected." << std::endl; + return EXIT_SUCCESS; +#else if (tester(1234344, 100000000)) { std::cout << "All tests ok." << std::endl; return EXIT_SUCCESS; } std::cout << "Failure." << std::endl; return EXIT_FAILURE; + +#endif } diff --git a/tests/short_random_string.cpp b/tests/short_random_string.cpp index 9bec6593..c71fbe4b 100644 --- a/tests/short_random_string.cpp +++ b/tests/short_random_string.cpp @@ -16,7 +16,21 @@ double cygwin_strtod_l(const char* start, char** end) { ss.imbue(std::locale::classic()); ss << start; ss >> d; - size_t nread = ss.tellg(); + if(ss.fail()) { *end = nullptr; } + if(ss.eof()) { ss.clear(); } + auto nread = ss.tellg(); + *end = const_cast(start) + nread; + return d; +} +float cygwin_strtof_l(const char* start, char** end) { + float d; + std::stringstream ss; + ss.imbue(std::locale::classic()); + ss << start; + ss >> d; + if(ss.fail()) { *end = nullptr; } + if(ss.eof()) { ss.clear(); } + auto nread = ss.tellg(); *end = const_cast(start) + nread; return d; } @@ -106,7 +120,9 @@ size_t build_random_string(RandomEngine &rand, char *buffer) { std::pair strtod_from_string(char *st) { double d; char *pr; -#ifdef _WIN32 +#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun) + d = cygwin_strtod_l(st, &pr); +#elif defined(_WIN32) static _locale_t c_locale = _create_locale(LC_ALL, "C"); d = _strtod_l(st, &pr, c_locale); #else @@ -124,7 +140,7 @@ std::pair strtof_from_string(char *st) { float d; char *pr; #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun) - d = cygwin_strtod_l(st, &pr); + d = cygwin_strtof_l(st, &pr); #elif defined(_WIN32) static _locale_t c_locale = _create_locale(LC_ALL, "C"); d = _strtof_l(st, &pr, c_locale); @@ -202,11 +218,13 @@ bool tester(uint64_t seed, size_t volume) { int main() { #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun) 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 + return EXIT_SUCCESS; +#else if (tester(1234344, 100000000)) { std::cout << "All tests ok." << std::endl; return EXIT_SUCCESS; } - std::cout << "Failure." << std::endl; return EXIT_FAILURE; + +#endif } diff --git a/tests/string_test.cpp b/tests/string_test.cpp index ebc4b356..e1d7e1fa 100644 --- a/tests/string_test.cpp +++ b/tests/string_test.cpp @@ -15,15 +15,32 @@ double cygwin_strtod_l(const char* start, char** end) { ss.imbue(std::locale::classic()); ss << start; ss >> d; - size_t nread = ss.tellg(); + if(ss.fail()) { *end = nullptr; } + if(ss.eof()) { ss.clear(); } + auto nread = ss.tellg(); + *end = const_cast(start) + nread; + return d; +} +float cygwin_strtof_l(const char* start, char** end) { + float d; + std::stringstream ss; + ss.imbue(std::locale::classic()); + ss << start; + ss >> d; + if(ss.fail()) { *end = nullptr; } + if(ss.eof()) { ss.clear(); } + auto nread = ss.tellg(); *end = const_cast(start) + nread; return d; } #endif inline void Assert(bool Assertion) { - if (!Assertion) - throw std::runtime_error("bug"); +#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun) + if (!Assertion) { std::cerr << "Omitting hard falure on msys/cygwin/sun systems."; } +#else + if (!Assertion) { throw std::runtime_error("bug"); } +#endif } template std::string to_string(T d) { @@ -70,7 +87,9 @@ void strtod_from_string(const std::string &st, T& d); template <> void strtod_from_string(const std::string &st, double& d) { char *pr = (char *)st.c_str(); -#ifdef _WIN32 +#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun) + d = cygwin_strtod_l(pr, &pr); +#elif defined(_WIN32) static _locale_t c_locale = _create_locale(LC_ALL, "C"); d = _strtod_l(st.c_str(), &pr, c_locale); #else @@ -86,7 +105,7 @@ template <> void strtod_from_string(const std::string &st, float& d) { char *pr = (char *)st.c_str(); #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun) - d = cygwin_strtod_l(st.c_str(), &pr); + d = cygwin_strtof_l(st.c_str(), &pr); #elif defined(_WIN32) static _locale_t c_locale = _create_locale(LC_ALL, "C"); d = _strtof_l(st.c_str(), &pr, c_locale); @@ -237,7 +256,7 @@ bool partow_test() { int main() { #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun) - 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; + std::cout << "Warning: msys/cygwin or solaris detected." << std::endl; #endif std::cout << "32 bits checks" << std::endl; Assert(partow_test()); From 42e98b695d8be644268ac310a78fd4b0bee4cbef Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Tue, 22 Dec 2020 16:05:25 -0500 Subject: [PATCH 8/9] Minor cleaning in the CI. --- .github/workflows/msys2-clang.yml | 6 ------ .github/workflows/vs16-clang-ninja-ci.yml | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/.github/workflows/msys2-clang.yml b/.github/workflows/msys2-clang.yml index 53701650..9b3c0489 100644 --- a/.github/workflows/msys2-clang.yml +++ b/.github/workflows/msys2-clang.yml @@ -19,12 +19,6 @@ jobs: - msystem: "MINGW32" install: mingw-w64-i686-cmake mingw-w64-i686-ninja mingw-w64-i686-clang type: Release - - msystem: "MINGW64" - install: mingw-w64-x86_64-cmake mingw-w64-x86_64-ninja mingw-w64-x86_64-gcc - type: Debug - - msystem: "MINGW32" - install: mingw-w64-i686-cmake mingw-w64-i686-ninja mingw-w64-i686-gcc - type: Debug env: CMAKE_GENERATOR: Ninja diff --git a/.github/workflows/vs16-clang-ninja-ci.yml b/.github/workflows/vs16-clang-ninja-ci.yml index e6aceb93..15fd7d23 100644 --- a/.github/workflows/vs16-clang-ninja-ci.yml +++ b/.github/workflows/vs16-clang-ninja-ci.yml @@ -9,7 +9,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: 'Run CMake with VS16' - uses: lukka/run-cmake@v2 + uses: lukka/run-cmake@v3 with: cmakeListsOrSettingsJson: CMakeListsTxtAdvanced cmakeListsTxtPath: '${{ github.workspace }}/CMakeLists.txt' From 92eca125b562adc7746c75fdacfaab9e22c3ed32 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Tue, 22 Dec 2020 16:15:22 -0500 Subject: [PATCH 9/9] Removing weird workflow. --- .github/workflows/vs16-clang-ninja-ci.yml | 25 ----------------------- 1 file changed, 25 deletions(-) delete mode 100644 .github/workflows/vs16-clang-ninja-ci.yml diff --git a/.github/workflows/vs16-clang-ninja-ci.yml b/.github/workflows/vs16-clang-ninja-ci.yml deleted file mode 100644 index 15fd7d23..00000000 --- a/.github/workflows/vs16-clang-ninja-ci.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: VS16-Ninja-CI - -on: [push, pull_request] - -jobs: - ci: - name: windows-vs16 - runs-on: windows-latest - steps: - - uses: actions/checkout@v2 - - name: 'Run CMake with VS16' - uses: lukka/run-cmake@v3 - with: - cmakeListsOrSettingsJson: CMakeListsTxtAdvanced - cmakeListsTxtPath: '${{ github.workspace }}/CMakeLists.txt' - buildDirectory: "${{ github.workspace }}/../../_temp/windows" - cmakeBuildType: Release - buildWithCMake: true - cmakeGenerator: VS16Win64 - cmakeAppendedArgs: -G Ninja -DFASTFLOAT_TEST=ON - buildWithCMakeArgs: - - - name: 'Run CTest' - run: ctest --verbose --output-on-failure -R basictest - working-directory: "${{ github.workspace }}/../../_temp/windows" \ No newline at end of file