hxassert.h
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:25k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. /////////////////////////////////////////////////////////////////////////////
  36. // HXASSERT.H
  37. //
  38. // Debugging support header.
  39. //
  40. // HX_ASSERT() - asserts an expression is TRUE. Compiles to no-ops in
  41. // retail builds. Provides message box or other UI when 
  42. // expression fails.
  43. //
  44. // HX_ASSERT_VALID_PTR() - asserts that a pointer is valid. Performs more
  45. // rigid verification specifically appropriate for pointers.
  46. //
  47. // HX_VERIFY() - verifies an expression is TRUE. Expression or code DOES NOT 
  48. // compile away in retail builds, but UI of failure is removed.
  49. // In debug builds provides message box or other UI when 
  50. // expression fails.
  51. //
  52. // HX_TRACE() - Similar to DEBUGPRINTF() but no buffer is required. 
  53. // Compiles to no-ops in retail builds.
  54. //
  55. #ifndef _HXASSERT_H_
  56. #define _HXASSERT_H_
  57. #include "hlxclib/assert.h"
  58. #ifndef ASSERT
  59. #if defined (DEBUG) || defined (_DEBUG)
  60. #if defined (_OSF1) && defined (_NATIVE_COMPILER)
  61. # define ASSERT(x) assert(((long)(x)) != 0L)
  62. #else
  63. #       define ASSERT(x)        assert(x)
  64. #endif
  65. #else
  66. # define ASSERT(x) /* x */
  67. #endif /* DEBUG */
  68. #endif /* ndef ASSERT */
  69. #include "hlxclib/limits.h"
  70. #include "hxtypes.h"
  71. #include "hxresult.h"           // for HX_RESULT
  72. #include "hlxclib/stdio.h"      // for sprintf
  73. #ifdef _SUN
  74. #include <stddef.h>     // for size_t
  75. #endif
  76. #ifdef __cplusplus
  77. extern "C" {
  78. #endif
  79. #if defined (_SOLARIS) || defined (_IRIX) || defined (_DECALPHA)
  80. #ifndef __inline
  81. #define __inline inline
  82. #endif
  83. #endif
  84. #if defined (_OSF1) && defined (_NATIVE_COMPILER)
  85. #if defined __cplusplus
  86. #define __inline inline
  87. #else
  88. #define __inline static
  89. #endif /* __cplusplus */
  90. #endif
  91. #ifdef _HPUX 
  92. #if defined __cplusplus
  93. #define __inline inline
  94. #else
  95. #define __inline 
  96. #endif /* __cplusplus */
  97. #endif
  98. #if defined _AIX
  99. #if defined __cplusplus
  100. #define __inline inline
  101. #else
  102. #define __inline 
  103. #endif /* __cplusplus */
  104. #endif /* _AIX */
  105. #ifdef _UNIX
  106. #include <signal.h> /* For kill() */
  107. #include <unistd.h> /* For getpid() */
  108. #include <stdio.h>
  109. void HXUnixDebugBreak();
  110. #endif
  111. /////////////////////////////////////////////////////////////////////////////
  112. // Diagnostic support
  113. // For _MAX_PATH
  114. #if defined ( _MACINTOSH )
  115. #include "platform/mac/maclibrary.h"
  116. #elif defined (_UNIX)
  117. #include <stdlib.h>
  118. #if !defined(_VXWORKS)
  119. #include <sys/param.h>
  120. #endif
  121. #define _MAX_PATH       MAXPATHLEN
  122. #elif defined (_WINDOWS)
  123. #include <stdlib.h>
  124. #endif
  125. #ifdef _SYMBIAN
  126. # include <unistd.h>
  127. # define _MAX_PATH MAXPATHLEN
  128. #endif
  129. #ifdef _OPENWAVE
  130. #ifndef _MAX_PATH
  131. #define _MAX_PATH 256
  132. #endif
  133. #endif
  134. #if defined (DEBUG) || defined (_DEBUG)
  135. #ifdef _MACINTOSH
  136. #  define MAX_TRACE_OUTPUT  255
  137. #else
  138. # ifdef _UNIX
  139. #  define MAX_TRACE_OUTPUT  255
  140. # elif _WIN16
  141. #  define MAX_TRACE_OUTPUT  255
  142. # elif _SYMBIAN
  143. #  define MAX_TRACE_OUTPUT  255
  144. # else
  145. #  define MAX_TRACE_OUTPUT  (_MAX_PATH*2 + 20)
  146. # endif
  147. #endif
  148. /////////////////////////////////////////////////////////////////////////////
  149. //
  150. // HXDebugOptionEnabled: 
  151. // Determine if the given debug option is enabled.
  152. // A lookup is done to the registry key, and if it's present
  153. // and set to '1', TRUE is returned otherwise FALSE
  154. // Similar to HXWantTraceMessages, except not specific to one option.
  155. #ifdef _WIN16
  156. // The STDMETHODCALLTYPE includes the _export keyword, even though this is
  157. // a static, not dll, library.  Seems to work on win32 ok, but not a win16
  158. // .exe.  rpapp would see this as duplicate symbol, until the _export was
  159. // removed, and all the libraries that rpapp linked with rebuilt.  There
  160. // may be a define for STDMETHODCALLTYPE without the _export that should be
  161. // used here. XXXTW.  april 98.
  162. BOOL far _cdecl HXDebugOptionEnabled(const char* szOption);
  163. #else
  164. BOOL STDMETHODCALLTYPE HXDebugOptionEnabled(const char* szOption);
  165. #endif
  166. /////////////////////////////////////////////////////////////////////////////
  167. //
  168. // HXWantTraceMessages: 
  169. // Helper function used to determine if the system has asked for trace 
  170. // messages.
  171. //
  172. BOOL STDMETHODCALLTYPE HXWantTraceMessages();
  173. /////////////////////////////////////////////////////////////////////////////
  174. //
  175. // HXOutputDebugString: 
  176. // Helper function used by DEBUGOUTSTR(). This is better than 
  177. // OutputDebugString, because it will check to see if output
  178. // tracing is turned off in the registry. This prevents the massive
  179. // slew of output messages.
  180. //
  181. void STDMETHODCALLTYPE HXOutputDebugString(const char* pString);
  182. /////////////////////////////////////////////////////////////////////////////
  183. //
  184. // HXTrace: Helper function used by HX_TRACE()
  185. //
  186. void STDMETHODVCALLTYPE HXTrace(const char* pszFormat, ...);
  187. /////////////////////////////////////////////////////////////////////////////
  188. //
  189. // HXAssertFailedLine: Helper function used by HX_ASSERT()
  190. //
  191. #ifdef _WIN16
  192. // The STDMETHODCALLTYPE includes the _export keyword, even though this is
  193. // a static, not dll, library.  Seems to work on win32 ok, but not a win16
  194. // .exe.  rpapp would see this as duplicate symbol, until the _export was
  195. // removed, and all the libraries that rpapp linked with rebuilt.  There
  196. // may be a define for STDMETHODCALLTYPE without the _export that should be
  197. // used here. XXXTW.  april 98.
  198. BOOL far _cdecl HXAssertFailedLine(const char* pszExpression, const char* pszFileName, int nLine);
  199. #else
  200. BOOL STDMETHODCALLTYPE HXAssertFailedLine(const char* pszExpression, const char* pszFileName, int nLine);
  201. #endif
  202. /////////////////////////////////////////////////////////////////////////////
  203. //
  204. // HXAssertValidPointer, HXIsValidAddress: Helper functions used by
  205. // HX_ASSERT_VALID_PTR()
  206. //
  207. void STDMETHODCALLTYPE HXAssertValidPointer(const void* pVoid, const char* pszFileName, int nLine);
  208. #ifdef __cplusplus
  209. #ifdef _WIN16
  210.     // see note above on the problem with STDMETHODCALLTYPE on win16
  211.     BOOL far _cdecl        HXIsValidAddress(const void* lp, ULONG32 nBytes = 1, BOOL bReadWrite = TRUE);
  212. #else
  213.     BOOL STDMETHODCALLTYPE HXIsValidAddress(const void* lp, ULONG32 nBytes = 1, BOOL bReadWrite = TRUE);
  214. #endif
  215. #else
  216. #ifdef _WIN16
  217.     // see note above on the problem with STDMETHODCALLTYPE on win16
  218.     BOOL far _cdecl        HXIsValidAddress(const void* lp, ULONG32 nBytes, BOOL bReadWrite);
  219. #else
  220.     BOOL STDMETHODCALLTYPE HXIsValidAddress(const void* lp, ULONG32 nBytes, BOOL bReadWrite);
  221. #endif
  222. #endif
  223. #ifdef _WIN16
  224. BOOL far _cdecl        HXIsValidString(const char* lpsz, int nLength);
  225. #else
  226. BOOL STDMETHODCALLTYPE HXIsValidString(const char* lpsz, int nLength);
  227. #endif
  228. /////////////////////////////////////////////////////////////////////////////
  229. //
  230. // HXDebugBreak: used to break into debugger at critical times
  231. //
  232. #ifndef HXDebugBreak
  233. // by default, debug break is asm int 3, or a call to DebugBreak, or nothing
  234. #if defined(_WINDOWS)
  235. #if !defined(_M_IX86)
  236. #include "windows.h"
  237. #define HXDebugBreak() DebugBreak()
  238. #else
  239. #define HXDebugBreak() _asm { int 3 }
  240. #endif // _M_ALPHA
  241. #elif defined( _MACINTOSH )
  242. #define HXDebugBreak() Debugger()
  243. #elif defined(_OPENWAVE)
  244. #if defined(_OPENWAVE_SIMULATOR) // windows app...
  245. #define HXDebugBreak() _asm { int 3 }
  246. #else
  247. void HXDebugBreak();
  248. #endif
  249. #elif defined(_SYMBIAN)
  250. #if defined(__WINS__)
  251. #define HXDebugBreak() _asm { int 3 }
  252. #else
  253. void HXDebugBreak();
  254. #endif //_SYMBIAN
  255. #elif  defined(_UNIX)
  256. void HXDebugBreak();
  257. #elif defined(_VXWORKS)
  258. #include <taskLib.h>
  259. #define HXDebugBreak() (taskSuspend(taskIdSelf()))
  260. #endif // end of#if defined(_WIN32) || defined(_WINDOWS)
  261. #endif // end of#ifndef HXDebugBreak
  262. #ifdef _UNIX
  263. #include "signal.h"
  264. #include "stdlib.h"
  265. #define HX_ENABLE_JIT_DEBUGGING()               
  266. do {
  267.     signal (SIGSEGV, (void (*)(int))HXDebugBreak);
  268.     signal (SIGBUS,  (void (*)(int))HXDebugBreak);
  269.     signal (SIGFPE,  (void (*)(int))HXDebugBreak);
  270.     if (!getenv("PROCESS_NAME"))                
  271.     {                                           
  272.     char *progname = new char[strlen(argv[0]) + 30]; 
  273.     sprintf(progname, "PROCESS_NAME=%s", argv[0]); /* Flawfinder: ignore */ 
  274.     putenv(progname);                           
  275.     } 
  276. } while (0);
  277. #else
  278. #define HX_ENABLE_JIT_DEBUGGING()
  279. #endif
  280. /////////////////////////////////////////////////////////////////////////////
  281. //
  282. // HXAbort: used to shut down the application at critical times
  283. //
  284. #ifndef HXAbort
  285. #if (defined(_WIN32) || defined(_WINDOWS)) && !defined(WIN32_PLATFORM_PSPC)
  286. # define HXAbort()  abort()
  287. #elif defined(WIN32_PLATFORM_PSPC)
  288. # define HXAbort()   exit(1)
  289. #elif defined(_SYMBIAN)
  290. # define HXAbort() exit(1)
  291. #elif defined(_OPENWAVE)
  292. // XXXSAB is this right??
  293. # define HXAbort() exit(1)
  294. #elif defined ( _MACINTOSH )
  295. # define HXAbort() DebugStr("pHXAbort: Please exit this program.")
  296. #elif defined ( _UNIX )
  297. # define HXAbort() printf("npnabort: Please exit this program.n")
  298. #endif // end of#if defined(_WIN32) || defined(_WINDOWS)
  299. #endif // end of#ifndef HXAbort
  300. /////////////////////////////////////////////////////////////////////////////
  301. //
  302. // HX_TRACE: see above.
  303. //
  304. #define HX_TRACE ::HXTrace
  305. /////////////////////////////////////////////////////////////////////////////
  306. //
  307. // HX_ASSERT: see above.
  308. //
  309. #define HX_ASSERT(f) 
  310. do 
  311. if (!(f) && HXAssertFailedLine(#f, __FILE__, __LINE__)) 
  312. HXDebugBreak(); 
  313. } while (0) 
  314. #define REQUIRE_REPORT(targ,file,line) HXAssertFailedLine(targ,file,line)
  315. /////////////////////////////////////////////////////////////////////////////
  316. //
  317. // Macros Defined for logging messges in the player. 
  318. //  
  319. //  STARTLOGSINK: Query for an IHXErrorSink
  320. //
  321. //  LOGINFO: Report the error to the error sink
  322. //
  323. //  STOPLOGSINK: Shutdown and Release the error sink.        
  324. //
  325. /////////////////////////////////////////////////////////////////////////////
  326. #ifndef _GOLD
  327. #ifndef _INTERFACE
  328. #define _INTERFACE struct
  329. #endif
  330. typedef _INTERFACE IHXErrorMessages IHXErrorMessages;
  331.     const char*     FileAndLine(const char* pFile, UINT32 ulLine);
  332.     HX_RESULT     HXLogf(IHXErrorMessages *pErr, UINT8 sev, HX_RESULT err, UINT32 usr, const char* pURL, const char* pUsrStr, ...);
  333.     HX_RESULT     HXLog(IHXErrorMessages *pErr, UINT8 sev, HX_RESULT err, UINT32 usr, const char* pStr, const char* pURL);
  334. #define THIS_LINE() FileAndLine(__FILE__, __LINE__)
  335. #define HX_STARTLOG(__IUnknown, __ErrorMessages) 
  336. __IUnknown->QueryInterface(IID_IHXErrorMessages, (void **)&__ErrorMessages); 
  337. HX_ASSERT(__ErrorMessages != NULL && "Must have IHXErrorMessages interface to start logging")
  338. #define HX_LOG HXLog
  339. #define HX_LOGF HXLogf
  340. #define HX_STOPLOG(__ErrorMessages) HX_RELEASE(__ErrorMessages)
  341. #else // _GOLD
  342. #define HX_STARTLOG(x,y)    (void)0
  343. #define HX_LOG 1 ? (void)0 : HXLog
  344. #define HX_LOGF 1 ? (void)0 : HXLogf
  345. #define HX_STOPLOG(x) (void)0
  346. #endif
  347. /////////////////////////////////////////////////////////////////////////////
  348. //
  349. // HX_SAFESIZE_T
  350. //
  351. #define HX_SAFESIZE_T(f) 
  352. ( ((ULONG32)(f) <= (size_t)-1)?((size_t)(f)): 
  353. (HXAssertFailedLine("size_t overflow",__FILE__, __LINE__), (size_t)(f)) ) 
  354. /////////////////////////////////////////////////////////////////////////////
  355. //
  356. // HX_SAFEINT
  357. //
  358. #ifndef _VXWORKS
  359. #define HX_SAFEINT(f) 
  360. ( ((LONG32)(f) <= LONG_MAX && ((LONG32)(f)) >= ((LONG32)(LONG_MIN)))?((int)(f)): 
  361. (HXAssertFailedLine("Integer Size Overflow",__FILE__, __LINE__), (int)(f)) ) 
  362. #else
  363. #ifdef __cplusplus
  364. extern "C"
  365. #endif
  366. int safe_int_func_call(LONG32 f);
  367. #define HX_SAFEINT(f) safe_int_func_call((LONG32)(f))
  368. #endif
  369. #define HX_SAFEUINT(f) 
  370. ( ((ULONG32)(f) <= ULONG_MAX && (LONG32)(f) >= 0)?((unsigned int)(f)): 
  371. (HXAssertFailedLine("Unsigned Integer Size Overflow",__FILE__, __LINE__), (unsigned int)(f)) ) 
  372. #define HX_SAFEINT16(f) 
  373. ( ((LONG32)(f) <= SHRT_MAX && (LONG32)(f) >= SHRT_MIN)?((short)(f)): 
  374. (HXAssertFailedLine("Short Integer Size Overflow",__FILE__, __LINE__), (short)(f)) ) 
  375. #define HX_SAFEUINT16(f) 
  376. ( ((ULONG32)(f) <= USHRT_MAX && (LONG32)(f) >= 0)?((unsigned short)(f)): 
  377. (HXAssertFailedLine("Unsigned Short Integer Size Overflow",__FILE__, __LINE__), (unsigned short)(f)) ) 
  378. #define HX_SAFEINT8(f) 
  379. ( ((LONG32)(f) <= SCHAR_MAX && (LONG32)(f) >= SCHAR_MIN)?((char)(f)): 
  380. (HXAssertFailedLine("Signed Char Size Overflow",__FILE__, __LINE__), (char)(f)) ) 
  381. #define HX_SAFEUINT8(f) 
  382. ( ((ULONG32)(f) <= UCHAR_MAX && (LONG32)(f) >= 0)?((unsigned char)(f)): 
  383. (HXAssertFailedLine("Unsigned Char Size Overflow",__FILE__, __LINE__), (unsigned char)(f)) ) 
  384. /////////////////////////////////////////////////////////////////////////////
  385. //
  386. // HX_SAFE_VOID2HANDLE
  387. //
  388. #if defined(_WINDOWS)
  389. #ifdef _WIN32
  390. #define HX_SAFE_VOID2HANDLE(f) ((HANDLE)(f))
  391. #else // !_WIN23
  392. #define HX_SAFE_VOID2HANDLE(f) ((HANDLE)LOWORD(f))
  393. // this doesn't work most of the time since the assignment of a handle (near *) to a
  394. // void * sets the high word to the SS.
  395. // ( ( (0xFFFF0000 & ((ULONG32)(f))) == 0)?((HANDLE)LOWORD(f)): 
  396. // (HXAssertFailedLine("HANDLE HIWORD NOT NULL",__FILE__, __LINE__), (HANDLE)LOWORD(f)) ) 
  397. #endif
  398. #elif defined ( __MWERKS__ )
  399. #define HX_SAFE_VOID2HANDLE(f) (f)
  400. #elif defined ( _UNIX )
  401. #define HX_SAFE_VOID2HANDLE(f) (f)
  402. #endif // end of#if defined(_WIN32) || defined(_WINDOWS)
  403. /////////////////////////////////////////////////////////////////////////////
  404. //
  405. // HX_VERIFY: see above.
  406. //
  407. #define HX_VERIFY(f)          HX_ASSERT(f)
  408. /////////////////////////////////////////////////////////////////////////////
  409. //
  410. // HX_ASSERT_VALID_PTR: see above.
  411. //
  412. #define HX_ASSERT_VALID_PTR(pOb)  (::HXAssertValidPointer(pOb, __FILE__, __LINE__))
  413. #define HX_ASSERT_VALID_READ_PTR(pOb)  HX_ASSERT(::HXIsValidAddress(pOb, 1, FALSE))
  414. /////////////////////////////////////////////////////////////////////////////
  415. //
  416. // _SAFESTRING: Similar to HX_TRACE() except that it assume you are
  417. // using a single format string, with a single parameter string, this will
  418. // ensure that the length of the resulting format is less than the maximum
  419. // trace string, and gracefully handle the situation...
  420. //
  421. #define HX_TRACE_SAFESTRING(f,s)
  422. if ((strlen(f) + strlen(s)) < (size_t)MAX_TRACE_OUTPUT)
  423. {
  424. HX_TRACE(f,s);
  425. }
  426. else
  427. {
  428. HX_TRACE(f,"Some really big URL");
  429. }
  430. #else   // _DEBUG
  431. #ifndef _DEBUG
  432. #ifndef HX_ENABLE_JIT_DEBUGGING
  433. #define HX_ENABLE_JIT_DEBUGGING()
  434. #endif
  435. #ifdef HXAbort
  436. #undef HXAbort
  437. #endif // end of#ifdef HXAbort
  438. #define HXAbort()
  439. #endif  // _DEBUG
  440. #ifndef _DEBUG
  441. #ifdef HXDebugBreak
  442. #undef HXDebugBreak
  443. #endif // end of#ifdef HXDebugBreak
  444. #define HXDebugBreak()
  445. #endif  // _DEBUG || DEBUG
  446. /////////////////////////////////////////////////////////////////////////////
  447. //
  448. // HX_SAFEINT
  449. //
  450. #define HX_SAFEINT(f) ((int)(f)) 
  451. #define HX_SAFEUINT(f) ((unsigned int)(f)) 
  452. #define HX_SAFEINT16(f) ((short)(f)) 
  453. #define HX_SAFEUINT16(f) ((unsigned short)(f)) 
  454. #define HX_SAFEINT8(f) ((char)(f)) 
  455. #define HX_SAFEUINT8(f) ((unsigned char)(f)) 
  456. #define HX_ASSERT(f)         ((void)0)
  457. #define HX_SAFESIZE_T(f) ((size_t)(f))
  458. #define HX_SAFEINT(f) ((int)(f))
  459. #define HX_SAFE_VOID2HANDLE(f) ((HANDLE)(ULONG32)(f))
  460. #define HX_ASSERT_VALID_PTR(pOb) ((void)0)
  461. #define HX_ASSERT_VALID_READ_PTR(pOb)   ((void)0)
  462. #define HXOutputDebugString(f) ((void)0)
  463. #define REQUIRE_REPORT(targ,file,line) ((int)0)
  464. #if defined (_MACINTOSH)
  465. // this is the proper release version of HX_VERIFY that preserves the syntactic
  466. // role of the debug version; it's necessary to quiet warnings on the Mac
  467. #define HX_VERIFY(f) do { if (!(f)) {} } while (0)
  468. #else
  469. #define HX_VERIFY(f) ((void)(f))
  470. #endif
  471. #if defined (_WINDOWS)
  472. __inline void __cdecl HXTrace(const char* x, ...) { }
  473. #else
  474. static __inline void HXTrace(const char* x, ...) {}
  475. #endif
  476. #define HX_TRACE               1 ? (void)0 : ::HXTrace
  477. #define HX_TRACE_SAFESTRING HX_TRACE
  478. #endif // !_DEBUG
  479. #ifdef __cplusplus
  480. } // end extern "C"
  481. #endif
  482. #ifdef __cplusplus
  483. /////////////////////////////////////////////////////////////////////////////
  484. //
  485. // Helper for loginfo for LOGINFO()
  486. //
  487. #ifndef _INTERFACE
  488. #define _INTERFACE struct
  489. #endif
  490. typedef _INTERFACE IHXErrorSink IHXErrorSink;
  491. class LogInfo
  492. {
  493.     public:
  494. static void STDMETHODCALLTYPE FileandLine(const char* file, int nLine);
  495. static void STDMETHODCALLTYPE Report(IHXErrorSink* mySink, const char* pUserInfo, ...);
  496.     private:
  497. static char m_pFile[_MAX_PATH]; /* Flawfinder: ignore */
  498. };
  499. #endif
  500. /////////////////////////////////////////////////////////////////////////////
  501. // CHECK/REQUIRE MACROS
  502. //
  503. // These macros are always valid (debug and release builds)
  504. //
  505. //
  506. //
  507. // REQUIRE and REQUIRE_ACTION _always_ emit code for the goto if the statement is false
  508. //
  509. // REQUIRE_REPORT only generates code in Debug builds
  510. //
  511. // The do {} while (0) construct ensures this is legal wherever a statement is legal
  512. //
  513. #define CHECK(stmt)  HX_ASSERT(stmt)
  514. #define REQUIRE_VOID_RETURN(stmt) 
  515. do { if ((stmt) == 0) { if (REQUIRE_REPORT(#stmt,__FILE__,__LINE__)) HXDebugBreak(); return; } } while (0)
  516. #define REQUIRE_RETURN(stmt,returned) 
  517. do { if ((stmt) == 0) { if (REQUIRE_REPORT(#stmt,__FILE__,__LINE__)) HXDebugBreak(); return (returned); } } while (0)
  518. #define REQUIRE_VOID_RETURN_QUIET(stmt) 
  519. do { if ((stmt) == 0) { return; } } while (0)
  520. #define REQUIRE_RETURN_QUIET(stmt,returned) 
  521. do { if ((stmt) == 0) { return (returned); } } while (0)
  522. #define REQUIRE(stmt,target) 
  523. do { if ((stmt) == 0) { REQUIRE_REPORT(#target,__FILE__,__LINE__); goto target; } } while (0)
  524. #define REQUIRE_ACTION(stmt,target,action) 
  525. do { if ((stmt) == 0) { REQUIRE_REPORT(#target,__FILE__,__LINE__); {{action;} goto target;} } } while (0)
  526. #define REQUIRE_QUIET(stmt,target) 
  527. do { if ((stmt) == 0) goto target; } while (0)
  528. #define REQUIRE_ACTION_QUIET(stmt,target,action) 
  529. do { if ((stmt) == 0) {{action;} goto target;} } while (0)
  530. #define PRE_REQUIRE_RETURN(stmt,returned) 
  531. REQUIRE_RETURN(stmt,returned)
  532. #define PRE_REQUIRE_VOID_RETURN(stmt) 
  533. REQUIRE_VOID_RETURN(stmt)
  534. #define POST_REQUIRE_RETURN(stmt,returned) 
  535. REQUIRE_RETURN(stmt,returned)
  536. #define POST_REQUIRE_VOID_RETURN(stmt) 
  537. REQUIRE_VOID_RETURN(stmt)
  538. #define REQUIRE_SUCCESS_RETURN_QUIET(expr) 
  539. do { register HX_RESULT const res = expr; if (FAILED (res)) return res; } while (0)
  540. #define REQUIRE_SUCCESS_RETURN(expr) 
  541. do { register HX_RESULT const res = expr; if (FAILED (res)) {  REQUIRE_REPORT("False condition, Aborting...",__FILE__,__LINE__); return res; } } while (0)
  542. //
  543. // REQUIRE_SUCCESS reports the error if an expected result failed
  544. // Ideally, this should report the status value as well
  545. //
  546. #define CHECK_SUCCESS(stat) HX_ASSERT(((unsigned long)(stat)>>31) == 0)
  547. #define REQUIRE_SUCCESS(stat,target) 
  548. do { if (((unsigned long)(stat)>>31) != 0) { REQUIRE_REPORT(#target,__FILE__,__LINE__); goto target; } } while (0)
  549. #define REQUIRE_SUCCESS_ACTION(stat,target,action) 
  550. do { if (((unsigned long)(stat)>>31) != 0) { REQUIRE_REPORT(#target,__FILE__,__LINE__); {{action;} goto target;} } } while (0)
  551. #define REQUIRE_SUCCESS_QUIET(stat,target) 
  552. do { if (((unsigned long)(stat)>>31) != 0) goto target; } while (0)
  553. #define REQUIRE_SUCCESS_ACTION_QUIET(stat,target,action) 
  554. do { if (((unsigned long)(stat)>>31) != 0) {{action;} goto target;} } while (0)
  555. //
  556. // REQUIRE_NOERR reports the error if the error value is non-zero
  557. // Ideally, this should report the error value as well
  558. //
  559. #define CHECK_NOERR(err) HX_ASSERT((err) == 0)
  560. #define REQUIRE_NOERR_RETURN(err,returned) 
  561. do { if ((err) != 0) { REQUIRE_REPORT("Toolbox error, Aborting...",__FILE__,__LINE__); return (returned); } } while (0)
  562. #define REQUIRE_NOERR(err,target) 
  563. do { if ((err) != 0) { REQUIRE_REPORT(#target,__FILE__,__LINE__); goto target; } } while (0)
  564. #define REQUIRE_NOERR_ACTION(err,target,action) 
  565. do { if ((err) != 0) { REQUIRE_REPORT(#target,__FILE__,__LINE__); {{action;} goto target;} } } while (0)
  566. #define REQUIRE_NOERR_QUIET(err,target) 
  567. do { if ((err) != 0) goto target; } while (0)
  568. #define REQUIRE_NOERR_ACTION_QUIET(err,target,action) 
  569. do { if ((err) != 0) {{action;} goto target;} } while (0)
  570. //
  571. // REQUIRE_NONNULL reports the error if the ptr value is null
  572. // Ideally, this should report the error value as well
  573. //
  574. #define CHECK_NONNULL(ptr) HX_ASSERT((ptr) != 0L)
  575. #define CHECK_NULL(ptr) HX_ASSERT((ptr) == 0L)
  576. #define REQUIRE_NONNULL_VOID_RETURN(ptr) 
  577. do { if ((ptr) == 0L) { REQUIRE_REPORT(#ptr" is nil, Aborting...",__FILE__,__LINE__); return; } } while (0)
  578. #define REQUIRE_NONNULL_RETURN(ptr,returned) 
  579. do { if ((ptr) == 0L) { REQUIRE_REPORT(#ptr" is nil, Aborting...",__FILE__,__LINE__); return (returned); } } while (0)
  580. #define REQUIRE_NONNULL(ptr,target) 
  581. do { if ((ptr) == 0L) { REQUIRE_REPORT(#target,__FILE__,__LINE__); goto target; } } while (0)
  582. #define REQUIRE_NONNULL_ACTION(ptr,target,action) 
  583. do { if ((ptr) == 0L) { REQUIRE_REPORT(#target,__FILE__,__LINE__); {{action;} goto target;} } } while (0)
  584. #define REQUIRE_NONNULL_QUIET(ptr,target) 
  585. do { if ((ptr) == 0L) goto target; } while (0)
  586. #define REQUIRE_NONNULL_ACTION_QUIET(ptr,target,action) 
  587. do { if ((ptr) == 0L) {{action;} goto target;} } while (0)
  588. // lower case versions make source code more readable
  589. #if defined(_CARBON) || defined(_MAC_MACHO)
  590. #undef check
  591. #undef require
  592. #undef require_action
  593. #undef require_quiet
  594. #undef check_noerr
  595. #undef require_action_quiet
  596. #undef require_noerr
  597. #undef require_noerr_action
  598. #undef require_noerr_quiet
  599. #undef require_noerr_action_quiet
  600. #endif
  601. #define check(stmt)  CHECK(stmt)
  602. #define require_void_return(stmt) REQUIRE_VOID_RETURN(stmt)
  603. #define require_return_void(stmt) REQUIRE_VOID_RETURN(stmt)
  604. #define require_return(stmt,returned) REQUIRE_RETURN(stmt,returned)
  605. #define require(stmt,target)  REQUIRE(stmt,target)
  606. #define require_action(stmt,target,action)  REQUIRE_ACTION(stmt,target,action)
  607. #define require_quiet(stmt,target)  REQUIRE_QUIET(stmt,target)
  608. #define require_action_quiet(stmt,target,action) REQUIRE_ACTION_QUIET(stmt,target,action)
  609. #define check_success(stat) CHECK_SUCCESS(stat)
  610. #define require_success(stat,target)  REQUIRE_SUCCESS(stat,target)
  611. #define require_success_action(stat,target,action)  REQUIRE_SUCCESS_ACTION(stat,target,action)
  612. #define require_success_quiet(stat,target)  REQUIRE_SUCCESS_QUIET(stat,target)
  613. #define require_success_action_quiet(stat,target,action) REQUIRE_SUCCESS_ACTION_QUIET(stat,target,action)
  614. #define check_noerr(err) CHECK_NOERR(err)
  615. #define require_noerr_return(err,returned) REQUIRE_NOERR_RETURN(err,returned)
  616. #define require_noerr(err,target)  REQUIRE_NOERR(err,target)
  617. #define require_noerr_action(err,target,action)  REQUIRE_NOERR_ACTION(err,target,action)
  618. #define require_noerr_quiet(err,target)  REQUIRE_NOERR_QUIET(err,target)
  619. #define require_noerr_action_quiet(err,target,action) REQUIRE_NOERR_ACTION_QUIET(err,target,action)
  620. #define check_nonnull(ptr) CHECK_NONNULL(ptr)
  621. #define check_null(ptr) CHECK_NULL(ptr)
  622. #define require_nonnull_void_return(ptr) REQUIRE_NONNULL_VOID_RETURN(ptr)
  623. #define require_nonnull_return(ptr,returned) REQUIRE_NONNULL_RETURN(ptr,returned)
  624. #define require_nonnull(ptr,target)  REQUIRE_NONNULL(ptr,target)
  625. #define require_nonnull_action(ptr,target,action)  REQUIRE_NONNULL_ACTION(ptr,target,action)
  626. #define require_nonnull_quiet(ptr,target)  REQUIRE_NONNULL_QUIET(ptr,target)
  627. #define require_nonnull_action_quiet(ptr,target,action) REQUIRE_NONNULL_ACTION_QUIET(ptr,target,action)
  628. #endif // !_HXASSERT_H_