summaryrefslogtreecommitdiffstats
path: root/amarok/src/engine/helix/helix-sp/helix-include/common/dbgtool/hxassert.h
blob: 73c006eae9e8819a75957364749da414f5af8fdc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727

/*
 *
 * This software is released under the provisions of the GPL version 2.
 * see file "COPYING".  If that file is not available, the full statement 
 * of the license can be found at
 *
 * http://www.fsf.org/licensing/licenses/gpl.txt
 *
 * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
 *
 */

/////////////////////////////////////////////////////////////////////////////
// HXASSERT.H
//
// Debugging support header.
//
// HX_ASSERT()	- asserts an expression is TRUE. Compiles to no-ops in
//				retail builds. Provides message box or other UI when 
//				expression fails.
//
// HX_ASSERT_VALID_PTR() - asserts that a pointer is valid. Performs more
//				rigid verification specifically appropriate for pointers.
//
// HX_VERIFY()	- verifies an expression is TRUE. Expression or code DOES NOT 
//				compile away in retail builds, but UI of failure is removed.
//				In debug builds provides message box or other UI when 
//				expression fails.
//
// HX_TRACE()	- Similar to DEBUGPRINTF() but no buffer is required. 
//				Compiles to no-ops in retail builds.
//

#ifndef _HXASSERT_H_
#define _HXASSERT_H_

#include "hlxclib/assert.h"

#ifndef ASSERT
#if defined (DEBUG) || defined (_DEBUG)
#if defined (_OSF1) && defined (_NATIVE_COMPILER)
#	define ASSERT(x)	assert(((long)(x)) != 0L)
#else
#       define ASSERT(x)        assert(x)
#endif
#else
#	define ASSERT(x)	/* x */
#endif /* DEBUG */
#endif /* ndef ASSERT */

#include "hlxclib/limits.h"
#include "hxtypes.h"
#include "hxresult.h"           // for HX_RESULT
#include "hlxclib/stdio.h"      // for sprintf

#ifdef _SUN
#include <stddef.h>     // for size_t
#endif

