/* Standard debugging and error tracking macros. */ #ifndef __STANDARD_DEBUG_HEADER__ #define __STANDARD_DEBUG_HEADER__ /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ /* Functional Summary */ /* Wrap function calls, default conditionals, and sanity-checks with the following wrappers to provide error testing and reporting on MacOS and ANSI platforms. Functions are divided into 5 categories: ASSERT - Debugging-only utility used to sanity-checking pointers and parameters that *should* always be valid, but for which you have provided an external API to another developer. Debug software will log a message and abort the program; non-debug software will completely optimize the tests out. TRACE - Simple logging utility for recording unusual circumstances or soft errors which must be ignored. Tracing evaluates and sets the "error" code, but does not stop or branch execution. THROW - Error testing and logging facility for hard errors, which force execution to branch. Require the presence of a CATCH macro toward the end of the function. REMAP - Identical to THROW, except that one error code is reported and another error code is returned. Useful for abstraction libraries which need to display low-level errors and return appropriate high-level errors. CATCH - Zero-overhead macro which acts as the target of execution after a THROW or REMAP event. Commands after a CATCH should dispose structures while carefully testing for exceptional or error cases. By redefining _DEBUGFTN, it is possible to change the method by which errors are reported. Be careful, however, because only certain report functions are interrupt-safe. Finally, the DEBUG #define differentiates between compiling a debug version (much larger, slower) for internal or beta testing, and a non-debug version for sending to end-users. */ /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ /* Preprocessor Includes */ #ifndef __STANDARD_TYPES_HEADER__ #include "stdtypes.h" #endif /* __STANDARD_TYPES_HEADER__ */ /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ /* Preprocessor Declarations */ /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ #ifndef DEBUG #define qAssert() do { ; } while(0) #define qAssertMsg(m) do { ; } while(0) #define qAssertErr(e,m) do { ; } while(0) #define qTrace() do { ; } while(0) #define qTraceMsg(m) do { ; } while(0) #define qTraceErr(e,m) do { (error = (e)); } while(0) #define qThrow() do { goto _CLEANUP; } while(0) #define qThrowMsg(m) do { goto _CLEANUP; } while(0) #define qThrowErr(e,m) do { (error = (e)); goto _CLEANUP; } while(0) #define qRemapErr(e,E,m) do { (error = (E)); goto _CLEANUP; } while(0) #else /* Kludges to make the preprocessor convert __LINE__ into a string */ #define _mkstr(x) _mkval(x) #define _mkval(x) #x #define _FL __FILE__ #define _LN _mkstr(__LINE__) #define qAssert() Debug(0,0,_FL,_LN,0,1) #define qAssertMsg(m) Debug((m),0,_FL,_LN,0,1) #define qAssertErr(e,m) Debug((m),error=(e),_FL,_LN,0,1) #define qTrace() Debug(0,0,_FL,_LN,0,0) #define qTraceMsg(m) Debug((m),0,_FL,_LN,0,0) #define qTraceErr(e,m) Debug((m),error=(e),_FL,_LN,0,0) #define qThrow() do { Debug(0,0,_FL,_LN,1,0); \ goto _CLEANUP; } while(0) #define qThrowMsg(m) do { Debug((m),0,_FL,_LN,1,0); \ goto _CLEANUP; } while(0) #define qThrowErr(e,m) do { Debug((m),error=(e),_FL,_LN,1,0); \ goto _CLEANUP; } while(0) #define qRemapErr(e,E,m) do { Debug((m),error=(e),_FL,_LN,1,0); \ error=(E); goto _CLEANUP; } while(0) #endif /* DEBUG */ #define qAssertIfError(e,m) do { register long _e; if (_e=(e)) \ qAssertErr(_e,(m));} while(0) #define qAssertIfNull(x,e,m) do { if (!(x)) qAssertErr((e),(m)); } while(0) #define qAssertIfFalse(x,e,m) do { if (!(x)) qAssertErr((e),(m)); } while(0) #define qAssertIfTrue(x,e,m) do { if (x) qAssertErr((e),(m)); } while(0) #define qTraceIfError(e,m) do { register long _e; if (_e=(e)) \ qTraceErr(_e,(m)); } while(0) #define qTraceIfNull(x,e,m) do { if (!(x)) qTraceErr((e),(m)); } while(0) #define qTraceIfFalse(x,e,m) do { if (!(x)) qTraceErr((e),(m)); } while(0) #define qTraceIfTrue(x,e,m) do { if (x) qTraceErr((e),(m)); } while(0) #define qThrowIfError(e,m) do { register long _e; if (_e=(e)) \ qThrowErr(_e,(m)); } while(0) #define qThrowIfNull(x,e,m) do { if (!(x)) qThrowErr((e),(m)); } while(0) #define qThrowIfFalse(x,e,m) do { if (!(x)) qThrowErr((e),(m)); } while(0) #define qThrowIfTrue(x,e,m) do { if (x) qThrowErr((e),(m)); } while(0) #define qRemapIfError(e,E,m) do { register long _e; if (_e=(e)) \ qRemapErr(_e,(E),(m)); } while(0) #define qRemapIfNull(x,e,E,m) do { if (!(x)) qRemapErr((e),(E),(m)); } while(0) #define qRemapIfFalse(x,e,E,m) do { if (!(x)) qRemapErr((e),(E),(m)); } while(0) #define qRemapIfTrue(x,e,E,m) do { if (x) qRemapErr((e),(E),(m)); } while(0) #define qCatch() { _CLEANUP: ; } /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ /* Structure/Class Declarations */ /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ /* Function Prototypes */ #ifdef __cplusplus extern "C" { #endif extern void Debug(char *, long, char *, char *, int, int); #ifdef __cplusplus } #endif /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ #endif /* __STANDARD_DEBUG_HEADER__ */