You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1117 lines
50 KiB
1117 lines
50 KiB
/* |
|
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__ */ |
|
|
|
|