/*++ Copyright (c) 1996 - 1999 Microsoft Corporation Module Name: debug.h Abstract: Macros used for debugging purposes Environment: Windows NT printer drivers Revision History: 03/16/96 -davidx- Created it. --*/ #ifndef _DEBUG_H_ #define _DEBUG_H_ #ifdef __cplusplus extern "C" { #endif // // These macros are used for debugging purposes. They expand // to white spaces on a free build. Here is a brief description // of what they do and how they are used: // // giDebugLevel // Global variable which set the current debug level to control // the amount of debug messages emitted. // // VERBOSE(msg) // Display a message if the current debug level is <= DBG_VERBOSE. // // TERSE(msg) // Display a message if the current debug level is <= DBG_TERSE. // // WARNING(msg) // Display a message if the current debug level is <= DBG_WARNING. // The message format is: WRN filename (linenumber): message // // ERR(msg) // Similiar to WARNING macro above - displays a message // if the current debug level is <= DBG_ERROR. // // ASSERT(cond) // Verify a condition is true. If not, force a breakpoint. // // ASSERTMSG(cond, msg) // Verify a condition is true. If not, display a message and // force a breakpoint. // // RIP(msg) // Display a message and force a breakpoint. // // Usage: // These macros require extra parantheses for the msg argument // example, ASSERTMSG(x > 0, ("x is less than 0\n")); // WARNING(("App passed NULL pointer, ignoring...\n")); // #define DBG_VERBOSE 1 #define DBG_TERSE 2 #define DBG_WARNING 3 #define DBG_ERROR 4 #define DBG_RIP 5 #if DBG // // Strip the directory prefix from a filename (ANSI version) // PCSTR StripDirPrefixA( IN PCSTR pstrFilename ); extern INT giDebugLevel; #if defined(KERNEL_MODE) && !defined(USERMODE_DRIVER) extern VOID DbgPrint(PCSTR, ...); #define DbgBreakPoint EngDebugBreak #else extern ULONG _cdecl DbgPrint(PCSTR, ...); extern VOID DbgBreakPoint(VOID); #endif #define DBGMSG(level, prefix, msg) { \ if (giDebugLevel <= (level)) { \ DbgPrint("%s %s (%d): ", prefix, StripDirPrefixA(__FILE__), __LINE__); \ DbgPrint msg; \ } \ } #define DBGPRINT(level, msg) { \ if (giDebugLevel <= (level)) { \ DbgPrint msg; \ } \ } #define VERBOSE(msg) DBGPRINT(DBG_VERBOSE, msg) #define TERSE(msg) DBGPRINT(DBG_TERSE, msg) #define WARNING(msg) DBGMSG(DBG_WARNING, "WRN", msg) #define ERR(msg) DBGMSG(DBG_ERROR, "ERR", msg) #ifndef __MDT__ // Don't redefine ASSERT when included in MINIDEV.EXE. #define ASSERT(cond) { \ if (! (cond)) { \ RIP(("\n")); \ } \ } #endif #define ASSERTMSG(cond, msg) { \ if (! (cond)) { \ RIP(msg); \ } \ } #define RIP(msg) { \ DBGMSG(DBG_RIP, "RIP", msg); \ DbgBreakPoint(); \ } #else // !DBG #define VERBOSE(msg) #define TERSE(msg) #define WARNING(msg) #define ERR(msg) #ifndef __MDT__ // Don't redefine ASSERT when included in MINIDEV.EXE. #define ASSERT(cond) #endif #define ASSERTMSG(cond, msg) #define RIP(msg) #define DBGMSG(level, prefix, msg) #define DBGPRINT(level, msg) #endif // // The following macros let you enable tracing on per-file and per-function level. // To use these macros in a file, here is what you should do: // // At the beginning of the file (after header includes): // // Define a bit constant for each function you want to trace // Add the following line // DEFINE_FUNCTION_TRACE_FLAGS(flags); // where flags is a bit-wise OR of the functions you want to trace, e.g. // TRACE_FLAG_FUNC1 | TRACE_FLAG_FUNC2 | ... // // To generate trace inside each function you want to trace, use: // FUNCTION_TRACE(FunctionTraceFlag, (args)); // #if DBG #define DEFINE_FUNCTION_TRACE_FLAGS(flags) \ static DWORD gdwFunctionTraceFlags = (flags) #define FUNCTION_TRACE(flag, args) { \ if (gdwFunctionTraceFlags & (flag)) { \ DbgPrint args; \ } \ } #else // !DBG #define DEFINE_FUNCTION_TRACE_FLAGS(flags) #define FUNCTION_TRACE(flag, args) #endif // !DBG #ifdef __cplusplus } #endif #endif // !_DEBUG_H_