From bcfc9a8a26a7a0ff1011312775d7bcbf8db1895d Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Thu, 2 Aug 2018 20:49:23 +0200 Subject: [PATCH] Fix printf tests for recent MinGW versions The default mantissa length was changed from 3 to 2 in MinGW 5.0.4. Fix the test for printing pointer addresses in 64bit MinGW. --- tests/strings/strings.cpp | 4 +--- tests/strings/vsnprintf.cpp | 41 +++++++++++++++---------------------- tests/testprec.h | 31 +++++++++++++++------------- 3 files changed, 34 insertions(+), 42 deletions(-) diff --git a/tests/strings/strings.cpp b/tests/strings/strings.cpp index 7e960ecb64..0829970c41 100644 --- a/tests/strings/strings.cpp +++ b/tests/strings/strings.cpp @@ -849,9 +849,7 @@ void StringTestCase::FromDouble() } testData[] = { { 1.23, -1, "1.23" }, - // All MSVC versions until MSVC 14 used 3 digits for the exponent - // unnecessarily, account for this non-standard behaviour. -#if defined(wxUSING_VC_CRT_IO) && !wxCHECK_VISUALC_VERSION(14) +#if defined(wxDEFAULT_MANTISSA_SIZE_3) { -3e-10, -1, "-3e-010" }, #else { -3e-10, -1, "-3e-10" }, diff --git a/tests/strings/vsnprintf.cpp b/tests/strings/vsnprintf.cpp index 9fe7232fd7..92dda3937d 100644 --- a/tests/strings/vsnprintf.cpp +++ b/tests/strings/vsnprintf.cpp @@ -71,12 +71,6 @@ int r; CPPUNIT_ASSERT_EQUAL( r, wxStrlen(buf) ); \ ASSERT_STR_EQUAL( wxT(expected), buf ); -#define CMP3i(expected, fmt, y) \ - r=wxSnprintf(buf, MAX_TEST_LEN, wxT(fmt), y); \ - CPPUNIT_ASSERT_EQUAL( r, wxStrlen(buf) ); \ - WX_ASSERT_MESSAGE( ("Expected \"%s\", got \"%s\"", expected, buf), \ - wxStricmp(expected, buf) == 0 ); - #define CMP2(expected, fmt) \ r=wxSnprintf(buf, MAX_TEST_LEN, wxT(fmt)); \ CPPUNIT_ASSERT_EQUAL( r, wxStrlen(buf) ); \ @@ -241,22 +235,23 @@ void VsnprintfTestCase::P() // the system sprintf() for actual formatting so the results are still // different under different systems). -#ifdef wxUSING_VC_CRT_IO - // MSVC always prints pointers as %8X on 32 bit systems and as %16X on 64 - // bit systems. +#if defined(__VISUALC__) || (defined(__MINGW32__) && \ + (!defined(__USE_MINGW_ANSI_STDIO) || !__USE_MINGW_ANSI_STDIO)) #if SIZEOF_VOID_P == 4 - CMP3i("00ABCDEF", "%p", (void*)0xABCDEF); + CMP3("00ABCDEF", "%p", (void*)0xABCDEF); CMP3("00000000", "%p", (void*)NULL); #elif SIZEOF_VOID_P == 8 - CMP3i("0000ABCDEFABCDEF", "%p", (void*)0xABCDEFABCDEF); + CMP3("0000ABCDEFABCDEF", "%p", (void*)0xABCDEFABCDEF); CMP3("0000000000000000", "%p", (void*)NULL); #endif #elif defined(__MINGW32__) - // mingw32 uses MSVC CRT in old versions but is own implementation now - // which is somewhere in the middle as it uses %8x, so to catch both cases - // we use case-insensitive comparison here. - CMP3("0xabcdef", "%p", (void*)0xABCDEF); - CMP3("0", "%p", (void*)NULL); + #if SIZEOF_VOID_P == 4 + CMP3("00abcdef", "%p", (void*)0xABCDEF); + CMP3("00000000", "%p", (void*)NULL); + #elif SIZEOF_VOID_P == 8 + CMP3("0000abcdefabcdef", "%p", (void*)0xABCDEFABCDEF); + CMP3("0000000000000000", "%p", (void*)NULL); + #endif #elif defined(__GNUG__) // glibc prints pointers as %#x except for NULL pointers which are printed // as '(nil)'. @@ -275,13 +270,10 @@ void VsnprintfTestCase::N() void VsnprintfTestCase::E() { - // NB: there are no standards about the minimum exponent width - // (and the width of the %e conversion specifier refers to the - // mantissa, not to the exponent). - // Since newer MSVC versions use 3 digits as minimum exponent - // width while GNU libc uses 2 digits as minimum width, here we - // workaround this problem using for the exponent values with at - // least three digits. + // NB: Use at least three digits for the exponent to workaround + // differences between MSVC, MinGW and GNU libc. + // See wxUSING_MANTISSA_SIZE_3 in testprec.h as well. + // // Some examples: // printf("%e",2.342E+02); // -> under MSVC7.1 prints: 2.342000e+002 @@ -601,8 +593,7 @@ void VsnprintfTestCase::GlibcMisc1() { CMP3(" ", "%5.s", "xyz"); CMP3(" 33", "%5.f", 33.3); -#ifdef wxUSING_VC_CRT_IO - // see the previous notes about the minimum width of mantissa: +#if defined(wxDEFAULT_MANTISSA_SIZE_3) CMP3(" 3e+008", "%8.e", 33.3e7); CMP3(" 3E+008", "%8.E", 33.3e7); CMP3("3e+001", "%.g", 33.3); diff --git a/tests/testprec.h b/tests/testprec.h index 03f5f624ce..d0bdb41aae 100644 --- a/tests/testprec.h +++ b/tests/testprec.h @@ -36,21 +36,24 @@ #endif #endif -// Define wxUSING_VC_CRT_IO when using MSVC CRT STDIO library as its standard -// functions give different results from glibc ones in several cases (of -// course, any code relying on this is not portable and probably won't work, -// i.e. will result in tests failures, with other platforms/compilers which -// should have checks for them added as well). +// Define wxUSING_MANTISSA_SIZE_3 for certain versions of MinGW and MSVC. +// These use a CRT which prints the exponent with a minimum of 3 +// digits instead of 2. // -// Notice that MinGW uses VC CRT by default but may use its own printf() -// implementation if __USE_MINGW_ANSI_STDIO is defined. And finally also notice -// that testing for __USE_MINGW_ANSI_STDIO directly results in a warning with -// -Wundef if it involves an operation with undefined __MINGW_FEATURES__ so -// test for the latter too to avoid it. -#if defined(__VISUALC__) || \ - (defined(__MINGW32__) && \ - (!defined(__MINGW_FEATURES__) || !__USE_MINGW_ANSI_STDIO)) - #define wxUSING_VC_CRT_IO +// This happens for all MSVC compilers before version 14 (VS2015). +// And for MinGW when it does not define or set __USE_MINGW_ANSI_STDIO. +// Since MinGW 5.0.4 it uses at least 2 digits for the exponent: +// https://sourceforge.net/p/mingw-w64/mailman/message/36333746/ + +#if (defined(__MINGW64_VERSION_MAJOR) && (__MINGW64_VERSION_MAJOR > 5 || \ + (__MINGW64_VERSION_MAJOR == 5 && __MINGW64_VERSION_MINOR >= 0) || \ + (__MINGW64_VERSION_MAJOR == 5 && __MINGW64_VERSION_MINOR == 0 && __MINGW64_VERSION_BUGFIX >= 4))) +#define wxMINGW_WITH_FIXED_MANTISSA +#endif +#if (defined(__VISUALC__) && !wxCHECK_VISUALC_VERSION(14)) || \ + (defined(__MINGW32__) && !defined(wxMINGW_WITH_FIXED_MANTISSA) && \ + (!defined(__USE_MINGW_ANSI_STDIO) || !__USE_MINGW_ANSI_STDIO)) + #define wxDEFAULT_MANTISSA_SIZE_3 #endif // thrown when assert fails in debug build