From 352853ed7e2592f224fc9e9f01e1314660e906e1 Mon Sep 17 00:00:00 2001 From: Tomas Zeman Date: Thu, 1 Mar 2018 18:41:17 +0100 Subject: [PATCH] Introduce conditional wchar_t (and std::wstring) support The support is turned on by default but the user might need to be able to turn it off which is now possible by defining CATCH_CONFIG_NO_WCHAR. --- docs/configuration.md | 4 ++++ include/internal/catch_compiler_capabilities.h | 4 ++++ include/internal/catch_default_main.hpp | 2 +- include/internal/catch_session.cpp | 2 +- include/internal/catch_session.h | 2 +- include/internal/catch_tostring.cpp | 4 ++++ include/internal/catch_tostring.h | 5 +++++ projects/SelfTest/UsageTests/Misc.tests.cpp | 2 ++ 8 files changed, 22 insertions(+), 3 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index c2fcc55e..3f963eec 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -120,6 +120,7 @@ by using `_NO_` in the macro, e.g. `CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS`. CATCH_CONFIG_WINDOWS_CRTDBG // Enable leak checking using Windows's CRT Debug Heap CATCH_CONFIG_DISABLE_STRINGIFICATION // Disable stringifying the original expression CATCH_CONFIG_DISABLE // Disables assertions and test case registration + CATCH_CONFIG_WCHAR // Enables use of wchart_t Currently Catch enables `CATCH_CONFIG_WINDOWS_SEH` only when compiled with MSVC, because some versions of MinGW do not have the necessary Win32 API support. @@ -127,6 +128,9 @@ Currently Catch enables `CATCH_CONFIG_WINDOWS_SEH` only when compiled with MSVC, `CATCH_CONFIG_WINDOWS_CRTDBG` is off by default. If enabled, Windows's CRT is used to check for memory leaks, and displays them after the tests finish running. +`CATCH_CONFIG_WCHAR` is on by default, but can be disabled. Currently +it is only used in support for DJGPP cross-compiler. + These toggles can be disabled by using `_NO_` form of the toggle, e.g. `CATCH_CONFIG_NO_WINDOWS_SEH`. ### `CATCH_CONFIG_FAST_COMPILE` diff --git a/include/internal/catch_compiler_capabilities.h b/include/internal/catch_compiler_capabilities.h index 50bb9e6e..b1acf99d 100644 --- a/include/internal/catch_compiler_capabilities.h +++ b/include/internal/catch_compiler_capabilities.h @@ -130,6 +130,10 @@ #if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS) # define CATCH_CONFIG_POSIX_SIGNALS #endif +// This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions. +#if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR) +# define CATCH_CONFIG_WCHAR +#endif #if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) # define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS diff --git a/include/internal/catch_default_main.hpp b/include/internal/catch_default_main.hpp index 4372e9cc..17ad090a 100644 --- a/include/internal/catch_default_main.hpp +++ b/include/internal/catch_default_main.hpp @@ -12,7 +12,7 @@ #ifndef __OBJC__ -#if defined(WIN32) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN) +#if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN) // Standard C/C++ Win32 Unicode wmain entry point extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) { #else diff --git a/include/internal/catch_session.cpp b/include/internal/catch_session.cpp index 9ccb16f8..0039fcb5 100644 --- a/include/internal/catch_session.cpp +++ b/include/internal/catch_session.cpp @@ -202,7 +202,7 @@ namespace Catch { return returnCode; } -#if defined(WIN32) && defined(UNICODE) +#if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE) int Session::run( int argc, wchar_t* const argv[] ) { char **utf8Argv = new char *[ argc ]; diff --git a/include/internal/catch_session.h b/include/internal/catch_session.h index b814aa6a..39f7a0dd 100644 --- a/include/internal/catch_session.h +++ b/include/internal/catch_session.h @@ -30,7 +30,7 @@ namespace Catch { void useConfigData( ConfigData const& configData ); int run( int argc, char* argv[] ); - #if defined(WIN32) && defined(UNICODE) + #if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE) int run( int argc, wchar_t* const argv[] ); #endif int run(); diff --git a/include/internal/catch_tostring.cpp b/include/internal/catch_tostring.cpp index a9f7735e..0d0158fa 100644 --- a/include/internal/catch_tostring.cpp +++ b/include/internal/catch_tostring.cpp @@ -116,6 +116,7 @@ std::string StringMaker::convert(const std::string& str) { return s; } +#ifdef CATCH_CONFIG_WCHAR std::string StringMaker::convert(const std::wstring& wstr) { std::string s; s.reserve(wstr.size()); @@ -124,6 +125,7 @@ std::string StringMaker::convert(const std::wstring& wstr) { } return ::Catch::Detail::stringify(s); } +#endif std::string StringMaker::convert(char const* str) { if (str) { @@ -139,6 +141,7 @@ std::string StringMaker::convert(char* str) { return{ "{null string}" }; } } +#ifdef CATCH_CONFIG_WCHAR std::string StringMaker::convert(wchar_t const * str) { if (str) { return ::Catch::Detail::stringify(std::wstring{ str }); @@ -153,6 +156,7 @@ std::string StringMaker::convert(wchar_t * str) { return{ "{null string}" }; } } +#endif std::string StringMaker::convert(int value) { diff --git a/include/internal/catch_tostring.h b/include/internal/catch_tostring.h index bb9cb0be..26756fa9 100644 --- a/include/internal/catch_tostring.h +++ b/include/internal/catch_tostring.h @@ -13,6 +13,7 @@ #include #include #include +#include "catch_compiler_capabilities.h" #include "catch_stream.h" #ifdef __OBJC__ @@ -119,10 +120,12 @@ namespace Catch { struct StringMaker { static std::string convert(const std::string& str); }; +#ifdef CATCH_CONFIG_WCHAR template<> struct StringMaker { static std::string convert(const std::wstring& wstr); }; +#endif template<> struct StringMaker { @@ -132,6 +135,7 @@ namespace Catch { struct StringMaker { static std::string convert(char * str); }; +#ifdef CATCH_CONFIG_WCHAR template<> struct StringMaker { static std::string convert(wchar_t const * str); @@ -140,6 +144,7 @@ namespace Catch { struct StringMaker { static std::string convert(wchar_t * str); }; +#endif template struct StringMaker { diff --git a/projects/SelfTest/UsageTests/Misc.tests.cpp b/projects/SelfTest/UsageTests/Misc.tests.cpp index 683b8391..fa158705 100644 --- a/projects/SelfTest/UsageTests/Misc.tests.cpp +++ b/projects/SelfTest/UsageTests/Misc.tests.cpp @@ -290,6 +290,7 @@ TEST_CASE( "Tabs and newlines show in output", "[.][whitespace][failing]" ) { } +#ifdef CATCH_CONFIG_WCHAR TEST_CASE( "toString on const wchar_t const pointer returns the string contents", "[toString]" ) { const wchar_t * const s = L"wide load"; std::string result = ::Catch::Detail::stringify( s ); @@ -313,6 +314,7 @@ TEST_CASE( "toString on wchar_t returns the string contents", "[toString]" ) { std::string result = ::Catch::Detail::stringify( s ); CHECK( result == "\"wide load\"" ); } +#endif TEST_CASE( "long long" ) { long long l = std::numeric_limits::max();