Added new logging macros

Visual Studio figured out variadic macros around 2005, so we can
finally replace the explicit-arg-count debug log macros.

Also, fixed some include guards.

Also, bumped version to 4.0.0d1.
This commit is contained in:
Andy McFadden 2014-11-17 17:54:34 -08:00
parent 7da3dc0efe
commit d21ba553ab
23 changed files with 255 additions and 231 deletions

View File

@ -222,7 +222,7 @@ BEGIN
PUSHBUTTON "Enter registration code",IDC_ABOUT_ENTER_REG,144,132,86,14
CONTROL IDB_FSLOGO,IDC_STATIC,"Static",SS_BITMAP,7,6,64,59
LTEXT "CiderPress v%d.%d.%d%ls%ls",IDC_CIDERPRESS_VERS_TEXT,77,7,153,9
LTEXT "Copyright © 2009 by CiderPress project authors\rAll Rights Reserved.",IDC_STATIC,77,20,153,19
LTEXT "Copyright © 2014 by CiderPress project authors\rAll Rights Reserved.",IDC_STATIC,77,20,153,19
ICON IDR_MAINFRAME,IDC_STATIC,77,45,20,20
ICON IDI_FILE_NUFX,IDC_STATIC,106,45,20,20
ICON IDI_FILE_BINARY2,IDC_STATIC,136,45,20,20
@ -1299,12 +1299,12 @@ BEGIN
VALUE "Comments", "The end is nigh."
VALUE "CompanyName", "CiderPress Project"
VALUE "FileDescription", "CiderPress"
VALUE "FileVersion", "3, 0, 1, 0"
VALUE "FileVersion", "4, 0, 0, 0"
VALUE "InternalName", "CiderPress"
VALUE "LegalCopyright", "Copyright © 2009 CiderPress project authors"
VALUE "LegalCopyright", "Copyright © 2014 CiderPress project authors"
VALUE "OriginalFilename", "CiderPress.exe"
VALUE "ProductName", "CiderPress"
VALUE "ProductVersion", "3, 0, 1, 0"
VALUE "ProductVersion", "4, 0, 0, 0"
END
END
BLOCK "VarFileInfo"

View File

@ -446,14 +446,7 @@ DiskArchive::DebugMsgHandler(const char* file, int line, const char* msg)
ASSERT(file != nil);
ASSERT(msg != nil);
#if defined(_DEBUG_LOG)
//fprintf(gLog, "%s(%d) : %s", file, line, msg);
fprintf(gLog, "%05u %s", gPid, msg);
#elif defined(_DEBUG)
_CrtDbgReport(_CRT_WARN, file, line, NULL, "%s", msg);
#else
/* do nothing */
#endif
LOG_BASE(DebugLog::LOG_INFO, file, line, "<diskimg> %hs", msg);
}
/*

View File

@ -17,10 +17,8 @@
/* magic global that MFC finds (or that finds MFC) */
MyApp gMyApp;
#if defined(_DEBUG_LOG)
FILE* gLog = nil;
int gPid = -1;
#endif
DebugLog* gDebugLog;
/*
* Constructor. This is the closest thing to "main" that we have, but we
@ -28,36 +26,11 @@ int gPid = -1;
*/
MyApp::MyApp(LPCTSTR lpszAppName) : CWinApp(lpszAppName)
{
const int kStaleLog = 8 * 60 * 60;
gDebugLog = new DebugLog(L"C:\\src\\cplog.txt");
//fclose(fopen("c:\\cp-myapp.txt", "w"));
time_t now = time(nil);
time_t now;
now = time(nil);
#ifdef _DEBUG_LOG
PathName debugPath(kDebugLog);
time_t when = debugPath.GetModWhen();
if (when > 0 && now - when > kStaleLog) {
/* log file is more than 8 hours old, remove it */
/* [consider opening it and truncating with chsize() instead, so we
don't hose somebody's custom access permissions. ++ATM 20041015] */
unlink(kDebugLog);
}
gLog = fopen(kDebugLog, "a");
if (gLog == nil)
abort();
::setvbuf(gLog, nil, _IONBF, 0);
gPid = ::getpid();
fprintf(gLog, "\n");
if (when > 0) {
WMSG2("(Log file was %.3f hours old; logs are reset after %.3f)\n",
(now - when) / 3600.0, kStaleLog / 3600.0);
}
#endif
WMSG5("CiderPress v%d.%d.%d%s started at %.24hs\n",
LOGI("CiderPress v%d.%d.%d%ls started at %.24hs\n",
kAppMajorVersion, kAppMinorVersion, kAppBugVersion,
kAppDevString, ctime(&now));
@ -78,10 +51,7 @@ MyApp::~MyApp(void)
NiftyList::AppCleanup();
WMSG0("SHUTTING DOWN\n\n");
#ifdef _DEBUG_LOG
if (gLog != nil)
fclose(gLog);
#endif
delete gDebugLog;
}

View File

@ -11,16 +11,11 @@
#include "Registry.h"
#if defined(_DEBUG_LOG)
//#define kDebugLog "C:\\test\\cplog.txt"
#define kDebugLog L"C:\\cplog.txt"
#endif
/* CiderPress version numbers */
#define kAppMajorVersion 3
#define kAppMajorVersion 4
#define kAppMinorVersion 0
#define kAppBugVersion 1
#define kAppDevString L""
#define kAppBugVersion 0
#define kAppDevString L"d1"
/*
* Windows application object.

View File

@ -533,28 +533,11 @@ NufxArchive::IsCompressionSupported(NuThreadFormat format)
NuResult
NufxArchive::NufxErrorMsgHandler(NuArchive* /*pArchive*/, void* vErrorMessage)
{
#if defined(_DEBUG_LOG)
const NuErrorMessage* pErrorMessage = (const NuErrorMessage*) vErrorMessage;
CStringA msg(pErrorMessage->message);
msg += "\n";
if (pErrorMessage->isDebug)
msg = "[D] " + msg;
fprintf(gLog, "%05u NufxLib %hs(%d) : %hs",
gPid, pErrorMessage->file, pErrorMessage->line, msg);
#elif defined(_DEBUG)
const NuErrorMessage* pErrorMessage = (const NuErrorMessage*) vErrorMessage;
CStringA msg(pErrorMessage->message);
msg += "\n";
if (pErrorMessage->isDebug)
msg = "[D] " + msg;
_CrtDbgReport(_CRT_WARN, pErrorMessage->file, pErrorMessage->line,
pErrorMessage->function, "%hs", msg);
#endif
LOG_BASE(pErrorMessage->isDebug ? DebugLog::LOG_DEBUG : DebugLog::LOG_WARNING,
pErrorMessage->file, pErrorMessage->line, "<nufxlib> %hs\n",
pErrorMessage->message);
return kNuOK;
}

View File

@ -14,8 +14,8 @@
**
******************************************************************************/
#ifndef __WNASPI32_H__
#define __WNASPI32_H__
#ifndef DISKIMG_WNASPI32_H
#define DISKIMG_WNASPI32_H
/*
** Make sure structures are packed and undecorated.
@ -322,4 +322,4 @@ extern BOOL TranslateASPI32Address( PDWORD, PDWORD );
}
#endif //__cplusplus
#endif //__WNASPI32_H__
#endif //DISKIMG_WNASPI32_H

View File

@ -20,8 +20,8 @@
*
*/
#ifndef __NTDDSCSI_H
#define __NTDDSCSI_H
#ifndef DISKIMG_NTDDSCSI_H
#define DISKIMG_NTDDSCSI_H
#if __GNUC__ >=3
#pragma GCC system_header
@ -181,4 +181,4 @@ typedef struct _DUMP_POINTERS {
}
#endif
#endif /* __NTDDSCSI_H */
#endif /*DISKIMG_NTDDSCSI_H*/

