|
|
//
// Copyright(c) 1997 - 1999. Microsoft Corporation.
//
#ifndef __usp_dbg__
#define __usp_dbg__
#include <windows.h>
#ifdef __cplusplus
extern "C" { #endif
//// USP_DBG.HXX
//
// We define three levels of debug support:
//
// Highest DBG=1, TRC=1 Invasive debug
// Middle DBG=0, TRC=1 Safe debug
// Lowest DBG=0, TRC=0 No debug
//
// Safe debugging
//
// o Assertions and other failure trace messages
// o Flag controlled trace messages
//
// Invasive debugging adds
//
// o Unflagged trace messages
// o Extra cross checking fields in internal structures
// o Extra win32 api calls for validity checking
// o Performance measurements
//
// As long as no error situations occur, safe debugging should produce
// no messages on the debugging terminal.
//
// 'Checked' builds are always compiled with DBG=1, TRC=1.
//
// 'Free' builds are compiled with safe debugging until
// shortly before release, then for the last releases with no debugging.
//
// Care should be taken to ensure that the presence of safe debugging
// code does not change operation in any way, as there is little time
// at the end of the project to validate this.
#undef ASSERT
#undef ASSERTS
#undef ASSERTHR
#undef TRACEMSG
#undef TRACE
#undef LPKPUTS
#undef THROW
#undef BIDIPUTS
// Debug support requires tracing support
#if DBG
#define TRC 1
#endif
#if !TRC
/// No debug or tracing support
#define TRACEMSG(a)
#define TRACE(a,b)
#define ASSERT(x)
#define ASSERTS(a,b)
#define ASSERTHR(a,b)
#define TIMEENTRY(id, charcount)
#define TIMEEXIT(id)
#define TIMESUSPEND
#define TIMERESUME
__inline HRESULT HRESULT_FROM_LAST_WIN32_ERROR() {
int iWin32Error = GetLastError();
if (FAILED(HRESULT_FROM_WIN32(iWin32Error))) { return HRESULT_FROM_WIN32(iWin32Error); } else { return E_FAIL; // Guarantee that a Win32 error is always treated as failure
} }
#else
//// Safe debug support
//
//
/// Trace constants - each flag is separately controlled through the
// global variable 'Debug'.
//
// The checked build initialises debug from the registry.
// Create a key named 'SOFTWARE\\Microsoft\\Uniscribe'
// Add a DWORD value named 'Debug' containg the flags as below.
#define TRACE_API 0x00000001u // USP APIs
#define TRACE_BIDI 0x00000002u // Bidi shaper - CNTXFSM.C
#define TRACE_EDIT 0x00000004u // Edit control
#define TRACE_FASC 0x00000008u // Font association
#define TRACE_FONT 0x00000010u // Font analysis
#define TRACE_GDI 0x00000020u // GDI interface calls
#define TRACE_ITEM 0x00000040u // Item analysis FSM
#define TRACE_NLS 0x00000080u // NLS Info
#define TRACE_POSN 0x00000100u // GAD positioning functions
#define TRACE_SSA 0x00000200u // ScriptStringAnalyse
#define TRACE_SSO 0x00000400u // ScriptStringOut
#define TRACE_THAI 0x00000800u // Thai shaper
#define TRACE_CACHE 0x00001000u // Font caching
#define TRACE_TIME 0x00002000u // Timing entry/exit points
#define TRACE_CDM 0x00004000u // CDM Shaper
#define TRACE_ALLOC 0x00008000u // Memory allocation and deallocation
#define DEBUG_IGNOREREALIZATIONID 0x80000000u
#define DEBUG_IGNOREREGETCHARABCWIDTHSI 0x40000000u
#define DEBUG_TIMINGREPORT 0x20000000u
/// Tracing and assertion macros
//
#define TRACEMSG(a) {DG.psFile=__FILE__; DG.iLine=__LINE__; DebugMsg a;}
#define TRACE(a,b) {if (!DG.fDebugInitialised){DbgReadRegistrySettings();};if (debug & TRACE_##a) TRACEMSG(b);}
#define ASSERT(a) {if (!(a)) TRACEMSG(("Assertion failure: "#a));}
#define ASSERTS(a,b) {if (!(a)) TRACEMSG(("Assertion failure: "#a" - "#b));}
#define ASSERTHR(a,b) {if (!SUCCEEDED(a)) {DG.psFile=__FILE__; \
DG.iLine=__LINE__; DG.hrLastError=a; DebugHr b;}} #define HRESULT_FROM_LAST_WIN32_ERROR() ( \
DG.psFile=__FILE__, DG.iLine=__LINE__, \ HrFromLastErrorDbg())
/// Debug variables
//
struct DebugGlobals { char *psFile; int iLine; HRESULT hrLastError; // Last hresult from GDI
CHAR sLastError[100]; int nAllocs; int nFrees; int nTotalBytesRequested; int nCurrentBytesAllocated; int nMaxBytesAllocated; BOOL fDebugInitialised; // Don't read registry settings until after process attach
};
/// Debug function prototypes
//
BOOL WINAPI DebugInit(); void WINAPIV DebugMsg(char *fmt, ...); void WINAPIV DebugHr(char *fmt, ...); HRESULT WINAPI HrFromLastErrorDbg();
#ifdef USP_DLL
extern DebugGlobals DG; extern UINT debug; #else
extern __declspec(dllimport) DebugGlobals DG; extern __declspec(dllimport) UINT debug; #endif
#if DBG
void WINAPI DbgReadRegistrySettings(); #endif
//// Performance tracking
//
// Defines macros TIMEENTRY and TIMEEXIT to time code sequences.
//
// If an inner level TIMENTRY is encountered while a more global
// code sequence is being timed, the more global timing is stopped
// until the inner level TIMEXIT.
// I.e. timings reported for a given TIMENTRY/TIMEEXIT pair exclude
// time spent in nested timed sequences.
#if !DBG || !defined(i386)
#define DbgTimeEntry(a, b)
#define DbgTimeExit(a)
#define DbgTimeSuspend()
#define DbgTimeResume()
#define DbgTimingReport()
#define TIMEENTRY(id, charcount)
#define TIMEEXIT(id)
#define TIMESUSPEND
#define TIMERESUME
#define TIMINGINFOHERE
#else
#define TIME_LSA 0
#define TIME_SSA 1
#define TIME_RNS 2
#define TIME_SSAGDI 3
#define TIME_SI 4
#define TIME_SS 5
#define TIME_SP 6
#define TIME_UC 7
#define TIME_GFD 8
#define TIME_ACMAP 9
#define TIME_FCMAP 10
#define TIME_GETUNAM 11
#define TIME_GRI 12
#define TIME_PCW 13
#define TIME_LGM 14
#define TIME_USPALLOCCACHE 15
#define TIME_USPALLOCTEMP 16
#define TIME_USPFREE 17
#define TIME_SSO 18
#define TIME_SSOSBL 19
#define TIME_ETOBGC 20
#define TIME_ETOCOD 21
#define TIME_SSOSFF 22
#define TIME_STO 23
#define TIME_STOETO 24
#define TIME_MAX 25
typedef struct tagTimingInfo { PSTR pcTitle; __int64 i64TotalClocksUsed; __int64 i64ClocksAtLastEntry; __int64 i64NumTimesEntered; __int64 i64CharCountProcessed; int iCaller; // Who was active when we started, -1 if none,
} TIMINGINFO;
void WINAPI DbgTimeEntry(int id, int charcount); void WINAPI DbgTimeExit(int id); void WINAPI DbgTimeSuspend(); void WINAPI DbgTimeResume(); void WINAPI DbgTimingReport();
#define TIMEENTRY(id, charcount) DbgTimeEntry(TIME_##id, charcount)
#define TIMEEXIT(id) DbgTimeExit(TIME_##id)
#define TIMESUSPEND DbgTimeSuspend()
#define TIMERESUME DbgTimeResume()
#define TIMINGINFOHERE \
\ TIMINGINFO ti[] = { \ {"LpkStringAnalyze", 0, 0, 0, 0, -1}, \ {"ScriptStringAnalyze", 0, 0, 0, 0, -1}, \ {"ReadNLSScriptSettings", 0, 0, 0, 0, -1}, \ {"SSA gdi calls", 0, 0, 0, 0, -1}, \ {"ScriptItemize", 0, 0, 0, 0, -1}, \ {"ScriptShape", 0, 0, 0, 0, -1}, \ {"ScriptPlace", 0, 0, 0, 0, -1}, \ {"UpdateCache", 0, 0, 0, 0, -1}, \ {"GetFontDetails", 0, 0, 0, 0, -1}, \ {"Allocate CMAP", 0, 0, 0, 0, -1}, \ {"Fill CMAP", 0, 0, 0, 0, -1}, \ {"Get Unicode Name and Metrics",0, 0, 0, 0, -1}, \ {"GetRealizationInfo", 0, 0, 0, 0, -1}, \ {"Preload common widths", 0, 0, 0, 0, -1}, \ {"LoadGlyphMetrics", 0, 0, 0, 0, -1}, \ {"USPALLOCCACHE", 0, 0, 0, 0, -1}, \ {"USPALLOCTEMP", 0, 0, 0, 0, -1}, \ {"USPFREE", 0, 0, 0, 0, -1}, \ {"ScriptStringOut", 0, 0, 0, 0, -1}, \ {"ScriptStringOut - StBtchLm", 0, 0, 0, 0, -1}, \ {"ScriptStringOut - bkg clr", 0, 0, 0, 0, -1}, \ {"ScriptStringOut - end pnts", 0, 0, 0, 0, -1}, \ {"ScriptStringOut - slctflbck", 0, 0, 0, 0, -1}, \ {"ScriptTextOut", 0, 0, 0, 0, -1}, \ {"SimpleTextOut - ETO", 0, 0, 0, 0, -1}, \ }; \ \ int iStdParent[TIME_MAX] = \ {-1,-1,-1,-1, \ -1,-1,-1,-1, \ -1,-1,-1,-1, \ -1,-1,-1,-1, \ -1,-1,-1,-1, \ -1,-1,-1,-1, \ -1};
#endif
#endif
#ifdef __cplusplus
} #endif
#endif
|