feat: update IO helper.
- add utf8 path to std::filesystem::path convertion function. - add left-padding zero format string for printing pointer. - update exception handler, but not finished because console helper need update.
This commit is contained in:
parent
015ff874f8
commit
0ef1939e6e
|
@ -1,11 +1,11 @@
|
||||||
#include "ExceptionHelper.hpp"
|
#include "ExceptionHelper.hpp"
|
||||||
#if YYCC_OS == YYCC_OS_WINDOWS
|
#if YYCC_OS == YYCC_OS_WINDOWS
|
||||||
|
|
||||||
|
#include "WinFctHelper.hpp"
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <cstdarg>
|
#include <cstdarg>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cinttypes>
|
#include <cinttypes>
|
||||||
#include "WinFctHelper.hpp"
|
|
||||||
|
|
||||||
#include "WinImportPrefix.hpp"
|
#include "WinImportPrefix.hpp"
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
@ -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
|
// write to file
|
||||||
va_list arg1;
|
va_list arg1;
|
||||||
va_start(arg1, fmt);
|
va_start(arg1, fmt);
|
||||||
|
@ -109,7 +109,7 @@ namespace YYCC::ExceptionHelper {
|
||||||
va_end(arg2);
|
va_end(arg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void UExceptionPrint(std::FILE* fs, const char* strl) {
|
static void UExceptionBacktraceWriteLine(std::FILE* fs, const char* strl) {
|
||||||
// write to file
|
// write to file
|
||||||
std::fputs(strl, fs);
|
std::fputs(strl, fs);
|
||||||
// write to stdout
|
// write to stdout
|
||||||
|
@ -127,7 +127,7 @@ namespace YYCC::ExceptionHelper {
|
||||||
// init symbol
|
// init symbol
|
||||||
if (!SymInitialize(process, 0, TRUE)) {
|
if (!SymInitialize(process, 0, TRUE)) {
|
||||||
// fail to load. return
|
// fail to load. return
|
||||||
UExceptionPrint(fs, "Lost symbol file!\n");
|
UExceptionBacktraceWriteLine(fs, "Lost symbol file!\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,7 +182,7 @@ namespace YYCC::ExceptionHelper {
|
||||||
// depth breaker
|
// depth breaker
|
||||||
--maxdepth;
|
--maxdepth;
|
||||||
if (maxdepth < 0) {
|
if (maxdepth < 0) {
|
||||||
UExceptionPrint(fs, "...\n"); // indicate there are some frames not listed
|
UExceptionBacktraceWriteLine(fs, "...\n"); // indicate there are some frames not listed
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,7 +205,7 @@ namespace YYCC::ExceptionHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
// write to file
|
// 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,
|
frame.AddrPC.Offset, frame.AddrPC.Offset - module_base, module_name,
|
||||||
source_file, source_file_line
|
source_file, source_file_line
|
||||||
);
|
);
|
||||||
|
@ -218,6 +218,10 @@ namespace YYCC::ExceptionHelper {
|
||||||
SymCleanup(process);
|
SymCleanup(process);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void UExceptionErrorLog(const std::wstring& filename, LPEXCEPTION_POINTERS info) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static void UExceptionCoreDump(LPCWSTR filename, LPEXCEPTION_POINTERS info) {
|
static void UExceptionCoreDump(LPCWSTR filename, LPEXCEPTION_POINTERS info) {
|
||||||
// open file and write
|
// open file and write
|
||||||
HANDLE hFile = CreateFileW(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
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) {
|
static LONG WINAPI UExceptionImpl(LPEXCEPTION_POINTERS info) {
|
||||||
// detect loop calling
|
// detect loop calling
|
||||||
if (g_IsProcessing) {
|
if (g_IsProcessing) goto end_proc;
|
||||||
goto end_proc;
|
|
||||||
}
|
|
||||||
// start process
|
// start process
|
||||||
g_IsProcessing = true;
|
g_IsProcessing = true;
|
||||||
|
|
||||||
|
|
|
@ -1,25 +1,22 @@
|
||||||
#include "IOHelper.hpp"
|
#include "IOHelper.hpp"
|
||||||
#if YYCC_OS == YYCC_OS_WINDOWS
|
|
||||||
|
|
||||||
#include "EncodingHelper.hpp"
|
#include "EncodingHelper.hpp"
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
#if YYCC_OS == YYCC_OS_WINDOWS
|
||||||
#include "WinImportPrefix.hpp"
|
#include "WinImportPrefix.hpp"
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <io.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include "WinImportSuffix.hpp"
|
#include "WinImportSuffix.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace YYCC::IOHelper {
|
namespace YYCC::IOHelper {
|
||||||
|
|
||||||
bool futf8(FILE* fs) {
|
FILE* UTF8FOpen(const char* u8_filepath, const char* u8_mode) {
|
||||||
// https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/setmode?view=msvc-170
|
#if YYCC_OS == YYCC_OS_WINDOWS
|
||||||
return _setmode(_fileno(fs), _O_U8TEXT) != -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
FILE* fopen(const char* u8_filepath, const char* u8_mode) {
|
|
||||||
// convert mode and file path to wchar
|
// convert mode and file path to wchar
|
||||||
std::wstring wmode, wpath;
|
std::wstring wmode, wpath;
|
||||||
if (!YYCC::EncodingHelper::UTF8ToWchar(u8_mode, wmode))
|
if (!YYCC::EncodingHelper::UTF8ToWchar(u8_mode, wmode))
|
||||||
|
@ -29,8 +26,28 @@ namespace YYCC::IOHelper {
|
||||||
|
|
||||||
// call microsoft specified fopen which support wchar as argument.
|
// call microsoft specified fopen which support wchar as argument.
|
||||||
return _wfopen(wpath.c_str(), wmode.c_str());
|
return _wfopen(wpath.c_str(), wmode.c_str());
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
#else
|
||||||
|
return std::fopen(u8_filepath, u8_mode);
|
||||||
#endif
|
#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
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,48 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "YYCCInternal.hpp"
|
#include "YYCCInternal.hpp"
|
||||||
#if YYCC_OS == YYCC_OS_WINDOWS
|
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
namespace YYCC::IOHelper {
|
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.
|
* @brief The left-padding zero format string of HEX-printed pointer type.
|
||||||
* @param fs[in] The FILE* need to be set as UTF8 mode.
|
* @details
|
||||||
* @return True if success, otherwise false.
|
* When printing a pointer with HEX style, we always hope it can be left-padded with some zero for easy reading.
|
||||||
* @warning Once this function success, you can not use any narrow char function on this FILE*,
|
* In different architecture, the size of this padding is differnet too so we create this macro.
|
||||||
* such as std::fputs, std::fprintf and etc. You only can use wide char function on it,
|
* \n
|
||||||
* or use the functions provided in this namespace by providing UTF8 string as their argument.
|
* 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
|
|
||||||
|
|
|
@ -216,7 +216,7 @@ namespace YYCCTestbench {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WinFctTestbench() {
|
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("Temp Directory: %s", YYCC::WinFctHelper::GetTempDirectory().c_str());
|
||||||
Console::WriteLine("Current Module Name: %s", YYCC::WinFctHelper::GetModuleName(YYCC::WinFctHelper::GetCurrentModule()).c_str());
|
Console::WriteLine("Current Module Name: %s", YYCC::WinFctHelper::GetModuleName(YYCC::WinFctHelper::GetCurrentModule()).c_str());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user