Full unicode hotfix Debug mode

This commit is contained in:
rtw1x1
2025-12-26 16:02:34 +00:00
parent 4729dafc12
commit 5d73d79eb8
2 changed files with 228 additions and 191 deletions

View File

@@ -2,6 +2,9 @@
#include <time.h> #include <time.h>
#include <stdio.h> #include <stdio.h>
#include <stdarg.h>
#include <string>
#include "Debug.h" #include "Debug.h"
#include "Singleton.h" #include "Singleton.h"
#include "Timer.h" #include "Timer.h"
@@ -13,228 +16,252 @@ const DWORD DEBUG_STRING_MAX_LEN = 1024;
static int isLogFile = false; static int isLogFile = false;
HWND g_PopupHwnd = NULL; HWND g_PopupHwnd = NULL;
// Convert UTF-8 char* -> wide and send to debugger (NO helper function, just a macro)
#ifdef _DEBUG
#define DBG_OUT_W_UTF8(psz) \
do { \
const char* __s = (psz) ? (psz) : ""; \
std::wstring __w = Utf8ToWide(__s); \
OutputDebugStringW(__w.c_str()); \
} while (0)
#else
#define DBG_OUT_W_UTF8(psz) do { (void)(psz); } while (0)
#endif
class CLogFile : public CSingleton<CLogFile> class CLogFile : public CSingleton<CLogFile>
{ {
public: public:
CLogFile() : m_fp(NULL) CLogFile() : m_fp(NULL) {}
{
}
virtual ~CLogFile() virtual ~CLogFile()
{ {
if (m_fp) if (m_fp)
fclose(m_fp); fclose(m_fp);
m_fp = NULL; m_fp = NULL;
} }
void Initialize() void Initialize()
{ {
m_fp = fopen("log/log.txt", "w"); m_fp = fopen("log/log.txt", "w");
} }
void Write(const char * c_pszMsg) void Write(const char* c_pszMsg)
{ {
if (!m_fp) if (!m_fp)
return; return;
time_t ct = time(0); time_t ct = time(0);
struct tm ctm = *localtime(&ct); struct tm ctm = *localtime(&ct);
fprintf(m_fp, "%02d%02d %02d:%02d:%05d :: %s", fprintf(m_fp, "%02d%02d %02d:%02d:%05d :: %s",
ctm.tm_mon + 1, ctm.tm_mon + 1,
ctm.tm_mday, ctm.tm_mday,
ctm.tm_hour, ctm.tm_hour,
ctm.tm_min, ctm.tm_min,
ELTimer_GetMSec() % 60000, ELTimer_GetMSec() % 60000,
c_pszMsg); c_pszMsg);
fflush(m_fp); fflush(m_fp);
} }
protected: protected:
FILE * m_fp; FILE* m_fp;
}; };
static CLogFile gs_logfile; static CLogFile gs_logfile;
static UINT gs_uLevel=0; static UINT gs_uLevel = 0;
void SetLogLevel(UINT uLevel) void SetLogLevel(UINT uLevel)
{ {
gs_uLevel=uLevel; gs_uLevel = uLevel;
} }
void Log(UINT uLevel, const char* c_szMsg) void Log(UINT uLevel, const char* c_szMsg)
{ {
if (uLevel>=gs_uLevel) if (uLevel >= gs_uLevel)
Trace(c_szMsg); Trace(c_szMsg);
} }
void Logn(UINT uLevel, const char* c_szMsg) void Logn(UINT uLevel, const char* c_szMsg)
{ {
if (uLevel>=gs_uLevel) if (uLevel >= gs_uLevel)
Tracen(c_szMsg); Tracen(c_szMsg);
} }
void Logf(UINT uLevel, const char* c_szFormat, ...) void Logf(UINT uLevel, const char* c_szFormat, ...)
{ {
if (uLevel<gs_uLevel) if (uLevel < gs_uLevel)
return; return;
char szBuf[DEBUG_STRING_MAX_LEN+1]; char szBuf[DEBUG_STRING_MAX_LEN + 1];
va_list args;
va_start(args, c_szFormat);
_vsnprintf_s(szBuf, sizeof(szBuf), _TRUNCATE, c_szFormat, args);
va_end(args);
va_list args;
va_start(args, c_szFormat);
_vsnprintf(szBuf, sizeof(szBuf), c_szFormat, args);
va_end(args);
#ifdef _DEBUG #ifdef _DEBUG
OutputDebugString(szBuf); DBG_OUT_W_UTF8(szBuf);
fputs(szBuf, stdout); fputs(szBuf, stdout);
#endif #endif
if (isLogFile) if (isLogFile)
LogFile(szBuf); LogFile(szBuf);
} }
void Lognf(UINT uLevel, const char* c_szFormat, ...) void Lognf(UINT uLevel, const char* c_szFormat, ...)
{ {
if (uLevel<gs_uLevel) if (uLevel < gs_uLevel)
return; return;
va_list args; char szBuf[DEBUG_STRING_MAX_LEN + 2];
va_start(args, c_szFormat);
char szBuf[DEBUG_STRING_MAX_LEN+2]; va_list args;
int len = _vsnprintf(szBuf, sizeof(szBuf)-1, c_szFormat, args); va_start(args, c_szFormat);
_vsnprintf_s(szBuf, sizeof(szBuf), _TRUNCATE, c_szFormat, args);
va_end(args);
size_t cur = strnlen(szBuf, sizeof(szBuf));
if (cur + 1 < sizeof(szBuf)) {
szBuf[cur] = '\n';
szBuf[cur + 1] = '\0';
}
else {
szBuf[sizeof(szBuf) - 2] = '\n';
szBuf[sizeof(szBuf) - 1] = '\0';
}
if (len > 0)
{
szBuf[len] = '\n';
szBuf[len + 1] = '\0';
}
va_end(args);
#ifdef _DEBUG #ifdef _DEBUG
OutputDebugString(szBuf); DBG_OUT_W_UTF8(szBuf);
puts(szBuf); fputs(szBuf, stdout);
#endif #endif
if (isLogFile) if (isLogFile)
LogFile(szBuf); LogFile(szBuf);
} }
void Trace(const char* c_szMsg)
void Trace(const char * c_szMsg)
{ {
#ifdef _DEBUG #ifdef _DEBUG
OutputDebugString(c_szMsg); DBG_OUT_W_UTF8(c_szMsg);
printf("%s", c_szMsg); printf("%s", c_szMsg ? c_szMsg : "");
#endif #endif
if (isLogFile) if (isLogFile)
LogFile(c_szMsg); LogFile(c_szMsg ? c_szMsg : "");
} }
void Tracen(const char* c_szMsg) void Tracen(const char* c_szMsg)
{ {
#ifdef _DEBUG #ifdef _DEBUG
char szBuf[DEBUG_STRING_MAX_LEN+1]; char szBuf[DEBUG_STRING_MAX_LEN + 2];
_snprintf(szBuf, sizeof(szBuf), "%s\n", c_szMsg); _snprintf_s(szBuf, sizeof(szBuf), _TRUNCATE, "%s\n", c_szMsg ? c_szMsg : "");
OutputDebugString(szBuf);
puts(c_szMsg);
if (isLogFile) DBG_OUT_W_UTF8(szBuf);
LogFile(szBuf);
puts(c_szMsg); fputs(szBuf, stdout);
putc('\n', stdout);
if (isLogFile)
LogFile(szBuf);
#else #else
if (isLogFile) if (isLogFile)
{ {
LogFile(c_szMsg); LogFile(c_szMsg ? c_szMsg : "");
LogFile("\n"); LogFile("\n");
} }
#endif #endif
} }
void Tracenf(const char* c_szFormat, ...) void Tracenf(const char* c_szFormat, ...)
{ {
va_list args; char szBuf[DEBUG_STRING_MAX_LEN + 2];
va_start(args, c_szFormat);
char szBuf[DEBUG_STRING_MAX_LEN+2]; va_list args;
int len = _vsnprintf(szBuf, sizeof(szBuf)-1, c_szFormat, args); va_start(args, c_szFormat);
_vsnprintf_s(szBuf, sizeof(szBuf), _TRUNCATE, c_szFormat, args);
va_end(args);
size_t cur = strnlen(szBuf, sizeof(szBuf));
if (cur + 1 < sizeof(szBuf)) {
szBuf[cur] = '\n';
szBuf[cur + 1] = '\0';
}
else {
szBuf[sizeof(szBuf) - 2] = '\n';
szBuf[sizeof(szBuf) - 1] = '\0';
}
if (len > 0)
{
szBuf[len] = '\n';
szBuf[len + 1] = '\0';
}
va_end(args);
#ifdef _DEBUG #ifdef _DEBUG
OutputDebugString(szBuf); DBG_OUT_W_UTF8(szBuf);
printf("%s", szBuf); fputs(szBuf, stdout);
#endif #endif
if (isLogFile) if (isLogFile)
LogFile(szBuf); LogFile(szBuf);
} }
void Tracef(const char* c_szFormat, ...) void Tracef(const char* c_szFormat, ...)
{ {
char szBuf[DEBUG_STRING_MAX_LEN+1]; char szBuf[DEBUG_STRING_MAX_LEN + 1];
va_list args; va_list args;
va_start(args, c_szFormat); va_start(args, c_szFormat);
_vsnprintf(szBuf, sizeof(szBuf), c_szFormat, args); _vsnprintf_s(szBuf, sizeof(szBuf), _TRUNCATE, c_szFormat, args);
va_end(args); va_end(args);
#ifdef _DEBUG #ifdef _DEBUG
OutputDebugString(szBuf); DBG_OUT_W_UTF8(szBuf);
fputs(szBuf, stdout); fputs(szBuf, stdout);
#endif #endif
if (isLogFile) if (isLogFile)
LogFile(szBuf); LogFile(szBuf);
} }
void TraceError(const char* c_szFormat, ...) void TraceError(const char* c_szFormat, ...)
{ {
#ifndef _DISTRIBUTE #ifndef _DISTRIBUTE
char szBuf[DEBUG_STRING_MAX_LEN + 2];
char szBuf[DEBUG_STRING_MAX_LEN+2]; strncpy_s(szBuf, sizeof(szBuf), "SYSERR: ", _TRUNCATE);
int prefixLen = (int)strlen(szBuf);
strncpy(szBuf, "SYSERR: ", DEBUG_STRING_MAX_LEN); va_list args;
int len = strlen(szBuf); va_start(args, c_szFormat);
_vsnprintf_s(szBuf + prefixLen, sizeof(szBuf) - prefixLen, _TRUNCATE, c_szFormat, args);
va_end(args);
va_list args; size_t cur = strnlen(szBuf, sizeof(szBuf));
va_start(args, c_szFormat); if (cur + 1 < sizeof(szBuf)) {
len = _vsnprintf(szBuf + len, sizeof(szBuf) - (len + 1), c_szFormat, args) + len; szBuf[cur] = '\n';
va_end(args); szBuf[cur + 1] = '\0';
}
else {
szBuf[sizeof(szBuf) - 2] = '\n';
szBuf[sizeof(szBuf) - 1] = '\0';
}
szBuf[len] = '\n'; time_t ct = time(0);
szBuf[len + 1] = '\0'; struct tm ctm = *localtime(&ct);
time_t ct = time(0); fprintf(stderr, "%02d%02d %02d:%02d:%05d :: %s",
struct tm ctm = *localtime(&ct); ctm.tm_mon + 1,
ctm.tm_mday,
ctm.tm_hour,
ctm.tm_min,
ELTimer_GetMSec() % 60000,
szBuf + 8);
fflush(stderr);
fprintf(stderr, "%02d%02d %02d:%02d:%05d :: %s",
ctm.tm_mon + 1,
ctm.tm_mday,
ctm.tm_hour,
ctm.tm_min,
ELTimer_GetMSec() % 60000,
szBuf + 8);
fflush(stderr);
#ifdef _DEBUG #ifdef _DEBUG
OutputDebugString(szBuf); DBG_OUT_W_UTF8(szBuf);
fputs(szBuf, stdout); fputs(szBuf, stdout);
#endif #endif
if (isLogFile) if (isLogFile)
LogFile(szBuf); LogFile(szBuf);
#endif #endif
} }
@@ -242,96 +269,101 @@ void TraceErrorWithoutEnter(const char* c_szFormat, ...)
{ {
#ifndef _DISTRIBUTE #ifndef _DISTRIBUTE
char szBuf[DEBUG_STRING_MAX_LEN]; char szBuf[DEBUG_STRING_MAX_LEN];
va_list args; va_list args;
va_start(args, c_szFormat); va_start(args, c_szFormat);
_vsnprintf(szBuf, sizeof(szBuf), c_szFormat, args); _vsnprintf_s(szBuf, sizeof(szBuf), _TRUNCATE, c_szFormat, args);
va_end(args); va_end(args);
time_t ct = time(0); time_t ct = time(0);
struct tm ctm = *localtime(&ct); struct tm ctm = *localtime(&ct);
fprintf(stderr, "%02d%02d %02d:%02d:%05d :: %s", fprintf(stderr, "%02d%02d %02d:%02d:%05d :: %s",
ctm.tm_mon + 1, ctm.tm_mon + 1,
ctm.tm_mday, ctm.tm_mday,
ctm.tm_hour, ctm.tm_hour,
ctm.tm_min, ctm.tm_min,
ELTimer_GetMSec() % 60000, ELTimer_GetMSec() % 60000,
szBuf + 8); szBuf + 8);
fflush(stderr); fflush(stderr);
#ifdef _DEBUG #ifdef _DEBUG
OutputDebugString(szBuf); DBG_OUT_W_UTF8(szBuf);
fputs(szBuf, stdout); fputs(szBuf, stdout);
#endif #endif
if (isLogFile) if (isLogFile)
LogFile(szBuf); LogFile(szBuf);
#endif #endif
} }
void LogBoxf(const char* c_szFormat, ...) void LogBoxf(const char* c_szFormat, ...)
{ {
va_list args; va_list args;
va_start(args, c_szFormat); va_start(args, c_szFormat);
char szBuf[2048]; char szBuf[2048];
_vsnprintf(szBuf, sizeof(szBuf), c_szFormat, args); _vsnprintf_s(szBuf, sizeof(szBuf), _TRUNCATE, c_szFormat, args);
LogBox(szBuf); va_end(args);
LogBox(szBuf);
} }
void LogBox(const char* c_szMsg, const char* c_szCaption, HWND hWnd) void LogBox(const char* c_szMsg, const char* c_szCaption, HWND hWnd)
{ {
if (!hWnd) if (!hWnd)
hWnd = g_PopupHwnd; hWnd = g_PopupHwnd;
std::wstring wMsg = Utf8ToWide(c_szMsg ? c_szMsg : ""); std::wstring wMsg = Utf8ToWide(c_szMsg ? c_szMsg : "");
std::wstring wCaption = Utf8ToWide(c_szCaption ? c_szCaption : "LOG"); std::wstring wCaption = Utf8ToWide(c_szCaption ? c_szCaption : "LOG");
MessageBoxW(hWnd, wMsg.c_str(), wCaption.c_str(), MB_OK); MessageBoxW(hWnd, wMsg.c_str(), wCaption.c_str(), MB_OK);
// Logging stays UTF-8 // Logging stays UTF-8
Tracen(c_szMsg ? c_szMsg : ""); Tracen(c_szMsg ? c_szMsg : "");
} }
void LogFile(const char * c_szMsg) void LogFile(const char* c_szMsg)
{ {
CLogFile::Instance().Write(c_szMsg); CLogFile::Instance().Write(c_szMsg);
} }
void LogFilef(const char * c_szMessage, ...) void LogFilef(const char* c_szMessage, ...)
{ {
va_list args; va_list args;
va_start(args, c_szMessage); va_start(args, c_szMessage);
char szBuf[DEBUG_STRING_MAX_LEN+1];
_vsnprintf(szBuf, sizeof(szBuf), c_szMessage, args);
CLogFile::Instance().Write(szBuf); char szBuf[DEBUG_STRING_MAX_LEN + 1];
_vsnprintf_s(szBuf, sizeof(szBuf), _TRUNCATE, c_szMessage, args);
va_end(args);
CLogFile::Instance().Write(szBuf);
} }
void OpenLogFile(bool bUseLogFIle) void OpenLogFile(bool bUseLogFIle)
{ {
if (!std::filesystem::exists("log")) { if (!std::filesystem::exists("log")) {
std::filesystem::create_directory("log"); std::filesystem::create_directory("log");
} }
#ifndef _DISTRIBUTE #ifndef _DISTRIBUTE
_wfreopen(L"log/syserr.txt", L"w", stderr); _wfreopen(L"log/syserr.txt", L"w", stderr);
if (bUseLogFIle) if (bUseLogFIle)
{ {
isLogFile = true; isLogFile = true;
CLogFile::Instance().Initialize(); CLogFile::Instance().Initialize();
} }
#endif #endif
} }
void OpenConsoleWindow() void OpenConsoleWindow()
{ {
AllocConsole(); AllocConsole();
_wfreopen(L"CONOUT$", L"a", stdout); _wfreopen(L"CONOUT$", L"a", stdout);
_wfreopen(L"CONIN$", L"r", stdin); _wfreopen(L"CONIN$", L"r", stdin);
} }

View File

@@ -24,16 +24,21 @@
inline void _TraceForImage(const char* c_szFormat, ...) inline void _TraceForImage(const char* c_szFormat, ...)
{ {
va_list args; va_list args;
va_start(args, c_szFormat); va_start(args, c_szFormat);
static char szBuf[1024]; static char szBuf[1024];
_vsnprintf(szBuf, sizeof(szBuf), c_szFormat, args); _vsnprintf_s(szBuf, sizeof(szBuf), _TRUNCATE, c_szFormat, args);
#ifdef _DEBUG #ifdef _DEBUG
OutputDebugString(szBuf); wchar_t wBuf[1024];
MultiByteToWideChar(CP_UTF8, 0, szBuf, -1, wBuf, _countof(wBuf));
OutputDebugStringW(wBuf);
#endif #endif
va_end(args);
printf(szBuf); va_end(args);
fputs(szBuf, stdout);
} }
#pragma warning(default:4018) #pragma warning(default:4018)