1/*
2     File:       AssertMacros.h
3
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.
7
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.
12
13     Copyright:  � 2002-2007 by Apple Inc., all rights reserved.
14
15     Bugs?:      For bug reports, consult the following page on
16                 the World Wide Web:
17
18                     http://developer.apple.com/bugreporter/
19*/
20#ifndef __ASSERTMACROS__
21#define __ASSERTMACROS__
22
23
24/*
25 *  Macro overview:
26 *
27 *      check(assertion)
28 *         In production builds, pre-processed away
29 *         In debug builds, if assertion evaluates to false, calls DEBUG_ASSERT_MESSAGE
30 *
31 *      verify(assertion)
32 *         In production builds, evaluates assertion and does nothing
33 *         In debug builds, if assertion evaluates to false, calls DEBUG_ASSERT_MESSAGE
34 *
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
39 *
40 *      In addition the following suffixes are available:
41 *
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
46 *
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
49 *        and jump to label.
50 *
51 *  Configuration:
52 *
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.
56 *
57 *      If DEBUG_ASSERT_COMPONENT_NAME_STRING is defined, all debug messages will
58 *      be prefixed with it.
59 *
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.
62 *
63 */
64
65
66/*
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.
70 *
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.
74 */
75#ifndef DEBUG_ASSERT_COMPONENT_NAME_STRING
76    #define DEBUG_ASSERT_COMPONENT_NAME_STRING ""
77#endif
78
79
80/*
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.
83 *
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).
86 */
87#ifndef DEBUG_ASSERT_PRODUCTION_CODE
88   #define DEBUG_ASSERT_PRODUCTION_CODE !DEBUG
89#endif
90
91
92/*
93 *  DEBUG_ASSERT_MESSAGE(component, assertion, label, error, file, line, errorCode)
94 *
95 *  Summary:
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.
99 *
100 *  Parameters:
101 *
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.
107 *
108 *    assertionString:
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
112 *      string constants.
113 *
114 *    exceptionLabelString:
115 *      A pointer to a string containing the exceptionLabel, or NULL.
116 *
117 *    errorString:
118 *      A pointer to the error string, or NULL. DEBUG_ASSERT_MESSAGE macros
119 *      must not attempt to concatenate this string with constant
120 *      character strings.
121 *
122 *    fileName:
123 *      A pointer to the fileName or pathname (generated by the
124 *      preprocessor __FILE__ identifier), or NULL.
125 *
126 *    lineNumber:
127 *      The line number in the file (generated by the preprocessor
128 *      __LINE__ identifier), or 0 (zero).
129 *
130 *    errorCode:
131 *      A value associated with the assertion, or 0.
132 *
133 *  Here is an example of a DEBUG_ASSERT_MESSAGE macro and a routine which displays
134 *  assertion messsages:
135 *
136 *      #define DEBUG_ASSERT_COMPONENT_NAME_STRING "MyCoolProgram"
137 *
138 *      #define DEBUG_ASSERT_MESSAGE(componentNameString, assertionString,                           \
139 *                                   exceptionLabelString, errorString, fileName, lineNumber, errorCode) \
140 *              MyProgramDebugAssert(componentNameString, assertionString,                           \
141 *                                   exceptionLabelString, errorString, fileName, lineNumber, errorCode)
142 *
143 *      static void
144 *      MyProgramDebugAssert(const char *componentNameString, const char *assertionString,
145 *                           const char *exceptionLabelString, const char *errorString,
146 *                           const char *fileName, long lineNumber, int errorCode)
147 *      {
148 *          if ( (assertionString != NULL) && (*assertionString != '\0') )
149 *              fprintf(stderr, "Assertion failed: %s: %s\n", componentNameString, assertionString);
150 *          else
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);
162 *      }
163 *
164 *  If you do not define DEBUG_ASSERT_MESSAGE, a simple printf to stderr will be used.
165 */
166#ifndef DEBUG_ASSERT_MESSAGE
167   #ifdef KERNEL
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);
171   #else
172      #include <stdio.h>
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);
175   #endif
176#endif
177
178
179
180
181
182/*
183 *  debug_string(message)
184 *
185 *  Summary:
186 *    Production builds: does nothing and produces no code.
187 *
188 *    Non-production builds: call DEBUG_ASSERT_MESSAGE.
189 *
190 *  Parameters:
191 *
192 *    message:
193 *      The C string to display.
194 *
195 */
196#if DEBUG_ASSERT_PRODUCTION_CODE
197   #define debug_string(message)
198#else
199   #define debug_string(message)                                              \
200      do                                                                      \
201      {                                                                       \
202          DEBUG_ASSERT_MESSAGE(                                               \
203              DEBUG_ASSERT_COMPONENT_NAME_STRING,                             \
204              "",                                                             \
205              0,                                                              \
206              message,                                                        \
207              __FILE__,                                                       \
208              __LINE__,                                                       \
209              0);                                                             \
210      } while ( 0 )
211#endif
212
213
214/*
215 *  check(assertion)
216 *
217 *  Summary:
218 *    Production builds: does nothing and produces no code.
219 *
220 *    Non-production builds: if the assertion expression evaluates to false,
221 *    call DEBUG_ASSERT_MESSAGE.
222 *
223 *  Parameters:
224 *
225 *    assertion:
226 *      The assertion expression.
227 */
228#if DEBUG_ASSERT_PRODUCTION_CODE
229   #define check(assertion)
230#else
231   #define check(assertion)                                                   \
232      do                                                                      \
233      {                                                                       \
234          if ( __builtin_expect(!(assertion), 0) )                            \
235          {                                                                   \
236              DEBUG_ASSERT_MESSAGE(                                           \
237                  DEBUG_ASSERT_COMPONENT_NAME_STRING,                         \
238                  #assertion,                                                 \
239                  0,                                                          \
240                  0,                                                          \
241                  __FILE__,                                                   \
242                  __LINE__,                                                   \
243                  0);                                                         \
244          }                                                                   \
245      } while ( 0 )
246#endif
247
248#define ncheck(assertion)                                                     \
249  check(!(assertion))
250
251
252/*
253 *  check_string(assertion, message)
254 *
255 *  Summary:
256 *    Production builds: does nothing and produces no code.
257 *
258 *    Non-production builds: if the assertion expression evaluates to false,
259 *    call DEBUG_ASSERT_MESSAGE.
260 *
261 *  Parameters:
262 *
263 *    assertion:
264 *      The assertion expression.
265 *
266 *    message:
267 *      The C string to display.
268 */
269#if DEBUG_ASSERT_PRODUCTION_CODE
270   #define check_string(assertion, message)
271#else
272   #define check_string(assertion, message)                                   \
273      do                                                                      \
274      {                                                                       \
275          if ( __builtin_expect(!(assertion), 0) )                            \
276          {                                                                   \
277              DEBUG_ASSERT_MESSAGE(                                           \
278                  DEBUG_ASSERT_COMPONENT_NAME_STRING,                         \
279                  #assertion,                                                 \
280                  0,                                                          \
281                  message,                                                    \
282                  __FILE__,                                                   \
283                  __LINE__,                                                   \
284                  0);                                                         \
285          }                                                                   \
286      } while ( 0 )
287#endif
288
289#define ncheck_string(assertion, message)                                     \
290  check_string(!(assertion), message)
291
292
293/*
294 *  check_noerr(errorCode)
295 *
296 *  Summary:
297 *    Production builds: does nothing and produces no code.
298 *
299 *    Non-production builds: if the errorCode expression does not equal 0 (noErr),
300 *    call DEBUG_ASSERT_MESSAGE.
301 *
302 *  Parameters:
303 *
304 *    errorCode:
305 *      The errorCode expression to compare with 0.
306 */
307#if DEBUG_ASSERT_PRODUCTION_CODE
308   #define check_noerr(errorCode)
309#else
310   #define check_noerr(errorCode)                                             \
311      do                                                                      \
312      {                                                                       \
313          long evalOnceErrorCode = (errorCode);                               \
314          if ( __builtin_expect(0 != evalOnceErrorCode, 0) )                  \
315          {                                                                   \
316              DEBUG_ASSERT_MESSAGE(                                           \
317                  DEBUG_ASSERT_COMPONENT_NAME_STRING,                         \
318                  #errorCode " == 0 ",                                        \
319                  0,                                                          \
320                  0,                                                          \
321                  __FILE__,                                                   \
322                  __LINE__,                                                   \
323                  evalOnceErrorCode);                                         \
324          }                                                                   \
325      } while ( 0 )
326#endif
327
328
329/*
330 *  check_noerr_string(errorCode, message)
331 *
332 *  Summary:
333 *    Production builds: check_noerr_string() does nothing and produces
334 *    no code.
335 *
336 *    Non-production builds: if the errorCode expression does not equal 0 (noErr),
337 *    call DEBUG_ASSERT_MESSAGE.
338 *
339 *  Parameters:
340 *
341 *    errorCode:
342 *      The errorCode expression to compare to 0.
343 *
344 *    message:
345 *      The C string to display.
346 */
347#if DEBUG_ASSERT_PRODUCTION_CODE
348   #define check_noerr_string(errorCode, message)
349#else
350   #define check_noerr_string(errorCode, message)                             \
351      do                                                                      \
352      {                                                                       \
353          long evalOnceErrorCode = (errorCode);                               \
354          if ( __builtin_expect(0 != evalOnceErrorCode, 0) )                  \
355          {                                                                   \
356              DEBUG_ASSERT_MESSAGE(                                           \
357                  DEBUG_ASSERT_COMPONENT_NAME_STRING,                         \
358                  #errorCode " == 0 ",                                        \
359                  0,                                                          \
360                  message,                                                    \
361                  __FILE__,                                                   \
362                  __LINE__,                                                   \
363                  evalOnceErrorCode);                                         \
364          }                                                                   \
365      } while ( 0 )
366#endif
367
368
369/*
370 *  verify(assertion)
371 *
372 *  Summary:
373 *    Production builds: evaluate the assertion expression, but ignore
374 *    the result.
375 *
376 *    Non-production builds: if the assertion expression evaluates to false,
377 *    call DEBUG_ASSERT_MESSAGE.
378 *
379 *  Parameters:
380 *
381 *    assertion:
382 *      The assertion expression.
383 */
384#if DEBUG_ASSERT_PRODUCTION_CODE
385   #define verify(assertion)                                                  \
386      do                                                                      \
387      {                                                                       \
388          if ( !(assertion) )                                                 \
389          {                                                                   \
390          }                                                                   \
391      } while ( 0 )
392#else
393   #define verify(assertion)                                                  \
394      do                                                                      \
395      {                                                                       \
396          if ( __builtin_expect(!(assertion), 0) )                            \
397          {                                                                   \
398              DEBUG_ASSERT_MESSAGE(                                           \
399                  DEBUG_ASSERT_COMPONENT_NAME_STRING,                         \
400                  #assertion,                                                 \
401                  0,                                                          \
402                  0,                                                          \
403                  __FILE__,                                                   \
404                  __LINE__,                                                   \
405                  0);                                                         \
406          }                                                                   \
407      } while ( 0 )
408#endif
409
410#define nverify(assertion)                                                    \
411  verify(!(assertion))
412
413
414/*
415 *  verify_string(assertion, message)
416 *
417 *  Summary:
418 *    Production builds: evaluate the assertion expression, but ignore
419 *    the result.
420 *
421 *    Non-production builds: if the assertion expression evaluates to false,
422 *    call DEBUG_ASSERT_MESSAGE.
423 *
424 *  Parameters:
425 *
426 *    assertion:
427 *      The assertion expression.
428 *
429 *    message:
430 *      The C string to display.
431 */
432#if DEBUG_ASSERT_PRODUCTION_CODE
433   #define verify_string(assertion, message)                                  \
434      do                                                                      \
435      {                                                                       \
436          if ( !(assertion) )                                                 \
437          {                                                                   \
438          }                                                                   \
439      } while ( 0 )
440#else
441   #define verify_string(assertion, message)                                  \
442      do                                                                      \
443      {                                                                       \
444          if ( __builtin_expect(!(assertion), 0) )                            \
445          {                                                                   \
446              DEBUG_ASSERT_MESSAGE(                                           \
447                  DEBUG_ASSERT_COMPONENT_NAME_STRING,                         \
448                  #assertion,                                                 \
449                  0,                                                          \
450                  message,                                                    \
451                  __FILE__,                                                   \
452                  __LINE__,                                                   \
453                  0);                                                         \
454          }                                                                   \
455      } while ( 0 )
456#endif
457
458#define nverify_string(assertion, message)                                    \
459  verify_string(!(assertion), message)
460
461
462/*
463 *  verify_noerr(errorCode)
464 *
465 *  Summary:
466 *    Production builds: evaluate the errorCode expression, but ignore
467 *    the result.
468 *
469 *    Non-production builds: if the errorCode expression does not equal 0 (noErr),
470 *    call DEBUG_ASSERT_MESSAGE.
471 *
472 *  Parameters:
473 *
474 *    errorCode:
475 *      The expression to compare to 0.
476 */
477#if DEBUG_ASSERT_PRODUCTION_CODE
478   #define verify_noerr(errorCode)                                            \
479      do                                                                      \
480      {                                                                       \
481          if ( 0 != (errorCode) )                                             \
482          {                                                                   \
483          }                                                                   \
484      } while ( 0 )
485#else
486   #define verify_noerr(errorCode)                                            \
487      do                                                                      \
488      {                                                                       \
489          long evalOnceErrorCode = (errorCode);                               \
490          if ( __builtin_expect(0 != evalOnceErrorCode, 0) )                  \
491          {                                                                   \
492              DEBUG_ASSERT_MESSAGE(                                           \
493                  DEBUG_ASSERT_COMPONENT_NAME_STRING,                         \
494                  #errorCode " == 0 ",                                        \
495                  0,                                                          \
496                  0,                                                          \
497                  __FILE__,                                                   \
498                  __LINE__,                                                   \
499                  evalOnceErrorCode);                                         \
500          }                                                                   \
501      } while ( 0 )
502#endif
503
504
505/*
506 *  verify_noerr_string(errorCode, message)
507 *
508 *  Summary:
509 *    Production builds: evaluate the errorCode expression, but ignore
510 *    the result.
511 *
512 *    Non-production builds: if the errorCode expression does not equal 0 (noErr),
513 *    call DEBUG_ASSERT_MESSAGE.
514 *
515 *  Parameters:
516 *
517 *    errorCode:
518 *      The expression to compare to 0.
519 *
520 *    message:
521 *      The C string to display.
522 */
523#if DEBUG_ASSERT_PRODUCTION_CODE
524   #define verify_noerr_string(errorCode, message)                            \
525      do                                                                      \
526      {                                                                       \
527          if ( 0 != (errorCode) )                                             \
528          {                                                                   \
529          }                                                                   \
530      } while ( 0 )
531#else
532   #define verify_noerr_string(errorCode, message)                            \
533      do                                                                      \
534      {                                                                       \
535          long evalOnceErrorCode = (errorCode);                               \
536          if ( __builtin_expect(0 != evalOnceErrorCode, 0) )                  \
537          {                                                                   \
538              DEBUG_ASSERT_MESSAGE(                                           \
539                  DEBUG_ASSERT_COMPONENT_NAME_STRING,                         \
540                  #errorCode " == 0 ",                                        \
541                  0,                                                          \
542                  message,                                                    \
543                  __FILE__,                                                   \
544                  __LINE__,                                                   \
545                  evalOnceErrorCode);                                         \
546          }                                                                   \
547      } while ( 0 )
548#endif
549
550
551/*
552 *  verify_action(assertion, action)
553 *
554 *  Summary:
555 *    Production builds: if the assertion expression evaluates to false,
556 *    then execute the action statement or compound statement (block).
557 *
558 *    Non-production builds: if the assertion expression evaluates to false,
559 *    call DEBUG_ASSERT_MESSAGE and then execute the action statement or compound
560 *    statement (block).
561 *
562 *  Parameters:
563 *
564 *    assertion:
565 *      The assertion expression.
566 *
567 *    action:
568 *      The statement or compound statement (block).
569 */
570#if DEBUG_ASSERT_PRODUCTION_CODE
571   #define verify_action(assertion, action)                                   \
572      do                                                                      \
573      {                                                                       \
574          if ( __builtin_expect(!(assertion), 0) )                           \
575          {                                                                   \
576              action;                                                         \
577          }                                                                   \
578      } while ( 0 )
579#else
580   #define verify_action(assertion, action)                                  \
581     do                                                                      \
582      {                                                                      \
583          if ( __builtin_expect(!(assertion), 0) )                           \
584          {                                                                  \
585             DEBUG_ASSERT_MESSAGE(                                           \
586                  DEBUG_ASSERT_COMPONENT_NAME_STRING,                        \
587                  #assertion,                                                \
588                  0,                                                         \
589                  0,                                                         \
590                  __FILE__,                                                  \
591                  __LINE__,                                                  \
592                  0);                                                        \
593             { action; }                                                     \
594         }                                                                   \
595     } while ( 0 )
596#endif
597
598
599/*
600 *  require(assertion, exceptionLabel)
601 *
602 *  Summary:
603 *    Production builds: if the assertion expression evaluates to false,
604 *    goto exceptionLabel.
605 *
606 *    Non-production builds: if the assertion expression evaluates to false,
607 *    call DEBUG_ASSERT_MESSAGE and then goto exceptionLabel.
608 *
609 *  Parameters:
610 *
611 *    assertion:
612 *      The assertion expression.
613 *
614 *    exceptionLabel:
615 *      The label.
616 */
617#if DEBUG_ASSERT_PRODUCTION_CODE
618   #define require(assertion, exceptionLabel)                                 \
619      do                                                                      \
620      {                                                                       \
621          if ( __builtin_expect(!(assertion), 0) )                            \
622          {                                                                   \
623              goto exceptionLabel;                                            \
624          }                                                                   \
625      } while ( 0 )
626#else
627   #define require(assertion, exceptionLabel)                                 \
628      do                                                                      \
629      {                                                                       \
630          if ( __builtin_expect(!(assertion), 0) )                            \
631          {                                                                   \
632              DEBUG_ASSERT_MESSAGE(                                           \
633                  DEBUG_ASSERT_COMPONENT_NAME_STRING,                         \
634                  #assertion,                                                 \
635                  #exceptionLabel,                                            \
636                  0,                                                          \
637                  __FILE__,                                                   \
638                  __LINE__,                                                   \
639                  0);                                                         \
640              goto exceptionLabel;                                            \
641          }                                                                   \
642      } while ( 0 )
643#endif
644
645#define nrequire(assertion, exceptionLabel)                                   \
646  require(!(assertion), exceptionLabel)
647
648
649/*
650 *  require_action(assertion, exceptionLabel, action)
651 *
652 *  Summary:
653 *    Production builds: if the assertion expression evaluates to false,
654 *    execute the action statement or compound statement (block) and then
655 *    goto exceptionLabel.
656 *
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.
660 *
661 *  Parameters:
662 *
663 *    assertion:
664 *      The assertion expression.
665 *
666 *    exceptionLabel:
667 *      The label.
668 *
669 *    action:
670 *      The statement or compound statement (block).
671 */
672#if DEBUG_ASSERT_PRODUCTION_CODE
673   #define require_action(assertion, exceptionLabel, action)                  \
674      do                                                                      \
675      {                                                                       \
676          if ( __builtin_expect(!(assertion), 0) )                            \
677          {                                                                   \
678              {                                                               \
679                  action;                                                     \
680              }                                                               \
681              goto exceptionLabel;                                            \
682          }                                                                   \
683      } while ( 0 )
684#else
685   #define require_action(assertion, exceptionLabel, action)                  \
686      do                                                                      \
687      {                                                                       \
688          if ( __builtin_expect(!(assertion), 0) )                            \
689          {                                                                   \
690              DEBUG_ASSERT_MESSAGE(                                           \
691                  DEBUG_ASSERT_COMPONENT_NAME_STRING,                         \
692                  #assertion,                                                 \
693                  #exceptionLabel,                                            \
694                  0,                                                          \
695                  __FILE__,                                                   \
696                  __LINE__,                                                   \
697                  0);                                                         \
698              {                                                               \
699                  action;                                                     \
700              }                                                               \
701              goto exceptionLabel;                                            \
702          }                                                                   \
703      } while ( 0 )
704#endif
705
706#define nrequire_action(assertion, exceptionLabel, action)                    \
707  require_action(!(assertion), exceptionLabel, action)
708
709
710/*
711 *  require_quiet(assertion, exceptionLabel)
712 *
713 *  Summary:
714 *    If the assertion expression evaluates to false, goto exceptionLabel.
715 *
716 *  Parameters:
717 *
718 *    assertion:
719 *      The assertion expression.
720 *
721 *    exceptionLabel:
722 *      The label.
723 */
724#define require_quiet(assertion, exceptionLabel)                              \
725  do                                                                          \
726  {                                                                           \
727      if ( __builtin_expect(!(assertion), 0) )                                \
728      {                                                                       \
729          goto exceptionLabel;                                                \
730      }                                                                       \
731  } while ( 0 )
732
733#define nrequire_quiet(assertion, exceptionLabel)                             \
734  require_quiet(!(assertion), exceptionLabel)
735
736
737/*
738 *  require_action_quiet(assertion, exceptionLabel, action)
739 *
740 *  Summary:
741 *    If the assertion expression evaluates to false, execute the action
742 *    statement or compound statement (block), and goto exceptionLabel.
743 *
744 *  Parameters:
745 *
746 *    assertion:
747 *      The assertion expression.
748 *
749 *    exceptionLabel:
750 *      The label.
751 *
752 *    action:
753 *      The statement or compound statement (block).
754 */
755#define require_action_quiet(assertion, exceptionLabel, action)               \
756  do                                                                          \
757  {                                                                           \
758      if ( __builtin_expect(!(assertion), 0) )                                \
759      {                                                                       \
760          {                                                                   \
761              action;                                                         \
762          }                                                                   \
763          goto exceptionLabel;                                                \
764      }                                                                       \
765  } while ( 0 )
766
767#define nrequire_action_quiet(assertion, exceptionLabel, action)              \
768  require_action_quiet(!(assertion), exceptionLabel, action)
769
770
771/*
772 *  require_string(assertion, exceptionLabel, message)
773 *
774 *  Summary:
775 *    Production builds: if the assertion expression evaluates to false,
776 *    goto exceptionLabel.
777 *
778 *    Non-production builds: if the assertion expression evaluates to false,
779 *    call DEBUG_ASSERT_MESSAGE, and then goto exceptionLabel.
780 *
781 *  Parameters:
782 *
783 *    assertion:
784 *      The assertion expression.
785 *
786 *    exceptionLabel:
787 *      The label.
788 *
789 *    message:
790 *      The C string to display.
791 */
792#if DEBUG_ASSERT_PRODUCTION_CODE
793   #define require_string(assertion, exceptionLabel, message)                 \
794      do                                                                      \
795      {                                                                       \
796          if ( __builtin_expect(!(assertion), 0) )                            \
797          {                                                                   \
798              goto exceptionLabel;                                            \
799          }                                                                   \
800      } while ( 0 )
801#else
802   #define require_string(assertion, exceptionLabel, message)                 \
803      do                                                                      \
804      {                                                                       \
805          if ( __builtin_expect(!(assertion), 0) )                            \
806          {                                                                   \
807              DEBUG_ASSERT_MESSAGE(                                           \
808                  DEBUG_ASSERT_COMPONENT_NAME_STRING,                         \
809                  #assertion,                                                 \
810                  #exceptionLabel,                                            \
811                  message,                                                    \
812                  __FILE__,                                                   \
813                  __LINE__,                                                   \
814                  0);                                                         \
815              goto exceptionLabel;                                            \
816          }                                                                   \
817      } while ( 0 )
818#endif
819
820#define nrequire_string(assertion, exceptionLabel, string)                    \
821  require_string(!(assertion), exceptionLabel, string)
822
823
824/*
825 *  require_action_string(assertion, exceptionLabel, action, message)
826 *
827 *  Summary:
828 *    Production builds: if the assertion expression evaluates to false,
829 *    execute the action statement or compound statement (block), and then
830 *    goto exceptionLabel.
831 *
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.
835 *
836 *  Parameters:
837 *
838 *    assertion:
839 *      The assertion expression.
840 *
841 *    exceptionLabel:
842 *      The label.
843 *
844 *    action:
845 *      The statement or compound statement (block).
846 *
847 *    message:
848 *      The C string to display.
849 */
850#if DEBUG_ASSERT_PRODUCTION_CODE
851   #define require_action_string(assertion, exceptionLabel, action, message)  \
852      do                                                                      \
853      {                                                                       \
854          if ( __builtin_expect(!(assertion), 0) )                            \
855          {                                                                   \
856              {                                                               \
857                  action;                                                     \
858              }                                                               \
859              goto exceptionLabel;                                            \
860          }                                                                   \
861      } while ( 0 )
862#else
863   #define require_action_string(assertion, exceptionLabel, action, message)  \
864      do                                                                      \
865      {                                                                       \
866          if ( __builtin_expect(!(assertion), 0) )                            \
867          {                                                                   \
868              DEBUG_ASSERT_MESSAGE(                                           \
869                  DEBUG_ASSERT_COMPONENT_NAME_STRING,                         \
870                  #assertion,                                                 \
871                  #exceptionLabel,                                            \
872                  message,                                                    \
873                  __FILE__,                                                   \
874                  __LINE__,                                                   \
875                  0);                                                         \
876              {                                                               \
877                  action;                                                     \
878              }                                                               \
879              goto exceptionLabel;                                            \
880          }                                                                   \
881      } while ( 0 )
882#endif
883
884#define nrequire_action_string(assertion, exceptionLabel, action, message)    \
885  require_action_string(!(assertion), exceptionLabel, action, message)
886
887
888/*
889 *  require_noerr(errorCode, exceptionLabel)
890 *
891 *  Summary:
892 *    Production builds: if the errorCode expression does not equal 0 (noErr),
893 *    goto exceptionLabel.
894 *
895 *    Non-production builds: if the errorCode expression does not equal 0 (noErr),
896 *    call DEBUG_ASSERT_MESSAGE and then goto exceptionLabel.
897 *
898 *  Parameters:
899 *
900 *    errorCode:
901 *      The expression to compare to 0.
902 *
903 *    exceptionLabel:
904 *      The label.
905 */
906#if DEBUG_ASSERT_PRODUCTION_CODE
907   #define require_noerr(errorCode, exceptionLabel)                           \
908      do                                                                      \
909      {                                                                       \
910          if ( __builtin_expect(0 != (errorCode), 0) )                        \
911          {                                                                   \
912              goto exceptionLabel;                                            \
913          }                                                                   \
914      } while ( 0 )
915#else
916   #define require_noerr(errorCode, exceptionLabel)                           \
917      do                                                                      \
918      {                                                                       \
919          long evalOnceErrorCode = (errorCode);                               \
920          if ( __builtin_expect(0 != evalOnceErrorCode, 0) )                  \
921          {                                                                   \
922              DEBUG_ASSERT_MESSAGE(                                           \
923                  DEBUG_ASSERT_COMPONENT_NAME_STRING,                         \
924                  #errorCode " == 0 ",                                        \
925                  #exceptionLabel,                                            \
926                  0,                                                          \
927                  __FILE__,                                                   \
928                  __LINE__,                                                   \
929                  evalOnceErrorCode);                                         \
930              goto exceptionLabel;                                            \
931          }                                                                   \
932      } while ( 0 )
933#endif
934
935/*
936 *  require_noerr_action(errorCode, exceptionLabel, action)
937 *
938 *  Summary:
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.
942 *
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.
946 *
947 *  Parameters:
948 *
949 *    errorCode:
950 *      The expression to compare to 0.
951 *
952 *    exceptionLabel:
953 *      The label.
954 *
955 *    action:
956 *      The statement or compound statement (block).
957 */
958#if DEBUG_ASSERT_PRODUCTION_CODE
959   #define require_noerr_action(errorCode, exceptionLabel, action)            \
960      do                                                                      \
961      {                                                                       \
962          if ( __builtin_expect(0 != (errorCode), 0) )                        \
963          {                                                                   \
964              {                                                               \
965                  action;                                                     \
966              }                                                               \
967              goto exceptionLabel;                                            \
968          }                                                                   \
969      } while ( 0 )
970#else
971   #define require_noerr_action(errorCode, exceptionLabel, action)            \
972      do                                                                      \
973      {                                                                       \
974          long evalOnceErrorCode = (errorCode);                               \
975          if ( __builtin_expect(0 != evalOnceErrorCode, 0) )                  \
976          {                                                                   \
977              DEBUG_ASSERT_MESSAGE(                                           \
978                  DEBUG_ASSERT_COMPONENT_NAME_STRING,                         \
979                  #errorCode " == 0 ",                                        \
980                  #exceptionLabel,                                            \
981                  0,                                                          \
982                  __FILE__,                                                   \
983                  __LINE__,                                                   \
984                  evalOnceErrorCode);                                         \
985              {                                                               \
986                  action;                                                     \
987              }                                                               \
988              goto exceptionLabel;                                            \
989          }                                                                   \
990      } while ( 0 )
991#endif
992
993
994/*
995 *  require_noerr_quiet(errorCode, exceptionLabel)
996 *
997 *  Summary:
998 *    If the errorCode expression does not equal 0 (noErr),
999 *    goto exceptionLabel.
1000 *
1001 *  Parameters:
1002 *
1003 *    errorCode:
1004 *      The expression to compare to 0.
1005 *
1006 *    exceptionLabel:
1007 *      The label.
1008 */
1009#define require_noerr_quiet(errorCode, exceptionLabel)                        \
1010  do                                                                          \
1011  {                                                                           \
1012      if ( __builtin_expect(0 != (errorCode), 0) )                            \
1013      {                                                                       \
1014          goto exceptionLabel;                                                \
1015      }                                                                       \
1016  } while ( 0 )
1017
1018
1019/*
1020 *  require_noerr_action_quiet(errorCode, exceptionLabel, action)
1021 *
1022 *  Summary:
1023 *    If the errorCode expression does not equal 0 (noErr),
1024 *    execute the action statement or compound statement (block) and
1025 *    goto exceptionLabel.
1026 *
1027 *  Parameters:
1028 *
1029 *    errorCode:
1030 *      The expression to compare to 0.
1031 *
1032 *    exceptionLabel:
1033 *      The label.
1034 *
1035 *    action:
1036 *      The statement or compound statement (block).
1037 */
1038#define require_noerr_action_quiet(errorCode, exceptionLabel, action)         \
1039  do                                                                          \
1040  {                                                                           \
1041      if ( __builtin_expect(0 != (errorCode), 0) )                            \
1042      {                                                                       \
1043          {                                                                   \
1044              action;                                                         \
1045          }                                                                   \
1046          goto exceptionLabel;                                                \
1047      }                                                                       \
1048  } while ( 0 )
1049
1050
1051/*
1052 *  require_noerr_string(errorCode, exceptionLabel, message)
1053 *
1054 *  Summary:
1055 *    Production builds: if the errorCode expression does not equal 0 (noErr),
1056 *    goto exceptionLabel.
1057 *
1058 *    Non-production builds: if the errorCode expression does not equal 0 (noErr),
1059 *    call DEBUG_ASSERT_MESSAGE, and then goto exceptionLabel.
1060 *
1061 *  Parameters:
1062 *
1063 *    errorCode:
1064 *      The expression to compare to 0.
1065 *
1066 *    exceptionLabel:
1067 *      The label.
1068 *
1069 *    message:
1070 *      The C string to display.
1071 */
1072#if DEBUG_ASSERT_PRODUCTION_CODE
1073   #define require_noerr_string(errorCode, exceptionLabel, message)           \
1074      do                                                                      \
1075      {                                                                       \
1076          if ( __builtin_expect(0 != (errorCode), 0) )                        \
1077          {                                                                   \
1078              goto exceptionLabel;                                            \
1079          }                                                                   \
1080      } while ( 0 )
1081#else
1082   #define require_noerr_string(errorCode, exceptionLabel, message)           \
1083      do                                                                      \
1084      {                                                                       \
1085          long evalOnceErrorCode = (errorCode);                               \
1086          if ( __builtin_expect(0 != evalOnceErrorCode, 0) )                  \
1087          {                                                                   \
1088              DEBUG_ASSERT_MESSAGE(                                           \
1089                  DEBUG_ASSERT_COMPONENT_NAME_STRING,                         \
1090                  #errorCode " == 0 ",                                        \
1091                  #exceptionLabel,                                            \
1092                  message,                                                    \
1093                  __FILE__,                                                   \
1094                  __LINE__,                                                   \
1095                  evalOnceErrorCode);                                         \
1096              goto exceptionLabel;                                            \
1097          }                                                                   \
1098      } while ( 0 )
1099#endif
1100
1101
1102/*
1103 *  require_noerr_action_string(errorCode, exceptionLabel, action, message)
1104 *
1105 *  Summary:
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.
1109 *
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.
1113 *
1114 *  Parameters:
1115 *
1116 *    errorCode:
1117 *      The expression to compare to 0.
1118 *
1119 *    exceptionLabel:
1120 *      The label.
1121 *
1122 *    action:
1123 *      The statement or compound statement (block).
1124 *
1125 *    message:
1126 *      The C string to display.
1127 */
1128#if DEBUG_ASSERT_PRODUCTION_CODE
1129   #define require_noerr_action_string(errorCode, exceptionLabel, action, message)\
1130      do                                                                      \
1131      {                                                                       \
1132          if ( __builtin_expect(0 != (errorCode), 0) )                        \
1133          {                                                                   \
1134              {                                                               \
1135                  action;                                                     \
1136              }                                                               \
1137              goto exceptionLabel;                                            \
1138          }                                                                   \
1139      } while ( 0 )
1140#else
1141   #define require_noerr_action_string(errorCode, exceptionLabel, action, message) \
1142      do                                                                      \
1143      {                                                                       \
1144          long evalOnceErrorCode = (errorCode);                               \
1145          if ( __builtin_expect(0 != evalOnceErrorCode, 0) )                  \
1146          {                                                                   \
1147              DEBUG_ASSERT_MESSAGE(                                           \
1148                  DEBUG_ASSERT_COMPONENT_NAME_STRING,                         \
1149                  #errorCode " == 0 ",                                        \
1150                  #exceptionLabel,                                            \
1151                  message,                                                    \
1152                  __FILE__,                                                   \
1153                  __LINE__,                                                   \
1154                  evalOnceErrorCode);                                         \
1155              {                                                               \
1156                  action;                                                     \
1157              }                                                               \
1158              goto exceptionLabel;                                            \
1159          }                                                                   \
1160      } while ( 0 )
1161#endif
1162
1163
1164#endif /* __ASSERTMACROS__ */
1165
1166