From 9ffb6666b8d502d7661fe054ba5fce9cb6362574 Mon Sep 17 00:00:00 2001 From: bbbradsmith Date: Mon, 22 Apr 2024 05:19:15 -0400 Subject: [PATCH] windows also needs a UTF8 fopen abstraction --- cmd/cmd.cpp | 10 ++++++++-- cmd/platform.cpp | 40 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/cmd/cmd.cpp b/cmd/cmd.cpp index 450c444..48aaede 100644 --- a/cmd/cmd.cpp +++ b/cmd/cmd.cpp @@ -1,15 +1,19 @@ -// stub +// cmd.cpp +// Main entry point for nsfplac. #include #include // std::fprintf #include // std::exit #include // std::strlen -// platform.cpp +// platform specific abstractions (platform.cpp) void platform_setup(int argc, char** argv); void platform_shutdown(); int platform_argc(); const char* platform_argv(int index); +FILE* platform_fopen(const char* path, const char* mode); + +// logging functions void error_log(const char* msg) { @@ -28,6 +32,8 @@ void fatal_log(const char* msg) std::exit(-1); } +// main + int main(int argc, char** argv) { platform_setup(argc,argv); diff --git a/cmd/platform.cpp b/cmd/platform.cpp index 2dce6c5..1d298f7 100644 --- a/cmd/platform.cpp +++ b/cmd/platform.cpp @@ -5,16 +5,23 @@ #define VC_EXTRALEAN #define WIN32_LEAN_AND_MEAN -#include // GetConsoleOutputCP, SetConsoleOutputCP +#include // GetConsoleOutputCP, SetConsoleOutputCP, WireCharToMultiByte, MultiByteToWideChar #include // GetCommandLineW, CommandLineToArgW #include // std::malloc, std::free -#include // HACK +#include // std::_wfopen + +#if defined(_MSC_VER) +#pragma warning(disable:6387) // MSVC thinks store_wconvert could be NULL and warns about _wfopen_s +#endif static UINT startup_cp = 0; static LPWSTR* store_argv; static int store_argc; static char* store_convert = NULL; static int store_convert_size = 0; +static wchar_t* store_wconvert = NULL; +static int store_wconvert_size = 0; + void platform_setup(int argc, char** argv) { @@ -30,6 +37,7 @@ void platform_setup(int argc, char** argv) void platform_shutdown() { + std::free(store_wconvert); std::free(store_convert); SetConsoleOutputCP(startup_cp); LocalFree(store_argv); @@ -48,14 +56,35 @@ const char* platform_argv(int index) { free(store_convert); store_convert_size = new_size; - store_convert = (char*)malloc(store_convert_size); + store_convert = (char*)std::malloc(store_convert_size); } WideCharToMultiByte(CP_UTF8,0,store_argv[index],-1,store_convert,store_convert_size,NULL,NULL); return store_convert; } +FILE* platform_fopen(const char* path, const char* mode) +{ + static wchar_t wmode[16]; + MultiByteToWideChar(CP_UTF8,0,mode,-1,wmode,sizeof(wmode)/sizeof(wmode[0])); + + int new_size = MultiByteToWideChar(CP_UTF8,0,path,-1,NULL,0); + if (new_size > store_wconvert_size) + { + free(store_wconvert); + store_wconvert_size = new_size; + store_wconvert = (wchar_t*)std::malloc(store_wconvert_size*sizeof(wchar_t)); + } + MultiByteToWideChar(CP_UTF8,0,path,-1,store_wconvert,store_wconvert_size); + + FILE* f; + if (0 == _wfopen_s(&f,store_wconvert,wmode)) return f; + return NULL; +} + #else +#include // std::fopen + // other platforms assume a UTF-8 by default static int store_argc; @@ -81,4 +110,9 @@ const char* platform_argv(int index) return store_argv[index]; } +FILE* platform_fopen(const char* path, const char* mode) +{ + return std::fopen(path,mode); +} + #endif