From 7fd9fe181150f166a098eaf4e006f878c28cb770 Mon Sep 17 00:00:00 2001 From: Gluzskiy Alexandr Date: Mon, 15 Feb 2010 05:51:01 +0300 Subject: sort --- Utilities/DebugHelper.h | 338 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 338 insertions(+) create mode 100644 Utilities/DebugHelper.h (limited to 'Utilities/DebugHelper.h') diff --git a/Utilities/DebugHelper.h b/Utilities/DebugHelper.h new file mode 100644 index 0000000..cf1b4b3 --- /dev/null +++ b/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 -- cgit v1.2.3