361 lines
7.1 KiB
C++
361 lines
7.1 KiB
C++
// Platform implementation of EterBase/Debug.h (40250 EterBase/Debug.cpp), the non-_DEBUG build: Log*/Trace*
|
|
// reach log.txt only after OpenLogFile(true), TraceError goes to stderr (syserr.txt after OpenLogFile). The
|
|
// MT_PLATFORM_STUB() bodies left are the _DEBUG console and the Debug.h declarations 40250 never defines.
|
|
#include "EterBase/StdAfx.h"
|
|
#include "EterBase/Debug.h"
|
|
|
|
#include "../PlatformStub.h"
|
|
#include "EterBase/Timer.h"
|
|
#include "EterBase/Singleton.h"
|
|
#include "LogBox.h"
|
|
#include "TraceErrorObserver.h"
|
|
|
|
#include <cstdarg>
|
|
#include <cstdio>
|
|
#include <ctime>
|
|
#include <string>
|
|
|
|
const DWORD DEBUG_STRING_MAX_LEN = 1024;
|
|
|
|
namespace
|
|
{
|
|
TraceErrorObserver g_trace_error_observer = nullptr;
|
|
}
|
|
|
|
void SetTraceErrorObserver(TraceErrorObserver observer)
|
|
{
|
|
g_trace_error_observer = observer;
|
|
}
|
|
|
|
// 40250 Debug.cpp:11
|
|
static int isLogFile = false;
|
|
HWND g_PopupHwnd = NULL;
|
|
|
|
// 40250 Debug.cpp:14
|
|
class CLogFile : public CSingleton<CLogFile>
|
|
{
|
|
public:
|
|
CLogFile() : m_fp(NULL)
|
|
{
|
|
}
|
|
|
|
virtual ~CLogFile()
|
|
{
|
|
if (m_fp)
|
|
fclose(m_fp);
|
|
|
|
m_fp = NULL;
|
|
}
|
|
|
|
void Initialize()
|
|
{
|
|
m_fp = fopen("log.txt", "w");
|
|
}
|
|
|
|
void Write(const char * c_pszMsg)
|
|
{
|
|
if (!m_fp)
|
|
return;
|
|
|
|
time_t ct = time(0);
|
|
struct tm ctm = *localtime(&ct);
|
|
|
|
fprintf(m_fp, "%02d%02d %02d:%02d:%05d :: %s",
|
|
ctm.tm_mon + 1,
|
|
ctm.tm_mday,
|
|
ctm.tm_hour,
|
|
ctm.tm_min,
|
|
ELTimer_GetMSec() % 60000,
|
|
c_pszMsg);
|
|
|
|
fflush(m_fp);
|
|
}
|
|
|
|
protected:
|
|
FILE * m_fp;
|
|
};
|
|
|
|
static CLogFile gs_logfile;
|
|
|
|
static UINT gs_uLevel=0;
|
|
|
|
// 40250 Debug.cpp:61. The Log*/Trace* bodies are the non-_DEBUG build: they only reach log.txt, which
|
|
// OpenLogFile(true) opens (40250 does that in _DEBUG builds only).
|
|
void SetLogLevel(UINT uLevel)
|
|
{
|
|
gs_uLevel=uLevel;
|
|
}
|
|
|
|
void Log(UINT uLevel, const char* c_szMsg)
|
|
{
|
|
if (uLevel>=gs_uLevel)
|
|
Trace(c_szMsg);
|
|
}
|
|
|
|
void Logn(UINT uLevel, const char* c_szMsg)
|
|
{
|
|
if (uLevel>=gs_uLevel)
|
|
Tracen(c_szMsg);
|
|
}
|
|
|
|
void Logf(UINT uLevel, const char* c_szFormat, ...)
|
|
{
|
|
if (uLevel<gs_uLevel)
|
|
return;
|
|
|
|
char szBuf[DEBUG_STRING_MAX_LEN+1];
|
|
|
|
va_list args;
|
|
va_start(args, c_szFormat);
|
|
_vsnprintf(szBuf, sizeof(szBuf), c_szFormat, args);
|
|
va_end(args);
|
|
szBuf[DEBUG_STRING_MAX_LEN] = '\0'; // PORT: _vsnprintf does not terminate on truncation
|
|
|
|
if (isLogFile)
|
|
LogFile(szBuf);
|
|
}
|
|
|
|
void Lognf(UINT uLevel, const char* c_szFormat, ...)
|
|
{
|
|
if (uLevel<gs_uLevel)
|
|
return;
|
|
|
|
va_list args;
|
|
va_start(args, c_szFormat);
|
|
|
|
char szBuf[DEBUG_STRING_MAX_LEN+2];
|
|
int len = _vsnprintf(szBuf, sizeof(szBuf)-1, c_szFormat, args);
|
|
|
|
if (len > 0)
|
|
{
|
|
szBuf[len] = '\n';
|
|
szBuf[len + 1] = '\0';
|
|
}
|
|
va_end(args);
|
|
|
|
if (isLogFile)
|
|
LogFile(szBuf);
|
|
}
|
|
|
|
|
|
void Trace(const char * c_szMsg)
|
|
{
|
|
if (isLogFile)
|
|
LogFile(c_szMsg);
|
|
}
|
|
|
|
void Tracen(const char* c_szMsg)
|
|
{
|
|
if (isLogFile)
|
|
{
|
|
LogFile(c_szMsg);
|
|
LogFile("\n");
|
|
}
|
|
}
|
|
|
|
void Tracenf(const char* c_szFormat, ...)
|
|
{
|
|
va_list args;
|
|
va_start(args, c_szFormat);
|
|
|
|
char szBuf[DEBUG_STRING_MAX_LEN+2];
|
|
int len = _vsnprintf(szBuf, sizeof(szBuf)-1, c_szFormat, args);
|
|
|
|
if (len > 0)
|
|
{
|
|
szBuf[len] = '\n';
|
|
szBuf[len + 1] = '\0';
|
|
}
|
|
va_end(args);
|
|
|
|
if (isLogFile)
|
|
LogFile(szBuf);
|
|
}
|
|
|
|
void Tracef(const char* c_szFormat, ...)
|
|
{
|
|
char szBuf[DEBUG_STRING_MAX_LEN+1];
|
|
|
|
va_list args;
|
|
va_start(args, c_szFormat);
|
|
_vsnprintf(szBuf, sizeof(szBuf), c_szFormat, args);
|
|
va_end(args);
|
|
szBuf[DEBUG_STRING_MAX_LEN] = '\0'; // PORT: _vsnprintf does not terminate on truncation
|
|
|
|
if (isLogFile)
|
|
LogFile(szBuf);
|
|
}
|
|
|
|
// 40250 Debug.cpp:199
|
|
void TraceError(const char* c_szFormat, ...)
|
|
{
|
|
#ifndef _DISTRIBUTE
|
|
char szBuf[DEBUG_STRING_MAX_LEN+2];
|
|
|
|
strncpy(szBuf, "SYSERR: ", DEBUG_STRING_MAX_LEN);
|
|
int len = strlen(szBuf);
|
|
|
|
va_list args;
|
|
va_start(args, c_szFormat);
|
|
len = _vsnprintf(szBuf + len, sizeof(szBuf) - (len + 1), c_szFormat, args) + len;
|
|
va_end(args);
|
|
|
|
// PORT: _vsnprintf returns -1 on truncation; 40250 then writes the terminator before the buffer.
|
|
if (len < 8)
|
|
len = DEBUG_STRING_MAX_LEN;
|
|
|
|
szBuf[len] = '\n';
|
|
szBuf[len + 1] = '\0';
|
|
|
|
time_t ct = time(0);
|
|
struct tm ctm = *localtime(&ct);
|
|
|
|
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);
|
|
if (g_trace_error_observer)
|
|
g_trace_error_observer(szBuf + 8);
|
|
|
|
if (isLogFile)
|
|
LogFile(szBuf);
|
|
#endif
|
|
}
|
|
|
|
// 40250 Debug.cpp:239. It prints from szBuf + 8 although nothing is prepended (TraceError's "SYSERR: "
|
|
// offset); there is no caller in 40250.
|
|
void TraceErrorWithoutEnter(const char* c_szFormat, ...)
|
|
{
|
|
#ifndef _DISTRIBUTE
|
|
|
|
char szBuf[DEBUG_STRING_MAX_LEN];
|
|
|
|
va_list args;
|
|
va_start(args, c_szFormat);
|
|
_vsnprintf(szBuf, sizeof(szBuf), c_szFormat, args);
|
|
va_end(args);
|
|
szBuf[DEBUG_STRING_MAX_LEN - 1] = '\0'; // PORT: _vsnprintf does not terminate on truncation
|
|
|
|
time_t ct = time(0);
|
|
struct tm ctm = *localtime(&ct);
|
|
|
|
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);
|
|
|
|
if (isLogFile)
|
|
LogFile(szBuf);
|
|
#endif
|
|
}
|
|
|
|
namespace
|
|
{
|
|
std::string& log_box_message()
|
|
{
|
|
static std::string message;
|
|
return message;
|
|
}
|
|
}
|
|
|
|
const std::string& LastLogBoxMessage()
|
|
{
|
|
return log_box_message();
|
|
}
|
|
|
|
void ClearLogBoxMessage()
|
|
{
|
|
log_box_message().clear();
|
|
}
|
|
|
|
void LogBox(const char * c_szMsg, const char * c_szCaption, HWND)
|
|
{
|
|
// 40250 pops a MessageBox on g_PopupHwnd and Tracen()s the text. There is no window here and no
|
|
// log file yet, so stderr is the whole of it; the text is also kept for the caller (LogBox.h),
|
|
// because it is the only place a script traceback survives.
|
|
std::string& message = log_box_message();
|
|
message = c_szCaption ? c_szCaption : "LOG";
|
|
message += ": ";
|
|
message += c_szMsg ? c_szMsg : "";
|
|
|
|
fprintf(stderr, "%s\n", message.c_str());
|
|
fflush(stderr);
|
|
Tracen(c_szMsg);
|
|
}
|
|
|
|
void LogBoxf(const char * c_szFormat, ...)
|
|
{
|
|
va_list args;
|
|
va_start(args, c_szFormat);
|
|
|
|
char szBuf[2048];
|
|
_vsnprintf(szBuf, sizeof(szBuf), c_szFormat, args);
|
|
va_end(args); // PORT: 40250 leaks the va_list; on this ABI va_end is not optional
|
|
|
|
// PORT: _vsnprintf does not terminate on truncation.
|
|
szBuf[sizeof(szBuf) - 1] = '\0';
|
|
LogBox(szBuf);
|
|
}
|
|
|
|
// 40250 Debug.cpp:292
|
|
void LogFile(const char * c_szMsg)
|
|
{
|
|
CLogFile::Instance().Write(c_szMsg);
|
|
}
|
|
|
|
void LogFilef(const char * c_szMessage, ...)
|
|
{
|
|
va_list args;
|
|
va_start(args, c_szMessage);
|
|
char szBuf[DEBUG_STRING_MAX_LEN+1];
|
|
_vsnprintf(szBuf, sizeof(szBuf), c_szMessage, args);
|
|
va_end(args); // PORT: 40250 leaks the va_list
|
|
szBuf[DEBUG_STRING_MAX_LEN] = '\0'; // PORT: _vsnprintf does not terminate on truncation
|
|
|
|
CLogFile::Instance().Write(szBuf);
|
|
}
|
|
|
|
// 40250 Debug.cpp:320: AllocConsole + CONOUT$/CONIN$, called by the _DEBUG WinMain only. The host
|
|
// process already has its terminal (or logcat).
|
|
auto OpenConsoleWindow() -> void
|
|
{
|
|
MT_PLATFORM_STUB();
|
|
}
|
|
|
|
auto CloseConsoleWindow() -> void
|
|
{
|
|
MT_PLATFORM_STUB();
|
|
}
|
|
|
|
auto SetupLog() -> void
|
|
{
|
|
MT_PLATFORM_STUB();
|
|
}
|
|
|
|
// 40250 Debug.cpp:307
|
|
void OpenLogFile(bool bUseLogFIle)
|
|
{
|
|
#ifndef _DISTRIBUTE
|
|
freopen("syserr.txt", "w", stderr);
|
|
|
|
if (bUseLogFIle)
|
|
{
|
|
isLogFile = true;
|
|
CLogFile::Instance().Initialize();
|
|
}
|
|
#endif
|
|
}
|
|
|
|
auto CloseLogFile() -> void
|
|
{
|
|
MT_PLATFORM_STUB();
|
|
}
|