diff options
author | Gluzskiy Alexandr <sss123next@list.ru> | 2009-10-13 05:04:06 +0300 |
---|---|---|
committer | Gluzskiy Alexandr <sss123next@list.ru> | 2009-10-13 05:04:06 +0300 |
commit | 227022d9ed977c75196725502847e0b371e4e879 (patch) | |
tree | 6fe79f5ae836fe4a974db459553eb6b46a1bf8eb /spamfilter/Utilities/DebugHelper.h | |
parent | 23d6d3e482927c13294f204b34ce23c6f445e8ac (diff) |
Diffstat (limited to 'spamfilter/Utilities/DebugHelper.h')
-rw-r--r-- | spamfilter/Utilities/DebugHelper.h | 338 |
1 files changed, 338 insertions, 0 deletions
diff --git a/spamfilter/Utilities/DebugHelper.h b/spamfilter/Utilities/DebugHelper.h new file mode 100644 index 0000000..cf1b4b3 --- /dev/null +++ b/spamfilter/Utilities/DebugHelper.h @@ -0,0 +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
|