📄 hxassert.h
字号:
//// STOPLOGSINK: Shutdown and Release the error sink. ///////////////////////////////////////////////////////////////////////////////#ifndef _GOLD#ifndef _INTERFACE#define _INTERFACE struct#endiftypedef _INTERFACE IHXErrorMessages IHXErrorMessages; const char* FileAndLine(const char* pFile, UINT32 ulLine); HX_RESULT HXLogf(IHXErrorMessages *pErr, UINT8 sev, HX_RESULT err, UINT32 usr, const char* pURL, const char* pUsrStr, ...); HX_RESULT HXLog(IHXErrorMessages *pErr, UINT8 sev, HX_RESULT err, UINT32 usr, const char* pStr, const char* pURL);#define THIS_LINE() FileAndLine(__FILE__, __LINE__)#define HX_STARTLOG(__IUnknown, __ErrorMessages) \ __IUnknown->QueryInterface(IID_IHXErrorMessages, (void **)&__ErrorMessages); \ HX_ASSERT(__ErrorMessages != NULL && "Must have IHXErrorMessages interface to start logging")#define HX_LOG HXLog#define HX_LOGF HXLogf#define HX_STOPLOG(__ErrorMessages) HX_RELEASE(__ErrorMessages)#else // _GOLD#define HX_STARTLOG(x,y) (void)0#define HX_LOG 1 ? (void)0 : HXLog#define HX_LOGF 1 ? (void)0 : HXLogf#define HX_STOPLOG(x) (void)0#endif///////////////////////////////////////////////////////////////////////////////// HX_SAFESIZE_T//#define HX_SAFESIZE_T(f) \ ( ((ULONG32)(f) <= (size_t)-1)?((size_t)(f)): \ (HXAssertFailedLine("size_t overflow",__FILE__, __LINE__), (size_t)(f)) ) \///////////////////////////////////////////////////////////////////////////////// HX_SAFEINT//#ifndef _VXWORKS#define HX_SAFEINT(f) \ ( ((LONG32)(f) <= LONG_MAX && ((LONG32)(f)) >= ((LONG32)(LONG_MIN)))?((int)(f)): \ (HXAssertFailedLine("Integer Size Overflow",__FILE__, __LINE__), (int)(f)) ) \#else#ifdef __cplusplusextern "C"#endifint safe_int_func_call(LONG32 f);#define HX_SAFEINT(f) safe_int_func_call((LONG32)(f))#endif#define HX_SAFEUINT(f) \ ( ((ULONG32)(f) <= ULONG_MAX && (LONG32)(f) >= 0)?((unsigned int)(f)): \ (HXAssertFailedLine("Unsigned Integer Size Overflow",__FILE__, __LINE__), (unsigned int)(f)) ) \#define HX_SAFEINT16(f) \ ( ((LONG32)(f) <= SHRT_MAX && (LONG32)(f) >= SHRT_MIN)?((short)(f)): \ (HXAssertFailedLine("Short Integer Size Overflow",__FILE__, __LINE__), (short)(f)) ) \#define HX_SAFEUINT16(f) \ ( ((ULONG32)(f) <= USHRT_MAX && (LONG32)(f) >= 0)?((unsigned short)(f)): \ (HXAssertFailedLine("Unsigned Short Integer Size Overflow",__FILE__, __LINE__), (unsigned short)(f)) ) \#define HX_SAFEINT8(f) \ ( ((LONG32)(f) <= SCHAR_MAX && (LONG32)(f) >= SCHAR_MIN)?((char)(f)): \ (HXAssertFailedLine("Signed Char Size Overflow",__FILE__, __LINE__), (char)(f)) ) \#define HX_SAFEUINT8(f) \ ( ((ULONG32)(f) <= UCHAR_MAX && (LONG32)(f) >= 0)?((unsigned char)(f)): \ (HXAssertFailedLine("Unsigned Char Size Overflow",__FILE__, __LINE__), (unsigned char)(f)) ) \ ///////////////////////////////////////////////////////////////////////////////// HX_SAFE_VOID2HANDLE//#if defined(_WINDOWS)#ifdef _WIN32#define HX_SAFE_VOID2HANDLE(f) ((HANDLE)(f))#else // !_WIN23#define HX_SAFE_VOID2HANDLE(f) ((HANDLE)LOWORD(f))// this doesn't work most of the time since the assignment of a handle (near *) to a// void * sets the high word to the SS.// ( ( (0xFFFF0000 & ((ULONG32)(f))) == 0)?((HANDLE)LOWORD(f)): // (HXAssertFailedLine("HANDLE HIWORD NOT NULL",__FILE__, __LINE__), (HANDLE)LOWORD(f)) ) #endif#elif defined ( __MWERKS__ )#define HX_SAFE_VOID2HANDLE(f) (f)#elif defined ( _UNIX )#define HX_SAFE_VOID2HANDLE(f) (f)#endif // end of#if defined(_WIN32) || defined(_WINDOWS)///////////////////////////////////////////////////////////////////////////////// HX_VERIFY: see above.//#define HX_VERIFY(f) HX_ASSERT(f)///////////////////////////////////////////////////////////////////////////////// HX_ASSERT_VALID_PTR: see above.//#define HX_ASSERT_VALID_PTR(pOb) (::HXAssertValidPointer(pOb, __FILE__, __LINE__))#define HX_ASSERT_VALID_READ_PTR(pOb) HX_ASSERT(::HXIsValidAddress(pOb, 1, FALSE))///////////////////////////////////////////////////////////////////////////////// _SAFESTRING: Similar to HX_TRACE() except that it assume you are// using a single format string, with a single parameter string, this will// ensure that the length of the resulting format is less than the maximum// trace string, and gracefully handle the situation...//#define HX_TRACE_SAFESTRING(f,s)\ if ((strlen(f) + strlen(s)) < (size_t)MAX_TRACE_OUTPUT)\ {\ HX_TRACE(f,s);\ }\ else\ {\ HX_TRACE(f,"Some really big URL");\ }\#else // _DEBUG#ifndef _DEBUG#ifndef HX_ENABLE_JIT_DEBUGGING#define HX_ENABLE_JIT_DEBUGGING()#endif#ifdef HXAbort#undef HXAbort#endif // end of#ifdef HXAbort#define HXAbort()#endif // _DEBUG#ifndef _DEBUG#ifdef HXDebugBreak#undef HXDebugBreak#endif // end of#ifdef HXDebugBreak#define HXDebugBreak()#endif // _DEBUG || DEBUG///////////////////////////////////////////////////////////////////////////////// HX_SAFEINT//#define HX_SAFEINT(f) ((int)(f)) #define HX_SAFEUINT(f) ((unsigned int)(f)) #define HX_SAFEINT16(f) ((short)(f)) #define HX_SAFEUINT16(f) ((unsigned short)(f)) #define HX_SAFEINT8(f) ((char)(f)) #define HX_SAFEUINT8(f) ((unsigned char)(f)) #define HX_ASSERT(f) ((void)0)#define HX_SAFESIZE_T(f) ((size_t)(f))#define HX_SAFEINT(f) ((int)(f))#define HX_SAFE_VOID2HANDLE(f) ((HANDLE)(ULONG32)(f))#define HX_ASSERT_VALID_PTR(pOb) ((void)0)#define HX_ASSERT_VALID_READ_PTR(pOb) ((void)0)#define HXOutputDebugString(f) ((void)0)#define REQUIRE_REPORT(targ,file,line) ((int)0)#if defined (_MACINTOSH)// this is the proper release version of HX_VERIFY that preserves the syntactic// role of the debug version; it's necessary to quiet warnings on the Mac#define HX_VERIFY(f) do { if (!(f)) {} } while (0)#else#define HX_VERIFY(f) ((void)(f))#endif#if defined (_WINDOWS)__inline void __cdecl HXTrace(const char* x, ...) { }#elsestatic __inline void HXTrace(const char* x, ...) {}#endif#define HX_TRACE 1 ? (void)0 : ::HXTrace#define HX_TRACE_SAFESTRING HX_TRACE#endif // !_DEBUG#ifdef __cplusplus} // end extern "C"#endif#ifdef __cplusplus///////////////////////////////////////////////////////////////////////////////// Helper for loginfo for LOGINFO()//#ifndef _INTERFACE#define _INTERFACE struct#endiftypedef _INTERFACE IHXErrorSink IHXErrorSink;class LogInfo{ public: static void STDMETHODCALLTYPE FileandLine(const char* file, int nLine); static void STDMETHODCALLTYPE Report(IHXErrorSink* mySink, const char* pUserInfo, ...); private: static char m_pFile[_MAX_PATH]; /* Flawfinder: ignore */};#endif/////////////////////////////////////////////////////////////////////////////// CHECK/REQUIRE MACROS//// These macros are always valid (debug and release builds)//////// REQUIRE and REQUIRE_ACTION _always_ emit code for the goto if the statement is false//// REQUIRE_REPORT only generates code in Debug builds//// The do {} while (0) construct ensures this is legal wherever a statement is legal//#define CHECK(stmt) HX_ASSERT(stmt)#define REQUIRE_VOID_RETURN(stmt) \ do { if ((stmt) == 0) { if (REQUIRE_REPORT(#stmt,__FILE__,__LINE__)) HXDebugBreak(); return; } } while (0)#define REQUIRE_RETURN(stmt,returned) \ do { if ((stmt) == 0) { if (REQUIRE_REPORT(#stmt,__FILE__,__LINE__)) HXDebugBreak(); return (returned); } } while (0)#define REQUIRE_VOID_RETURN_QUIET(stmt) \ do { if ((stmt) == 0) { return; } } while (0)#define REQUIRE_RETURN_QUIET(stmt,returned) \ do { if ((stmt) == 0) { return (returned); } } while (0)#define REQUIRE(stmt,target) \ do { if ((stmt) == 0) { REQUIRE_REPORT(#target,__FILE__,__LINE__); goto target; } } while (0)#define REQUIRE_ACTION(stmt,target,action) \ do { if ((stmt) == 0) { REQUIRE_REPORT(#target,__FILE__,__LINE__); {{action;} goto target;} } } while (0)#define REQUIRE_QUIET(stmt,target) \ do { if ((stmt) == 0) goto target; } while (0)#define REQUIRE_ACTION_QUIET(stmt,target,action) \ do { if ((stmt) == 0) {{action;} goto target;} } while (0)#define PRE_REQUIRE_RETURN(stmt,returned) \ REQUIRE_RETURN(stmt,returned)#define PRE_REQUIRE_VOID_RETURN(stmt) \ REQUIRE_VOID_RETURN(stmt)#define POST_REQUIRE_RETURN(stmt,returned) \ REQUIRE_RETURN(stmt,returned)#define POST_REQUIRE_VOID_RETURN(stmt) \ REQUIRE_VOID_RETURN(stmt)#define REQUIRE_SUCCESS_RETURN_QUIET(expr) \ do { register HX_RESULT const res = expr; if (FAILED (res)) return res; } while (0)#define REQUIRE_SUCCESS_RETURN(expr) \ do { register HX_RESULT const res = expr; if (FAILED (res)) { REQUIRE_REPORT("False condition, Aborting...",__FILE__,__LINE__); return res; } } while (0)//// REQUIRE_SUCCESS reports the error if an expected result failed// Ideally, this should report the status value as well//#define CHECK_SUCCESS(stat) HX_ASSERT(((unsigned long)(stat)>>31) == 0)#define REQUIRE_SUCCESS(stat,target) \ do { if (((unsigned long)(stat)>>31) != 0) { REQUIRE_REPORT(#target,__FILE__,__LINE__); goto target; } } while (0)#define REQUIRE_SUCCESS_ACTION(stat,target,action) \ do { if (((unsigned long)(stat)>>31) != 0) { REQUIRE_REPORT(#target,__FILE__,__LINE__); {{action;} goto target;} } } while (0)#define REQUIRE_SUCCESS_QUIET(stat,target) \ do { if (((unsigned long)(stat)>>31) != 0) goto target; } while (0)#define REQUIRE_SUCCESS_ACTION_QUIET(stat,target,action) \ do { if (((unsigned long)(stat)>>31) != 0) {{action;} goto target;} } while (0)//// REQUIRE_NOERR reports the error if the error value is non-zero// Ideally, this should report the error value as well//#define CHECK_NOERR(err) HX_ASSERT((err) == 0)#define REQUIRE_NOERR_RETURN(err,returned) \ do { if ((err) != 0) { REQUIRE_REPORT("Toolbox error, Aborting...",__FILE__,__LINE__); return (returned); } } while (0)#define REQUIRE_NOERR(err,target) \ do { if ((err) != 0) { REQUIRE_REPORT(#target,__FILE__,__LINE__); goto target; } } while (0)#define REQUIRE_NOERR_ACTION(err,target,action) \ do { if ((err) != 0) { REQUIRE_REPORT(#target,__FILE__,__LINE__); {{action;} goto target;} } } while (0)#define REQUIRE_NOERR_QUIET(err,target) \ do { if ((err) != 0) goto target; } while (0)#define REQUIRE_NOERR_ACTION_QUIET(err,target,action) \ do { if ((err) != 0) {{action;} goto target;} } while (0)//// REQUIRE_NONNULL reports the error if the ptr value is null// Ideally, this should report the error value as well//#define CHECK_NONNULL(ptr) HX_ASSERT((ptr) != 0L)#define CHECK_NULL(ptr) HX_ASSERT((ptr) == 0L)#define REQUIRE_NONNULL_VOID_RETURN(ptr) \ do { if ((ptr) == 0L) { REQUIRE_REPORT(#ptr" is nil, Aborting...",__FILE__,__LINE__); return; } } while (0)#define REQUIRE_NONNULL_RETURN(ptr,returned) \ do { if ((ptr) == 0L) { REQUIRE_REPORT(#ptr" is nil, Aborting...",__FILE__,__LINE__); return (returned); } } while (0)#define REQUIRE_NONNULL(ptr,target) \ do { if ((ptr) == 0L) { REQUIRE_REPORT(#target,__FILE__,__LINE__); goto target; } } while (0)#define REQUIRE_NONNULL_ACTION(ptr,target,action) \ do { if ((ptr) == 0L) { REQUIRE_REPORT(#target,__FILE__,__LINE__); {{action;} goto target;} } } while (0)#define REQUIRE_NONNULL_QUIET(ptr,target) \ do { if ((ptr) == 0L) goto target; } while (0)#define REQUIRE_NONNULL_ACTION_QUIET(ptr,target,action) \ do { if ((ptr) == 0L) {{action;} goto target;} } while (0)// lower case versions make source code more readable#if defined(_CARBON) || defined(_MAC_MACHO)#undef check#undef require#undef require_action#undef require_quiet#undef check_noerr#undef require_action_quiet#undef require_noerr#undef require_noerr_action#undef require_noerr_quiet#undef require_noerr_action_quiet#endif#define check(stmt) CHECK(stmt)#define require_void_return(stmt) REQUIRE_VOID_RETURN(stmt)#define require_return_void(stmt) REQUIRE_VOID_RETURN(stmt)#define require_return(stmt,returned) REQUIRE_RETURN(stmt,returned)#define require(stmt,target) REQUIRE(stmt,target)#define require_action(stmt,target,action) REQUIRE_ACTION(stmt,target,action)#define require_quiet(stmt,target) REQUIRE_QUIET(stmt,target)#define require_action_quiet(stmt,target,action) REQUIRE_ACTION_QUIET(stmt,target,action)#define check_success(stat) CHECK_SUCCESS(stat)#define require_success(stat,target) REQUIRE_SUCCESS(stat,target)#define require_success_action(stat,target,action) REQUIRE_SUCCESS_ACTION(stat,target,action)#define require_success_quiet(stat,target) REQUIRE_SUCCESS_QUIET(stat,target)#define require_success_action_quiet(stat,target,action) REQUIRE_SUCCESS_ACTION_QUIET(stat,target,action)#define check_noerr(err) CHECK_NOERR(err)#define require_noerr_return(err,returned) REQUIRE_NOERR_RETURN(err,returned)#define require_noerr(err,target) REQUIRE_NOERR(err,target)#define require_noerr_action(err,target,action) REQUIRE_NOERR_ACTION(err,target,action)#define require_noerr_quiet(err,target) REQUIRE_NOERR_QUIET(err,target)#define require_noerr_action_quiet(err,target,action) REQUIRE_NOERR_ACTION_QUIET(err,target,action)#define check_nonnull(ptr) CHECK_NONNULL(ptr)#define check_null(ptr) CHECK_NULL(ptr)#define require_nonnull_void_return(ptr) REQUIRE_NONNULL_VOID_RETURN(ptr)#define require_nonnull_return(ptr,returned) REQUIRE_NONNULL_RETURN(ptr,returned)#define require_nonnull(ptr,target) REQUIRE_NONNULL(ptr,target)#define require_nonnull_action(ptr,target,action) REQUIRE_NONNULL_ACTION(ptr,target,action)#define require_nonnull_quiet(ptr,target) REQUIRE_NONNULL_QUIET(ptr,target)#define require_nonnull_action_quiet(ptr,target,action) REQUIRE_NONNULL_ACTION_QUIET(ptr,target,action)#endif // !_HXASSERT_H_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -