From d21ba553ab2f4c35d77a896471a1d11b63c4eaa7 Mon Sep 17 00:00:00 2001 From: Andy McFadden Date: Mon, 17 Nov 2014 17:54:34 -0800 Subject: [PATCH] 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. --- app/CiderPress.rc | 8 +-- app/DiskArchive.cpp | 9 +-- app/MyApp.cpp | 42 ++----------- app/MyApp.h | 11 +--- app/NufxArchive.cpp | 23 +------- diskimg/CP_WNASPI32.H | 6 +- diskimg/CP_ntddscsi.h | 6 +- diskimg/DIUtil.cpp | 2 + diskimg/DiskImg.h | 6 +- diskimg/DiskImgPriv.h | 58 ++++++++---------- diskimg/GenericFD.h | 4 +- diskimg/Global.cpp | 14 ++--- diskimg/SCSIDefs.h | 6 +- diskimg/SPTI.h | 8 +-- diskimg/TwoImg.h | 8 +-- mdc/Main.cpp | 30 ++-------- mdc/mdc.cpp | 29 +++------ mdc/mdc.h | 8 --- util/FaddenStd.h | 8 +++ util/MyDebug.cpp | 75 +++++++++++++++++++++++ util/MyDebug.h | 121 +++++++++++++++++++++++++------------- util/util.vcxproj | 1 + util/util.vcxproj.filters | 3 + 23 files changed, 255 insertions(+), 231 deletions(-) create mode 100644 util/MyDebug.cpp diff --git a/app/CiderPress.rc b/app/CiderPress.rc index 811cc2f..9f2d2d9 100644 --- a/app/CiderPress.rc +++ b/app/CiderPress.rc @@ -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" diff --git a/app/DiskArchive.cpp b/app/DiskArchive.cpp index 89a359f..e83d4b2 100644 --- a/app/DiskArchive.cpp +++ b/app/DiskArchive.cpp @@ -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, " %hs", msg); } /* diff --git a/app/MyApp.cpp b/app/MyApp.cpp index eef0dc0..48716f5 100644 --- a/app/MyApp.cpp +++ b/app/MyApp.cpp @@ -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; } diff --git a/app/MyApp.h b/app/MyApp.h index 665242a..d098cc8 100644 --- a/app/MyApp.h +++ b/app/MyApp.h @@ -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. diff --git a/app/NufxArchive.cpp b/app/NufxArchive.cpp index 98646d1..5b3f4db 100644 --- a/app/NufxArchive.cpp +++ b/app/NufxArchive.cpp @@ -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, " %hs\n", + pErrorMessage->message); return kNuOK; } diff --git a/diskimg/CP_WNASPI32.H b/diskimg/CP_WNASPI32.H index ae5ca0b..5695f9b 100644 --- a/diskimg/CP_WNASPI32.H +++ b/diskimg/CP_WNASPI32.H @@ -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 diff --git a/diskimg/CP_ntddscsi.h b/diskimg/CP_ntddscsi.h index a28db87..5ac6a45 100644 --- a/diskimg/CP_ntddscsi.h +++ b/diskimg/CP_ntddscsi.h @@ -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*/ diff --git a/diskimg/DIUtil.cpp b/diskimg/DIUtil.cpp index fc0bed3..1bc181e 100644 --- a/diskimg/DIUtil.cpp +++ b/diskimg/DIUtil.cpp @@ -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) diff --git a/diskimg/DiskImg.h b/diskimg/DiskImg.h index aafb422..98fd7a7 100644 --- a/diskimg/DiskImg.h +++ b/diskimg/DiskImg.h @@ -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 #include @@ -1659,4 +1659,4 @@ private: }; // namespace DiskImgLib -#endif /*__DISK_IMG__*/ +#endif /*DISKIMG_DISKIMG_H*/ diff --git a/diskimg/DiskImgPriv.h b/diskimg/DiskImgPriv.h index 69829d6..cbe3c9c 100644 --- a/diskimg/DiskImgPriv.h +++ b/diskimg/DiskImgPriv.h @@ -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 @@ -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*/ diff --git a/diskimg/GenericFD.h b/diskimg/GenericFD.h index caefe13..6266b0b 100644 --- a/diskimg/GenericFD.h +++ b/diskimg/GenericFD.h @@ -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" diff --git a/diskimg/Global.cpp b/diskimg/Global.cpp index 42cb581..61bb1a8 100644 --- a/diskimg/Global.cpp +++ b/diskimg/Global.cpp @@ -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; diff --git a/diskimg/SCSIDefs.h b/diskimg/SCSIDefs.h index f257f63..58ae883 100644 --- a/diskimg/SCSIDefs.h +++ b/diskimg/SCSIDefs.h @@ -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*/ diff --git a/diskimg/SPTI.h b/diskimg/SPTI.h index 6f28b61..bda0865 100644 --- a/diskimg/SPTI.h +++ b/diskimg/SPTI.h @@ -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*/ diff --git a/diskimg/TwoImg.h b/diskimg/TwoImg.h index 669be82..175d716 100644 --- a/diskimg/TwoImg.h +++ b/diskimg/TwoImg.h @@ -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*/ diff --git a/mdc/Main.cpp b/mdc/Main.cpp index 90a3c1b..55ca3b0 100644 --- a/mdc/Main.cpp +++ b/mdc/Main.cpp @@ -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, " %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 [D] %hs\n", gPid, pErrorMessage->message); - } else { - fprintf(gLog, "%05u %hs\n", gPid, pErrorMessage->message); - } -#elif defined(_DEBUG) - if (pErrorMessage->isDebug) { - _CrtDbgReport(_CRT_WARN, pErrorMessage->file, pErrorMessage->line, - NULL, " [D] %hs\n", pErrorMessage->message); - } else { - _CrtDbgReport(_CRT_WARN, pErrorMessage->file, pErrorMessage->line, - NULL, " %hs\n", pErrorMessage->message); - } -#else - /* do nothing */ -#endif + LOG_BASE(pErrorMessage->isDebug ? DebugLog::LOG_DEBUG : DebugLog::LOG_WARNING, + pErrorMessage->file, pErrorMessage->line, " %hs\n", + pErrorMessage->message); return kNuOK; } diff --git a/mdc/mdc.cpp b/mdc/mdc.cpp index 17e24e9..b13d49e 100644 --- a/mdc/mdc.cpp +++ b/mdc/mdc.cpp @@ -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; } diff --git a/mdc/mdc.h b/mdc/mdc.h index 4f5b4d0..4fdc9bc 100644 --- a/mdc/mdc.h +++ b/mdc/mdc.h @@ -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 diff --git a/util/FaddenStd.h b/util/FaddenStd.h index 8546a3c..259ee44 100644 --- a/util/FaddenStd.h +++ b/util/FaddenStd.h @@ -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 diff --git a/util/MyDebug.cpp b/util/MyDebug.cpp new file mode 100644 index 0000000..d10eb23 --- /dev/null +++ b/util/MyDebug.cpp @@ -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); +} diff --git a/util/MyDebug.h b/util/MyDebug.h index 39cc876..5f6e964 100644 --- a/util/MyDebug.h +++ b/util/MyDebug.h @@ -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 -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 diff --git a/util/util.vcxproj b/util/util.vcxproj index 22f6c26..3b74cc3 100644 --- a/util/util.vcxproj +++ b/util/util.vcxproj @@ -124,6 +124,7 @@ + diff --git a/util/util.vcxproj.filters b/util/util.vcxproj.filters index aa30a22..c3aa577 100644 --- a/util/util.vcxproj.filters +++ b/util/util.vcxproj.filters @@ -103,5 +103,8 @@ Source Files + + Source Files + \ No newline at end of file