#ifdef __cplusplus
extern "C" {
#endif

#if defined (_SOLARIS) || defined (_IRIX) || defined (_DECALPHA)
#ifndef __inline
#define __inline inline
#endif
#endif

#if defined (_OSF1) && defined (_NATIVE_COMPILER)
#if defined __cplusplus
#define __inline inline
#else
#define __inline static
#endif /* __cplusplus */
#endif

#ifdef _HPUX 
#if defined __cplusplus
#define __inline inline
#else
#define __inline 
#endif /* __cplusplus */
#endif

#if defined _AIX
#if defined __cplusplus
#define __inline inline
#else
#define __inline 
#endif /* __cplusplus */
#endif /* _AIX */

#ifdef _UNIX
#include <signal.h> /* For kill() */
#include <unistd.h> /* For getpid() */
#include <stdio.h>
void HXUnixDebugBreak();
#endif


/////////////////////////////////////////////////////////////////////////////
// Diagnostic support

// For _MAX_PATH
#if defined ( _MACINTOSH )
#include "platform/mac/maclibrary.h"
#elif defined (_UNIX)
#include <stdlib.h>
#if !defined(_VXWORKS)
#include <sys/param.h>
#endif
#define _MAX_PATH       MAXPATHLEN
#elif defined (_WINDOWS)
#include <stdlib.h>
#endif

#ifdef _SYMBIAN
# include <unistd.h>
# define _MAX_PATH MAXPATHLEN
#endif

#ifdef _OPENWAVE
#ifndef _MAX_PATH
#define _MAX_PATH 256
#endif
#endif

#if defined (DEBUG) || defined (_DEBUG)

#ifdef _MACINTOSH
#  define MAX_TRACE_OUTPUT  255
#else
# ifdef _UNIX
#  define MAX_TRACE_OUTPUT  255
# elif _WIN16
#  define MAX_TRACE_OUTPUT  255
# elif _SYMBIAN
#  define MAX_TRACE_OUTPUT  255
# else
#  define MAX_TRACE_OUTPUT  (_MAX_PATH*2 + 20)
# endif
#endif


/////////////////////////////////////////////////////////////////////////////
//
//	HXDebugOptionEnabled: 
//		Determine if the given debug option is enabled.
//		A lookup is done to the registry key, and if it's present
//		and set to '1', TRUE is returned otherwise FALSE
//		Similar to HXWantTraceMessages, except not specific to one option.
#ifdef _WIN16
// The STDMETHODCALLTYPE includes the _export keyword, even though this is
// a static, not dll, library.  Seems to work on win32 ok, but not a win16
// .exe.  rpapp would see this as duplicate symbol, until the _export was
// removed, and all the libraries that rpapp linked with rebuilt.  There
// may be a define for STDMETHODCALLTYPE without the _export that should be
// used here. XXXTW.  april 98.
HXBOOL far _cdecl HXDebugOptionEnabled(const char* szOption);
#else
HXBOOL STDMETHODCALLTYPE HXDebugOptionEnabled(const char* szOption);
#endif

/////////////////////////////////////////////////////////////////////////////
//
//	HXWantTraceMessages: 
//		Helper function used to determine if the system has asked for trace 
//		messages.
//
HXBOOL STDMETHODCALLTYPE HXWantTraceMessages();

/////////////////////////////////////////////////////////////////////////////
//
//	HXOutputDebugString: 
//		Helper function used by DEBUGOUTSTR(). This is better than 
//		OutputDebugString, because it will check to see if output
//		tracing is turned off in the registry. This prevents the massive
//		slew of output messages.
//
void STDMETHODCALLTYPE HXOutputDebugString(const char* pString);

/////////////////////////////////////////////////////////////////////////////
//
// HXTrace: Helper function used by HX_TRACE()
//
void STDMETHODVCALLTYPE HXTrace(const char* pszFormat, ...);


/////////////////////////////////////////////////////////////////////////////
//
// HXAssertFailedLine: Helper function used by HX_ASSERT()
//
#ifdef _WIN16
// The STDMETHODCALLTYPE includes the _export keyword, even though this is
// a static, not dll, library.  Seems to work on win32 ok, but not a win16
// .exe.  rpapp would see this as duplicate symbol, until the _export was
// removed, and all the libraries that rpapp linked with rebuilt.  There
// may be a define for STDMETHODCALLTYPE without the _export that should be
// used here. XXXTW.  april 98.
HXBOOL far _cdecl HXAssertFailedLine(const char* pszExpression, const char* pszFileName, int nLine);
#else
HXBOOL STDMETHODCALLTYPE HXAssertFailedLine(const char* pszExpression, const char* pszFileName, int nLine);
#endif

/////////////////////////////////////////////////////////////////////////////
//
// HXAssertValidPointer, HXIsValidAddress: Helper functions used by
// HX_ASSERT_VALID_PTR()
//
void STDMETHODCALLTYPE HXAssertValidPointer(const void* pVoid, const char* pszFileName, int nLine);
#ifdef __cplusplus
#ifdef _WIN16
    // see note above on the problem with STDMETHODCALLTYPE on win16
    HXBOOL far _cdecl        HXIsValidAddress(const void* lp, ULONG32 nBytes = 1, HXBOOL bReadWrite = TRUE);
#else
    HXBOOL STDMETHODCALLTYPE HXIsValidAddress(const void* lp, ULONG32 nBytes = 1, HXBOOL bReadWrite = TRUE);
#endif
#else
#ifdef _WIN16
    // see note above on the problem with STDMETHODCALLTYPE on win16
    HXBOOL far _cdecl        HXIsValidAddress(const void* lp, ULONG32 nBytes, HXBOOL bReadWrite);
#else
    HXBOOL STDMETHODCALLTYPE HXIsValidAddress(const void* lp, ULONG32 nBytes, HXBOOL bReadWrite);
#endif
#endif

#ifdef _WIN16
HXBOOL far _cdecl        HXIsValidString(const char* lpsz, int nLength);
#else
HXBOOL STDMETHODCALLTYPE HXIsValidString(const char* lpsz, int nLength);
#endif

/////////////////////////////////////////////////////////////////////////////
//
// HXDebugBreak: used to break into debugger at critical times
//
#ifndef HXDebugBreak
// by default, debug break is asm int 3, or a call to DebugBreak, or nothing

#if defined(_WINDOWS)
#if !defined(_M_IX86)
#include "windows.h"
#define HXDebugBreak() DebugBreak()
#else
#define HXDebugBreak() _asm { int 3 }
#endif // _M_ALPHA
#elif defined( _MACINTOSH )
#define HXDebugBreak() Debugger()
#elif defined(_OPENWAVE)
#if defined(_OPENWAVE_SIMULATOR) // windows app...
#define HXDebugBreak() _asm { int 3 }
#else
void HXDebugBreak();
#endif
#elif defined(_SYMBIAN)
#if defined(__WINS__)
#define HXDebugBreak() _asm { int 3 }
#else
void HXDebugBreak();
#endif //_SYMBIAN
#elif  defined(_UNIX)
void HXDebugBreak();
#elif defined(_VXWORKS)
#include <taskLib.h>
#define HXDebugBreak() (taskSuspend(taskIdSelf()))

#endif // end of#if defined(_WIN32) || defined(_WINDOWS)

#endif // end of#ifndef HXDebugBreak

#ifdef _UNIX
#include "signal.h"
#include "stdlib.h"

#define HX_ENABLE_JIT_DEBUGGING()               \
do {						\
    signal (SIGSEGV, (void (*)(int))HXDebugBreak);		\
    signal (SIGBUS,  (void (*)(int))HXDebugBreak);		\
    signal (SIGFPE,  (void (*)(int))HXDebugBreak);		\
    if (!getenv("PROCESS_NAME"))                \
    {                                           \
    char *progname = new char[strlen(argv[0]) + 30]; \
    sprintf(progname, "PROCESS_NAME=%s", argv[0]); /* Flawfinder: ignore */ \
    putenv(progname);                           \
    } \
} while (0);
#else
#define HX_ENABLE_JIT_DEBUGGING()
#endif

/////////////////////////////////////////////////////////////////////////////
//
// HXAbort: used to shut down the application at critical times
//
#ifndef HXAbort

#if (defined(_WIN32) || defined(_WINDOWS)) && !defined(WIN32_PLATFORM_PSPC)
# define HXAbort() 	abort()
#elif defined(WIN32_PLATFORM_PSPC)
# define HXAbort()   exit(1)
#elif defined(_SYMBIAN)
# define HXAbort() exit(1)
#elif defined(_OPENWAVE)
// XXXSAB is this right??
# define HXAbort() exit(1)
#elif defined ( _MACINTOSH )
# define HXAbort() DebugStr("\pHXAbort: Please exit this program.")
#elif defined ( _UNIX )
# define HXAbort() printf("\npnabort: Please exit this program.\n")
#endif // end of#if defined(_WIN32) || defined(_WINDOWS)

#endif // end of#ifndef HXAbort


/////////////////////////////////////////////////////////////////////////////
//
// HX_TRACE: see above.
//
#define HX_TRACE			::HXTrace

/////////////////////////////////////////////////////////////////////////////
//
// HX_ASSERT: see above.
//
#define HX_ASSERT(f) \
	do \
	{ \
	if (!(f) && HXAssertFailedLine(#f, __FILE__, __LINE__)) \
		HXDebugBreak(); \
	} while (0) \


#define RETQUIRE_REPORT(targ,file,line)	HXAssertFailedLine(targ,file,line)




/////////////////////////////////////////////////////////////////////////////
//
//	Macros Defined for logging messges in the player. 
//  
//  STARTLOGSINK: Query for an IHXErrorSink
//
//  LOGINFO: Report the error to the error sink
//
//  STOPLOGSINK: Shutdown and Release the error sink.	       
//
/////////////////////////////////////////////////////////////////////////////
#ifndef _GOLD

#ifndef _INTERFACE
#define _INTERFACE struct
#endif

typedef _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 __cplusplus
extern "C"
#endif
int 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((const void*)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 RETQUIRE_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, ...) { }
#else
static __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
#endif

typedef _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/RETQUIRE MACROS
//
// These macros are always valid (debug and release builds)
//
//

//
// RETQUIRE and RETQUIRE_ACTION _always_ emit code for the goto if the statement is false
//
// RETQUIRE_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 RETQUIRE_VOID_RETURN(stmt) \
	do { if ((stmt) == 0) { if (RETQUIRE_REPORT(#stmt,__FILE__,__LINE__)) HXDebugBreak(); return; } } while (0)
#define RETQUIRE_RETURN(stmt,returned) \
	do { if ((stmt) == 0) { if (RETQUIRE_REPORT(#stmt,__FILE__,__LINE__)) HXDebugBreak(); return (returned); } } while (0)
#define RETQUIRE_VOID_RETURN_TQUIET(stmt) \
	do { if ((stmt) == 0) { return; } } while (0)
#define RETQUIRE_RETURN_TQUIET(stmt,returned) \
	do { if ((stmt) == 0) { return (returned); } } while (0)
#define RETQUIRE(stmt,target) \
	do { if ((stmt) == 0) { RETQUIRE_REPORT(#target,__FILE__,__LINE__); goto target; } } while (0)
#define RETQUIRE_ACTION(stmt,target,action) \
	do { if ((stmt) == 0) { RETQUIRE_REPORT(#target,__FILE__,__LINE__); {{action;} goto target;} } } while (0)
#define RETQUIRE_TQUIET(stmt,target) \
	do { if ((stmt) == 0) goto target; } while (0)
#define RETQUIRE_ACTION_TQUIET(stmt,target,action) \
	do { if ((stmt) == 0) {{action;} goto target;} } while (0)
#define PRE_RETQUIRE_RETURN(stmt,returned) \
	RETQUIRE_RETURN(stmt,returned)
#define PRE_RETQUIRE_VOID_RETURN(stmt) \
	RETQUIRE_VOID_RETURN(stmt)
#define POST_RETQUIRE_RETURN(stmt,returned) \
	RETQUIRE_RETURN(stmt,returned)
#define POST_RETQUIRE_VOID_RETURN(stmt) \
	RETQUIRE_VOID_RETURN(stmt)

#define RETQUIRE_SUCCESS_RETURN_TQUIET(expr) \
	do { register HX_RESULT const res = expr; if (FAILED (res)) return res; } while (0)
#define RETQUIRE_SUCCESS_RETURN(expr) \
	do { register HX_RESULT const res = expr; if (FAILED (res)) {  RETQUIRE_REPORT("False condition, Aborting...",__FILE__,__LINE__); return res; } } while (0)

//
// RETQUIRE_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 RETQUIRE_SUCCESS(stat,target) \
	do { if (((unsigned long)(stat)>>31) != 0) { RETQUIRE_REPORT(#target,__FILE__,__LINE__); goto target; } } while (0)
#define RETQUIRE_SUCCESS_ACTION(stat,target,action) \
	do { if (((unsigned long)(stat)>>31) != 0) { RETQUIRE_REPORT(#target,__FILE__,__LINE__); {{action;} goto target;} } } while (0)
#define RETQUIRE_SUCCESS_TQUIET(stat,target) \
	do { if (((unsigned long)(stat)>>31) != 0) goto target; } while (0)
#define RETQUIRE_SUCCESS_ACTION_TQUIET(stat,target,action) \
	do { if (((unsigned long)(stat)>>31) != 0) {{action;} goto target;} } while (0)

//
// RETQUIRE_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 RETQUIRE_NOERR_RETURN(err,returned) \
	do { if ((err) != 0) { RETQUIRE_REPORT("Toolbox error, Aborting...",__FILE__,__LINE__); return (returned); } } while (0)
#define RETQUIRE_NOERR(err,target) \
	do { if ((err) != 0) { RETQUIRE_REPORT(#target,__FILE__,__LINE__); goto target; } } while (0)
#define RETQUIRE_NOERR_ACTION(err,target,action) \
	do { if ((err) != 0) { RETQUIRE_REPORT(#target,__FILE__,__LINE__); {{action;} goto target;} } } while (0)
#define RETQUIRE_NOERR_TQUIET(err,target) \
	do { if ((err) != 0) goto target; } while (0)
#define RETQUIRE_NOERR_ACTION_TQUIET(err,target,action) \
	do { if ((err) != 0) {{action;} goto target;} } while (0)

//
// RETQUIRE_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 RETQUIRE_NONNULL_VOID_RETURN(ptr) \
	do { if ((ptr) == 0L) { RETQUIRE_REPORT(#ptr" is nil, Aborting...",__FILE__,__LINE__); return; } } while (0)
#define RETQUIRE_NONNULL_RETURN(ptr,returned) \
	do { if ((ptr) == 0L) { RETQUIRE_REPORT(#ptr" is nil, Aborting...",__FILE__,__LINE__); return (returned); } } while (0)
#define RETQUIRE_NONNULL(ptr,target) \
	do { if ((ptr) == 0L) { RETQUIRE_REPORT(#target,__FILE__,__LINE__); goto target; } } while (0)
#define RETQUIRE_NONNULL_ACTION(ptr,target,action) \
	do { if ((ptr) == 0L) { RETQUIRE_REPORT(#target,__FILE__,__LINE__); {{action;} goto target;} } } while (0)
#define RETQUIRE_NONNULL_TQUIET(ptr,target) \
	do { if ((ptr) == 0L) goto target; } while (0)
#define RETQUIRE_NONNULL_ACTION_TQUIET(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)							RETQUIRE_VOID_RETURN(stmt)
#define require_return_void(stmt)							RETQUIRE_VOID_RETURN(stmt)
#define require_return(stmt,returned)						RETQUIRE_RETURN(stmt,returned)
#define require(stmt,target) 								RETQUIRE(stmt,target)
#define require_action(stmt,target,action) 					RETQUIRE_ACTION(stmt,target,action)
#define require_quiet(stmt,target) 							RETQUIRE_TQUIET(stmt,target)
#define require_action_quiet(stmt,target,action)			RETQUIRE_ACTION_TQUIET(stmt,target,action)

#define check_success(stat)									CHECK_SUCCESS(stat)

#define require_success(stat,target) 						RETQUIRE_SUCCESS(stat,target)
#define require_success_action(stat,target,action) 			RETQUIRE_SUCCESS_ACTION(stat,target,action)
#define require_success_quiet(stat,target) 					RETQUIRE_SUCCESS_TQUIET(stat,target)
#define require_success_action_quiet(stat,target,action)	RETQUIRE_SUCCESS_ACTION_TQUIET(stat,target,action)

#define check_noerr(err)									CHECK_NOERR(err)

#define require_noerr_return(err,returned)					RETQUIRE_NOERR_RETURN(err,returned)
#define require_noerr(err,target) 							RETQUIRE_NOERR(err,target)
#define require_noerr_action(err,target,action) 			RETQUIRE_NOERR_ACTION(err,target,action)
#define require_noerr_quiet(err,target) 					RETQUIRE_NOERR_TQUIET(err,target)
#define require_noerr_action_quiet(err,target,action)		RETQUIRE_NOERR_ACTION_TQUIET(err,target,action)

#define check_nonnull(ptr)									CHECK_NONNULL(ptr)
#define check_null(ptr)										CHECK_NULL(ptr)

#define require_nonnull_void_return(ptr)					RETQUIRE_NONNULL_VOID_RETURN(ptr)
#define require_nonnull_return(ptr,returned)				RETQUIRE_NONNULL_RETURN(ptr,returned)
#define require_nonnull(ptr,target) 						RETQUIRE_NONNULL(ptr,target)
#define require_nonnull_action(ptr,target,action) 			RETQUIRE_NONNULL_ACTION(ptr,target,action)
#define require_nonnull_quiet(ptr,target) 					RETQUIRE_NONNULL_TQUIET(ptr,target)
#define require_nonnull_action_quiet(ptr,target,action)		RETQUIRE_NONNULL_ACTION_TQUIET(ptr,target,action)


#endif // !_HXASSERT_H_