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.
This commit is contained in:
Tomas Zeman 2018-03-01 18:41:17 +01:00 committed by Martin Hořeňovský
parent 865d5f59b4
commit 352853ed7e
8 changed files with 22 additions and 3 deletions

View File

@ -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_WINDOWS_CRTDBG // Enable leak checking using Windows's CRT Debug Heap
CATCH_CONFIG_DISABLE_STRINGIFICATION // Disable stringifying the original expression CATCH_CONFIG_DISABLE_STRINGIFICATION // Disable stringifying the original expression
CATCH_CONFIG_DISABLE // Disables assertions and test case registration 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. 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_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`. These toggles can be disabled by using `_NO_` form of the toggle, e.g. `CATCH_CONFIG_NO_WINDOWS_SEH`.
### `CATCH_CONFIG_FAST_COMPILE` ### `CATCH_CONFIG_FAST_COMPILE`

View File

@ -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) #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 # define CATCH_CONFIG_POSIX_SIGNALS
#endif #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) #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 # define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS

View File

@ -12,7 +12,7 @@
#ifndef __OBJC__ #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 // Standard C/C++ Win32 Unicode wmain entry point
extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) { extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) {
#else #else

View File

@ -202,7 +202,7 @@ namespace Catch {
return returnCode; 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[] ) { int Session::run( int argc, wchar_t* const argv[] ) {
char **utf8Argv = new char *[ argc ]; char **utf8Argv = new char *[ argc ];

View File

@ -30,7 +30,7 @@ namespace Catch {
void useConfigData( ConfigData const& configData ); void useConfigData( ConfigData const& configData );
int run( int argc, char* argv[] ); 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[] ); int run( int argc, wchar_t* const argv[] );
#endif #endif
int run(); int run();

View File

@ -116,6 +116,7 @@ std::string StringMaker<std::string>::convert(const std::string& str) {
return s; return s;
} }
#ifdef CATCH_CONFIG_WCHAR
std::string StringMaker<std::wstring>::convert(const std::wstring& wstr) { std::string StringMaker<std::wstring>::convert(const std::wstring& wstr) {
std::string s; std::string s;
s.reserve(wstr.size()); s.reserve(wstr.size());
@ -124,6 +125,7 @@ std::string StringMaker<std::wstring>::convert(const std::wstring& wstr) {
} }
return ::Catch::Detail::stringify(s); return ::Catch::Detail::stringify(s);
} }
#endif
std::string StringMaker<char const*>::convert(char const* str) { std::string StringMaker<char const*>::convert(char const* str) {
if (str) { if (str) {
@ -139,6 +141,7 @@ std::string StringMaker<char*>::convert(char* str) {
return{ "{null string}" }; return{ "{null string}" };
} }
} }
#ifdef CATCH_CONFIG_WCHAR
std::string StringMaker<wchar_t const*>::convert(wchar_t const * str) { std::string StringMaker<wchar_t const*>::convert(wchar_t const * str) {
if (str) { if (str) {
return ::Catch::Detail::stringify(std::wstring{ str }); return ::Catch::Detail::stringify(std::wstring{ str });
@ -153,6 +156,7 @@ std::string StringMaker<wchar_t *>::convert(wchar_t * str) {
return{ "{null string}" }; return{ "{null string}" };
} }
} }
#endif
std::string StringMaker<int>::convert(int value) { std::string StringMaker<int>::convert(int value) {

View File

@ -13,6 +13,7 @@
#include <cstddef> #include <cstddef>
#include <type_traits> #include <type_traits>
#include <string> #include <string>
#include "catch_compiler_capabilities.h"
#include "catch_stream.h" #include "catch_stream.h"
#ifdef __OBJC__ #ifdef __OBJC__
@ -119,10 +120,12 @@ namespace Catch {
struct StringMaker<std::string> { struct StringMaker<std::string> {
static std::string convert(const std::string& str); static std::string convert(const std::string& str);
}; };
#ifdef CATCH_CONFIG_WCHAR
template<> template<>
struct StringMaker<std::wstring> { struct StringMaker<std::wstring> {
static std::string convert(const std::wstring& wstr); static std::string convert(const std::wstring& wstr);
}; };
#endif
template<> template<>
struct StringMaker<char const *> { struct StringMaker<char const *> {
@ -132,6 +135,7 @@ namespace Catch {
struct StringMaker<char *> { struct StringMaker<char *> {
static std::string convert(char * str); static std::string convert(char * str);
}; };
#ifdef CATCH_CONFIG_WCHAR
template<> template<>
struct StringMaker<wchar_t const *> { struct StringMaker<wchar_t const *> {
static std::string convert(wchar_t const * str); static std::string convert(wchar_t const * str);
@ -140,6 +144,7 @@ namespace Catch {
struct StringMaker<wchar_t *> { struct StringMaker<wchar_t *> {
static std::string convert(wchar_t * str); static std::string convert(wchar_t * str);
}; };
#endif
template<int SZ> template<int SZ>
struct StringMaker<char[SZ]> { struct StringMaker<char[SZ]> {

View File

@ -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]" ) { TEST_CASE( "toString on const wchar_t const pointer returns the string contents", "[toString]" ) {
const wchar_t * const s = L"wide load"; const wchar_t * const s = L"wide load";
std::string result = ::Catch::Detail::stringify( s ); 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 ); std::string result = ::Catch::Detail::stringify( s );
CHECK( result == "\"wide load\"" ); CHECK( result == "\"wide load\"" );
} }
#endif
TEST_CASE( "long long" ) { TEST_CASE( "long long" ) {
long long l = std::numeric_limits<long long>::max(); long long l = std::numeric_limits<long long>::max();