View File

@ -309,6 +309,8 @@ DiskImgLib::FindExtension(const char* pathname, char fssep)
* Like strcpy(), but allocate with new[] instead.
*
* If "str" is nil, or "new" fails, this returns nil.
*
* TODO: should be "StrdupNew()"
*/
char*
DiskImgLib::StrcpyNew(const char* str)

View File

@ -19,8 +19,8 @@
* different objects will work, though modifying the same disk image
* file from multiple objects will lead to unpredictable results.
*/
#ifndef __DISK_IMG__
#define __DISK_IMG__
#ifndef DISKIMG_DISKIMG_H
#define DISKIMG_DISKIMG_H
#include <stdio.h>
#include <stdlib.h>
@ -1659,4 +1659,4 @@ private:
}; // namespace DiskImgLib
#endif /*__DISK_IMG__*/
#endif /*DISKIMG_DISKIMG_H*/

View File

@ -8,8 +8,8 @@
*
* External code should not include this.
*/
#ifndef __DISK_IMG_PRIV__
#define __DISK_IMG_PRIV__
#ifndef DISKIMG_DISKIMGPRIV_H
#define DISKIMG_DISKIMGPRIV_H
#include "DiskImgDetail.h"
#include <errno.h>
@ -20,38 +20,32 @@ using namespace DiskImgLib; // make life easy for all internal code
namespace DiskImgLib {
#ifndef _DEBUG_LOG
//# define _DEBUG_LOG /* define this to force log msgs in non-debug build */
#endif
#if defined(_DEBUG) || defined(_DEBUG_LOG)
# define _DEBUG_MSGS
#endif
/*
* Win32-style debug message macros.
* Debug logging macros.
*
* The macro choice implies a severity level, but we don't currently
* support that in the callback interface, so it's not used.
*/
#ifdef _DEBUG_MSGS
#define WMSG0(fmt) \
Global::PrintDebugMsg(__FILE__, __LINE__, fmt)
#define WMSG1(fmt, arg0) \
Global::PrintDebugMsg(__FILE__, __LINE__, fmt, arg0)
#define WMSG2(fmt, arg0, arg1) \
Global::PrintDebugMsg(__FILE__, __LINE__, fmt, arg0, arg1)
#define WMSG3(fmt, arg0, arg1, arg2) \
Global::PrintDebugMsg(__FILE__, __LINE__, fmt, arg0, arg1, arg2)
#define WMSG4(fmt, arg0, arg1, arg2, arg3) \
Global::PrintDebugMsg(__FILE__, __LINE__, fmt, arg0, arg1, arg2, arg3)
#define WMSG5(fmt, arg0, arg1, arg2, arg3, arg4) \
Global::PrintDebugMsg(__FILE__, __LINE__, fmt, arg0, arg1, arg2, arg3, arg4)
#define DLOG_BASE(file, line, format, ...) \
Global::PrintDebugMsg((file), (line), (format), __VA_ARGS__)
#ifdef SHOW_LOGV
# define LOGV(format, ...) DLOG_BASE(__FILE__, __LINE__, (format), __VA_ARGS__)
#else
#define WMSG0(fmt) ((void) 0)
#define WMSG1(fmt, arg0) ((void) 0)
#define WMSG2(fmt, arg0, arg1) ((void) 0)
#define WMSG3(fmt, arg0, arg1, arg2) ((void) 0)
#define WMSG4(fmt, arg0, arg1, arg2, arg3) ((void) 0)
#define WMSG5(fmt, arg0, arg1, arg2, arg3, arg4) ((void) 0)
# define LOGV(format, ...) ((void) 0)
#endif
#define LOGD(format, ...) DLOG_BASE(__FILE__, __LINE__, (format), __VA_ARGS__)
#define LOGI(format, ...) DLOG_BASE(__FILE__, __LINE__, (format), __VA_ARGS__)
#define LOGW(format, ...) DLOG_BASE(__FILE__, __LINE__, (format), __VA_ARGS__)
#define LOGE(format, ...) DLOG_BASE(__FILE__, __LINE__, (format), __VA_ARGS__)
// TODO: remove these
#define WMSG0(fmt) LOGI(fmt)
#define WMSG1(fmt, arg0) LOGI(fmt, arg0)
#define WMSG2(fmt, arg0, arg1) LOGI(fmt, arg0, arg1)
#define WMSG3(fmt, arg0, arg1, arg2) LOGI(fmt, arg0, arg1, arg2)
#define WMSG4(fmt, arg0, arg1, arg2, arg3) LOGI(fmt, arg0, arg1, arg2, arg3)
#define WMSG5(fmt, arg0, arg1, arg2, arg3, arg4) LOGI(fmt, arg0, arg1, arg2, arg3, arg4)
/* put this in to break on interesting events when built debug */
#if defined(_DEBUG)
@ -354,11 +348,11 @@ private:
};
}; // namespace DiskImgLib
} // namespace DiskImgLib
/*
* Most of the code needs these.
*/
#include "GenericFD.h"
#endif /*__DISK_IMG_PRIV__*/
#endif /*DISKIMG_DISKIMGPRIV_H*/

