__inline static void OUTPUT_DEBUG_TRACE_A(LPCSTR lpszFormat, ...)
{
va_list args;
size_t size = 0;
LPSTR lpt = NULL;
va_start(args, lpszFormat);
size = _vscprintf(lpszFormat, args);
if (size > 0)
{
size++;
lpt = (LPSTR)malloc(size * sizeof(CHAR));
if (lpt)
{
memset(lpt, 0, size * sizeof(CHAR));
_vsnprintf(lpt, size, lpszFormat, args);
OutputDebugStringA((LPCSTR)lpt);
free(lpt);
lpt = NULL;
}
}
va_end(args);
}
__inline static void OUTPUT_DEBUG_TRACE_W(LPCWSTR lpszFormat, ...)
{
va_list args;
size_t size = 0;
LPWSTR lpt = NULL;
va_start(args, lpszFormat);
size = _vscwprintf(lpszFormat, args);
if (size > 0)
{
size++;
lpt = (LPWSTR)malloc(size * sizeof(WCHAR));
if (lpt)
{
memset(lpt, 0, size * sizeof(WCHAR));
_vsnwprintf(lpt, size, lpszFormat, args);
OutputDebugStringW((LPCWSTR)lpt);
free(lpt);
lpt = NULL;
}
}
va_end(args);
}
////////////////////////////////////////////////////////////////////////////////////
// 五个级别
// DEBUG Level : 指出细粒度信息事件对调试应用程序是非常有帮助的, 就是输出debug的信息.
// INFO level : 表明消息在粗粒度级别上突出强调应用程序的运行过程, 就是输出提示信息.
// WARN level : 表明会出现潜在错误的情形, 就是显示警告信息.
// ERROR level : 指出虽然发生错误事件, 但仍然不影响系统的继续运行.就是显示错误信息.
// FATAL level : 指出每个严重的错误事件将会导致应用程序的退出.
// 两个开关
// ALL level : 是最低等级的, 用于打开所有日志记录.
// OFF level : 是最高等级的, 用于关闭所有日志记录.
__inline static void TRACE_PRINT_A(FILE * fStream, LPCSTR lpType, LPCSTR lpszFormat, ...)
{
va_list args;
size_t size = 0;
LPSTR lpt = NULL;
WORD wAttributes = 0;
switch (*(lpType + sizeof(BYTE)))
{
case ('D'):
{
wAttributes = FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY;
}
break;
case ('I'):
{
wAttributes = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY;
}
break;
case ('W'):
{
wAttributes = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
}
break;
case ('E'):
{
wAttributes = FOREGROUND_RED;
}
break;
case ('F'):
{
wAttributes = FOREGROUND_GREEN | FOREGROUND_INTENSITY;
}
break;
default:
{
return;
}
break;
}
va_start(args, lpszFormat);
size = _vscprintf_p(lpszFormat, args);
if (size > 0)
{
size++;
lpt = (LPSTR)malloc(size * sizeof(CHAR));
if (lpt)
{
memset(lpt, 0, size * sizeof(CHAR));
_vsnprintf(lpt, size, lpszFormat, args);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), wAttributes);
fprintf(fStream, ("%s%s"), lpType, lpt);
free(lpt);
lpt = NULL;
}
}
va_end(args);
}
__inline static void TRACE_PRINT_W(FILE * fStream, LPCWSTR lpType, LPCWSTR lpszFormat, ...)
{
va_list args;
size_t size = 0;
LPWSTR lpt = NULL;
WORD wAttributes = 0;
switch (*(lpType + sizeof(BYTE)))
{
case (L'D'):
{
wAttributes = FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY;
}
break;
case (L'I'):
{
wAttributes = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY;
}
break;
case (L'W'):
{
wAttributes = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
}
break;
case (L'E'):
{
wAttributes = FOREGROUND_RED;
}
break;
case (L'F'):
{
wAttributes = FOREGROUND_GREEN | FOREGROUND_INTENSITY;
}
break;
default:
{
return;
}
break;
}
va_start(args, lpszFormat);
size = _vscwprintf(lpszFormat, args);
if (size > 0)
{
size++;
lpt = (LPWSTR)malloc(size * sizeof(WCHAR));
if (lpt)
{
memset(lpt, 0, size * sizeof(WCHAR));
_vsnwprintf(lpt, size, lpszFormat, args);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), wAttributes);
fwprintf(fStream, (L"%s%s"), lpType, lpt);
free(lpt);
lpt = NULL;
}
}
va_end(args);
}
#if !defined(_UNICODE) && !defined(UNICODE)
#define OUTPUT_DEBUG_TRACE OUTPUT_DEBUG_TRACE_A
#define INFO_PRINT(lpszFormat, ...) TRACE_PRINT_A(stdout, ("[INFO]"), lpszFormat, __VA_ARGS__)
#define DEBUG_PRINT(lpszFormat, ...) TRACE_PRINT_A(stdout, ("[DEBUG]"), lpszFormat, __VA_ARGS__)
#define WARN_PRINT(lpszFormat, ...) TRACE_PRINT_A(stdout, ("[WARN]"), lpszFormat, __VA_ARGS__)
#define ERROR_PRINT(lpszFormat, ...) TRACE_PRINT_A(stderr, ("[ERROR]"), lpszFormat, __VA_ARGS__)
#define FATAL_PRINT(lpszFormat, ...) TRACE_PRINT_A(stderr, ("[FATAL]"), lpszFormat, __VA_ARGS__)
#else
#define OUTPUT_DEBUG_TRACE OUTPUT_DEBUG_TRACE_W
#define INFO_PRINT(lpszFormat, ...) TRACE_PRINT_W(stdout, (L"[INFO]"), lpszFormat, __VA_ARGS__)
#define DEBUG_PRINT(lpszFormat, ...) TRACE_PRINT_W(stdout, (L"[DEBUG]"), lpszFormat, __VA_ARGS__)
#define WARN_PRINT(lpszFormat, ...) TRACE_PRINT_W(stdout, (L"[WARN]"), lpszFormat, __VA_ARGS__)
#define ERROR_PRINT(lpszFormat, ...) TRACE_PRINT_W(stderr, (L"[ERROR]"), lpszFormat, __VA_ARGS__)
#define FATAL_PRINT(lpszFormat, ...) TRACE_PRINT_W(stderr, (L"[FATAL]"), lpszFormat, __VA_ARGS__)
#endif