mirror of
https://github.com/nillerusr/source-engine.git
synced 2024-12-23 06:36:54 +00:00
1118 lines
50 KiB
C
1118 lines
50 KiB
C
/*
|
|
File: AssertMacros.h
|
|
|
|
Contains: This file defines structured error handling and assertion macros for
|
|
programming in C. Originally used in QuickDraw GX and later enhanced.
|
|
These macros are used throughout Apple's software.
|
|
|
|
See "Living In an Exceptional World" by Sean Parent
|
|
(develop, The Apple Technical Journal, Issue 11, August/September 1992)
|
|
<http://developer.apple.com/dev/techsupport/develop/issue11toc.shtml>
|
|
for the methodology behind these error handling and assertion macros.
|
|
|
|
Copyright: © 2002 by Apple Computer, Inc., all rights reserved.
|
|
|
|
Bugs?: For bug reports, consult the following page on
|
|
the World Wide Web:
|
|
|
|
http://developer.apple.com/bugreporter/
|
|
*/
|
|
#ifndef __ASSERTMACROS__
|
|
#define __ASSERTMACROS__
|
|
|
|
|
|
/*
|
|
* Macro overview:
|
|
*
|
|
* check(assertion)
|
|
* In production builds, pre-processed away
|
|
* In debug builds, if assertion evaluates to false, calls DEBUG_ASSERT_MESSAGE
|
|
*
|
|
* verify(assertion)
|
|
* In production builds, evaluates assertion and does nothing
|
|
* In debug builds, if assertion evaluates to false, calls DEBUG_ASSERT_MESSAGE
|
|
*
|
|
* require(assertion, exceptionLabel)
|
|
* In production builds, if the assertion expression evaluates to false, goto exceptionLabel
|
|
* In debug builds, if the assertion expression evaluates to false, calls DEBUG_ASSERT_MESSAGE
|
|
* and jumps to exceptionLabel
|
|
*
|
|
* In addition the following suffixes are available:
|
|
*
|
|
* _noerr Adds "!= 0" to assertion. Useful for asserting and OSStatus or OSErr is noErr (zero)
|
|
* _action Adds statement to be executued if assertion fails
|
|
* _quiet Suppress call to DEBUG_ASSERT_MESSAGE
|
|
* _string Allows you to add explanitory message to DEBUG_ASSERT_MESSAGE
|
|
*
|
|
* For instance, require_noerr_string(resultCode, label, msg) will do nothing if
|
|
* resultCode is zero, otherwise it will call DEBUG_ASSERT_MESSAGE with msg
|
|
* and jump to label.
|
|
*
|
|
* Configuration:
|
|
*
|
|
* By default all macros generate "production code" (i.e non-debug). If
|
|
* DEBUG_ASSERT_PRODUCTION_CODE is defined to zero or DEBUG is defined to non-zero
|
|
* while this header is included, the macros will generated debug code.
|
|
*
|
|
* If DEBUG_ASSERT_COMPONENT_NAME_STRING is defined, all debug messages will
|
|
* be prefixed with it.
|
|
*
|
|
* By default, all messages write to stderr. If you would like to write a custom
|
|
* error message formater, defined DEBUG_ASSERT_MESSAGE to your function name.
|
|
*
|
|
*/
|
|
|
|
|
|
/*
|
|
* Before including this file, #define DEBUG_ASSERT_COMPONENT_NAME_STRING to
|
|
* a C-string containing the name of your client. This string will be passed to
|
|
* the DEBUG_ASSERT_MESSAGE macro for inclusion in any assertion messages.
|
|
*
|
|
* If you do not define DEBUG_ASSERT_COMPONENT_NAME_STRING, the default
|
|
* DEBUG_ASSERT_COMPONENT_NAME_STRING value, an empty string, will be used by
|
|
* the assertion macros.
|
|
*/
|
|
#ifndef DEBUG_ASSERT_COMPONENT_NAME_STRING
|
|
#define DEBUG_ASSERT_COMPONENT_NAME_STRING ""
|
|
#endif
|
|
|
|
|
|
/*
|
|
* To activate the additional assertion code and messages for non-production builds,
|
|
* #define DEBUG_ASSERT_PRODUCTION_CODE to zero before including this file.
|
|
*
|
|
* If you do not define DEBUG_ASSERT_PRODUCTION_CODE, the default value 1 will be used
|
|
* (production code = no assertion code and no messages).
|
|
*/
|
|
#ifndef DEBUG_ASSERT_PRODUCTION_CODE
|
|
#define DEBUG_ASSERT_PRODUCTION_CODE !DEBUG
|
|
#endif
|
|
|
|
|
|
/*
|
|
* DEBUG_ASSERT_MESSAGE()
|
|
*
|
|
* Summary:
|
|
* All assertion messages are routed through this macro. If you wish to use your
|
|
* own routine to display assertion messages, you can override DEBUG_ASSERT_MESSAGE
|
|
* by #defining DEBUG_ASSERT_MESSAGE before including this file.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* componentNameString:
|
|
* A pointer to a string constant containing the name of the
|
|
* component this code is part of. This must be a string constant
|
|
* (and not a string variable or NULL) because the preprocessor
|
|
* concatenates it with other string constants.
|
|
*
|
|
* assertionString:
|
|
* A pointer to a string constant containing the assertion.
|
|
* This must be a string constant (and not a string variable or
|
|
* NULL) because the Preprocessor concatenates it with other
|
|
* string constants.
|
|
*
|
|
* exceptionLabelString:
|
|
* A pointer to a string containing the exceptionLabel, or NULL.
|
|
*
|
|
* errorString:
|
|
* A pointer to the error string, or NULL. DEBUG_ASSERT_MESSAGE macros
|
|
* must not attempt to concatenate this string with constant
|
|
* character strings.
|
|
*
|
|
* fileName:
|
|
* A pointer to the fileName or pathname (generated by the
|
|
* preprocessor __FILE__ identifier), or NULL.
|
|
*
|
|
* lineNumber:
|
|
* The line number in the file (generated by the preprocessor
|
|
* __LINE__ identifier), or 0 (zero).
|
|
*
|
|
* errorCode:
|
|
* A value associated with the assertion, or 0.
|
|
*
|
|
* Here is an example of a DEBUG_ASSERT_MESSAGE macro and a routine which displays
|
|
* assertion messsages:
|
|
*
|
|
* #define DEBUG_ASSERT_COMPONENT_NAME_STRING "MyCoolProgram"
|
|
*
|
|
* #define DEBUG_ASSERT_MESSAGE(componentNameString, assertionString, \
|
|
* exceptionLabelString, errorString, fileName, lineNumber, errorCode) \
|
|
* MyProgramDebugAssert(componentNameString, assertionString, \
|
|
* exceptionLabelString, errorString, fileName, lineNumber, errorCode)
|
|
*
|
|
* static void
|
|
* MyProgramDebugAssert(const char *componentNameString, const char *assertionString,
|
|
* const char *exceptionLabelString, const char *errorString,
|
|
* const char *fileName, long lineNumber, int errorCode)
|
|
* {
|
|
* if ( (assertionString != NULL) && (*assertionString != \'0') )
|
|
* fprintf(stderr, "Assertion failed: %s: %s\n", componentNameString, assertionString);
|
|
* else
|
|
* fprintf(stderr, "Check failed: %s:\n", componentNameString);
|
|
* if ( exceptionLabelString != NULL )
|
|
* fprintf(stderr, " %s\n", exceptionLabelString);
|
|
* if ( errorString != NULL )
|
|
* fprintf(stderr, " %s\n", errorString);
|
|
* if ( fileName != NULL )
|
|
* fprintf(stderr, " file: %s\n", fileName);
|
|
* if ( lineNumber != 0 )
|
|
* fprintf(stderr, " line: %ld\n", lineNumber);
|
|
* if ( errorCode != 0 )
|
|
* fprintf(stderr, " error: %d\n", errorCode);
|
|
* }
|
|
*
|
|
* If you do not define DEBUG_ASSERT_MESSAGE, a simple printf to stderr will be used.
|
|
*/
|
|
#ifndef DEBUG_ASSERT_MESSAGE
|
|
#ifdef KERNEL
|
|
#include <syslog.h>
|
|
#define DEBUG_ASSERT_MESSAGE(name, assertion, label, message, file, line, value) \
|
|
syslog(LOG_ERR, "AssertMacros: %s, %s file: %s, line: %d\n", assertion, (message!=0) ? message : "", file, line);
|
|
#else
|
|
#include <stdio.h>
|
|
#define DEBUG_ASSERT_MESSAGE(name, assertion, label, message, file, line, value) \
|
|
fprintf(stderr, "AssertMacros: %s, %s file: %s, line: %d\n", assertion, (message!=0) ? message : "", file, line);
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
* debug_string(message)
|
|
*
|
|
* Summary:
|
|
* Production builds: does nothing and produces no code.
|
|
*
|
|
* Non-production builds: call DEBUG_ASSERT_MESSAGE.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* message:
|
|
* The C string to display.
|
|
*
|
|
*/
|
|
#if DEBUG_ASSERT_PRODUCTION_CODE
|
|
#define debug_string(message)
|
|
#else
|
|
#define debug_string(message) \
|
|
do \
|
|
{ \
|
|
DEBUG_ASSERT_MESSAGE( \
|
|
DEBUG_ASSERT_COMPONENT_NAME_STRING, \
|
|
"", \
|
|
0, \
|
|
message, \
|
|
__FILE__, \
|
|
__LINE__, \
|
|
0); \
|
|
} while ( 0 )
|
|
#endif
|
|
|
|
|
|
/*
|
|
* check(assertion)
|
|
*
|
|
* Summary:
|
|
* Production builds: does nothing and produces no code.
|
|
*
|
|
* Non-production builds: if the assertion expression evaluates to false,
|
|
* call DEBUG_ASSERT_MESSAGE.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* assertion:
|
|
* The assertion expression.
|
|
*/
|
|
#if DEBUG_ASSERT_PRODUCTION_CODE
|
|
#define check(assertion)
|
|
#else
|
|
#define check(assertion) \
|
|
do \
|
|
{ \
|
|
if ( !(assertion) ) \
|
|
{ \
|
|
DEBUG_ASSERT_MESSAGE( \
|
|
DEBUG_ASSERT_COMPONENT_NAME_STRING, \
|
|
#assertion, \
|
|
0, \
|
|
0, \
|
|
__FILE__, \
|
|
__LINE__, \
|
|
0); \
|
|
} \
|
|
} while ( 0 )
|
|
#endif
|
|
|
|
#define ncheck(assertion) \
|
|
check(!(assertion))
|
|
|
|
|
|
/*
|
|
* check_string(assertion, message)
|
|
*
|
|
* Summary:
|
|
* Production builds: does nothing and produces no code.
|
|
*
|
|
* Non-production builds: if the assertion expression evaluates to false,
|
|
* call DEBUG_ASSERT_MESSAGE.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* assertion:
|
|
* The assertion expression.
|
|
*
|
|
* message:
|
|
* The C string to display.
|
|
*/
|
|
#if DEBUG_ASSERT_PRODUCTION_CODE
|
|
#define check_string(assertion, message)
|
|
#else
|
|
#define check_string(assertion, message) \
|
|
do \
|
|
{ \
|
|
if ( !(assertion) ) \
|
|
{ \
|
|
DEBUG_ASSERT_MESSAGE( \
|
|
DEBUG_ASSERT_COMPONENT_NAME_STRING, \
|
|
#assertion, \
|
|
0, \
|
|
message, \
|
|
__FILE__, \
|
|
__LINE__, \
|
|
0); \
|
|
} \
|
|
} while ( 0 )
|
|
#endif
|
|
|
|
#define ncheck_string(assertion, message) \
|
|
check_string(!(assertion), message)
|
|
|
|
|
|
/*
|
|
* check_noerr(errorCode)
|
|
*
|
|
* Summary:
|
|
* Production builds: does nothing and produces no code.
|
|
*
|
|
* Non-production builds: if the errorCode expression does not equal 0 (noErr),
|
|
* call DEBUG_ASSERT_MESSAGE.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* errorCode:
|
|
* The errorCode expression to compare with 0.
|
|
*/
|
|
#if DEBUG_ASSERT_PRODUCTION_CODE
|
|
#define check_noerr(errorCode)
|
|
#else
|
|
#define check_noerr(errorCode) \
|
|
do \
|
|
{ \
|
|
int evalOnceErrorCode = (errorCode); \
|
|
if ( 0 != evalOnceErrorCode ) \
|
|
{ \
|
|
DEBUG_ASSERT_MESSAGE( \
|
|
DEBUG_ASSERT_COMPONENT_NAME_STRING, \
|
|
#errorCode " == 0 ", \
|
|
0, \
|
|
0, \
|
|
__FILE__, \
|
|
__LINE__, \
|
|
evalOnceErrorCode); \
|
|
} \
|
|
} while ( 0 )
|
|
#endif
|
|
|
|
|
|
/*
|
|
* check_noerr_string(errorCode, message)
|
|
*
|
|
* Summary:
|
|
* Production builds: check_noerr_string() does nothing and produces
|
|
* no code.
|
|
*
|
|
* Non-production builds: if the errorCode expression does not equal 0 (noErr),
|
|
* call DEBUG_ASSERT_MESSAGE.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* errorCode:
|
|
* The errorCode expression to compare to 0.
|
|
*
|
|
* message:
|
|
* The C string to display.
|
|
*/
|
|
#if DEBUG_ASSERT_PRODUCTION_CODE
|
|
#define check_noerr_string(errorCode, message)
|
|
#else
|
|
#define check_noerr_string(errorCode, message) \
|
|
do \
|
|
{ \
|
|
int evalOnceErrorCode = (errorCode); \
|
|
if ( 0 != evalOnceErrorCode ) \
|
|
{ \
|
|
DEBUG_ASSERT_MESSAGE( \
|
|
DEBUG_ASSERT_COMPONENT_NAME_STRING, \
|
|
#errorCode " == 0 ", \
|
|
0, \
|
|
message, \
|
|
__FILE__, \
|
|
__LINE__, \
|
|
evalOnceErrorCode); \
|
|
} \
|
|
} while ( 0 )
|
|
#endif
|
|
|
|
|
|
/*
|
|
* verify(assertion)
|
|
*
|
|
* Summary:
|
|
* Production builds: evaluate the assertion expression, but ignore
|
|
* the result.
|
|
*
|
|
* Non-production builds: if the assertion expression evaluates to false,
|
|
* call DEBUG_ASSERT_MESSAGE.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* assertion:
|
|
* The assertion expression.
|
|
*/
|
|
#if DEBUG_ASSERT_PRODUCTION_CODE
|
|
#define verify(assertion) \
|
|
do \
|
|
{ \
|
|
if ( !(assertion) ) \
|
|
{ \
|
|
} \
|
|
} while ( 0 )
|
|
#else
|
|
#define verify(assertion) \
|
|
do \
|
|
{ \
|
|
if ( !(assertion) ) \
|
|
{ \
|
|
DEBUG_ASSERT_MESSAGE( \
|
|
DEBUG_ASSERT_COMPONENT_NAME_STRING, \
|
|
#assertion, \
|
|
0, \
|
|
0, \
|
|
__FILE__, \
|
|
__LINE__, \
|
|
0); \
|
|
} \
|
|
} while ( 0 )
|
|
#endif
|
|
|
|
#define nverify(assertion) \
|
|
verify(!(assertion))
|
|
|
|
|
|
/*
|
|
* verify_string(assertion, message)
|
|
*
|
|
* Summary:
|
|
* Production builds: evaluate the assertion expression, but ignore
|
|
* the result.
|
|
*
|
|
* Non-production builds: if the assertion expression evaluates to false,
|
|
* call DEBUG_ASSERT_MESSAGE.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* assertion:
|
|
* The assertion expression.
|
|
*
|
|
* message:
|
|
* The C string to display.
|
|
*/
|
|
#if DEBUG_ASSERT_PRODUCTION_CODE
|
|
#define verify_string(assertion, message) \
|
|
do \
|
|
{ \
|
|
if ( !(assertion) ) \
|
|
{ \
|
|
} \
|
|
} while ( 0 )
|
|
#else
|
|
#define verify_string(assertion, message) \
|
|
do \
|
|
{ \
|
|
if ( !(assertion) ) \
|
|
{ \
|
|
DEBUG_ASSERT_MESSAGE( \
|
|
DEBUG_ASSERT_COMPONENT_NAME_STRING, \
|
|
#assertion, \
|
|
0, \
|
|
message, \
|
|
__FILE__, \
|
|
__LINE__, \
|
|
0); \
|
|
} \
|
|
} while ( 0 )
|
|
#endif
|
|
|
|
#define nverify_string(assertion, message) \
|
|
verify_string(!(assertion), message)
|
|
|
|
|
|
/*
|
|
* verify_noerr(errorCode)
|
|
*
|
|
* Summary:
|
|
* Production builds: evaluate the errorCode expression, but ignore
|
|
* the result.
|
|
*
|
|
* Non-production builds: if the errorCode expression does not equal 0 (noErr),
|
|
* call DEBUG_ASSERT_MESSAGE.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* errorCode:
|
|
* The expression to compare to 0.
|
|
*/
|
|
#if DEBUG_ASSERT_PRODUCTION_CODE
|
|
#define verify_noerr(errorCode) \
|
|
do \
|
|
{ \
|
|
if ( 0 != (errorCode) ) \
|
|
{ \
|
|
} \
|
|
} while ( 0 )
|
|
#else
|
|
#define verify_noerr(errorCode) \
|
|
do \
|
|
{ \
|
|
int evalOnceErrorCode = (errorCode); \
|
|
if ( 0 != evalOnceErrorCode ) \
|
|
{ \
|
|
DEBUG_ASSERT_MESSAGE( \
|
|
DEBUG_ASSERT_COMPONENT_NAME_STRING, \
|
|
#errorCode " == 0 ", \
|
|
0, \
|
|
0, \
|
|
__FILE__, \
|
|
__LINE__, \
|
|
evalOnceErrorCode); \
|
|
} \
|
|
} while ( 0 )
|
|
#endif
|
|
|
|
|
|
/*
|
|
* verify_noerr_string(errorCode, message)
|
|
*
|
|
* Summary:
|
|
* Production builds: evaluate the errorCode expression, but ignore
|
|
* the result.
|
|
*
|
|
* Non-production builds: if the errorCode expression does not equal 0 (noErr),
|
|
* call DEBUG_ASSERT_MESSAGE.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* errorCode:
|
|
* The expression to compare to 0.
|
|
*
|
|
* message:
|
|
* The C string to display.
|
|
*/
|
|
#if DEBUG_ASSERT_PRODUCTION_CODE
|
|
#define verify_noerr_string(errorCode, message) \
|
|
do \
|
|
{ \
|
|
if ( 0 != (errorCode) ) \
|
|
{ \
|
|
} \
|
|
} while ( 0 )
|
|
#else
|
|
#define verify_noerr_string(errorCode, message) \
|
|
do \
|
|
{ \
|
|
int evalOnceErrorCode = (errorCode); \
|
|
if ( 0 != evalOnceErrorCode ) \
|
|
{ \
|
|
DEBUG_ASSERT_MESSAGE( \
|
|
DEBUG_ASSERT_COMPONENT_NAME_STRING, \
|
|
#errorCode " == 0 ", \
|
|
0, \
|
|
message, \
|
|
__FILE__, \
|
|
__LINE__, \
|
|
evalOnceErrorCode); \
|
|
} \
|
|
} while ( 0 )
|
|
#endif
|
|
|
|
|
|
/*
|
|
* require(assertion, exceptionLabel)
|
|
*
|
|
* Summary:
|
|
* Production builds: if the assertion expression evaluates to false,
|
|
* goto exceptionLabel.
|
|
*
|
|
* Non-production builds: if the assertion expression evaluates to false,
|
|
* call DEBUG_ASSERT_MESSAGE and then goto exceptionLabel.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* assertion:
|
|
* The assertion expression.
|
|
*
|
|
* exceptionLabel:
|
|
* The label.
|
|
*/
|
|
#if DEBUG_ASSERT_PRODUCTION_CODE
|
|
#define require(assertion, exceptionLabel) \
|
|
do \
|
|
{ \
|
|
if ( !(assertion) ) \
|
|
{ \
|
|
goto exceptionLabel; \
|
|
} \
|
|
} while ( 0 )
|
|
#else
|
|
#define require(assertion, exceptionLabel) \
|
|
do \
|
|
{ \
|
|
if ( !(assertion) ) \
|
|
{ \
|
|
DEBUG_ASSERT_MESSAGE( \
|
|
DEBUG_ASSERT_COMPONENT_NAME_STRING, \
|
|
#assertion, \
|
|
#exceptionLabel, \
|
|
0, \
|
|
__FILE__, \
|
|
__LINE__, \
|
|
0); \
|
|
goto exceptionLabel; \
|
|
} \
|
|
} while ( 0 )
|
|
#endif
|
|
|
|
#define nrequire(assertion, exceptionLabel) \
|
|
require(!(assertion), exceptionLabel)
|
|
|
|
|
|
/*
|
|
* require_action(assertion, exceptionLabel, action)
|
|
*
|
|
* Summary:
|
|
* Production builds: if the assertion expression evaluates to false,
|
|
* execute the action statement or compound statement (block) and then
|
|
* goto exceptionLabel.
|
|
*
|
|
* Non-production builds: if the assertion expression evaluates to false,
|
|
* call DEBUG_ASSERT_MESSAGE, execute the action statement or compound
|
|
* statement (block), and then goto exceptionLabel.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* assertion:
|
|
* The assertion expression.
|
|
*
|
|
* exceptionLabel:
|
|
* The label.
|
|
*
|
|
* action:
|
|
* The statement or compound statement (block).
|
|
*/
|
|
#if DEBUG_ASSERT_PRODUCTION_CODE
|
|
#define require_action(assertion, exceptionLabel, action) \
|
|
do \
|
|
{ \
|
|
if ( !(assertion) ) \
|
|
{ \
|
|
{ \
|
|
action; \
|
|
} \
|
|
goto exceptionLabel; \
|
|
} \
|
|
} while ( 0 )
|
|
#else
|
|
#define require_action(assertion, exceptionLabel, action) \
|
|
do \
|
|
{ \
|
|
if ( !(assertion) ) \
|
|
{ \
|
|
DEBUG_ASSERT_MESSAGE( \
|
|
DEBUG_ASSERT_COMPONENT_NAME_STRING, \
|
|
#assertion, \
|
|
#exceptionLabel, \
|
|
0, \
|
|
__FILE__, \
|
|
__LINE__, \
|
|
0); \
|
|
{ \
|
|
action; \
|
|
} \
|
|
goto exceptionLabel; \
|
|
} \
|
|
} while ( 0 )
|
|
#endif
|
|
|
|
#define nrequire_action(assertion, exceptionLabel, action) \
|
|
require_action(!(assertion), exceptionLabel, action)
|
|
|
|
|
|
/*
|
|
* require_quiet(assertion, exceptionLabel)
|
|
*
|
|
* Summary:
|
|
* If the assertion expression evaluates to false, goto exceptionLabel.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* assertion:
|
|
* The assertion expression.
|
|
*
|
|
* exceptionLabel:
|
|
* The label.
|
|
*/
|
|
#define require_quiet(assertion, exceptionLabel) \
|
|
do \
|
|
{ \
|
|
if ( !(assertion) ) \
|
|
{ \
|
|
goto exceptionLabel; \
|
|
} \
|
|
} while ( 0 )
|
|
|
|
#define nrequire_quiet(assertion, exceptionLabel) \
|
|
require_quiet(!(assertion), exceptionLabel)
|
|
|
|
|
|
/*
|
|
* require_action_quiet(assertion, exceptionLabel, action)
|
|
*
|
|
* Summary:
|
|
* If the assertion expression evaluates to false, execute the action
|
|
* statement or compound statement (block), and goto exceptionLabel.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* assertion:
|
|
* The assertion expression.
|
|
*
|
|
* exceptionLabel:
|
|
* The label.
|
|
*
|
|
* action:
|
|
* The statement or compound statement (block).
|
|
*/
|
|
#define require_action_quiet(assertion, exceptionLabel, action) \
|
|
do \
|
|
{ \
|
|
if ( !(assertion) ) \
|
|
{ \
|
|
{ \
|
|
action; \
|
|
} \
|
|
goto exceptionLabel; \
|
|
} \
|
|
} while ( 0 )
|
|
|
|
#define nrequire_action_quiet(assertion, exceptionLabel, action) \
|
|
require_action_quiet(!(assertion), exceptionLabel, action)
|
|
|
|
|
|
/*
|
|
* require_string(assertion, exceptionLabel, message)
|
|
*
|
|
* Summary:
|
|
* Production builds: if the assertion expression evaluates to false,
|
|
* goto exceptionLabel.
|
|
*
|
|
* Non-production builds: if the assertion expression evaluates to false,
|
|
* call DEBUG_ASSERT_MESSAGE, and then goto exceptionLabel.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* assertion:
|
|
* The assertion expression.
|
|
*
|
|
* exceptionLabel:
|
|
* The label.
|
|
*
|
|
* message:
|
|
* The C string to display.
|
|
*/
|
|
#if DEBUG_ASSERT_PRODUCTION_CODE
|
|
#define require_string(assertion, exceptionLabel, message) \
|
|
do \
|
|
{ \
|
|
if ( !(assertion) ) \
|
|
{ \
|
|
goto exceptionLabel; \
|
|
} \
|
|
} while ( 0 )
|
|
#else
|
|
#define require_string(assertion, exceptionLabel, message) \
|
|
do \
|
|
{ \
|
|
if ( !(assertion) ) \
|
|
{ \
|
|
DEBUG_ASSERT_MESSAGE( \
|
|
DEBUG_ASSERT_COMPONENT_NAME_STRING, \
|
|
#assertion, \
|
|
#exceptionLabel, \
|
|
message, \
|
|
__FILE__, \
|
|
__LINE__, \
|
|
0); \
|
|
goto exceptionLabel; \
|
|
} \
|
|
} while ( 0 )
|
|
#endif
|
|
|
|
#define nrequire_string(assertion, exceptionLabel, string) \
|
|
require_string(!(assertion), exceptionLabel, string)
|
|
|
|
|
|
/*
|
|
* require_action_string(assertion, exceptionLabel, action, message)
|
|
*
|
|
* Summary:
|
|
* Production builds: if the assertion expression evaluates to false,
|
|
* execute the action statement or compound statement (block), and then
|
|
* goto exceptionLabel.
|
|
*
|
|
* Non-production builds: if the assertion expression evaluates to false,
|
|
* call DEBUG_ASSERT_MESSAGE, execute the action statement or compound
|
|
* statement (block), and then goto exceptionLabel.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* assertion:
|
|
* The assertion expression.
|
|
*
|
|
* exceptionLabel:
|
|
* The label.
|
|
*
|
|
* action:
|
|
* The statement or compound statement (block).
|
|
*
|
|
* message:
|
|
* The C string to display.
|
|
*/
|
|
#if DEBUG_ASSERT_PRODUCTION_CODE
|
|
#define require_action_string(assertion, exceptionLabel, action, message) \
|
|
do \
|
|
{ \
|
|
if ( !(assertion) ) \
|
|
{ \
|
|
{ \
|
|
action; \
|
|
} \
|
|
goto exceptionLabel; \
|
|
} \
|
|
} while ( 0 )
|
|
#else
|
|
#define require_action_string(assertion, exceptionLabel, action, message) \
|
|
do \
|
|
{ \
|
|
if ( !(assertion) ) \
|
|
{ \
|
|
DEBUG_ASSERT_MESSAGE( \
|
|
DEBUG_ASSERT_COMPONENT_NAME_STRING, \
|
|
#assertion, \
|
|
#exceptionLabel, \
|
|
message, \
|
|
__FILE__, \
|
|
__LINE__, \
|
|
0); \
|
|
{ \
|
|
action; \
|
|
} \
|
|
goto exceptionLabel; \
|
|
} \
|
|
} while ( 0 )
|
|
#endif
|
|
|
|
#define nrequire_action_string(assertion, exceptionLabel, action, message) \
|
|
require_action_string(!(assertion), exceptionLabel, action, message)
|
|
|
|
|
|
/*
|
|
* require_noerr(errorCode, exceptionLabel)
|
|
*
|
|
* Summary:
|
|
* Production builds: if the errorCode expression does not equal 0 (noErr),
|
|
* goto exceptionLabel.
|
|
*
|
|
* Non-production builds: if the errorCode expression does not equal 0 (noErr),
|
|
* call DEBUG_ASSERT_MESSAGE and then goto exceptionLabel.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* errorCode:
|
|
* The expression to compare to 0.
|
|
*
|
|
* exceptionLabel:
|
|
* The label.
|
|
*/
|
|
#if DEBUG_ASSERT_PRODUCTION_CODE
|
|
#define require_noerr(errorCode, exceptionLabel) \
|
|
do \
|
|
{ \
|
|
if ( 0 != (errorCode) ) \
|
|
{ \
|
|
goto exceptionLabel; \
|
|
} \
|
|
} while ( 0 )
|
|
#else
|
|
#define require_noerr(errorCode, exceptionLabel) \
|
|
do \
|
|
{ \
|
|
int evalOnceErrorCode = (errorCode); \
|
|
if ( 0 != evalOnceErrorCode ) \
|
|
{ \
|
|
DEBUG_ASSERT_MESSAGE( \
|
|
DEBUG_ASSERT_COMPONENT_NAME_STRING, \
|
|
#errorCode " == 0 ", \
|
|
#exceptionLabel, \
|
|
0, \
|
|
__FILE__, \
|
|
__LINE__, \
|
|
evalOnceErrorCode); \
|
|
goto exceptionLabel; \
|
|
} \
|
|
} while ( 0 )
|
|
#endif
|
|
|
|
/*
|
|
* require_noerr_action(errorCode, exceptionLabel, action)
|
|
*
|
|
* Summary:
|
|
* Production builds: if the errorCode expression does not equal 0 (noErr),
|
|
* execute the action statement or compound statement (block) and
|
|
* goto exceptionLabel.
|
|
*
|
|
* Non-production builds: if the errorCode expression does not equal 0 (noErr),
|
|
* call DEBUG_ASSERT_MESSAGE, execute the action statement or
|
|
* compound statement (block), and then goto exceptionLabel.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* errorCode:
|
|
* The expression to compare to 0.
|
|
*
|
|
* exceptionLabel:
|
|
* The label.
|
|
*
|
|
* action:
|
|
* The statement or compound statement (block).
|
|
*/
|
|
#if DEBUG_ASSERT_PRODUCTION_CODE
|
|
#define require_noerr_action(errorCode, exceptionLabel, action) \
|
|
do \
|
|
{ \
|
|
if ( 0 != (errorCode) ) \
|
|
{ \
|
|
{ \
|
|
action; \
|
|
} \
|
|
goto exceptionLabel; \
|
|
} \
|
|
} while ( 0 )
|
|
#else
|
|
#define require_noerr_action(errorCode, exceptionLabel, action) \
|
|
do \
|
|
{ \
|
|
int evalOnceErrorCode = (errorCode); \
|
|
if ( 0 != evalOnceErrorCode ) \
|
|
{ \
|
|
DEBUG_ASSERT_MESSAGE( \
|
|
DEBUG_ASSERT_COMPONENT_NAME_STRING, \
|
|
#errorCode " == 0 ", \
|
|
#exceptionLabel, \
|
|
0, \
|
|
__FILE__, \
|
|
__LINE__, \
|
|
evalOnceErrorCode); \
|
|
{ \
|
|
action; \
|
|
} \
|
|
goto exceptionLabel; \
|
|
} \
|
|
} while ( 0 )
|
|
#endif
|
|
|
|
|
|
/*
|
|
* require_noerr_quiet(errorCode, exceptionLabel)
|
|
*
|
|
* Summary:
|
|
* If the errorCode expression does not equal 0 (noErr),
|
|
* goto exceptionLabel.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* errorCode:
|
|
* The expression to compare to 0.
|
|
*
|
|
* exceptionLabel:
|
|
* The label.
|
|
*/
|
|
#define require_noerr_quiet(errorCode, exceptionLabel) \
|
|
do \
|
|
{ \
|
|
if ( 0 != (errorCode) ) \
|
|
{ \
|
|
goto exceptionLabel; \
|
|
} \
|
|
} while ( 0 )
|
|
|
|
|
|
/*
|
|
* require_noerr_action_quiet(errorCode, exceptionLabel, action)
|
|
*
|
|
* Summary:
|
|
* If the errorCode expression does not equal 0 (noErr),
|
|
* execute the action statement or compound statement (block) and
|
|
* goto exceptionLabel.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* errorCode:
|
|
* The expression to compare to 0.
|
|
*
|
|
* exceptionLabel:
|
|
* The label.
|
|
*
|
|
* action:
|
|
* The statement or compound statement (block).
|
|
*/
|
|
#define require_noerr_action_quiet(errorCode, exceptionLabel, action) \
|
|
do \
|
|
{ \
|
|
if ( 0 != (errorCode) ) \
|
|
{ \
|
|
{ \
|
|
action; \
|
|
} \
|
|
goto exceptionLabel; \
|
|
} \
|
|
} while ( 0 )
|
|
|
|
|
|
/*
|
|
* require_noerr_string(errorCode, exceptionLabel, message)
|
|
*
|
|
* Summary:
|
|
* Production builds: if the errorCode expression does not equal 0 (noErr),
|
|
* goto exceptionLabel.
|
|
*
|
|
* Non-production builds: if the errorCode expression does not equal 0 (noErr),
|
|
* call DEBUG_ASSERT_MESSAGE, and then goto exceptionLabel.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* errorCode:
|
|
* The expression to compare to 0.
|
|
*
|
|
* exceptionLabel:
|
|
* The label.
|
|
*
|
|
* message:
|
|
* The C string to display.
|
|
*/
|
|
#if DEBUG_ASSERT_PRODUCTION_CODE
|
|
#define require_noerr_string(errorCode, exceptionLabel, message) \
|
|
do \
|
|
{ \
|
|
if ( 0 != (errorCode) ) \
|
|
{ \
|
|
goto exceptionLabel; \
|
|
} \
|
|
} while ( 0 )
|
|
#else
|
|
#define require_noerr_string(errorCode, exceptionLabel, message) \
|
|
do \
|
|
{ \
|
|
int evalOnceErrorCode = (errorCode); \
|
|
if ( 0 != evalOnceErrorCode ) \
|
|
{ \
|
|
DEBUG_ASSERT_MESSAGE( \
|
|
DEBUG_ASSERT_COMPONENT_NAME_STRING, \
|
|
#errorCode " == 0 ", \
|
|
#exceptionLabel, \
|
|
message, \
|
|
__FILE__, \
|
|
__LINE__, \
|
|
evalOnceErrorCode); \
|
|
goto exceptionLabel; \
|
|
} \
|
|
} while ( 0 )
|
|
#endif
|
|
|
|
|
|
/*
|
|
* require_noerr_action_string(errorCode, exceptionLabel, action, message)
|
|
*
|
|
* Summary:
|
|
* Production builds: if the errorCode expression does not equal 0 (noErr),
|
|
* execute the action statement or compound statement (block) and
|
|
* goto exceptionLabel.
|
|
*
|
|
* Non-production builds: if the errorCode expression does not equal 0 (noErr),
|
|
* call DEBUG_ASSERT_MESSAGE, execute the action statement or compound
|
|
* statement (block), and then goto exceptionLabel.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* errorCode:
|
|
* The expression to compare to 0.
|
|
*
|
|
* exceptionLabel:
|
|
* The label.
|
|
*
|
|
* action:
|
|
* The statement or compound statement (block).
|
|
*
|
|
* message:
|
|
* The C string to display.
|
|
*/
|
|
#if DEBUG_ASSERT_PRODUCTION_CODE
|
|
#define require_noerr_action_string(errorCode, exceptionLabel, action, message)\
|
|
do \
|
|
{ \
|
|
if ( 0 != (errorCode) ) \
|
|
{ \
|
|
{ \
|
|
action; \
|
|
} \
|
|
goto exceptionLabel; \
|
|
} \
|
|
} while ( 0 )
|
|
#else
|
|
#define require_noerr_action_string(errorCode, exceptionLabel, action, message) \
|
|
do \
|
|
{ \
|
|
int evalOnceErrorCode = (errorCode); \
|
|
if ( 0 != evalOnceErrorCode ) \
|
|
{ \
|
|
DEBUG_ASSERT_MESSAGE( \
|
|
DEBUG_ASSERT_COMPONENT_NAME_STRING, \
|
|
#errorCode " == 0 ", \
|
|
#exceptionLabel, \
|
|
message, \
|
|
__FILE__, \
|
|
__LINE__, \
|
|
evalOnceErrorCode); \
|
|
{ \
|
|
action; \
|
|
} \
|
|
goto exceptionLabel; \
|
|
} \
|
|
} while ( 0 )
|
|
#endif
|
|
|
|
|
|
#endif /* __ASSERTMACROS__ */
|
|
|