From b8443e67da47f02ec865ab38edc5756b1895b7e4 Mon Sep 17 00:00:00 2001 From: Antonio Di Monaco Date: Thu, 11 May 2017 13:00:03 +0200 Subject: [PATCH] Added Win32 UNICODE wmain support (#903) * Added wmain support * Added appveyor.yml wmain configuration * Added wmain configuration flag to CMake --- CMakeLists.txt | 4 ++++ appveyor.yml | 8 +++++++- include/catch_session.hpp | 26 +++++++++++++++++++++++++ include/internal/catch_default_main.hpp | 6 ++++++ 4 files changed, 43 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8d39bdb8..0bd7dd1f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,10 @@ elseif(USE_CPP14) set(CMAKE_CXX_FLAGS "-std=c++14 ${CMAKE_CXX_FLAGS}") endif() +if(USE_WMAIN) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ENTRY:wmainCRTStartup") +endif() + #checks that the given hard-coded list contains all headers + sources in the given folder function(CheckFileList LIST_VAR FOLDER) set(MESSAGE " should be added to the variable ${LIST_VAR}") diff --git a/appveyor.yml b/appveyor.yml index f6fce08a..d09c1dd5 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -9,7 +9,13 @@ os: environment: matrix: - additional_flags: "/permissive- /std:c++latest" + wmain: 0 + - additional_flags: "" + wmain: 0 + + - additional_flags: "/D_UNICODE /DUNICODE" + wmain: 1 matrix: exclude: @@ -42,7 +48,7 @@ configuration: #Cmake will autodetect the compiler, but we set the arch before_build: - set CXXFLAGS=%additional_flags% - - cmake -H. -BBuild -A%PLATFORM% + - cmake -H. -BBuild -A%PLATFORM% -DUSE_WMAIN=%wmain% # build with MSBuild build: diff --git a/include/catch_session.hpp b/include/catch_session.hpp index be51bef8..a501634d 100644 --- a/include/catch_session.hpp +++ b/include/catch_session.hpp @@ -166,6 +166,32 @@ namespace Catch { return returnCode; } + #if defined(WIN32) && defined(UNICODE) + int run( int argc, wchar_t const* const* const argv ) { + + char **utf8Argv = new char *[ argc ]; + + for ( int i = 0; i < argc; ++i ) { + int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL ); + + utf8Argv[ i ] = new char[ bufSize ]; + + WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, NULL, NULL ); + } + + int returnCode = applyCommandLine( argc, utf8Argv ); + if( returnCode == 0 ) + returnCode = run(); + + for ( int i = 0; i < argc; ++i ) + delete [] utf8Argv[ i ]; + + delete [] utf8Argv; + + return returnCode; + } + #endif + int run() { if( m_configData.showHelp ) return 0; diff --git a/include/internal/catch_default_main.hpp b/include/internal/catch_default_main.hpp index a0c4239d..69337244 100644 --- a/include/internal/catch_default_main.hpp +++ b/include/internal/catch_default_main.hpp @@ -10,8 +10,14 @@ #ifndef __OBJC__ +#if 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 // Standard C/C++ main entry point int main (int argc, char * argv[]) { +#endif + int result = Catch::Session().run( argc, argv ); return ( result < 0xff ? result : 0xff ); }