📄 ehm.h
字号:
/***********************************************************
ehm.h
Error handling macros
Author(s): KKennedy (derived from many sources)
{x,}{CVD}{H,P,B,W}R{A,}{Ex,}
C=check, V=verify, D=dump
H=hresult, P=ptr, B=bool, W=windows
R=result
A=assert
Ex=extended version
x=wart, suppresses assert due to practical pblm (obsolete!)
C checks, and bails on failure after setting hr
A adds an ASSERT before the bail
V checks, and ASSERTs on failure
D checks, and SPEWs on failure
(yes, the 'A' is inconsistent)
Ex adds overriding failure-case 'E_*' of user's choice
x is obsolete, you shouldn't use it
n.b. we only have some of the above implemented (the ones we've needed
so far...)
if you're an unlucky soul and run into a label collision, use the
_ehmErrorLab mechanism (see below).
_ehmOnAssertionFail
Allows custom processing of a failure in macros that assert.
As defined here, this maps to OnAssertionFail().
By defining this earlier, you could implement custom logging of the failure
_ehmOnFail
Allows custom processing of a failure in macros that don't assert.
As defined here, this maps to nothing.
By defining this earlier, you could implement custom logging of the failure.
UTCore.H - takes advantage of both _ehmOnFail and _ehmOnAssertionFail
extensions to provide slightly different behavior and enable logging
for unit tests.
see also the document: <todo: ptr to in kk's ehm .doc>
NOTES
we use the "if (0,fResult), while (0,0)" style in order to suppress W4 warnings. the PF_EXPR wraps that to keep prefix happy.
*/
#ifndef _EHM_H_
#define _EHM_H_
#ifdef FAILPOINTS_ENABLED
#include "fault\failpt.h"
#endif // FAILPOINTS_ENABLED
#ifdef __cplusplus
extern "C"
{
#endif
// 99% of the time ehm.h "just works". however 1% of the time the "Error"
// label is already in use (e.g. for some other macro package). if you hit
// that, do this:
// #define _ehmErrorLab EhmError
// #include <ehm.h>
// ... and then use EhmError as your label. it may seem a bit silly to add
// this extra indirection vs. just use EhmError always, but given that it's
// a 99%/1%, it seems worthwhile.
//
// our suggestion is that custom clients standardize on "EhmError", but if
// need be, they can choose whatever they want.
#ifndef _ehmErrorLab
#define _ehmErrorLab Error
#endif
// If you define the value for _ehmOnAssertionFail before #including ehm.h you
// can change what _ehmOnAssertionFail does
// Remember this affects all xxxA macros
#ifndef _ehmOnAssertionFail
#define _ehmOnAssertionFail(eType, dwCode, pszFile, ulLine, pszMessage) \
OnAssertionFail(eType, dwCode, pszFile, ulLine, pszMessage)
#endif
// If you define the value for _ehmOnFail before #including ehm.h you
// can change what _ehmOnFail does
// Remember this affects all non-A macros
#ifndef _ehmOnFail
#define _ehmOnFail(eType, dwCode, pszFile, ulLine, pszMessage) { }
#endif
typedef enum
{
eHRESULT,
eBOOL,
ePOINTER,
eWINDOWS
} eCodeType;
BOOL ShouldBreakOnAssert();
BOOL OnAssertionFail(eCodeType eType, DWORD dwCode, const TCHAR* pszFile, unsigned long ulLine, const TCHAR* pszMessage);
// Check HRESULT
#define _CHREx0_DONTINJECTFAILURE(hResult) \
do { \
hr = (hResult); \
if(FAILED(hr)) \
{ \
_ehmOnFail(eHRESULT, 0, TEXT(__FILE__), __LINE__, TEXT("CHR(") TEXT( # hResult ) TEXT(")")); \
goto _ehmErrorLab; \
} \
} while (0,0)
#define _CHR_DONTINJECTFAILURE(hResult, hrFail) \
do { \
hr = (hResult); \
if(FAILED(hr)) \
{ \
hr = (hrFail); \
_ehmOnFail(eHRESULT, 0, TEXT(__FILE__), __LINE__, TEXT("CHR(") TEXT( # hResult ) TEXT(")")); \
goto _ehmErrorLab; \
} \
} while (0,0)
#ifdef FAILPOINTS_ENABLED
#define _CHREx0(hResult) \
do { \
BOOL fFailPoint = SOS_StackHashingControl__GenericFailure(); \
hr = (hResult); \
hr = FAILED(hr) ? \
hr : \
fFailPoint ? \
E_HRFAILPOINT: \
hr; \
if(FAILED(hr)) \
{ \
_ehmOnFail(eHRESULT, 0, TEXT(__FILE__), __LINE__, TEXT("CHR(") TEXT( # hResult ) TEXT(")")); \
goto _ehmErrorLab; \
} \
} while (0,0)
#define _CHR(hResult, hrFail) \
do { \
BOOL fFailPoint = SOS_StackHashingControl__GenericFailure(); \
hr = (hResult); \
hr = FAILED(hr) ? \
hr : \
fFailPoint ? \
E_HRFAILPOINT: \
hr; \
if(FAILED(hr)) \
{ \
hr = (hrFail); \
_ehmOnFail(eHRESULT, 0, TEXT(__FILE__), __LINE__, TEXT("CHR(") TEXT( # hResult ) TEXT(")")); \
goto _ehmErrorLab; \
} \
} while (0,0)
#else // #ifdef FAILPOINTS_ENABLED
#define _CHREx0(hResult) _CHREx0_DONTINJECTFAILURE(hResult)
#define _CHR(hResult, hrFail) _CHR_DONTINJECTFAILURE(hResult, hrFail)
#endif // #ifdef FAILPOINTS_ENABLED
// Check pointer result
#define _CPR_DONTINJECTFAILURE(p, hrFail) \
do { \
if (PF_EXPR(!(p))) \
{ \
hr = (hrFail); \
_ehmOnFail(ePOINTER, 0, TEXT(__FILE__), __LINE__, TEXT("CPR(") TEXT( # p ) TEXT(")")); \
goto _ehmErrorLab; \
} \
} while (0,0)
// Check boolean result
#define _CBR_DONTINJECTFAILURE(fResult, hrFail) \
do { \
if (PF_EXPR(!(fResult))) \
{ \
hr = (hrFail); \
_ehmOnFail(eBOOL, 0, TEXT(__FILE__), __LINE__, TEXT("CBR(") TEXT( # fResult ) TEXT(")")); \
goto _ehmErrorLab; \
} \
} while(0,0)
#ifdef FAILPOINTS_ENABLED
// Check pointer result
#define _CPR(p, hrFail) \
do { \
BOOL fFailPoint = SOS_StackHashingControl__GenericFailure(); \
if (fFailPoint || PF_EXPR(!(p))) \
{ \
hr = (hrFail); \
_ehmOnFail(ePOINTER, 0, TEXT(__FILE__), __LINE__, TEXT("CPR(") TEXT( # p ) TEXT(")")); \
goto _ehmErrorLab; \
} \
} while (0,0)
// Check boolean result
#define _CBR(fResult, hrFail) \
do { \
BOOL fFailPoint = SOS_StackHashingControl__GenericFailure(); \
if (fFailPoint || PF_EXPR(!(fResult))) \
{ \
hr = (hrFail); \
_ehmOnFail(eBOOL, 0, TEXT(__FILE__), __LINE__, TEXT("CBR(") TEXT( # fResult ) TEXT(")")); \
goto _ehmErrorLab; \
} \
} while(0,0)
#else // #ifdef FAILPOINTS_ENABLED
#define _CPR(hResult, hrFail) _CPR_DONTINJECTFAILURE(hResult, hrFail)
#define _CBR(hResult, hrFail) _CBR_DONTINJECTFAILURE(hResult, hrFail)
#endif // #ifdef FAILPOINTS_ENABLED
// Check windows result. Exactly like CBR for the non-Asserting case - BUT we log differently
#define _CWR(fResult, hrFail) \
do { \
if (PF_EXPR(!(fResult))) \
{ \
hr = (hrFail); \
_ehmOnFail(eWINDOWS, 0, TEXT(__FILE__), __LINE__, TEXT("CWR(") TEXT( # fResult ) TEXT(")")); \
goto _ehmErrorLab; \
} \
} while(0,0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -