diff --git a/src/ExceptionHelper.cpp b/src/ExceptionHelper.cpp index b137486..d83f23b 100644 --- a/src/ExceptionHelper.cpp +++ b/src/ExceptionHelper.cpp @@ -1,11 +1,11 @@ #include "ExceptionHelper.hpp" #if YYCC_OS == YYCC_OS_WINDOWS +#include "WinFctHelper.hpp" #include #include #include #include -#include "WinFctHelper.hpp" #include "WinImportPrefix.hpp" #include @@ -96,7 +96,7 @@ namespace YYCC::ExceptionHelper { } } - static void UExceptionFormat(std::FILE* fs, const char* fmt, ...) { + static void UExceptionBacktraceFormatLine(std::FILE* fs, const char* fmt, ...) { // write to file va_list arg1; va_start(arg1, fmt); @@ -109,7 +109,7 @@ namespace YYCC::ExceptionHelper { va_end(arg2); } - static void UExceptionPrint(std::FILE* fs, const char* strl) { + static void UExceptionBacktraceWriteLine(std::FILE* fs, const char* strl) { // write to file std::fputs(strl, fs); // write to stdout @@ -127,7 +127,7 @@ namespace YYCC::ExceptionHelper { // init symbol if (!SymInitialize(process, 0, TRUE)) { // fail to load. return - UExceptionPrint(fs, "Lost symbol file!\n"); + UExceptionBacktraceWriteLine(fs, "Lost symbol file!\n"); return; } @@ -182,7 +182,7 @@ namespace YYCC::ExceptionHelper { // depth breaker --maxdepth; if (maxdepth < 0) { - UExceptionPrint(fs, "...\n"); // indicate there are some frames not listed + UExceptionBacktraceWriteLine(fs, "...\n"); // indicate there are some frames not listed break; } @@ -205,7 +205,7 @@ namespace YYCC::ExceptionHelper { } // write to file - UExceptionFormat(fs, "0x%016llx(rel: 0x%016llx)[%s]\t%s#%llu\n", + UExceptionBacktraceFormatLine(fs, "0x%016llx(rel: 0x%016llx)[%s]\t%s#%llu\n", frame.AddrPC.Offset, frame.AddrPC.Offset - module_base, module_name, source_file, source_file_line ); @@ -218,6 +218,10 @@ namespace YYCC::ExceptionHelper { SymCleanup(process); } + static void UExceptionErrorLog(const std::wstring& filename, LPEXCEPTION_POINTERS info) { + + } + static void UExceptionCoreDump(LPCWSTR filename, LPEXCEPTION_POINTERS info) { // open file and write HANDLE hFile = CreateFileW(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); @@ -236,11 +240,13 @@ namespace YYCC::ExceptionHelper { } } + static void UExceptionFetchRecordPath(std::wstring& log_path, std::wstring& coredump_path) { + + } + static LONG WINAPI UExceptionImpl(LPEXCEPTION_POINTERS info) { // detect loop calling - if (g_IsProcessing) { - goto end_proc; - } + if (g_IsProcessing) goto end_proc; // start process g_IsProcessing = true; diff --git a/src/IOHelper.cpp b/src/IOHelper.cpp index d6fd32d..23541ea 100644 --- a/src/IOHelper.cpp +++ b/src/IOHelper.cpp @@ -1,25 +1,22 @@ #include "IOHelper.hpp" -#if YYCC_OS == YYCC_OS_WINDOWS #include "EncodingHelper.hpp" #include #include #include +#include +#if YYCC_OS == YYCC_OS_WINDOWS #include "WinImportPrefix.hpp" #include -#include -#include #include "WinImportSuffix.hpp" +#endif namespace YYCC::IOHelper { - bool futf8(FILE* fs) { - // https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/setmode?view=msvc-170 - return _setmode(_fileno(fs), _O_U8TEXT) != -1; - } + FILE* UTF8FOpen(const char* u8_filepath, const char* u8_mode) { +#if YYCC_OS == YYCC_OS_WINDOWS - FILE* fopen(const char* u8_filepath, const char* u8_mode) { // convert mode and file path to wchar std::wstring wmode, wpath; if (!YYCC::EncodingHelper::UTF8ToWchar(u8_mode, wmode)) @@ -29,8 +26,28 @@ namespace YYCC::IOHelper { // call microsoft specified fopen which support wchar as argument. return _wfopen(wpath.c_str(), wmode.c_str()); + +#else + return std::fopen(u8_filepath, u8_mode); +#endif } + std::filesystem::path UTF8Path(const char* u8_path) { +#if YYCC_OS == YYCC_OS_WINDOWS + + // convert path to wchar + std::wstring wpath; + if (!YYCC::EncodingHelper::UTF8ToWchar(u8_path, wpath)) + throw std::invalid_argument("Fail to convert given UTF8 string."); + + // call microsoft specified fopen which support wchar as argument. + return std::filesystem::path(wpath); + +#else + return std::filesystem::path(u8_path); +#endif + } + + } -#endif diff --git a/src/IOHelper.hpp b/src/IOHelper.hpp index 888caca..47e6690 100644 --- a/src/IOHelper.hpp +++ b/src/IOHelper.hpp @@ -1,23 +1,48 @@ #pragma once #include "YYCCInternal.hpp" -#if YYCC_OS == YYCC_OS_WINDOWS #include +#include namespace YYCC::IOHelper { +#if UINTPTR_MAX == UINT32_MAX +#define PRI_XPTR_LEFT_PADDING "08" +#elif UINTPTR_MAX == UINT64_MAX /** - * @brief Set given FILE* as UTF8 mode. - * @param fs[in] The FILE* need to be set as UTF8 mode. - * @return True if success, otherwise false. - * @warning Once this function success, you can not use any narrow char function on this FILE*, - * such as std::fputs, std::fprintf and etc. You only can use wide char function on it, - * or use the functions provided in this namespace by providing UTF8 string as their argument. + * @brief The left-padding zero format string of HEX-printed pointer type. + * @details + * When printing a pointer with HEX style, we always hope it can be left-padded with some zero for easy reading. + * In different architecture, the size of this padding is differnet too so we create this macro. + * \n + * In 32-bit environment, it will be "08" meaning left pad zero until 8 number position. + * In 64-bit environment, it will be "016" meaning left pad zero until 16 number position. */ - bool futf8(FILE* fs); +#define PRI_XPTR_LEFT_PADDING "016" +#else +#error "Not supported pointer size." +#endif - FILE* fopen(const char* u8_filepath, const char* u8_mode); + /** + * @brief The UTF8 version of std::fopen. + * @param u8_filepath[in] The UTF8 encoded path to the file to be opened. + * @param u8_mode[in] UTF8 encoded mode string of the file to be opened. + * @remarks + * This function is suit for Windows because std::fopen do not support UTF8 on Windows. + * On other platforms, this function will delegate request directly to std::fopen. + * @return FILE* of the file to be opened, or nullptr if failed. + */ + FILE* UTF8FOpen(const char* u8_filepath, const char* u8_mode); + + /** + * @brief Build std::filesystem::path from UTF8 string. + * @param u8_path[in] UTF8 path string for building this std::filesystem::path. + * @return std::filesystem::path instance. + * @exception std::invalid_argument Fail to parse given UTF8 string (maybe invalid?). + * @remarks + * This function is suit for Windows. + * On other platforms, it will simply call the constructor of std::filesystem::path. + */ + std::filesystem::path UTF8Path(const char* u8_path); } - -#endif diff --git a/testbench/main.cpp b/testbench/main.cpp index a5fd429..75f17e3 100644 --- a/testbench/main.cpp +++ b/testbench/main.cpp @@ -216,7 +216,7 @@ namespace YYCCTestbench { } static void WinFctTestbench() { - Console::WriteLine("Current Module HANDLE: 0x%016" PRIXPTR, YYCC::WinFctHelper::GetCurrentModule()); + Console::WriteLine("Current Module HANDLE: 0x%" PRI_XPTR_LEFT_PADDING PRIXPTR, YYCC::WinFctHelper::GetCurrentModule()); Console::WriteLine("Temp Directory: %s", YYCC::WinFctHelper::GetTempDirectory().c_str()); Console::WriteLine("Current Module Name: %s", YYCC::WinFctHelper::GetModuleName(YYCC::WinFctHelper::GetCurrentModule()).c_str()); }