Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

303 lines
8.6 KiB

//----------------------------------------------------------------------------
//
// cppdbg.hpp
//
// C++-only debugging support.
//
// Copyright (C) Microsoft Corporation, 1997.
//
//----------------------------------------------------------------------------
#ifndef _CPPDBG_HPP_
#define _CPPDBG_HPP_
#if DBG
#include <stdarg.h>
typedef unsigned int UINT;
//
// Mask bits common to all modules.
//
#define DBG_MASK_NO_PREFIX 0x80000000
#define DBG_MASK_FORCE 0x40000000
// Mask bits checked against output mask.
#define DBG_MASK_CHECK (~(DBG_MASK_NO_PREFIX | \
DBG_MASK_FORCE))
// Forced continuation mask.
#define DBG_MASK_FORCE_CONT (DBG_MASK_NO_PREFIX | DBG_MASK_FORCE)
//
// Failure control bits for assert and HRESULT failures.
//
#define DBG_FAILURE_BREAK 0x00000001
#define DBG_FAILURE_OUTPUT 0x00000002
#define DBG_FAILURE_PROMPT 0x00000004
#define DBG_FAILURE_FILENAME_ONLY 0x00000008
//
// Overall output control bits.
//
#define DBG_OUTPUT_SUPPRESS 0x00000001
#define DBG_OUTPUT_ALL_MATCH 0x00000002
//----------------------------------------------------------------------------
//
// DebugModule
//
//----------------------------------------------------------------------------
struct DebugModuleFlags
{
UINT uFlag;
char *pName;
};
// Declares a DebugModuleFlags entry.
#define DBG_DECLARE_MODFLAG(Group, Name) \
Group ## _ ## Name, #Name
enum
{
DBG_ASSERT_FLAGS,
DBG_HR_FLAGS,
DBG_OUTPUT_FLAGS,
DBG_OUTPUT_MASK,
DBG_USER_FLAGS,
DBG_FLAGS_COUNT
};
class DebugModule
{
public:
DebugModule(char *pModule, char *pPrefix,
DebugModuleFlags *pOutputMasks, UINT uOutputMask,
DebugModuleFlags *pUserFlags, UINT uUserFlags);
void Out(char *pFmt, ...);
void OutMask(UINT uMask, char *pFmt, ...)
{
if ((uMask & DBG_MASK_FORCE) ||
((m_uFlags[DBG_OUTPUT_FLAGS] & DBG_OUTPUT_ALL_MATCH) &&
(uMask & m_uFlags[DBG_OUTPUT_MASK] & DBG_MASK_CHECK) == uMask) ||
((m_uFlags[DBG_OUTPUT_FLAGS] & DBG_OUTPUT_ALL_MATCH) == 0 &&
(uMask & m_uFlags[DBG_OUTPUT_MASK] & DBG_MASK_CHECK) != 0))
{
va_list Args;
va_start(Args, pFmt);
OutVa(uMask, pFmt, Args);
va_end(Args);
}
}
void AssertFailed(char *pExp);
void AssertFailedMsg(char *pFmt, ...);
void HrStmtFailed(HRESULT hr);
HRESULT HrExpFailed(HRESULT hr);
void SetFileLine(char *pFile, int iLine)
{
m_pFile = pFile;
m_iLine = iLine;
}
void Prompt(char *pFmt, ...);
UINT GetFlags(int iIdx)
{
return m_uFlags[iIdx];
}
void SetFlags(int iIdx, UINT uValue)
{
m_uFlags[iIdx] = uValue;
}
private:
void OutVa(UINT uMask, char *pFmt, va_list Args);
void AssertFailedVa(char *pFmt, va_list Args, BOOL bNewLine);
HKEY OpenDebugKey(void);
UINT GetRegUint(HKEY hKey, char *pValue, UINT uDefault);
BOOL SetRegUint(HKEY hKey, char *pValue, UINT uValue);
void ReadReg(void);
void WriteReg(void);
UINT ParseUint(char *pString, DebugModuleFlags *pFlags);
void OutUint(char *pName, DebugModuleFlags *pFlags, UINT uValue);
void AdvanceCols(int iCols);
void ShowFlags(char *pName, DebugModuleFlags *pFlags);
char *PathFile(char *pPath);
BOOL OutPathFile(char *pPrefix, UINT uFailureFlags);
void HrFailure(HRESULT hr, char *pPrefix);
char *HrString(HRESULT hr);
// Module information given.
char *m_pModule;
char *m_pPrefix;
// Flag descriptions and values.
DebugModuleFlags *m_pModFlags[DBG_FLAGS_COUNT];
UINT m_uFlags[DBG_FLAGS_COUNT];
// Temporary file and line number storage.
char *m_pFile;
int m_iLine;
// Output column during multiline display.
int m_iModuleStartCol;
int m_iCol;
int m_iStartCol;
};
//----------------------------------------------------------------------------
//
// Support macros.
//
//----------------------------------------------------------------------------
#define DBG_MODULE(Prefix) Prefix ## _Debug
// Put this in one source file.
#define DBG_DECLARE_ONCE(Module, Prefix, pOutputMasks, uOutputMask, \
pUserFlags, uUserFlags) \
DebugModule DBG_MODULE(Prefix)(#Module, #Prefix, \
pOutputMasks, uOutputMask, \
pUserFlags, uUserFlags)
// Put this in your derived debugging header.
#define DBG_DECLARE_HEADER(Prefix) \
extern DebugModule DBG_MODULE(Prefix)
// Put this in every file.
#define DBG_DECLARE_FILE() \
static char *g_pStaticDebugFile = __FILE__
#define DBG_DECLARE_DPF(Prefix, Args) \
DBG_MODULE(Prefix).Out Args
#define DBG_DECLARE_DPFM(Prefix, Args) \
DBG_MODULE(Prefix).OutMask Args
#define DBG_DECLARE_ASSERT(Prefix, Exp) \
if (!(Exp)) \
{ DBG_MODULE(Prefix).SetFileLine(g_pStaticDebugFile, __LINE__); \
DBG_MODULE(Prefix).AssertFailed(#Exp); } \
else 0
#define DBG_DECLARE_ASSERTMSG(Prefix, Exp, Args) \
if (!(Exp)) \
{ DBG_MODULE(Prefix).SetFileLine(g_pStaticDebugFile, __LINE__); \
DBG_MODULE(Prefix).AssertFailedMsg Args ; } \
else 0
#define DBG_DECLARE_VERIFY(Prefix, Exp) \
DBG_DECLARE_ASSERT(Prefix, Exp)
#define DBG_DECLARE_VERIFYMSG(Prefix, Exp, Args)\
DBG_DECLARE_ASSERTMSG(Prefix, Exp, Args)
#define DBG_DECLARE_PROMPT(Prefix, Args) \
DBG_MODULE(Prefix).Prompt Args
#define DBG_DECLARE_GETFLAGS(Prefix, Idx) \
DBG_MODULE(Prefix).GetFlags(Idx)
#define DBG_DECLARE_SETFLAGS(Prefix, Idx, Value) \
DBG_MODULE(Prefix).SetFlags(Idx, Value)
//
// These macros assume a variable 'hr' exists.
//
// HRESULT test in expression form.
#define DBG_DECLARE_HRCHK(Prefix, Exp) \
((hr = (Exp)) != S_OK ? \
(DBG_MODULE(Prefix).SetFileLine(g_pStaticDebugFile, __LINE__), \
DBG_MODULE(Prefix).HrExpFailed(hr)) : hr)
// HRESULT test in if/then form.
#define DBGI_DECLARE_HRIF(Prefix, Exp, DoFail) \
if ((hr = (Exp)) != S_OK) \
{ DBG_MODULE(Prefix).SetFileLine(g_pStaticDebugFile, __LINE__); \
DBG_MODULE(Prefix).HrStmtFailed(hr); \
DoFail; } \
else hr
#define DBG_DECLARE_HRGO(Prefix, Exp, Label) \
DBGI_DECLARE_HRIF(Prefix, Exp, goto Label)
#define DBG_DECLARE_HRERR(Prefix, Exp) \
DBG_DECLARE_HRGO(Prefix, Exp, HR_Err)
#define DBG_DECLARE_HRRET(Prefix, Exp) \
DBGI_DECLARE_HRIF(Prefix, Exp, return hr)
#else // #if DBG
//
// Empty macros for free builds.
//
#define DBG_MODULE(Prefix) 0
#define DBG_DECLARE_ONCE(Module, Prefix, pOutputMasks, uOutputMask, \
pUserFlags, uUserFlags)
#define DBG_DECLARE_HEADER(Prefix)
#define DBG_DECLARE_FILE()
#define DBG_DECLARE_DPF(Prefix, Args)
#define DBG_DECLARE_DPFM(Prefix, Args)
#define DBG_DECLARE_ASSERT(Prefix, Exp)
#define DBG_DECLARE_ASSERTMSG(Prefix, Exp, Args)
#define DBG_DECLARE_PROMPT(Prefix, Args)
#define DBG_DECLARE_GETFLAGS(Prefix, Idx) 0
#define DBG_DECLARE_SETFLAGS(Prefix, Idx, Value)
//
// Macros which evaluate to code on free builds.
//
#define DBG_DECLARE_VERIFY(Prefix, Exp) (Exp)
#define DBG_DECLARE_VERIFYMSG(Prefix, Exp, Args) (Exp)
#define DBG_DECLARE_HRCHK(Prefix, Exp) \
(hr = (Exp))
#define DBGI_DECLARE_HRIF(Prefix, Exp, DoFail) \
if ((hr = (Exp)) != S_OK) DoFail; else hr
#define DBG_DECLARE_HRGO(Prefix, Exp, Label) \
DBGI_DECLARE_HRIF(Prefix, Exp, goto Label)
#define DBG_DECLARE_HRERR(Prefix, Exp) \
DBG_DECLARE_HRGO(Prefix, Exp, HR_Err)
#define DBG_DECLARE_HRRET(Prefix, Exp) \
DBGI_DECLARE_HRIF(Prefix, Exp, return hr)
#endif // #if DBG
//----------------------------------------------------------------------------
//
// Global debug module.
//
//----------------------------------------------------------------------------
DBG_DECLARE_HEADER(G);
#define GDPF(Args) DBG_DECLARE_DPF(G, Args)
#define GDPFM(Args) DBG_DECLARE_DPFM(G, Args)
#define GASSERT(Exp) DBG_DECLARE_ASSERT(G, Exp)
#define GASSERTMSG(Exp, Args) DBG_DECLARE_ASSERTMSG(G, Exp, Args)
#define GVERIFY(Exp) DBG_DECLARE_VERIFY(G, Exp)
#define GVERIFYMSG(Exp) DBG_DECLARE_VERIFYMSG(G, Exp, Args)
#define GPROMPT(Args) DBG_DECLARE_PROMPT(G, Args)
#define GGETFLAGS(Idx) DBG_DECLARE_GETFLAGS(G, Idx)
#define GSETFLAGS(Idx, Value) DBG_DECLARE_SETFLAGS(G, Idx, Value)
#define GHRCHK(Exp) DBG_DECLARE_HRCHK(G, Exp)
#define GHRGO(Exp, Label) DBG_DECLARE_HRGO(G, Exp, Label)
#define GHRERR(Exp) DBG_DECLARE_HRERR(G, Exp)
#define GHRRET(Exp) DBG_DECLARE_HRRET(G, Exp)
#endif // #ifndef _CPPDBG_HPP_