View File

@ -6,8 +6,8 @@
/*
* Declarations for GenericFD class and sub-classes.
*/
#ifndef __GENERIC_FD__
#define __GENERIC_FD__
#ifndef DISKIMG_GENERICFD_H
#define DISKIMG_GENERICFD_H
#include "Win32BlockIO.h"

View File

@ -28,11 +28,11 @@ Global::AppInit(void)
long major, minor, bug;
if (fAppInitCalled) {
WMSG0("DiskImg AppInit already called\n");
LOGW("DiskImg AppInit already called\n");
return kDIErrNone;
}
WMSG3("AppInit for DiskImg library v%d.%d.%d\n",
LOGI("Initializing DiskImg library v%d.%d.%d\n",
kDiskImgVersionMajor, kDiskImgVersionMinor, kDiskImgVersionBug);
#ifdef _WIN32
@ -44,9 +44,9 @@ Global::AppInit(void)
sizeof(fileNameBuf) / sizeof(WCHAR)) != 0)
{
// GetModuleHandle does not increase ref count, so no need to release
WMSG1("DiskImg DLL loaded from '%ls'\n", fileNameBuf);
LOGD("DiskImg DLL loaded from '%ls'\n", fileNameBuf);
} else {
WMSG0("Unable to get DiskImg DLL filename\n");
LOGW("Unable to get DiskImg DLL filename\n");
}
#endif
@ -55,12 +55,12 @@ Global::AppInit(void)
*/
nerr = NuGetVersion(&major, &minor, &bug, NULL, NULL);
if (nerr != kNuErrNone) {
WMSG0("Unable to get version number from NufxLib.");
LOGE("Unable to get version number from NufxLib.");
return kDIErrNufxLibInitFailed;
}
if (major != kNuVersionMajor || minor < kNuVersionMinor) {
WMSG3("Unexpected NufxLib version %ld.%ld.%ld\n",
LOGE("Unexpected NufxLib version %ld.%ld.%ld\n",
major, minor, bug);
return kDIErrNufxLibInitFailed;
}
@ -79,7 +79,7 @@ Global::AppInit(void)
}
}
#endif
WMSG2("DiskImg HasSPTI=%d HasASPI=%d\n", GetHasSPTI(), GetHasASPI());
LOGD("DiskImg HasSPTI=%d HasASPI=%d\n", GetHasSPTI(), GetHasASPI());
fAppInitCalled = true;

View File

