]>
git.saurik.com Git - apple/xnu.git/blob - EXTERNAL_HEADERS/AssertMacros.h
4 Contains: This file defines structured error handling and assertion macros for
5 programming in C. Originally used in QuickDraw GX and later enhanced.
6 These macros are used throughout Apple's software.
8 See "Living In an Exceptional World" by Sean Parent
9 (develop, The Apple Technical Journal, Issue 11, August/September 1992)
10 <http://developer.apple.com/dev/techsupport/develop/issue11toc.shtml>
11 for the methodology behind these error handling and assertion macros.
13 Copyright: © 2002-2007 by Apple Inc., all rights reserved.
15 Bugs?: For bug reports, consult the following page on
18 http://developer.apple.com/bugreporter/
20 #ifndef __ASSERTMACROS__
21 #define __ASSERTMACROS__
28 * In production builds, pre-processed away
29 * In debug builds, if assertion evaluates to false, calls DEBUG_ASSERT_MESSAGE
32 * In production builds, evaluates assertion and does nothing
33 * In debug builds, if assertion evaluates to false, calls DEBUG_ASSERT_MESSAGE
35 * require(assertion, exceptionLabel)
36 * In production builds, if the assertion expression evaluates to false, goto exceptionLabel
37 * In debug builds, if the assertion expression evaluates to false, calls DEBUG_ASSERT_MESSAGE
38 * and jumps to exceptionLabel
40 * In addition the following suffixes are available:
42 * _noerr Adds "!= 0" to assertion. Useful for asserting and OSStatus or OSErr is noErr (zero)
43 * _action Adds statement to be executued if assertion fails
44 * _quiet Suppress call to DEBUG_ASSERT_MESSAGE
45 * _string Allows you to add explanitory message to DEBUG_ASSERT_MESSAGE
47 * For instance, require_noerr_string(resultCode, label, msg) will do nothing if
48 * resultCode is zero, otherwise it will call DEBUG_ASSERT_MESSAGE with msg
53 * By default all macros generate "production code" (i.e non-debug). If
54 * DEBUG_ASSERT_PRODUCTION_CODE is defined to zero or DEBUG is defined to non-zero
55 * while this header is included, the macros will generated debug code.
57 * If DEBUG_ASSERT_COMPONENT_NAME_STRING is defined, all debug messages will
58 * be prefixed with it.
60 * By default, all messages write to stderr. If you would like to write a custom
61 * error message formater, defined DEBUG_ASSERT_MESSAGE to your function name.
67 * Before including this file, #define DEBUG_ASSERT_COMPONENT_NAME_STRING to
68 * a C-string containing the name of your client. This string will be passed to
69 * the DEBUG_ASSERT_MESSAGE macro for inclusion in any assertion messages.
71 * If you do not define DEBUG_ASSERT_COMPONENT_NAME_STRING, the default
72 * DEBUG_ASSERT_COMPONENT_NAME_STRING value, an empty string, will be used by
73 * the assertion macros.
75 #ifndef DEBUG_ASSERT_COMPONENT_NAME_STRING
76 #define DEBUG_ASSERT_COMPONENT_NAME_STRING ""
81 * To activate the additional assertion code and messages for non-production builds,
82 * #define DEBUG_ASSERT_PRODUCTION_CODE to zero before including this file.
84 * If you do not define DEBUG_ASSERT_PRODUCTION_CODE, the default value 1 will be used
85 * (production code = no assertion code and no messages).
87 #ifndef DEBUG_ASSERT_PRODUCTION_CODE
88 #define DEBUG_ASSERT_PRODUCTION_CODE !DEBUG
93 * DEBUG_ASSERT_MESSAGE(component, assertion, label, error, file, line, errorCode)
96 * All assertion messages are routed through this macro. If you wish to use your
97 * own routine to display assertion messages, you can override DEBUG_ASSERT_MESSAGE
98 * by #defining DEBUG_ASSERT_MESSAGE before including this file.
102 * componentNameString:
103 * A pointer to a string constant containing the name of the
104 * component this code is part of. This must be a string constant
105 * (and not a string variable or NULL) because the preprocessor
106 * concatenates it with other string constants.
109 * A pointer to a string constant containing the assertion.
110 * This must be a string constant (and not a string variable or
111 * NULL) because the Preprocessor concatenates it with other
114 * exceptionLabelString:
115 * A pointer to a string containing the exceptionLabel, or NULL.
118 * A pointer to the error string, or NULL. DEBUG_ASSERT_MESSAGE macros
119 * must not attempt to concatenate this string with constant
123 * A pointer to the fileName or pathname (generated by the
124 * preprocessor __FILE__ identifier), or NULL.
127 * The line number in the file (generated by the preprocessor
128 * __LINE__ identifier), or 0 (zero).
131 * A value associated with the assertion, or 0.
133 * Here is an example of a DEBUG_ASSERT_MESSAGE macro and a routine which displays
134 * assertion messsages:
136 * #define DEBUG_ASSERT_COMPONENT_NAME_STRING "MyCoolProgram"
138 * #define DEBUG_ASSERT_MESSAGE(componentNameString, assertionString, \
139 * exceptionLabelString, errorString, fileName, lineNumber, errorCode) \
140 * MyProgramDebugAssert(componentNameString, assertionString, \
141 * exceptionLabelString, errorString, fileName, lineNumber, errorCode)
144 * MyProgramDebugAssert(const char *componentNameString, const char *assertionString,
145 * const char *exceptionLabelString, const char *errorString,
146 * const char *fileName, long lineNumber, int errorCode)
148 * if ( (assertionString != NULL) && (*assertionString != '\0') )
149 * fprintf(stderr, "Assertion failed: %s: %s\n", componentNameString, assertionString);
151 * fprintf(stderr, "Check failed: %s:\n", componentNameString);
152 * if ( exceptionLabelString != NULL )
153 * fprintf(stderr, " %s\n", exceptionLabelString);
154 * if ( errorString != NULL )
155 * fprintf(stderr, " %s\n", errorString);
156 * if ( fileName != NULL )
157 * fprintf(stderr, " file: %s\n", fileName);
158 * if ( lineNumber != 0 )
159 * fprintf(stderr, " line: %ld\n", lineNumber);
160 * if ( errorCode != 0 )
161 * fprintf(stderr, " error: %d\n", errorCode);
164 * If you do not define DEBUG_ASSERT_MESSAGE, a simple printf to stderr will be used.
166 #ifndef DEBUG_ASSERT_MESSAGE
168 #include <libkern/libkern.h>
169 #define DEBUG_ASSERT_MESSAGE(name, assertion, label, message, file, line, value) \
170 printf( "AssertMacros: %s, %s file: %s, line: %d\n", assertion, (message!=0) ? message : "", file, line);
173 #define DEBUG_ASSERT_MESSAGE(name, assertion, label, message, file, line, value) \
174 fprintf(stderr, "AssertMacros: %s, %s file: %s, line: %d\n", assertion, (message!=0) ? message : "", file, line);
183 * debug_string(message)
186 * Production builds: does nothing and produces no code.
188 * Non-production builds: call DEBUG_ASSERT_MESSAGE.
193 * The C string to display.
196 #if DEBUG_ASSERT_PRODUCTION_CODE
197 #define debug_string(message)
199 #define debug_string(message) \
202 DEBUG_ASSERT_MESSAGE( \
203 DEBUG_ASSERT_COMPONENT_NAME_STRING, \
218 * Production builds: does nothing and produces no code.
220 * Non-production builds: if the assertion expression evaluates to false,
221 * call DEBUG_ASSERT_MESSAGE.
226 * The assertion expression.
228 #if DEBUG_ASSERT_PRODUCTION_CODE
229 #define check(assertion)
231 #define check(assertion) \
234 if ( __builtin_expect(!(assertion), 0) ) \
236 DEBUG_ASSERT_MESSAGE( \
237 DEBUG_ASSERT_COMPONENT_NAME_STRING, \
248 #define ncheck(assertion) \
253 * check_string(assertion, message)
256 * Production builds: does nothing and produces no code.
258 * Non-production builds: if the assertion expression evaluates to false,
259 * call DEBUG_ASSERT_MESSAGE.
264 * The assertion expression.
267 * The C string to display.
269 #if DEBUG_ASSERT_PRODUCTION_CODE
270 #define check_string(assertion, message)
272 #define check_string(assertion, message) \
275 if ( __builtin_expect(!(assertion), 0) ) \
277 DEBUG_ASSERT_MESSAGE( \
278 DEBUG_ASSERT_COMPONENT_NAME_STRING, \
289 #define ncheck_string(assertion, message) \
290 check_string(!(assertion), message)
294 * check_noerr(errorCode)
297 * Production builds: does nothing and produces no code.
299 * Non-production builds: if the errorCode expression does not equal 0 (noErr),
300 * call DEBUG_ASSERT_MESSAGE.
305 * The errorCode expression to compare with 0.
307 #if DEBUG_ASSERT_PRODUCTION_CODE
308 #define check_noerr(errorCode)
310 #define check_noerr(errorCode) \
313 long evalOnceErrorCode = (errorCode); \
314 if ( __builtin_expect(0 != evalOnceErrorCode, 0) ) \
316 DEBUG_ASSERT_MESSAGE( \
317 DEBUG_ASSERT_COMPONENT_NAME_STRING, \
318 #errorCode " == 0 ", \
323 evalOnceErrorCode); \
330 * check_noerr_string(errorCode, message)
333 * Production builds: check_noerr_string() does nothing and produces
336 * Non-production builds: if the errorCode expression does not equal 0 (noErr),
337 * call DEBUG_ASSERT_MESSAGE.
342 * The errorCode expression to compare to 0.
345 * The C string to display.
347 #if DEBUG_ASSERT_PRODUCTION_CODE
348 #define check_noerr_string(errorCode, message)
350 #define check_noerr_string(errorCode, message) \
353 long evalOnceErrorCode = (errorCode); \
354 if ( __builtin_expect(0 != evalOnceErrorCode, 0) ) \
356 DEBUG_ASSERT_MESSAGE( \
357 DEBUG_ASSERT_COMPONENT_NAME_STRING, \
358 #errorCode " == 0 ", \
363 evalOnceErrorCode); \
373 * Production builds: evaluate the assertion expression, but ignore
376 * Non-production builds: if the assertion expression evaluates to false,
377 * call DEBUG_ASSERT_MESSAGE.
382 * The assertion expression.
384 #if DEBUG_ASSERT_PRODUCTION_CODE
385 #define verify(assertion) \
388 if ( !(assertion) ) \
393 #define verify(assertion) \
396 if ( __builtin_expect(!(assertion), 0) ) \
398 DEBUG_ASSERT_MESSAGE( \
399 DEBUG_ASSERT_COMPONENT_NAME_STRING, \
410 #define nverify(assertion) \
415 * verify_string(assertion, message)
418 * Production builds: evaluate the assertion expression, but ignore
421 * Non-production builds: if the assertion expression evaluates to false,
422 * call DEBUG_ASSERT_MESSAGE.
427 * The assertion expression.
430 * The C string to display.
432 #if DEBUG_ASSERT_PRODUCTION_CODE
433 #define verify_string(assertion, message) \
436 if ( !(assertion) ) \
441 #define verify_string(assertion, message) \
444 if ( __builtin_expect(!(assertion), 0) ) \
446 DEBUG_ASSERT_MESSAGE( \
447 DEBUG_ASSERT_COMPONENT_NAME_STRING, \
458 #define nverify_string(assertion, message) \
459 verify_string(!(assertion), message)
463 * verify_noerr(errorCode)
466 * Production builds: evaluate the errorCode expression, but ignore
469 * Non-production builds: if the errorCode expression does not equal 0 (noErr),
470 * call DEBUG_ASSERT_MESSAGE.
475 * The expression to compare to 0.
477 #if DEBUG_ASSERT_PRODUCTION_CODE
478 #define verify_noerr(errorCode) \
481 if ( 0 != (errorCode) ) \
486 #define verify_noerr(errorCode) \
489 long evalOnceErrorCode = (errorCode); \
490 if ( __builtin_expect(0 != evalOnceErrorCode, 0) ) \
492 DEBUG_ASSERT_MESSAGE( \
493 DEBUG_ASSERT_COMPONENT_NAME_STRING, \
494 #errorCode " == 0 ", \
499 evalOnceErrorCode); \
506 * verify_noerr_string(errorCode, message)
509 * Production builds: evaluate the errorCode expression, but ignore
512 * Non-production builds: if the errorCode expression does not equal 0 (noErr),
513 * call DEBUG_ASSERT_MESSAGE.
518 * The expression to compare to 0.
521 * The C string to display.
523 #if DEBUG_ASSERT_PRODUCTION_CODE
524 #define verify_noerr_string(errorCode, message) \
527 if ( 0 != (errorCode) ) \
532 #define verify_noerr_string(errorCode, message) \
535 long evalOnceErrorCode = (errorCode); \
536 if ( __builtin_expect(0 != evalOnceErrorCode, 0) ) \
538 DEBUG_ASSERT_MESSAGE( \
539 DEBUG_ASSERT_COMPONENT_NAME_STRING, \
540 #errorCode " == 0 ", \
545 evalOnceErrorCode); \
552 * verify_action(assertion, action)
555 * Production builds: if the assertion expression evaluates to false,
556 * then execute the action statement or compound statement (block).
558 * Non-production builds: if the assertion expression evaluates to false,
559 * call DEBUG_ASSERT_MESSAGE and then execute the action statement or compound
565 * The assertion expression.
568 * The statement or compound statement (block).
570 #if DEBUG_ASSERT_PRODUCTION_CODE
571 #define verify_action(assertion, action) \
574 if ( __builtin_expect(!(assertion), 0) ) \
580 #define verify_action(assertion, action) \
583 if ( __builtin_expect(!(assertion), 0) ) \
585 DEBUG_ASSERT_MESSAGE( \
586 DEBUG_ASSERT_COMPONENT_NAME_STRING, \
600 * require(assertion, exceptionLabel)
603 * Production builds: if the assertion expression evaluates to false,
604 * goto exceptionLabel.
606 * Non-production builds: if the assertion expression evaluates to false,
607 * call DEBUG_ASSERT_MESSAGE and then goto exceptionLabel.
612 * The assertion expression.
617 #if DEBUG_ASSERT_PRODUCTION_CODE
618 #define require(assertion, exceptionLabel) \
621 if ( __builtin_expect(!(assertion), 0) ) \
623 goto exceptionLabel; \
627 #define require(assertion, exceptionLabel) \
630 if ( __builtin_expect(!(assertion), 0) ) \
632 DEBUG_ASSERT_MESSAGE( \
633 DEBUG_ASSERT_COMPONENT_NAME_STRING, \
640 goto exceptionLabel; \
645 #define nrequire(assertion, exceptionLabel) \
646 require(!(assertion), exceptionLabel)
650 * require_action(assertion, exceptionLabel, action)
653 * Production builds: if the assertion expression evaluates to false,
654 * execute the action statement or compound statement (block) and then
655 * goto exceptionLabel.
657 * Non-production builds: if the assertion expression evaluates to false,
658 * call DEBUG_ASSERT_MESSAGE, execute the action statement or compound
659 * statement (block), and then goto exceptionLabel.
664 * The assertion expression.
670 * The statement or compound statement (block).
672 #if DEBUG_ASSERT_PRODUCTION_CODE
673 #define require_action(assertion, exceptionLabel, action) \
676 if ( __builtin_expect(!(assertion), 0) ) \
681 goto exceptionLabel; \
685 #define require_action(assertion, exceptionLabel, action) \
688 if ( __builtin_expect(!(assertion), 0) ) \
690 DEBUG_ASSERT_MESSAGE( \
691 DEBUG_ASSERT_COMPONENT_NAME_STRING, \
701 goto exceptionLabel; \
706 #define nrequire_action(assertion, exceptionLabel, action) \
707 require_action(!(assertion), exceptionLabel, action)
711 * require_quiet(assertion, exceptionLabel)
714 * If the assertion expression evaluates to false, goto exceptionLabel.
719 * The assertion expression.
724 #define require_quiet(assertion, exceptionLabel) \
727 if ( __builtin_expect(!(assertion), 0) ) \
729 goto exceptionLabel; \
733 #define nrequire_quiet(assertion, exceptionLabel) \
734 require_quiet(!(assertion), exceptionLabel)
738 * require_action_quiet(assertion, exceptionLabel, action)
741 * If the assertion expression evaluates to false, execute the action
742 * statement or compound statement (block), and goto exceptionLabel.
747 * The assertion expression.
753 * The statement or compound statement (block).
755 #define require_action_quiet(assertion, exceptionLabel, action) \
758 if ( __builtin_expect(!(assertion), 0) ) \
763 goto exceptionLabel; \
767 #define nrequire_action_quiet(assertion, exceptionLabel, action) \
768 require_action_quiet(!(assertion), exceptionLabel, action)
772 * require_string(assertion, exceptionLabel, message)
775 * Production builds: if the assertion expression evaluates to false,
776 * goto exceptionLabel.
778 * Non-production builds: if the assertion expression evaluates to false,
779 * call DEBUG_ASSERT_MESSAGE, and then goto exceptionLabel.
784 * The assertion expression.
790 * The C string to display.
792 #if DEBUG_ASSERT_PRODUCTION_CODE
793 #define require_string(assertion, exceptionLabel, message) \
796 if ( __builtin_expect(!(assertion), 0) ) \
798 goto exceptionLabel; \
802 #define require_string(assertion, exceptionLabel, message) \
805 if ( __builtin_expect(!(assertion), 0) ) \
807 DEBUG_ASSERT_MESSAGE( \
808 DEBUG_ASSERT_COMPONENT_NAME_STRING, \
815 goto exceptionLabel; \
820 #define nrequire_string(assertion, exceptionLabel, string) \
821 require_string(!(assertion), exceptionLabel, string)
825 * require_action_string(assertion, exceptionLabel, action, message)
828 * Production builds: if the assertion expression evaluates to false,
829 * execute the action statement or compound statement (block), and then
830 * goto exceptionLabel.
832 * Non-production builds: if the assertion expression evaluates to false,
833 * call DEBUG_ASSERT_MESSAGE, execute the action statement or compound
834 * statement (block), and then goto exceptionLabel.
839 * The assertion expression.
845 * The statement or compound statement (block).
848 * The C string to display.
850 #if DEBUG_ASSERT_PRODUCTION_CODE
851 #define require_action_string(assertion, exceptionLabel, action, message) \
854 if ( __builtin_expect(!(assertion), 0) ) \
859 goto exceptionLabel; \
863 #define require_action_string(assertion, exceptionLabel, action, message) \
866 if ( __builtin_expect(!(assertion), 0) ) \
868 DEBUG_ASSERT_MESSAGE( \
869 DEBUG_ASSERT_COMPONENT_NAME_STRING, \
879 goto exceptionLabel; \
884 #define nrequire_action_string(assertion, exceptionLabel, action, message) \
885 require_action_string(!(assertion), exceptionLabel, action, message)
889 * require_noerr(errorCode, exceptionLabel)
892 * Production builds: if the errorCode expression does not equal 0 (noErr),
893 * goto exceptionLabel.
895 * Non-production builds: if the errorCode expression does not equal 0 (noErr),
896 * call DEBUG_ASSERT_MESSAGE and then goto exceptionLabel.
901 * The expression to compare to 0.
906 #if DEBUG_ASSERT_PRODUCTION_CODE
907 #define require_noerr(errorCode, exceptionLabel) \
910 if ( __builtin_expect(0 != (errorCode), 0) ) \
912 goto exceptionLabel; \
916 #define require_noerr(errorCode, exceptionLabel) \
919 long evalOnceErrorCode = (errorCode); \
920 if ( __builtin_expect(0 != evalOnceErrorCode, 0) ) \
922 DEBUG_ASSERT_MESSAGE( \
923 DEBUG_ASSERT_COMPONENT_NAME_STRING, \
924 #errorCode " == 0 ", \
929 evalOnceErrorCode); \
930 goto exceptionLabel; \
936 * require_noerr_action(errorCode, exceptionLabel, action)
939 * Production builds: if the errorCode expression does not equal 0 (noErr),
940 * execute the action statement or compound statement (block) and
941 * goto exceptionLabel.
943 * Non-production builds: if the errorCode expression does not equal 0 (noErr),
944 * call DEBUG_ASSERT_MESSAGE, execute the action statement or
945 * compound statement (block), and then goto exceptionLabel.
950 * The expression to compare to 0.
956 * The statement or compound statement (block).
958 #if DEBUG_ASSERT_PRODUCTION_CODE
959 #define require_noerr_action(errorCode, exceptionLabel, action) \
962 if ( __builtin_expect(0 != (errorCode), 0) ) \
967 goto exceptionLabel; \
971 #define require_noerr_action(errorCode, exceptionLabel, action) \
974 long evalOnceErrorCode = (errorCode); \
975 if ( __builtin_expect(0 != evalOnceErrorCode, 0) ) \
977 DEBUG_ASSERT_MESSAGE( \
978 DEBUG_ASSERT_COMPONENT_NAME_STRING, \
979 #errorCode " == 0 ", \
984 evalOnceErrorCode); \
988 goto exceptionLabel; \
995 * require_noerr_quiet(errorCode, exceptionLabel)
998 * If the errorCode expression does not equal 0 (noErr),
999 * goto exceptionLabel.
1004 * The expression to compare to 0.
1009 #define require_noerr_quiet(errorCode, exceptionLabel) \
1012 if ( __builtin_expect(0 != (errorCode), 0) ) \
1014 goto exceptionLabel; \
1020 * require_noerr_action_quiet(errorCode, exceptionLabel, action)
1023 * If the errorCode expression does not equal 0 (noErr),
1024 * execute the action statement or compound statement (block) and
1025 * goto exceptionLabel.
1030 * The expression to compare to 0.
1036 * The statement or compound statement (block).
1038 #define require_noerr_action_quiet(errorCode, exceptionLabel, action) \
1041 if ( __builtin_expect(0 != (errorCode), 0) ) \
1046 goto exceptionLabel; \
1052 * require_noerr_string(errorCode, exceptionLabel, message)
1055 * Production builds: if the errorCode expression does not equal 0 (noErr),
1056 * goto exceptionLabel.
1058 * Non-production builds: if the errorCode expression does not equal 0 (noErr),
1059 * call DEBUG_ASSERT_MESSAGE, and then goto exceptionLabel.
1064 * The expression to compare to 0.
1070 * The C string to display.
1072 #if DEBUG_ASSERT_PRODUCTION_CODE
1073 #define require_noerr_string(errorCode, exceptionLabel, message) \
1076 if ( __builtin_expect(0 != (errorCode), 0) ) \
1078 goto exceptionLabel; \
1082 #define require_noerr_string(errorCode, exceptionLabel, message) \
1085 long evalOnceErrorCode = (errorCode); \
1086 if ( __builtin_expect(0 != evalOnceErrorCode, 0) ) \
1088 DEBUG_ASSERT_MESSAGE( \
1089 DEBUG_ASSERT_COMPONENT_NAME_STRING, \
1090 #errorCode " == 0 ", \
1095 evalOnceErrorCode); \
1096 goto exceptionLabel; \
1103 * require_noerr_action_string(errorCode, exceptionLabel, action, message)
1106 * Production builds: if the errorCode expression does not equal 0 (noErr),
1107 * execute the action statement or compound statement (block) and
1108 * goto exceptionLabel.
1110 * Non-production builds: if the errorCode expression does not equal 0 (noErr),
1111 * call DEBUG_ASSERT_MESSAGE, execute the action statement or compound
1112 * statement (block), and then goto exceptionLabel.
1117 * The expression to compare to 0.
1123 * The statement or compound statement (block).
1126 * The C string to display.
1128 #if DEBUG_ASSERT_PRODUCTION_CODE
1129 #define require_noerr_action_string(errorCode, exceptionLabel, action, message)\
1132 if ( __builtin_expect(0 != (errorCode), 0) ) \
1137 goto exceptionLabel; \
1141 #define require_noerr_action_string(errorCode, exceptionLabel, action, message) \
1144 long evalOnceErrorCode = (errorCode); \
1145 if ( __builtin_expect(0 != evalOnceErrorCode, 0) ) \
1147 DEBUG_ASSERT_MESSAGE( \
1148 DEBUG_ASSERT_COMPONENT_NAME_STRING, \
1149 #errorCode " == 0 ", \
1154 evalOnceErrorCode); \
1158 goto exceptionLabel; \
1164 #endif /* __ASSERTMACROS__ */