summaryrefslogtreecommitdiff
path: root/Utilities
diff options
context:
space:
mode:
Diffstat (limited to 'Utilities')
-rw-r--r--Utilities/DebugHelper.h676
1 files changed, 338 insertions, 338 deletions
diff --git a/Utilities/DebugHelper.h b/Utilities/DebugHelper.h
index cf1b4b3..aa2af94 100644
--- a/Utilities/DebugHelper.h
+++ b/Utilities/DebugHelper.h
@@ -1,338 +1,338 @@
-/*
-
-DebugHelper.h
-Copyright © 2004-2006 Heiko Herkenrath
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-// Version 3.0, Sept 26 2005
-// Heiko Herkenrath
-
-// -----------------------------
-
-// Switches:
-
-//#define DEACTIVATE_DEBUG_HELPER
-//#define NO_DEBUG_HELPER
-//#define ALSO_USE_DEBUG_HELPER_FOR_RELEASE
-
-// -----------------------------
-
-#if !defined(ALSO_USE_DEBUG_HELPER_FOR_RELEASE)
- #if !defined(_DEBUG)
- #define DEACTIVATE_DEBUG_HELPER
- #endif
-#endif
-
-// -----------------------------
-
-#ifndef NO_DEBUG_HELPERS
-
- #define DEBUG_BUFFER_SIZE 1024
-
- // Creating display text for all functions
- #if !defined(DEACTIVATE_DEBUG_HELPER)
- __inline WCHAR* CreateDebugText(const WCHAR* pszFmt, const WCHAR* pszFile, unsigned int uLine, va_list va)
- {
- static int iDebugCallCount = 0;
- TCHAR* pszDebugText;
- TCHAR* pszDebugBuf;
- TCHAR* ptszLastError;
- DWORD dwLastError;
- #if defined(UNICODE)
- char* pszLastError;
- #endif
-
- dwLastError = GetLastError();
- iDebugCallCount++;
- MessageBeep(MB_ICONQUESTION);
-
- if (!pszFmt) return NULL;
-
- pszDebugText = (TCHAR*)malloc(DEBUG_BUFFER_SIZE*sizeof(TCHAR));
- if (pszDebugText)
- {
- pszDebugBuf = (TCHAR*)malloc(DEBUG_BUFFER_SIZE*sizeof(TCHAR));
- if (pszDebugBuf)
- {
- ptszLastError = NULL;
-
- #if defined(UNICODE) // FormatMessageW does not work with UnicoWS layer on Win9x/ME
-
- pszLastError = NULL;
-
- if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwLastError, 0, (LPWSTR)&ptszLastError, 0, NULL) == 0)
- FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwLastError, 0, (LPSTR)&pszLastError, 0, NULL);
-
- mir_sntprintf(pszDebugBuf, DEBUG_BUFFER_SIZE, _T("[Message %i]\r\nLast Error: %u\r\nDescription: %hs%sCall: %s, %u\r\n\r\n%s"), iDebugCallCount, dwLastError, pszLastError?pszLastError:"", ptszLastError?ptszLastError:_T(""), PathFindFileName(pszFile), uLine, pszFmt);
-
- if (pszLastError) LocalFree(pszLastError);
- if (ptszLastError) LocalFree(ptszLastError);
-
- #else
-
- FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwLastError, 0, (LPTSTR)&ptszLastError, 0, NULL);
- mir_sntprintf(pszDebugBuf, DEBUG_BUFFER_SIZE, _T("[Message %i]\r\nLast Error: %u\r\nDescription: %sCall: %s, %u\r\n\r\n%s"), iDebugCallCount, dwLastError, ptszLastError?ptszLastError:_T(""), PathFindFileName(pszFile), uLine, pszFmt);
- if (ptszLastError) LocalFree(ptszLastError);
-
- #endif
-
- mir_vsnprintf(pszDebugText, DEBUG_BUFFER_SIZE, pszDebugBuf, va);
- free(pszDebugBuf);
- }
- }
-
- SetLastError(ERROR_SUCCESS);
- return pszDebugText;
- }
- #endif
-
-
- // Check if a specific flag is bitwise-or'ed into a flags variable
- // (returns flag name as string or empty string if not contained)
- #if !defined(DEACTIVATE_DEBUG_HELPER)
- #define INFLAGS(flags, flag) ( ((flags&flag) && ((flags^=flag)||TRUE))?_T("|"#flag):_T(""))
- #else
- #define INFLAGS(flags, flag)
- #endif
-
-
- // BOOLSTR [make a string out of a boolean value]
- #if !defined(DEACTIVATE_DEBUG_HELPER)
- #define BOOLSTR(b) ((b)?_T("TRUE"):_T("FALSE"))
- #else
- #define BOOLSTR(b)
- #endif
-
-
- // BOX [show debug message box with text]
- #if !defined(DEACTIVATE_DEBUG_HELPER)
-
- // Functions:
- #define BOX(str) BOX_Helper(_T(__FILE__), __LINE__, _T("%s"), _T(str))
- #define BOX1(fmt, p1) BOX_Helper(_T(__FILE__), __LINE__, _T(fmt), (p1), NULL, NULL, NULL)
- #define BOX2(fmt, p1, p2) BOX_Helper(_T(__FILE__), __LINE__, _T(fmt), (p1), (p2), NULL, NULL)
- #define BOX3(fmt, p1, p2, p3) BOX_Helper(_T(__FILE__), __LINE__, _T(fmt), (p1), (p2), (p3), NULL)
- #define BOX4(fmt, p1, p2, p3, p4) BOX_Helper(_T(__FILE__), __LINE__, _T(fmt), (p1), (p2), (p3), (p4))
- // ---
-
- __inline void BOX_Helper(const TCHAR* pszFile, unsigned int uLine, const TCHAR* pszFmt, ...)
- {
- va_list va;
- TCHAR* pszText;
-
- va_start(va, pszFmt);
- pszText = CreateDebugText(pszFmt, pszFile, uLine, va);
- va_end(va);
-
- if (pszText)
- {
- // Only show if CTRL is not pressed
- if (!(GetAsyncKeyState(VK_CONTROL)&0x8000))
- MessageBoxEx(NULL, pszText, _T("Debug"), MB_OK|MB_TASKMODAL|MB_SETFOREGROUND, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT));
-
- free(pszText);
- }
- }
-
- #else
- #define BOX(str)
- #define BOX1(fmt, p1)
- #define BOX2(fmt, p1, p2)
- #define BOX3(fmt, p1, p2, p3)
- #define BOX4(fmt, p1, p2, p3, p4)
- #endif
-
-
-
- // STEP [show debug message box with current code step]
- #define STEP(section, id) BOX2("Reached Step %s|%u", _T(section), id)
-
-
-
- // STR [write line into debugger output]
- #if !defined(DEACTIVATE_DEBUG_HELPER)
-
- // Functions:
- #define STR(str) STR_Helper(_T(__FILE__), __LINE__, _T("%s"), _T(str))
- #define STR1(fmt, p1) STR_Helper(_T(__FILE__), __LINE__, _T(fmt), (p1), NULL, NULL, NULL)
- #define STR2(fmt, p1, p2) STR_Helper(_T(__FILE__), __LINE__, _T(fmt), (p1), (p2), NULL, NULL)
- #define STR3(fmt, p1, p2, p3) STR_Helper(_T(__FILE__), __LINE__, _T(fmt), (p1), (p2), (p3), NULL, NULL)
- #define STR4(fmt, p1, p2, p3, p4) STR_Helper(_T(__FILE__), __LINE__, _T(fmt), (p1), (p2), (p3), (p4))
- // ---
-
- __inline void STR_Helper(const TCHAR* pszFile, unsigned int uLine, const TCHAR* pszFmt, ...)
- {
- va_list va;
- TCHAR* pszText;
-
- va_start(va, pszFmt);
- pszText = CreateDebugText(pszFmt, pszFile, uLine, va);
- va_end(va);
-
- if (pszText)
- {
- OutputDebugString(pszText);
- OutputDebugString(_T("\r\n"));
-
- free(pszText);
- }
- }
-
- #else
- #define STR(str)
- #define STR1(fmt, p1)
- #define STR2(fmt, p1, p2)
- #define STR3(fmt, p1, p2, p3)
- #define STR4(fmt, p1, p2, p3, p4)
- #endif
-
-
-
- // DBG [simple wrapper around OutputDebugString]
- #if !defined(DEACTIVATE_DEBUG_HELPER)
- #define DBGT(str) OutputDebugString(_T(str)_T("\r\n"))
- #define DBG(str) { OutputDebugString(str); OutputDebugString(_T("\r\n")); }
- #else
- #define DBGT(str)
- #define DBG(str)
- #endif
-
-
-
- // LOG [append line to debug log file]
- #if !defined(DEACTIVATE_DEBUG_HELPER)
-
- // Functions:
- #define LOG(str) LOG_Helper(_T(__FILE__), __LINE__, _T("%s"), _T(str))
- #define LOG1(fmt, p1) LOG_Helper(_T(__FILE__), __LINE__, _T(fmt), (p1), NULL, NULL, NULL)
- #define LOG2(fmt, p1, p2) LOG_Helper(_T(__FILE__), __LINE__, _T(fmt), (p1), (p2), NULL, NULL)
- #define LOG3(fmt, p1, p2, p3) LOG_Helper(_T(__FILE__), __LINE__, _T(fmt), (p1), (p2), (p3), NULL)
- #define LOG4(fmt, p1, p2, p3, p4) LOG_Helper(_T(__FILE__), __LINE__, _T(fmt), (p1), (p2), (p3), (p4))
- // ---
-
- __inline void LOG_Helper(const TCHAR* pszFile, unsigned int uLine, const TCHAR* pszFmt, ...)
- {
- va_list va;
- DWORD dwDebugFileWritten = 0;
- TCHAR* pszText;
- TCHAR szDebugLogFile[MAX_PATH];
- HANDLE hDebugLogFile;
-
- static BOOL bFirstCall = TRUE;
-
- va_start(va, pszFmt);
- pszText = CreateDebugText(pszFmt, pszFile, uLine, va);
- va_end(va);
-
- // Filename
- if (pszText)
- {
- GetModuleFileName(NULL, szDebugLogFile, sizeof(szDebugLogFile)-1);
- PathRemoveFileSpec(szDebugLogFile);
- PathAppend(szDebugLogFile, _T("Debug.log"));
-
- hDebugLogFile = CreateFile(szDebugLogFile, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
-
- if (hDebugLogFile == INVALID_HANDLE_VALUE)
- BOX("LOG ERROR: INVALID_HANDLE_VALUE");
-
- SetFilePointer(hDebugLogFile, 0, NULL, bFirstCall?FILE_BEGIN:FILE_END);
- WriteFile(hDebugLogFile, "\r\n", 2*sizeof(TCHAR), &dwDebugFileWritten, NULL);
- WriteFile(hDebugLogFile, (PBYTE*)pszText, (DWORD)(lstrlen(pszText)*sizeof(TCHAR)), &dwDebugFileWritten, NULL);
- SetEndOfFile(hDebugLogFile);
-
- CloseHandle(hDebugLogFile);
- free(pszText);
-
- bFirstCall = FALSE;
- }
- }
-
- #else
- #define LOG(str)
- #define LOG1(fmt, p1)
- #define LOG2(fmt, p1, p2)
- #define LOG3(fmt, p1, p2, p3)
- #define LOG4(fmt, p1, p2, p3, p4)
- #endif
-
-
-
- // POP [show debug popup (Popup Plugin) with text]
- /*
- #if !defined(DEACTIVATE_DEBUG_HELPER)
-
- // Functions:
- #define POP(str) POP_Helper(_T(__FILE__), __LINE__, _T("%s"), _T(str))
- #define POP1(fmt, p1) POP_Helper(_T(__FILE__), __LINE__, _T(fmt), (p1), NULL, NULL, NULL)
- #define POP2(fmt, p1, p2) POP_Helper(_T(__FILE__), __LINE__, _T(fmt), (p1), (p2), NULL, NULL)
- #define POP3(fmt, p1, p2, p3) POP_Helper(_T(__FILE__), __LINE__, _T(fmt), (p1), (p2), (p3), NULL)
- #define POP4(fmt, p1, p2, p3, p4) POP_Helper(_T(__FILE__), __LINE__, _T(fmt), (p1), (p2), (p3), (p4))
- // ---
-
- __inline void POP_Helper(const TCHAR* pszFile, unsigned int uLine, const TCHAR* pszFmt, ...)
- {
- #ifdef MS_POPUP_SHOWMESSAGE
- va_list va;
- TCHAR* pszText;
-
- va_start(va, pszFmt);
- pszText = CreateDebugText(pszFmt, pszFile, uLine, va);
- va_end(va);
-
- // Only show if CTRL is not pressed
- if (pszText)
- {
- if (!(GetAsyncKeyState(VK_CONTROL)&0x8000))
- CallServiceSync(MS_POPUP_SHOWMESSAGE, (WPARAM)pszText, (LPARAM)SM_NOTIFY);
-
- free(pszText);
- }
- #endif
- }
- #else
- #define POP(str)
- #define POP1(fmt, p1)
- #define POP2(fmt, p1, p2)
- #define POP3(fmt, p1, p2, p3)
- #define POP4(fmt, p1, p2, p3, p4)
- #endif
- */
-
-
- // LOOPPROT [prevent a loop (for/while/repeat) from becoming an infinite loop]
- #if !defined(DEACTIVATE_DEBUG_HELPER)
-
- // LOOPROT(0) breaks the loop when "Esc" is pressed
-
- #define LOOPPROT(max) { \
- static unsigned int uDebugLoopCount = 1; \
- uDebugLoopCount++; \
- if (GetAsyncKeyState(VK_ESCAPE)&0x8000) break; \
- MessageBeep(MB_ICONEXCLAMATION); \
- if (uDebugLoopCount > (max)) { \
- break; \
- BOX1("LOOPPROT:\nThe execution of the loop was stopped because it looped %u times.", max); \
- uDebugLoopCount = 1;\
- } \
- }
-
- #else
- #define LOOPPROT(max)
- #endif
-
-#endif
+/*
+
+DebugHelper.h
+Copyright © 2004-2006 Heiko Herkenrath
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+// Version 3.0, Sept 26 2005
+// Heiko Herkenrath
+
+// -----------------------------
+
+// Switches:
+
+//#define DEACTIVATE_DEBUG_HELPER
+//#define NO_DEBUG_HELPER
+//#define ALSO_USE_DEBUG_HELPER_FOR_RELEASE
+
+// -----------------------------
+
+#if !defined(ALSO_USE_DEBUG_HELPER_FOR_RELEASE)
+ #if !defined(_DEBUG)
+ #define DEACTIVATE_DEBUG_HELPER
+ #endif
+#endif
+
+// -----------------------------
+
+#ifndef NO_DEBUG_HELPERS
+
+ #define DEBUG_BUFFER_SIZE 1024
+
+ // Creating display text for all functions
+ #if !defined(DEACTIVATE_DEBUG_HELPER)
+ __inline WCHAR* CreateDebugText(const WCHAR* pszFmt, const WCHAR* pszFile, unsigned int uLine, va_list va)
+ {
+ static int iDebugCallCount = 0;
+ TCHAR* pszDebugText;
+ TCHAR* pszDebugBuf;
+ TCHAR* ptszLastError;
+ DWORD dwLastError;
+ #if defined(UNICODE)
+ char* pszLastError;
+ #endif
+
+ dwLastError = GetLastError();
+ iDebugCallCount++;
+ MessageBeep(MB_ICONQUESTION);
+
+ if (!pszFmt) return NULL;
+
+ pszDebugText = (TCHAR*)malloc(DEBUG_BUFFER_SIZE*sizeof(TCHAR));
+ if (pszDebugText)
+ {
+ pszDebugBuf = (TCHAR*)malloc(DEBUG_BUFFER_SIZE*sizeof(TCHAR));
+ if (pszDebugBuf)
+ {
+ ptszLastError = NULL;
+
+ #if defined(UNICODE) // FormatMessageW does not work with UnicoWS layer on Win9x/ME
+
+ pszLastError = NULL;
+
+ if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwLastError, 0, (LPWSTR)&ptszLastError, 0, NULL) == 0)
+ FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwLastError, 0, (LPSTR)&pszLastError, 0, NULL);
+
+ mir_sntprintf(pszDebugBuf, DEBUG_BUFFER_SIZE, _T("[Message %i]\r\nLast Error: %u\r\nDescription: %hs%sCall: %s, %u\r\n\r\n%s"), iDebugCallCount, dwLastError, pszLastError?pszLastError:"", ptszLastError?ptszLastError:_T(""), PathFindFileName(pszFile), uLine, pszFmt);
+
+ if (pszLastError) LocalFree(pszLastError);
+ if (ptszLastError) LocalFree(ptszLastError);
+
+ #else
+
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwLastError, 0, (LPTSTR)&ptszLastError, 0, NULL);
+ mir_sntprintf(pszDebugBuf, DEBUG_BUFFER_SIZE, _T("[Message %i]\r\nLast Error: %u\r\nDescription: %sCall: %s, %u\r\n\r\n%s"), iDebugCallCount, dwLastError, ptszLastError?ptszLastError:_T(""), PathFindFileName(pszFile), uLine, pszFmt);
+ if (ptszLastError) LocalFree(ptszLastError);
+
+ #endif
+
+ mir_vsnprintf(pszDebugText, DEBUG_BUFFER_SIZE, pszDebugBuf, va);
+ free(pszDebugBuf);
+ }
+ }
+
+ SetLastError(ERROR_SUCCESS);
+ return pszDebugText;
+ }
+ #endif
+
+
+ // Check if a specific flag is bitwise-or'ed into a flags variable
+ // (returns flag name as string or empty string if not contained)
+ #if !defined(DEACTIVATE_DEBUG_HELPER)
+ #define INFLAGS(flags, flag) ( ((flags&flag) && ((flags^=flag)||TRUE))?_T("|"#flag):_T(""))
+ #else
+ #define INFLAGS(flags, flag)
+ #endif
+
+
+ // BOOLSTR [make a string out of a boolean value]
+ #if !defined(DEACTIVATE_DEBUG_HELPER)
+ #define BOOLSTR(b) ((b)?_T("TRUE"):_T("FALSE"))
+ #else
+ #define BOOLSTR(b)
+ #endif
+
+
+ // BOX [show debug message box with text]
+ #if !defined(DEACTIVATE_DEBUG_HELPER)
+
+ // Functions:
+ #define BOX(str) BOX_Helper(_T(__FILE__), __LINE__, _T("%s"), _T(str))
+ #define BOX1(fmt, p1) BOX_Helper(_T(__FILE__), __LINE__, _T(fmt), (p1), NULL, NULL, NULL)
+ #define BOX2(fmt, p1, p2) BOX_Helper(_T(__FILE__), __LINE__, _T(fmt), (p1), (p2), NULL, NULL)
+ #define BOX3(fmt, p1, p2, p3) BOX_Helper(_T(__FILE__), __LINE__, _T(fmt), (p1), (p2), (p3), NULL)
+ #define BOX4(fmt, p1, p2, p3, p4) BOX_Helper(_T(__FILE__), __LINE__, _T(fmt), (p1), (p2), (p3), (p4))
+ // ---
+
+ __inline void BOX_Helper(const TCHAR* pszFile, unsigned int uLine, const TCHAR* pszFmt, ...)
+ {
+ va_list va;
+ TCHAR* pszText;
+
+ va_start(va, pszFmt);
+ pszText = CreateDebugText(pszFmt, pszFile, uLine, va);
+ va_end(va);
+
+ if (pszText)
+ {
+ // Only show if CTRL is not pressed
+ if (!(GetAsyncKeyState(VK_CONTROL)&0x8000))
+ MessageBoxEx(NULL, pszText, _T("Debug"), MB_OK|MB_TASKMODAL|MB_SETFOREGROUND, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT));
+
+ free(pszText);
+ }
+ }
+
+ #else
+ #define BOX(str)
+ #define BOX1(fmt, p1)
+ #define BOX2(fmt, p1, p2)
+ #define BOX3(fmt, p1, p2, p3)
+ #define BOX4(fmt, p1, p2, p3, p4)
+ #endif
+
+
+
+ // STEP [show debug message box with current code step]
+ #define STEP(section, id) BOX2("Reached Step %s|%u", _T(section), id)
+
+
+
+ // STR [write line into debugger output]
+ #if !defined(DEACTIVATE_DEBUG_HELPER)
+
+ // Functions:
+ #define STR(str) STR_Helper(_T(__FILE__), __LINE__, _T("%s"), _T(str))
+ #define STR1(fmt, p1) STR_Helper(_T(__FILE__), __LINE__, _T(fmt), (p1), NULL, NULL, NULL)
+ #define STR2(fmt, p1, p2) STR_Helper(_T(__FILE__), __LINE__, _T(fmt), (p1), (p2), NULL, NULL)
+ #define STR3(fmt, p1, p2, p3) STR_Helper(_T(__FILE__), __LINE__, _T(fmt), (p1), (p2), (p3), NULL, NULL)
+ #define STR4(fmt, p1, p2, p3, p4) STR_Helper(_T(__FILE__), __LINE__, _T(fmt), (p1), (p2), (p3), (p4))
+ // ---
+
+ __inline void STR_Helper(const TCHAR* pszFile, unsigned int uLine, const TCHAR* pszFmt, ...)
+ {
+ va_list va;
+ TCHAR* pszText;
+
+ va_start(va, pszFmt);
+ pszText = CreateDebugText(pszFmt, pszFile, uLine, va);
+ va_end(va);
+
+ if (pszText)
+ {
+ OutputDebugString(pszText);
+ OutputDebugString(_T("\r\n"));
+
+ free(pszText);
+ }
+ }
+
+ #else
+ #define STR(str)
+ #define STR1(fmt, p1)
+ #define STR2(fmt, p1, p2)
+ #define STR3(fmt, p1, p2, p3)
+ #define STR4(fmt, p1, p2, p3, p4)
+ #endif
+
+
+
+ // DBG [simple wrapper around OutputDebugString]
+ #if !defined(DEACTIVATE_DEBUG_HELPER)
+ #define DBGT(str) OutputDebugString(_T(str)_T("\r\n"))
+ #define DBG(str) { OutputDebugString(str); OutputDebugString(_T("\r\n")); }
+ #else
+ #define DBGT(str)
+ #define DBG(str)
+ #endif
+
+
+
+ // LOG [append line to debug log file]
+ #if !defined(DEACTIVATE_DEBUG_HELPER)
+
+ // Functions:
+ #define LOG(str) LOG_Helper(_T(__FILE__), __LINE__, _T("%s"), _T(str))
+ #define LOG1(fmt, p1) LOG_Helper(_T(__FILE__), __LINE__, _T(fmt), (p1), NULL, NULL, NULL)
+ #define LOG2(fmt, p1, p2) LOG_Helper(_T(__FILE__), __LINE__, _T(fmt), (p1), (p2), NULL, NULL)
+ #define LOG3(fmt, p1, p2, p3) LOG_Helper(_T(__FILE__), __LINE__, _T(fmt), (p1), (p2), (p3), NULL)
+ #define LOG4(fmt, p1, p2, p3, p4) LOG_Helper(_T(__FILE__), __LINE__, _T(fmt), (p1), (p2), (p3), (p4))
+ // ---
+
+ __inline void LOG_Helper(const TCHAR* pszFile, unsigned int uLine, const TCHAR* pszFmt, ...)
+ {
+ va_list va;
+ DWORD dwDebugFileWritten = 0;
+ TCHAR* pszText;
+ TCHAR szDebugLogFile[MAX_PATH];
+ HANDLE hDebugLogFile;
+
+ static BOOL bFirstCall = TRUE;
+
+ va_start(va, pszFmt);
+ pszText = CreateDebugText(pszFmt, pszFile, uLine, va);
+ va_end(va);
+
+ // Filename
+ if (pszText)
+ {
+ GetModuleFileName(NULL, szDebugLogFile, sizeof(szDebugLogFile)-1);
+ PathRemoveFileSpec(szDebugLogFile);
+ PathAppend(szDebugLogFile, _T("Debug.log"));
+
+ hDebugLogFile = CreateFile(szDebugLogFile, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+
+ if (hDebugLogFile == INVALID_HANDLE_VALUE)
+ BOX("LOG ERROR: INVALID_HANDLE_VALUE");
+
+ SetFilePointer(hDebugLogFile, 0, NULL, bFirstCall?FILE_BEGIN:FILE_END);
+ WriteFile(hDebugLogFile, "\r\n", 2*sizeof(TCHAR), &dwDebugFileWritten, NULL);
+ WriteFile(hDebugLogFile, (PBYTE*)pszText, (DWORD)(lstrlen(pszText)*sizeof(TCHAR)), &dwDebugFileWritten, NULL);
+ SetEndOfFile(hDebugLogFile);
+
+ CloseHandle(hDebugLogFile);
+ free(pszText);
+
+ bFirstCall = FALSE;
+ }
+ }
+
+ #else
+ #define LOG(str)
+ #define LOG1(fmt, p1)
+ #define LOG2(fmt, p1, p2)
+ #define LOG3(fmt, p1, p2, p3)
+ #define LOG4(fmt, p1, p2, p3, p4)
+ #endif
+
+
+
+ // POP [show debug popup (Popup Plugin) with text]
+ /*
+ #if !defined(DEACTIVATE_DEBUG_HELPER)
+
+ // Functions:
+ #define POP(str) POP_Helper(_T(__FILE__), __LINE__, _T("%s"), _T(str))
+ #define POP1(fmt, p1) POP_Helper(_T(__FILE__), __LINE__, _T(fmt), (p1), NULL, NULL, NULL)
+ #define POP2(fmt, p1, p2) POP_Helper(_T(__FILE__), __LINE__, _T(fmt), (p1), (p2), NULL, NULL)
+ #define POP3(fmt, p1, p2, p3) POP_Helper(_T(__FILE__), __LINE__, _T(fmt), (p1), (p2), (p3), NULL)
+ #define POP4(fmt, p1, p2, p3, p4) POP_Helper(_T(__FILE__), __LINE__, _T(fmt), (p1), (p2), (p3), (p4))
+ // ---
+
+ __inline void POP_Helper(const TCHAR* pszFile, unsigned int uLine, const TCHAR* pszFmt, ...)
+ {
+ #ifdef MS_POPUP_SHOWMESSAGE
+ va_list va;
+ TCHAR* pszText;
+
+ va_start(va, pszFmt);
+ pszText = CreateDebugText(pszFmt, pszFile, uLine, va);
+ va_end(va);
+
+ // Only show if CTRL is not pressed
+ if (pszText)
+ {
+ if (!(GetAsyncKeyState(VK_CONTROL)&0x8000))
+ CallServiceSync(MS_POPUP_SHOWMESSAGE, (WPARAM)pszText, (LPARAM)SM_NOTIFY);
+
+ free(pszText);
+ }
+ #endif
+ }
+ #else
+ #define POP(str)
+ #define POP1(fmt, p1)
+ #define POP2(fmt, p1, p2)
+ #define POP3(fmt, p1, p2, p3)
+ #define POP4(fmt, p1, p2, p3, p4)
+ #endif
+ */
+
+
+ // LOOPPROT [prevent a loop (for/while/repeat) from becoming an infinite loop]
+ #if !defined(DEACTIVATE_DEBUG_HELPER)
+
+ // LOOPROT(0) breaks the loop when "Esc" is pressed
+
+ #define LOOPPROT(max) { \
+ static unsigned int uDebugLoopCount = 1; \
+ uDebugLoopCount++; \
+ if (GetAsyncKeyState(VK_ESCAPE)&0x8000) break; \
+ MessageBeep(MB_ICONEXCLAMATION); \
+ if (uDebugLoopCount > (max)) { \
+ break; \
+ BOX1("LOOPPROT:\nThe execution of the loop was stopped because it looped %u times.", max); \
+ uDebugLoopCount = 1;\
+ } \
+ }
+
+ #else
+ #define LOOPPROT(max)
+ #endif
+
+#endif