@ -11,8 +11,8 @@
*
* Consult the SCSI-2 and MMC-2 specifications for details.
*/
#ifndef __SCSI_DEFS__
#define __SCSI_DEFS__
#ifndef DISKIMG_SCSIDEFS_H
#define DISKIMG_SCSIDEFS_H
/*
* SCSI-2 operation codes.
@ -305,4 +305,4 @@ typedef struct CDB_ReadCapacityData {
unsigned char bytesPerBlock3; // LSB
} CDB_ReadCapacityData;
#endif /*__SCSI_DEFS__*/
#endif /*DISKIMG_SCSIDEFS_H*/

View File

@ -6,8 +6,8 @@
/*
* Declarations for the Win32 SCSI Pass-Through Interface.
*/
#ifndef __SPTI__
#define __SPTI__
#ifndef DISKIMG_SPTI_H
#define DISKIMG_SPTI_H
#ifdef _WIN32
@ -33,8 +33,8 @@ private:
~SPTI(void) {}
};
}; // namespace DiskImgLib
} // namespace DiskImgLib
#endif /*_WIN32*/
#endif /*__SPTI__*/
#endif /*DISKIMG_SPTI_H*/

View File

@ -9,8 +9,8 @@
* This gets its own header because CiderPress uses these definitions and
* functions directly.
*/
#ifndef __TWOIMG__
#define __TWOIMG__
#ifndef DISKIMG_TWOIMG_H
#define DISKIMG_TWOIMG_H
#include "DiskImg.h"
@ -131,6 +131,6 @@ private:
char* fCreatorChunk;
};
}; // namespace DiskImgLib
} // namespace DiskImgLib
#endif /*TWOIMG*/
#endif /*DISKIMG_TWOIMG_H*/

View File

@ -176,15 +176,9 @@ MainWindow::DebugMsgHandler(const char* file, int line, const char* msg)
ASSERT(file != nil);
ASSERT(msg != nil);
#if defined(_DEBUG_LOG)
//fprintf(gLog, "%s(%d) : %s", file, line, msg);
fprintf(gLog, "%05u %hs", gPid, msg);
#elif defined(_DEBUG)
_CrtDbgReport(_CRT_WARN, file, line, NULL, "%hs", msg);
#else
/* do nothing */
#endif
LOG_BASE(DebugLog::LOG_INFO, file, line, "<diskimg> %hs", msg);
}
/*
* Handle a global error message from the NufxLib library.
*/
@ -193,23 +187,9 @@ MainWindow::NufxErrorMsgHandler(NuArchive* /*pArchive*/, void* vErrorMessage)
{
const NuErrorMessage* pErrorMessage = (const NuErrorMessage*) vErrorMessage;
#if defined(_DEBUG_LOG)
if (pErrorMessage->isDebug) {
fprintf(gLog, "%05u <nufxlib> [D] %hs\n", gPid, pErrorMessage->message);
} else {
fprintf(gLog, "%05u <nufxlib> %hs\n", gPid, pErrorMessage->message);
}
#elif defined(_DEBUG)
if (pErrorMessage->isDebug) {
_CrtDbgReport(_CRT_WARN, pErrorMessage->file, pErrorMessage->line,
NULL, "<nufxlib> [D] %hs\n", pErrorMessage->message);
} else {
_CrtDbgReport(_CRT_WARN, pErrorMessage->file, pErrorMessage->line,
NULL, "<nufxlib> %hs\n", pErrorMessage->message);
}
#else
/* do nothing */
#endif
LOG_BASE(pErrorMessage->isDebug ? DebugLog::LOG_DEBUG : DebugLog::LOG_WARNING,
pErrorMessage->file, pErrorMessage->line, "<nufxlib> %hs\n",
pErrorMessage->message);
return kNuOK;
}

View File

