hxassert.h
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:26k
源码类别:

Symbian

开发平台:

Visual C++

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