@ -14,10 +14,7 @@
/* magic global that MFC finds (or that finds MFC) */
MyApp gMyApp;
#if defined(_DEBUG_LOG)
FILE* gLog = nil;
int gPid = -1;
#endif
DebugLog* gDebugLog;
/*
* Constructor. This is the closest thing to "main" that we have, but we
@ -25,20 +22,13 @@ int gPid = -1;
*/
MyApp::MyApp(LPCTSTR lpszAppName) : CWinApp(lpszAppName)
{
time_t now;
now = time(nil);
// TODO: make the log file configurable
gDebugLog = new DebugLog(L"C:\\src\\mdclog.txt");
#ifdef _DEBUG_LOG
gLog = fopen(kDebugLog, "w");
if (gLog == nil)
abort();
::setvbuf(gLog, nil, _IONBF, 0);
gPid = ::getpid();
fprintf(gLog, "\n");
#endif
WMSG1("MDC started at %.24hs\n", ctime(&now));
time_t now = time(nil);
LOGI("MDC v%d.%d.%d started at %.24hs\n",
kAppMajorVersion, kAppMinorVersion, kAppBugVersion,
ctime(&now));
int tmpDbgFlag;
// enable memory leak detection
@ -54,10 +44,7 @@ MyApp::MyApp(LPCTSTR lpszAppName) : CWinApp(lpszAppName)
MyApp::~MyApp(void)
{
WMSG0("MDC SHUTTING DOWN\n\n");
#ifdef _DEBUG_LOG
if (gLog != nil)
fclose(gLog);
#endif
delete gDebugLog;
}

View File

@ -12,14 +12,6 @@
#include "resource.h"
/*
* Application object.
*/
#if defined(_DEBUG_LOG)
#define kDebugLog "C:\\mdclog.txt"
#endif
/* MDC version numbers */
#define kAppMajorVersion 2
#define kAppMinorVersion 2

View File

@ -11,6 +11,14 @@
#define NELEM(x) ((int) (sizeof(x) / sizeof(x[0])))
/*
* Declare copy construction and operator=. Put this in a private section
* of a class declaration to prevent objects from being copied.
*/
#define DECLARE_COPY_AND_OPEQ(_TYPE) \
_TYPE(const _TYPE&); \
_TYPE& operator= (const _TYPE&);
// TODO: nuke this
#define nil NULL

75
util/MyDebug.cpp Normal file
View File

@ -0,0 +1,75 @@
/*
* CiderPress
* Copyright (C) 2014 by CiderPress authors. All Rights Reserved.
* See the file LICENSE for distribution terms.
*/
/*
* Debug log support.
*/
#include "stdafx.h"
DebugLog::DebugLog(const WCHAR* logFile)
: fLogFp(NULL)
{
fPid = getpid();
if (logFile == NULL) {
return;
}
PathName debugPath(logFile);
time_t now = time(NULL);
time_t when = debugPath.GetModWhen();
if (when > 0 && now - when > kStaleLog) {
/* log file is more than 8 hours old, remove it */
/* [consider opening it and truncating with chsize() instead, so we
don't hose somebody's custom access permissions. ++ATM 20041015] */
_wunlink(logFile);
}
fLogFp = _wfopen(logFile, L"a");
if (fLogFp == nil) {
_CrtDbgReport(_CRT_WARN, __FILE__, __LINE__, NULL,
"Unable to open %ls: %d\n", logFile, errno);
} else {
// disable buffering so we don't lose anything if app crashes
setvbuf(fLogFp, nil, _IONBF, 0);
fprintf(fLogFp, "\n");
if (when > 0) {
fprintf(fLogFp,
"(Log file was %.3f hours old; logs are reset after %.3f)\n",
(now - when) / 3600.0, kStaleLog / 3600.0);
}
}
}
DebugLog::~DebugLog() {
if (fLogFp != NULL) {
fclose(fLogFp);
}
}
void DebugLog::Log(LogSeverity severity, const char* file, int line,
const char* format, ...)
{
if (fLogFp == NULL) {
return;
}
static const char kSeverityChars[] = "?VDIWE";
if (severity < 0 || severity > sizeof(kSeverityChars) - 1) {
severity = LOG_UNKNOWN;
}
struct tm tmbuf;
time_t now = time(NULL);
localtime_s(&tmbuf, &now);
va_list argptr;
va_start(argptr, format);
// had %05u fPid before; not sure that's useful
fprintf(fLogFp, "%02d:%02d:%02d %c ", tmbuf.tm_hour,
tmbuf.tm_min, tmbuf.tm_sec, kSeverityChars[severity]);
vfprintf(fLogFp, format, argptr);
}

View File

@ -9,52 +9,93 @@
#ifndef UTIL_MYDEBUG_H
#define UTIL_MYDEBUG_H
//#define _DEBUG_LOG /* set this to force logging in all builds */
#include "PathName.h"
#include "FaddenStd.h"
#ifndef _DEBUG
//# define _DEBUG_LOG /* define this to use logging for !_DEBUG */
#endif
/*
* Debug log output.
*
* Generally an application will only want one instance of this, which will be
* accessed through a global variable by log macros.
*/
class DebugLog {
public:
/*
* Pass in the log file name, or NULL if logging to a file is not
* desired. If the log file cannot be opened, no error is reported,
* but the Log call will do nothing.
*/
DebugLog(const WCHAR* logFile);
#if defined(_DEBUG_LOG)
#include <stdio.h>
extern FILE* gLog;
extern int gPid;
#define WMSG0(fmt) \
{ fprintf(gLog, "%05u ", gPid); fprintf(gLog, fmt); }
#define WMSG1(fmt, arg0) \
{ fprintf(gLog, "%05u ", gPid); fprintf(gLog, fmt, arg0); }
#define WMSG2(fmt, arg0, arg1) \
{ fprintf(gLog, "%05u ", gPid); fprintf(gLog, fmt, arg0, arg1); }
#define WMSG3(fmt, arg0, arg1, arg2) \
{ fprintf(gLog, "%05u ", gPid); fprintf(gLog, fmt, arg0, arg1, arg2); }
#define WMSG4(fmt, arg0, arg1, arg2, arg3) \
{ fprintf(gLog, "%05u ", gPid); fprintf(gLog, fmt, arg0, arg1, arg2, arg3); }
#define WMSG5(fmt, arg0, arg1, arg2, arg3, arg4) \
{ fprintf(gLog, "%05u ", gPid); fprintf(gLog, fmt, arg0, arg1, arg2, arg3, \
arg4); }
~DebugLog();
typedef enum {
LOG_UNKNOWN=0, LOG_VERBOSE=1, LOG_DEBUG=2,
LOG_INFO=3, LOG_WARNING=4, LOG_ERROR=5
} LogSeverity;
/*
* Write a message to the log file.
*
* There doesn't seem to be a va_arg form of _CrtDbgReport, just "...",
* so we can't call that from here unless we snprintf to a buffer.
*/
void Log(LogSeverity severity, const char* file, int line,
const char* format, ...);
private:
DECLARE_COPY_AND_OPEQ(DebugLog)
const int kStaleLog = 8 * 60 * 60; // 8 hours
FILE* fLogFp;
int fPid;
};
extern DebugLog* gDebugLog; // declare and allocate in app
/* send the message to the log file (if open) and the CRT debug mechanism */
#define LOG_BASE(severity, file, line, format, ...) \
{ \
gDebugLog->Log((severity), (file), (line), (format), __VA_ARGS__); \
if (_CrtDbgReport(_CRT_WARN, (file), (line), NULL, (format), \
__VA_ARGS__) == 1) { \
_CrtDbgBreak(); \
} \
}
/*
* Log macros, with priority specifier. The output will be written to the
* log file, if one is open, and to the debugger output window, if available.
*
* The verbose-level debugging should be enabled on a file-by-file basis,
* but that doesn't seem to work (pre-compiled header interference, maybe?).
*/
#ifdef SHOW_LOGV
# define LOGV(format, ...) \
LOG_BASE(DebugLog::LOG_VERBOSE, __FILE__, __LINE__, format, __VA_ARGS__)
#else
/* can use TRACE0, TRACE1, etc to avoid header and '\n' */
#define WMSG0(fmt) _RPTF0(_CRT_WARN, fmt)
#define WMSG1(fmt, arg0) _RPTF1(_CRT_WARN, fmt, arg0)
#define WMSG2(fmt, arg0, arg1) _RPTF2(_CRT_WARN, fmt, arg0, arg1)
#define WMSG3(fmt, arg0, arg1, arg2) _RPTF3(_CRT_WARN, fmt, arg0, arg1, arg2)
#define WMSG4(fmt, arg0, arg1, arg2, arg3) _RPTF4(_CRT_WARN, fmt, arg0, arg1, \
arg2, arg3)
#if !defined(_RPTF5)
# if defined(_DEBUG)
# define _RPTF5(rptno, msg, arg1, arg2, arg3, arg4, arg5) \
do { if ((1 == _CrtDbgReport(rptno, __FILE__, __LINE__, NULL, msg, \
arg1, arg2, arg3, arg4, arg5))) \
_CrtDbgBreak(); } while (0)
# else
# define _RPTF5(rptno, msg, arg1, arg2, arg3, arg4, arg5)
# endif
# define LOGV(format, ...) ((void)0)
#endif
#define LOGD(format, ...) \
LOG_BASE(DebugLog::LOG_DEBUG, __FILE__, __LINE__, format, __VA_ARGS__)
#define LOGI(format, ...) \
LOG_BASE(DebugLog::LOG_INFO, __FILE__, __LINE__, format, __VA_ARGS__)
#define LOGW(format, ...) \
LOG_BASE(DebugLog::LOG_WARN, __FILE__, __LINE__, format, __VA_ARGS__)
#define LOGE(format, ...) \
LOG_BASE(DebugLog::LOG_ERROR, __FILE__, __LINE__, format, __VA_ARGS__)
#define WMSG5(fmt, arg0, arg1, arg2, arg3, arg4) _RPTF5(_CRT_WARN, fmt, arg0, \
// TODO: remove these
#define WMSG0(fmt) LOGI(fmt)
#define WMSG1(fmt, arg0) LOGI(fmt, arg0)
#define WMSG2(fmt, arg0, arg1) LOGI(fmt, arg0, arg1)
#define WMSG3(fmt, arg0, arg1, arg2) LOGI(fmt, arg0, arg1, arg2)
#define WMSG4(fmt, arg0, arg1, arg2, arg3) LOGI(fmt, arg0, arg1, \
arg2, arg3)
#define WMSG5(fmt, arg0, arg1, arg2, arg3, arg4) LOGI(fmt, arg0, \
arg1, arg2, arg3, arg4)
#endif
/* make the memory leak test output more interesting */
#ifdef _DEBUG
@ -69,7 +110,7 @@ extern int gPid;
/* put this in to break on interesting events when built debug */
#if defined(_DEBUG)
# define DebugBreak() { assert(false); }
# define DebugBreak() { _CrtDbgBreak(); }
#else
# define DebugBreak() ((void) 0)
#endif

View File

@ -124,6 +124,7 @@
<ItemGroup>
<ClCompile Include="ImageDataObject.cpp" />
<ClCompile Include="MyBitmapButton.cpp" />
<ClCompile Include="MyDebug.cpp" />
<ClCompile Include="MyDIBitmap.cpp" />
<ClCompile Include="MyEdit.cpp" />
<ClCompile Include="MySpinCtrl.cpp" />

View File

@ -103,5 +103,8 @@
<ClCompile Include="Util.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="MyDebug.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>