]> git.saurik.com Git - apple/mdnsresponder.git/blob - mDNSWindows/DebugServices.h
mDNSResponder-87.tar.gz
[apple/mdnsresponder.git] / mDNSWindows / DebugServices.h
1 /*
2 * Copyright (c) 1997-2004 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22
23 Change History (most recent first):
24
25 $Log: DebugServices.h,v $
26 Revision 1.4 2004/04/15 08:59:08 bradley
27 Removed deprecated debug and log levels and replaced them with modern equivalents.
28
29 Revision 1.3 2004/04/08 09:29:55 bradley
30 Manually do host->network byte order conversion to avoid needing libraries for htons/htonl. Changed
31 hex dumps to better separate hex and ASCII. Added support for %.8a syntax in DebugSNPrintF for Fibre
32 Channel addresses (00:11:22:33:44:55:66:77). Fixed a few places where HeaderDoc was incorrect.
33
34 Revision 1.2 2004/03/07 05:59:34 bradley
35 Sync'd with internal version: Added expect macros, error codes, and CoreServices exclusion.
36
37 Revision 1.1 2004/01/30 02:27:30 bradley
38 Debugging support for various platforms.
39
40 */
41
42 //---------------------------------------------------------------------------------------------------------------------------
43 /*! @header DebugServices
44
45 Debugging Library
46 */
47
48 #ifndef __DEBUG_SERVICES__
49 #define __DEBUG_SERVICES__
50
51 #include <stdarg.h>
52
53 #include "CommonServices.h"
54
55 #if( TARGET_OS_VXWORKS )
56 #include "logLib.h"
57 #endif
58
59 #if 0
60 #pragma mark == Settings ==
61 #endif
62
63 //===========================================================================================================================
64 // Settings
65 //===========================================================================================================================
66
67 // General
68
69 #if( !defined( DEBUG ) )
70 #define DEBUG 0
71 #endif
72
73 #if( defined( NDEBUG ) && DEBUG )
74 #error NDEBUG defined and DEBUG is also enabled...they need to be in-sync
75 #endif
76
77 // AssertMacros.h/Debugging.h overrides.
78
79 #if( !defined( DEBUG_OVERRIDE_APPLE_MACROS ) )
80 #define DEBUG_OVERRIDE_APPLE_MACROS 1
81 #endif
82
83 // Routine name. Uses ISO __func__ where possible. Otherwise, uses the best thing that is available (if anything).
84
85 #if( defined( __MWERKS__ ) || ( __GNUC__ > 2 ) || ( ( __GNUC__ == 2 ) && ( __GNUC_MINOR__ >= 9 ) ) )
86 #define __ROUTINE__ __func__
87 #elif( defined( __GNUC__ ) )
88 #define __ROUTINE__ __PRETTY_FUNCTION__
89 #elif( defined( _MSC_VER ) && !defined( _WIN32_WCE ) )
90 #define __ROUTINE__ __FUNCTION__
91 #else
92 #define __ROUTINE__ ""
93 #endif
94
95 // Variable argument macro support. Use ANSI C99 __VA_ARGS__ where possible. Otherwise, use the next best thing.
96
97 #if( defined( __GNUC__ ) )
98 #if( ( __GNUC__ > 3 ) || ( ( __GNUC__ == 3 ) && ( __GNUC_MINOR__ >= 3) ) )
99 #define DEBUG_C99_VA_ARGS 1
100 #define DEBUG_GNU_VA_ARGS 0
101 #else
102 #define DEBUG_C99_VA_ARGS 0
103 #define DEBUG_GNU_VA_ARGS 1
104 #endif
105 #elif( defined( __MWERKS__ ) )
106 #define DEBUG_C99_VA_ARGS 1
107 #define DEBUG_GNU_VA_ARGS 0
108 #else
109 #define DEBUG_C99_VA_ARGS 0
110 #define DEBUG_GNU_VA_ARGS 0
111 #endif
112
113 #if 0
114 #pragma mark == Output ==
115 #endif
116
117 //---------------------------------------------------------------------------------------------------------------------------
118 /*! @defined DEBUG_FPRINTF_ENABLED
119
120 @abstract Enables ANSI C fprintf output.
121 */
122
123 #if( !defined( DEBUG_FPRINTF_ENABLED ) )
124 #if( !TARGET_API_MAC_OSX_KERNEL && !TARGET_OS_WINDOWS_CE )
125 #define DEBUG_FPRINTF_ENABLED 1
126 #else
127 #define DEBUG_FPRINTF_ENABLED 0
128 #endif
129 #else
130 #if( TARGET_API_MAC_OSX_KERNEL || TARGET_OS_WINDOWS_CE )
131 #error fprintf enabled, but not supported on Mac OS X kernel or Windows CE
132 #endif
133 #endif
134
135 //---------------------------------------------------------------------------------------------------------------------------
136 /*! @defined DEBUG_MAC_OS_X_IOLOG_ENABLED
137
138 @abstract Enables IOLog (Mac OS X Kernel) output.
139 */
140
141 #if( !defined( DEBUG_MAC_OS_X_IOLOG_ENABLED ) )
142 #define DEBUG_MAC_OS_X_IOLOG_ENABLED TARGET_API_MAC_OSX_KERNEL
143 #endif
144
145 //---------------------------------------------------------------------------------------------------------------------------
146 /*! @defined DEBUG_KPRINTF_ENABLED
147
148 @abstract Enables kprintf (Mac OS X Kernel) output.
149 */
150
151 #if( !defined( DEBUG_KPRINTF_ENABLED ) )
152 #define DEBUG_KPRINTF_ENABLED TARGET_API_MAC_OSX_KERNEL
153 #endif
154
155 //---------------------------------------------------------------------------------------------------------------------------
156 /*! @defined DEBUG_IDEBUG_ENABLED
157
158 @abstract Enables iDebug (Mac OS X user and Kernel) output.
159
160 @discussion
161
162 For Mac OS X kernel development, iDebug is enabled by default because we can dynamically check for the presence
163 of iDebug via some exported IOKit symbols. Mac OS X app usage doesn't allow dynamic detection because it relies
164 on statically linking to the iDebugServices.cp file so for Mac OS X app usage, you have to manually enable iDebug.
165 */
166
167 #if( !defined( DEBUG_IDEBUG_ENABLED ) )
168 #define DEBUG_IDEBUG_ENABLED TARGET_API_MAC_OSX_KERNEL
169 #endif
170
171 //---------------------------------------------------------------------------------------------------------------------------
172 /*! @defined DEBUG_CORE_SERVICE_ASSERTS_ENABLED
173
174 @abstract Controls whether Core Services assert handling is enabled. Enabling requires CoreServices framework.
175 */
176
177 #if( !defined( DEBUG_CORE_SERVICE_ASSERTS_ENABLED ) )
178 #if( defined( __DEBUGGING__ ) )
179 #define DEBUG_CORE_SERVICE_ASSERTS_ENABLED 1
180 #else
181 #define DEBUG_CORE_SERVICE_ASSERTS_ENABLED 0
182 #endif
183 #endif
184
185 //---------------------------------------------------------------------------------------------------------------------------
186 /*! @typedef DebugOutputType
187
188 @abstract Type of debug output (i.e. where the output goes).
189 */
190
191 typedef uint32_t DebugOutputType;
192
193 #define kDebugOutputTypeNone 0x6E6F6E65U // 'none' - no params
194 #define kDebugOutputTypeCustom 0x63757374U // 'cust' - 1st param = function ptr, 2nd param = context
195 #define kDebugOutputTypeFPrintF 0x66707269U // 'fpri' - 1st param = DebugOutputTypeFlags [, 2nd param = filename]
196 #define kDebugOutputTypeiDebug 0x69646267U // 'idbg' - no params
197 #define kDebugOutputTypeKPrintF 0x6B707266U // 'kprf' - no params
198 #define kDebugOutputTypeMacOSXIOLog 0x696C6F67U // 'ilog' - no params
199 #define kDebugOutputTypeMacOSXLog 0x786C6F67U // 'xlog' - no params
200 #define kDebugOutputTypeWindowsDebugger 0x77696E64U // 'wind' - no params
201 #define kDebugOutputTypeWindowsEventLog 0x7765766CU // 'wevl' - 1st param = C-string name, 2nd param = HMODULE or NULL.
202
203 // Console meta output kind - Any kind of Console output (in horizontal order of preference):
204 //
205 // Mac OS X = ANSI printf (viewable in Console.app)
206 // Mac OS X Kernel = IOLog (/var/log/system.log) or kprintf (serial).
207 // Windows = ANSI printf (Console window) or OutputDebugString (debugger).
208 // Other = ANSI printf (viewer varies).
209
210 #define kDebugOutputTypeMetaConsole 0x434F4E53U // 'CONS' - no params
211
212 //---------------------------------------------------------------------------------------------------------------------------
213 /*! @typedef DebugOutputTypeFlags
214
215 @abstract Flags controlling how the output type is configured.
216
217 @constant kDebugOutputTypeFlagsTypeMask Bit mask for the output type (e.g. stdout, stderr, file, etc.).
218 @constant kDebugOutputTypeFlagsStdOut fprintf should go to stdout.
219 @constant kDebugOutputTypeFlagsStdErr fprintf should go to stderr.
220 @constant kDebugOutputTypeFlagsFile fprintf should go to a specific file (filename passed as va_arg).
221 */
222
223 typedef unsigned int DebugOutputTypeFlags;
224
225 #define kDebugOutputTypeFlagsTypeMask 0xF
226 #define kDebugOutputTypeFlagsStdOut 1
227 #define kDebugOutputTypeFlagsStdErr 2
228 #define kDebugOutputTypeFlagsFile 10
229
230 //---------------------------------------------------------------------------------------------------------------------------
231 /*! @typedef DebugOutputFunctionPtr
232
233 @abstract Function ptr for a custom callback to print debug output.
234 */
235
236 typedef void ( *DebugOutputFunctionPtr )( char *inData, size_t inSize, void *inContext );
237
238 //===========================================================================================================================
239 // Constants
240 //===========================================================================================================================
241
242 #if 0
243 #pragma mark == Flags ==
244 #endif
245
246 //---------------------------------------------------------------------------------------------------------------------------
247 /*! @typedef DebugFlags
248
249 @abstract Flags controlling how output is printed.
250 */
251
252 typedef uint32_t DebugFlags;
253
254 #define kDebugFlagsNone 0
255 #define kDebugFlagsNoAddress ( 1 << 0 )
256 #define kDebugFlagsNoOffset ( 1 << 1 )
257 #define kDebugFlags32BitOffset ( 1 << 2 )
258 #define kDebugFlagsNoASCII ( 1 << 3 )
259 #define kDebugFlagsNoNewLine ( 1 << 4 )
260 #define kDebugFlags8BitSeparator ( 1 << 5 )
261 #define kDebugFlags16BitSeparator ( 1 << 6 )
262 #define kDebugFlagsNo32BitSeparator ( 1 << 7 )
263 #define kDebugFlagsNo16ByteHexPad ( 1 << 8 )
264 #define kDebugFlagsNoByteCount ( 1 << 9 )
265
266 //---------------------------------------------------------------------------------------------------------------------------
267 /*! @enum DebugTaskLevelFlags
268
269 @abstract Flags indicating the task level.
270 */
271
272 enum
273 {
274 kDebugInterruptLevelShift = 0,
275 kDebugInterruptLevelMask = 0x00000007,
276 kDebugInVBLTaskMask = 0x00000010,
277 kDebugInDeferredTaskMask = 0x00000020,
278 kDebugInSecondaryInterruptHandlerMask = 0x00000040,
279 kDebugPageFaultFatalMask = 0x00000100, // There should be a "kPageFaultFatalMask" in Debugging.h.
280 kDebugMPTaskLevelMask = 0x00000200, // There should be a "kMPTaskLevelMask" in Debugging.h.
281 kDebugInterruptDepthShift = 16,
282 kDebugInterruptDepthMask = 0x00FF0000
283 };
284
285 #define DebugExtractTaskLevelInterruptLevel( LEVEL ) \
286 ( ( ( LEVEL ) & kDebugInterruptLevelMask ) >> kDebugInterruptLevelShift )
287
288 #define DebugExtractTaskLevelInterruptDepth( LEVEL ) \
289 ( ( ( LEVEL ) & kDebugInterruptDepthMask ) >> kDebugInterruptDepthShift )
290
291 #if 0
292 #pragma mark == Levels ==
293 #endif
294
295 //===========================================================================================================================
296 // Constants & Types - Levels
297 //===========================================================================================================================
298
299 //---------------------------------------------------------------------------------------------------------------------------
300 /*! @typedef DebugLevel
301
302 @abstract Level used to control debug logging.
303 */
304
305 typedef int32_t DebugLevel;
306
307 // Levels
308
309 #define kDebugLevelMask 0x0000FFFF
310 #define kDebugLevelChatty 100
311 #define kDebugLevelVerbose 500
312 #define kDebugLevelTrace 800
313 #define kDebugLevelInfo 1000
314 #define kDebugLevelNotice 3000
315 #define kDebugLevelWarning 5000
316 #define kDebugLevelAssert 6000
317 #define kDebugLevelRequire 7000
318 #define kDebugLevelError 8000
319 #define kDebugLevelCritical 9000
320 #define kDebugLevelAlert 10000
321 #define kDebugLevelEmergency 11000
322 #define kDebugLevelTragic 12000
323 #define kDebugLevelMax 0x0000FFFF
324
325 // Level Flags
326
327 #define kDebugLevelFlagMask 0xFFFF0000
328 #define kDebugLevelFlagStackTrace 0x00010000
329 #define kDebugLevelFlagDebugBreak 0x00020000
330
331 //---------------------------------------------------------------------------------------------------------------------------
332 /*! @typedef LogLevel
333
334 @abstract Level used to control which events are logged.
335 */
336
337 typedef int32_t LogLevel;
338
339 #define kLogLevelUninitialized -1L
340 #define kLogLevelAll 0L
341 #define kLogLevelChatty 100L
342 #define kLogLevelVerbose 500L
343 #define kLogLevelTrace 800L
344 #define kLogLevelInfo 1000L
345 #define kLogLevelNotice 3000L
346 #define kLogLevelWarning 4000L
347 #define kLogLevelAssert 6000L
348 #define kLogLevelRequire 7000L
349 #define kLogLevelError 8000L
350 #define kLogLevelCritical 9000L
351 #define kLogLevelAlert 10000L
352 #define kLogLevelEmergency 11000L
353 #define kLogLevelTragic 12000L
354 #define kLogLevelOff 0x0000FFFEL
355
356 #if 0
357 #pragma mark == Properties ==
358 #endif
359
360 //---------------------------------------------------------------------------------------------------------------------------
361 /*! @typedef DebugPropertyTag
362
363 @abstract Tag for properties.
364 */
365
366 typedef uint32_t DebugPropertyTag;
367
368 #define kDebugPropertyTagPrintLevelMin 0x6D696E70U // 'minp' Get: 1st param = DebugLevel *
369 // Set: 1st param = DebugLevel
370
371 #define kDebugPropertyTagPrintLevel kDebugPropertyTagPrintLevelMin
372
373 #define kDebugPropertyTagPrintLevelMax 0x706D786CU // 'maxp' Get: 1st param = DebugLevel *
374 // Set: 1st param = DebugLevel
375
376 #define kDebugPropertyTagBreakLevel 0x62726B6CU // 'brkl' Get: 1st param = DebugLevel *
377 // Set: 1st param = DebugLevel
378 #if 0
379 #pragma mark == General macros ==
380 #endif
381
382 //---------------------------------------------------------------------------------------------------------------------------
383 /*! @defined DEBUG_UNUSED
384
385 @abstract Macro to mark a paramter as unused to avoid unused parameter warnings.
386
387 @discussion
388
389 There is no universally supported pragma/attribute for indicating a variable is unused. DEBUG_UNUSED lets us
390 indicate a variable is unused in a manner that is supported by most compilers.
391 */
392
393 #define DEBUG_UNUSED( X ) (void)( X )
394
395 //---------------------------------------------------------------------------------------------------------------------------
396 /*! @defined DEBUG_USE_ONLY
397
398 @abstract Macro to mark a variable as used only when debugging is enabled.
399
400 @discussion
401
402 Variables are sometimes needed only for debugging. When debugging is turned off, these debug-only variables generate
403 compiler warnings about unused variables. To eliminate these warnings, use these macros to indicate variables that
404 are only used for debugging.
405 */
406
407 #if( DEBUG )
408 #define DEBUG_USE_ONLY( X )
409 #else
410 #define DEBUG_USE_ONLY( X ) (void)( X )
411 #endif
412
413 //---------------------------------------------------------------------------------------------------------------------------
414 /*! @defined DEBUG_LOCAL
415
416 @abstract Macros to make variables and functions static when debugging is off, but extern when debugging is on.
417
418 @discussion
419
420 Rather than using "static" directly, using this macros allows you to access these variables external while
421 debugging without being penalized for production builds.
422 */
423
424 #if( DEBUG )
425 #define DEBUG_LOCAL
426 #else
427 #define DEBUG_LOCAL static
428 #endif
429
430 //---------------------------------------------------------------------------------------------------------------------------
431 /*! @defined DEBUG_STATIC
432
433 @abstract Macros to make variables and functions static when debugging is off, but extern when debugging is on.
434
435 @discussion
436
437 Rather than using "static" directly, using this macros allows you to access these variables external while
438 debugging without being penalized for production builds.
439 */
440
441 #if( DEBUG )
442 #define DEBUG_STATIC
443 #else
444 #define DEBUG_STATIC static
445 #endif
446
447 //---------------------------------------------------------------------------------------------------------------------------
448 /*! @defined DEBUG_EXPORT
449
450 @abstract Macros to export variables.
451
452 @discussion
453
454 "__private_extern__" is a hack for IOKit to allow symbols to be exported from compilation units, but
455 // not exported outside a driver (IOKit uses a lame global namespace for symbols). This still does not
456 // solve the problem of multiple drivers in the same dependency chain since they share symbols.
457 */
458
459 #if( TARGET_API_MAC_OSX_KERNEL )
460 #define DEBUG_EXPORT __private_extern__
461 #else
462 #define DEBUG_EXPORT extern
463 #endif
464
465 //---------------------------------------------------------------------------------------------------------------------------
466 /*! @defined debug_add
467
468 @abstract Macro to add (or subtract if negative) a value when debugging is on. Does nothing if debugging is off.
469 */
470
471 #if( DEBUG )
472 #define debug_add( A, B ) ( A ) += ( B )
473 #else
474 #define debug_add( A, B )
475 #endif
476
477 //---------------------------------------------------------------------------------------------------------------------------
478 /*! @defined debug_perform
479
480 @abstract Macro to perform something in debug-only builds.
481 */
482
483 #if( DEBUG )
484 #define debug_perform( X ) do { X; } while( 0 )
485 #else
486 #define debug_perform( X )
487 #endif
488
489 //---------------------------------------------------------------------------------------------------------------------------
490 /*! @function translate_errno
491
492 @abstract Returns 0 if the test success. If the test fails, returns errno if non-zero and othewise the alternate error.
493 */
494
495 #define translate_errno( TEST, ERRNO, ALTERNATE_ERROR ) ( ( TEST ) ? 0 : ( ERRNO ) ? ( ERRNO ) : ( ALTERNATE_ERROR ) )
496
497 #if 0
498 #pragma mark == Compile Time macros ==
499 #endif
500
501 //---------------------------------------------------------------------------------------------------------------------------
502 /*! @defined check_compile_time
503
504 @abstract Performs a compile-time check of something such as the size of an int.
505
506 @discussion
507
508 This declares an array with a size that is determined by a compile-time expression. If the expression evaluates
509 to 0, the array has a size of -1, which is illegal and generates a compile-time error.
510
511 For example:
512
513 check_compile_time( sizeof( int ) == 4 );
514
515 Note: This only works with compile-time expressions.
516 Note: This only works in places where extern declarations are allowed (e.g. global scope).
517
518 References:
519
520 <http://www.jaggersoft.com/pubs/CVu11_3.html>
521 <http://www.jaggersoft.com/pubs/CVu11_5.html>
522
523 Note: The following macros differ from the macros on the www.jaggersoft.com web site because those versions do not
524 work with GCC due to GCC allow a zero-length array. Using a -1 condition turned out to be more portable.
525 */
526
527 #define check_compile_time( X ) extern int debug_compile_time_name[ ( X ) ? 1 : -1 ]
528
529 //---------------------------------------------------------------------------------------------------------------------------
530 /*! @defined check_compile_time_code
531
532 @abstract Perform a compile-time check, suitable for placement in code, of something such as the size of an int.
533
534 @discussion
535
536 This creates a switch statement with an existing case for 0 and an additional case using the result of a
537 compile-time expression. A switch statement cannot have two case labels with the same constant so if the
538 compile-time expression evaluates to 0, it is illegal and generates a compile-time error. If the compile-time
539 expression does not evaluate to 0, the resulting value is used as the case label and it compiles without error.
540
541 For example:
542
543 check_compile_time_code( sizeof( int ) == 4 );
544
545 Note: This only works with compile-time expressions.
546 Note: This does not work in a global scope so it must be inside a function.
547
548 References:
549
550 <http://www.jaggersoft.com/pubs/CVu11_3.html>
551 <http://www.jaggersoft.com/pubs/CVu11_5.html>
552 */
553
554 #define check_compile_time_code( X ) switch( 0 ) { case 0: case X:; }
555
556 #if 0
557 #pragma mark == check macros ==
558 #endif
559
560 //---------------------------------------------------------------------------------------------------------------------------
561 /*! @defined check
562
563 @abstract Check that an expression is true (non-zero).
564
565 @discussion
566
567 If expression evalulates to false, this prints debugging information (actual expression string, file, line number,
568 function name, etc.) using the default debugging output method.
569
570 Code inside check() statements is not compiled into production builds.
571 */
572
573 #if( DEBUG_OVERRIDE_APPLE_MACROS )
574 #undef check
575 #endif
576 #if( !defined( check ) )
577 #if( DEBUG )
578 #define check( X ) \
579 do \
580 { \
581 if( !( X ) ) \
582 { \
583 debug_print_assert( 0, #X, NULL, __FILE__, __LINE__, __ROUTINE__ ); \
584 } \
585 } while( 0 )
586 #else
587 #define check( X )
588 #endif
589 #endif
590
591 //---------------------------------------------------------------------------------------------------------------------------
592 /*! @defined check_string
593
594 @abstract Check that an expression is true (non-zero) with an explanation.
595
596 @discussion
597
598 If expression evalulates to false, this prints debugging information (actual expression string, file, line number,
599 function name, etc.) and a custom explanation string using the default debugging output method.
600
601 Code inside check_string() statements is not compiled into production builds.
602 */
603
604 #if( DEBUG_OVERRIDE_APPLE_MACROS )
605 #undef check_string
606 #endif
607 #if( !defined( check_string ) )
608 #if( DEBUG )
609 #define check_string( X, STR ) \
610 do \
611 { \
612 if( !( X ) ) \
613 { \
614 debug_print_assert( 0, #X, STR, __FILE__, __LINE__, __ROUTINE__ ); \
615 } \
616 \
617 } while( 0 )
618 #else
619 #define check_string( X, STR )
620 #endif
621 #endif
622
623 //---------------------------------------------------------------------------------------------------------------------------
624 /*! @defined check_noerr
625
626 @abstract Check that an error code is noErr (0).
627
628 @discussion
629
630 If the error code is non-0, this prints debugging information (actual expression string, file, line number,
631 function name, etc.) using the default debugging output method.
632
633 Code inside check_noerr() statements is not compiled into production builds.
634 */
635
636 #if( DEBUG_OVERRIDE_APPLE_MACROS )
637 #undef check_noerr
638 #endif
639 #if( !defined( check_noerr ) )
640 #if( DEBUG )
641 #define check_noerr( ERR ) \
642 do \
643 { \
644 int_least32_t localErr; \
645 \
646 localErr = (int_least32_t)( ERR ); \
647 if( localErr != 0 ) \
648 { \
649 debug_print_assert( localErr, NULL, NULL, __FILE__, __LINE__, __ROUTINE__ ); \
650 } \
651 \
652 } while( 0 )
653 #else
654 #define check_noerr( ERR )
655 #endif
656 #endif
657
658 //---------------------------------------------------------------------------------------------------------------------------
659 /*! @defined check_noerr_string
660
661 @abstract Check that an error code is noErr (0) with an explanation.
662
663 @discussion
664
665 If the error code is non-0, this prints debugging information (actual expression string, file, line number,
666 function name, etc.) and a custom explanation string using the default debugging output method.
667
668 Code inside check_noerr_string() statements is not compiled into production builds.
669 */
670
671 #if( DEBUG_OVERRIDE_APPLE_MACROS )
672 #undef check_noerr_string
673 #endif
674 #if( !defined( check_noerr_string ) )
675 #if( DEBUG )
676 #define check_noerr_string( ERR, STR ) \
677 do \
678 { \
679 int_least32_t localErr; \
680 \
681 localErr = (int_least32_t)( ERR ); \
682 if( localErr != 0 ) \
683 { \
684 debug_print_assert( localErr, NULL, STR, __FILE__, __LINE__, __ROUTINE__ ); \
685 } \
686 \
687 } while( 0 )
688 #else
689 #define check_noerr_string( ERR, STR )
690 #endif
691 #endif
692
693 //---------------------------------------------------------------------------------------------------------------------------
694 /*! @defined check_translated_errno
695
696 @abstract Check a condition and prints errno (if non-zero) to the log.
697
698 @discussion
699
700 Code inside check_translated_errno() statements is not compiled into production builds.
701 */
702
703 #if( !defined( check_translated_errno ) )
704 #if( DEBUG )
705 #define check_translated_errno( TEST, ERRNO, ALTERNATE_ERROR ) \
706 do \
707 { \
708 if( !( TEST ) ) \
709 { \
710 int_least32_t localErr; \
711 \
712 localErr = (int_least32_t)( ERRNO ); \
713 localErr = ( localErr != 0 ) ? localErr : (int_least32_t)( ALTERNATE_ERROR ); \
714 debug_print_assert( localErr, #TEST, NULL, __FILE__, __LINE__, __ROUTINE__ ); \
715 } \
716 \
717 } while( 0 )
718 #else
719 #define check_translated_errno( TEST, ERRNO, ALTERNATE_ERROR )
720 #endif
721 #endif
722
723 //---------------------------------------------------------------------------------------------------------------------------
724 /*! @defined check_ptr_overlap
725
726 @abstract Checks that two ptrs do not overlap.
727 */
728
729 #define check_ptr_overlap( P1, P1_SIZE, P2, P2_SIZE ) \
730 do \
731 { \
732 check( !( ( (uintptr_t)( P1 ) >= (uintptr_t)( P2 ) ) && \
733 ( (uintptr_t)( P1 ) < ( ( (uintptr_t)( P2 ) ) + ( P2_SIZE ) ) ) ) ); \
734 check( !( ( (uintptr_t)( P2 ) >= (uintptr_t)( P1 ) ) && \
735 ( (uintptr_t)( P2 ) < ( ( (uintptr_t)( P1 ) ) + ( P1_SIZE ) ) ) ) ); \
736 \
737 } while( 0 )
738
739 #if 0
740 #pragma mark == require macros ==
741 #endif
742
743 //---------------------------------------------------------------------------------------------------------------------------
744 /*! @defined require
745
746 @abstract Requires that an expression evaluate to true.
747
748 @discussion
749
750 If expression evalulates to false, this prints debugging information (actual expression string, file, line number,
751 function name, etc.) using the default debugging output method then jumps to a label.
752 */
753
754 #if( DEBUG_OVERRIDE_APPLE_MACROS )
755 #undef require
756 #endif
757 #if( !defined( require ) )
758 #define require( X, LABEL ) \
759 do \
760 { \
761 if( !( X ) ) \
762 { \
763 debug_print_assert( 0, #X, NULL, __FILE__, __LINE__, __ROUTINE__ ); \
764 goto LABEL; \
765 } \
766 \
767 } while( 0 )
768 #endif
769
770 //---------------------------------------------------------------------------------------------------------------------------
771 /*! @defined require_string
772
773 @abstract Requires that an expression evaluate to true with an explanation.
774
775 @discussion
776
777 If expression evalulates to false, this prints debugging information (actual expression string, file, line number,
778 function name, etc.) and a custom explanation string using the default debugging output method then jumps to a label.
779 */
780
781 #if( DEBUG_OVERRIDE_APPLE_MACROS )
782 #undef require_string
783 #endif
784 #if( !defined( require_string ) )
785 #define require_string( X, LABEL, STR ) \
786 do \
787 { \
788 if( !( X ) ) \
789 { \
790 debug_print_assert( 0, #X, STR, __FILE__, __LINE__, __ROUTINE__ ); \
791 goto LABEL; \
792 } \
793 \
794 } while( 0 )
795 #endif
796
797 //---------------------------------------------------------------------------------------------------------------------------
798 /*! @defined require_quiet
799
800 @abstract Requires that an expression evaluate to true.
801
802 @discussion
803
804 If expression evalulates to false, this jumps to a label. No debugging information is printed.
805 */
806
807 #if( DEBUG_OVERRIDE_APPLE_MACROS )
808 #undef require_quiet
809 #endif
810 #if( !defined( require_quiet ) )
811 #define require_quiet( X, LABEL ) \
812 do \
813 { \
814 if( !( X ) ) \
815 { \
816 goto LABEL; \
817 } \
818 \
819 } while( 0 )
820 #endif
821
822 //---------------------------------------------------------------------------------------------------------------------------
823 /*! @defined require_noerr
824
825 @abstract Require that an error code is noErr (0).
826
827 @discussion
828
829 If the error code is non-0, this prints debugging information (actual expression string, file, line number,
830 function name, etc.) using the default debugging output method then jumps to a label.
831 */
832
833 #if( DEBUG_OVERRIDE_APPLE_MACROS )
834 #undef require_noerr
835 #endif
836 #if( !defined( require_noerr ) )
837 #define require_noerr( ERR, LABEL ) \
838 do \
839 { \
840 int_least32_t localErr; \
841 \
842 localErr = (int_least32_t)( ERR ); \
843 if( localErr != 0 ) \
844 { \
845 debug_print_assert( localErr, NULL, NULL, __FILE__, __LINE__, __ROUTINE__ ); \
846 goto LABEL; \
847 } \
848 \
849 } while( 0 )
850 #endif
851
852 //---------------------------------------------------------------------------------------------------------------------------
853 /*! @defined require_noerr_string
854
855 @abstract Require that an error code is noErr (0).
856
857 @discussion
858
859 If the error code is non-0, this prints debugging information (actual expression string, file, line number,
860 function name, etc.), and a custom explanation string using the default debugging output method using the
861 default debugging output method then jumps to a label.
862 */
863
864 #if( DEBUG_OVERRIDE_APPLE_MACROS )
865 #undef require_noerr_string
866 #endif
867 #if( !defined( require_noerr_string ) )
868 #define require_noerr_string( ERR, LABEL, STR ) \
869 do \
870 { \
871 int_least32_t localErr; \
872 \
873 localErr = (int_least32_t)( ERR ); \
874 if( localErr != 0 ) \
875 { \
876 debug_print_assert( localErr, NULL, STR, __FILE__, __LINE__, __ROUTINE__ ); \
877 goto LABEL; \
878 } \
879 \
880 } while( 0 )
881 #endif
882
883 //---------------------------------------------------------------------------------------------------------------------------
884 /*! @defined require_noerr_action_string
885
886 @abstract Require that an error code is noErr (0).
887
888 @discussion
889
890 If the error code is non-0, this prints debugging information (actual expression string, file, line number,
891 function name, etc.), and a custom explanation string using the default debugging output method using the
892 default debugging output method then executes an action and jumps to a label.
893 */
894
895 #if( DEBUG_OVERRIDE_APPLE_MACROS )
896 #undef require_noerr_action_string
897 #endif
898 #if( !defined( require_noerr_action_string ) )
899 #define require_noerr_action_string( ERR, LABEL, ACTION, STR ) \
900 do \
901 { \
902 int_least32_t localErr; \
903 \
904 localErr = (int_least32_t)( ERR ); \
905 if( localErr != 0 ) \
906 { \
907 debug_print_assert( localErr, NULL, STR, __FILE__, __LINE__, __ROUTINE__ ); \
908 { ACTION; } \
909 goto LABEL; \
910 } \
911 \
912 } while( 0 )
913 #endif
914
915 //---------------------------------------------------------------------------------------------------------------------------
916 /*! @defined require_noerr_quiet
917
918 @abstract Require that an error code is noErr (0).
919
920 @discussion
921
922 If the error code is non-0, this jumps to a label. No debugging information is printed.
923 */
924
925 #if( DEBUG_OVERRIDE_APPLE_MACROS )
926 #undef require_noerr_quiet
927 #endif
928 #if( !defined( require_noerr_quiet ) )
929 #define require_noerr_quiet( ERR, LABEL ) \
930 do \
931 { \
932 if( ( ERR ) != 0 ) \
933 { \
934 goto LABEL; \
935 } \
936 \
937 } while( 0 )
938 #endif
939
940 //---------------------------------------------------------------------------------------------------------------------------
941 /*! @defined require_noerr_action
942
943 @abstract Require that an error code is noErr (0) with an action to execute otherwise.
944
945 @discussion
946
947 If the error code is non-0, this prints debugging information (actual expression string, file, line number,
948 function name, etc.) using the default debugging output method then executes an action and jumps to a label.
949 */
950
951 #if( DEBUG_OVERRIDE_APPLE_MACROS )
952 #undef require_noerr_action
953 #endif
954 #if( !defined( require_noerr_action ) )
955 #define require_noerr_action( ERR, LABEL, ACTION ) \
956 do \
957 { \
958 int_least32_t localErr; \
959 \
960 localErr = (int_least32_t)( ERR ); \
961 if( localErr != 0 ) \
962 { \
963 debug_print_assert( localErr, NULL, NULL, __FILE__, __LINE__, __ROUTINE__ ); \
964 { ACTION; } \
965 goto LABEL; \
966 } \
967 \
968 } while( 0 )
969 #endif
970
971 //---------------------------------------------------------------------------------------------------------------------------
972 /*! @defined require_noerr_action_quiet
973
974 @abstract Require that an error code is noErr (0) with an action to execute otherwise.
975
976 @discussion
977
978 If the error code is non-0, this executes an action and jumps to a label. No debugging information is printed.
979 */
980
981 #if( DEBUG_OVERRIDE_APPLE_MACROS )
982 #undef require_noerr_action_quiet
983 #endif
984 #if( !defined( require_noerr_action_quiet ) )
985 #define require_noerr_action_quiet( ERR, LABEL, ACTION ) \
986 do \
987 { \
988 if( ( ERR ) != 0 ) \
989 { \
990 { ACTION; } \
991 goto LABEL; \
992 } \
993 \
994 } while( 0 )
995 #endif
996
997 //---------------------------------------------------------------------------------------------------------------------------
998 /*! @defined require_action
999
1000 @abstract Requires that an expression evaluate to true with an action to execute otherwise.
1001
1002 @discussion
1003
1004 If expression evalulates to false, this prints debugging information (actual expression string, file, line number,
1005 function name, etc.) using the default debugging output method then executes an action and jumps to a label.
1006 */
1007
1008 #if( DEBUG_OVERRIDE_APPLE_MACROS )
1009 #undef require_action
1010 #endif
1011 #if( !defined( require_action ) )
1012 #define require_action( X, LABEL, ACTION ) \
1013 do \
1014 { \
1015 if( !( X ) ) \
1016 { \
1017 debug_print_assert( 0, #X, NULL, __FILE__, __LINE__, __ROUTINE__ ); \
1018 { ACTION; } \
1019 goto LABEL; \
1020 } \
1021 \
1022 } while( 0 )
1023 #endif
1024
1025 //---------------------------------------------------------------------------------------------------------------------------
1026 /*! @defined require_action_quiet
1027
1028 @abstract Requires that an expression evaluate to true with an action to execute otherwise.
1029
1030 @discussion
1031
1032 If expression evalulates to false, this executes an action and jumps to a label. No debugging information is printed.
1033 */
1034
1035 #if( DEBUG_OVERRIDE_APPLE_MACROS )
1036 #undef require_action_quiet
1037 #endif
1038 #if( !defined( require_action_quiet ) )
1039 #define require_action_quiet( X, LABEL, ACTION ) \
1040 do \
1041 { \
1042 if( !( X ) ) \
1043 { \
1044 { ACTION; } \
1045 goto LABEL; \
1046 } \
1047 \
1048 } while( 0 )
1049 #endif
1050
1051 //---------------------------------------------------------------------------------------------------------------------------
1052 /*! @defined require_action_string
1053
1054 @abstract Requires that an expression evaluate to true with an explanation and action to execute otherwise.
1055
1056 @discussion
1057
1058 If expression evalulates to false, this prints debugging information (actual expression string, file, line number,
1059 function name, etc.) and a custom explanation string using the default debugging output method then executes an
1060 action and jumps to a label.
1061 */
1062
1063 #if( DEBUG_OVERRIDE_APPLE_MACROS )
1064 #undef require_action_string
1065 #endif
1066 #if( !defined( require_action_string ) )
1067 #define require_action_string( X, LABEL, ACTION, STR ) \
1068 do \
1069 { \
1070 if( !( X ) ) \
1071 { \
1072 debug_print_assert( 0, #X, STR, __FILE__, __LINE__, __ROUTINE__ ); \
1073 { ACTION; } \
1074 goto LABEL; \
1075 } \
1076 \
1077 } while( 0 )
1078
1079 #endif
1080
1081 //---------------------------------------------------------------------------------------------------------------------------
1082 /*! @defined require_throw
1083
1084 @abstract Requires that an expression evaluates to true or an exception is thrown.
1085
1086 @discussion
1087
1088 If the expression evaluates to false, this prints debugging information (actual expression string, file,
1089 line number, function name, etc.) using the default debugging output method then throws an exception.
1090 */
1091
1092 #if( defined( __cplusplus ) )
1093 #define require_throw( X ) \
1094 do \
1095 { \
1096 if( !( X ) ) \
1097 { \
1098 debug_print_assert( 0, #X, NULL, __FILE__, __LINE__, __ROUTINE__ ); \
1099 throw kUnknownErr; \
1100 } \
1101 \
1102 } while( 0 )
1103 #endif
1104
1105 #if 0
1106 #pragma mark == Design-By-Contract macros ==
1107 #endif
1108
1109 //===========================================================================================================================
1110 // Design-By-Contract macros
1111 //===========================================================================================================================
1112
1113 #define ensure( X ) check( X )
1114 #define ensure_string( X, STR ) check_string( X, STR )
1115 #define ensure_noerr( ERR ) check_noerr( ERR )
1116 #define ensure_noerr_string( ERR, STR ) check_noerr_string( ERR, STR )
1117 #define ensure_translated_errno( TEST, ERRNO, ALTERNATE_ERROR ) check_translated_errno( TEST, ERRNO, ALTERNATE_ERROR )
1118
1119 // Note: Design-By-Contract "require" macros are already defined elsewhere.
1120
1121 #if 0
1122 #pragma mark == Expect macros ==
1123 #endif
1124
1125 //===========================================================================================================================
1126 // Expect macros
1127 //===========================================================================================================================
1128
1129 // Expect macros allow code to include runtime checking of things that should not happen in shipping code (e.g. internal
1130 // programmer errors, such as a NULL parameter where it is not allowed). Once the code has been verified to work correctly
1131 // without asserting, the DEBUG_EXPECT_VERIFIED conditional can be set to eliminate the error checking entirely. It can
1132 // also be useful to measure the cost of error checking code by profiling with it enable and with it disabled.
1133
1134 #if( DEBUG_EXPECT_VERIFIED )
1135 #define require_expect
1136 #define require_string_expect
1137 #define require_quiet_expect
1138 #define require_noerr_expect
1139 #define require_noerr_string_expect
1140 #define require_noerr_action_string_expect
1141 #define require_noerr_quiet_expect
1142 #define require_noerr_action_expect
1143 #define require_noerr_action_quiet_expect
1144 #define require_action_expect
1145 #define require_action_quiet_expect
1146 #define require_action_string_expect
1147 #else
1148 #define require_expect require
1149 #define require_string_expect require_string
1150 #define require_quiet_expect require_quiet
1151 #define require_noerr_expect require_noerr
1152 #define require_noerr_string_expect require_noerr_string
1153 #define require_noerr_action_string_expect require_noerr_action_string
1154 #define require_noerr_quiet_expect require_noerr_quiet
1155 #define require_noerr_action_expect require_noerr_action
1156 #define require_noerr_action_quiet_expect require_noerr_action_quiet
1157 #define require_action_expect require_action
1158 #define require_action_quiet_expect require_action_quiet
1159 #define require_action_string_expect require_action_string
1160 #endif
1161
1162 #if 0
1163 #pragma mark == Output macros ==
1164 #endif
1165
1166 //---------------------------------------------------------------------------------------------------------------------------
1167 /*! @defined debug_string
1168
1169 @abstract Prints a debugging C string.
1170 */
1171
1172 #if( DEBUG_OVERRIDE_APPLE_MACROS )
1173 #undef debug_string
1174 #endif
1175 #if( !defined( debug_string ) )
1176 #if( DEBUG )
1177 #define debug_string( STR ) \
1178 do \
1179 { \
1180 debug_print_assert( 0, NULL, STR, __FILE__, __LINE__, __ROUTINE__ ); \
1181 \
1182 } while( 0 )
1183 #else
1184 #define debug_string( STR )
1185 #endif
1186 #endif
1187
1188 //---------------------------------------------------------------------------------------------------------------------------
1189 /*! @defined debug_print_assert
1190
1191 @abstract Prints an assertion.
1192 */
1193
1194 #if( DEBUG )
1195 #define debug_print_assert( ERROR_CODE, ASSERT_STRING, MESSAGE, FILENAME, LINE_NUMBER, FUNCTION ) \
1196 DebugPrintAssert( ERROR_CODE, ASSERT_STRING, MESSAGE, FILENAME, LINE_NUMBER, FUNCTION )
1197 #else
1198 #define debug_print_assert( ERROR_CODE, ASSERT_STRING, MESSAGE, FILENAME, LINE_NUMBER, FUNCTION )
1199 #endif
1200
1201 //---------------------------------------------------------------------------------------------------------------------------
1202 /*! @defined dlog
1203
1204 @abstract Prints a debug-only message.
1205 */
1206
1207 #if( DEBUG )
1208 #if( DEBUG_C99_VA_ARGS )
1209 #define dlog( ... ) DebugPrintF( __VA_ARGS__ )
1210 #elif( DEBUG_GNU_VA_ARGS )
1211 #define dlog( ARGS... ) DebugPrintF( ## ARGS )
1212 #else
1213 #define dlog DebugPrintF
1214 #endif
1215 #else
1216 #if( DEBUG_C99_VA_ARGS )
1217 #define dlog( ... )
1218 #elif( DEBUG_GNU_VA_ARGS )
1219 #define dlog( ARGS... )
1220 #else
1221 #define dlog while( 0 )
1222 #endif
1223 #endif
1224
1225 //---------------------------------------------------------------------------------------------------------------------------
1226 /*! @defined dlogv
1227
1228 @abstract Prints a debug-only message.
1229 */
1230
1231 #if( DEBUG )
1232 #define dlogv( LEVEL, FORMAT, LIST ) DebugPrintFVAList( ( LEVEL ), ( FORMAT ), ( LIST ) )
1233 #else
1234 #define dlogv( LEVEL, FORMAT, LIST )
1235 #endif
1236
1237 //---------------------------------------------------------------------------------------------------------------------------
1238 /*! @defined dlogmem
1239
1240 @abstract Prints a debug-only dump of memory.
1241 */
1242
1243 #if( DEBUG )
1244 #define dlogmem( LEVEL, PTR, SIZE ) \
1245 DebugHexDump( ( LEVEL ), 0, NULL, 0, 0, NULL, 0, ( PTR ), ( PTR ), ( SIZE ), kDebugFlagsNone, NULL, 0 )
1246 #else
1247 #define dlogmem( LEVEL, PTR, SIZE )
1248 #endif
1249
1250 //---------------------------------------------------------------------------------------------------------------------------
1251 /*! @defined DebugNSLog
1252
1253 @abstract Debug-only macro for the Cocoa NSLog function.
1254 */
1255
1256 #if( DEBUG )
1257 #if( DEBUG_C99_VA_ARGS )
1258 #define DebugNSLog( ... ) NSLog( __VA_ARGS__ )
1259 #elif( DEBUG_GNU_VA_ARGS )
1260 #define DebugNSLog( ARGS... ) NSLog( ## ARGS )
1261 #else
1262 #define DebugNSLog NSLog
1263 #endif
1264 #else
1265 #if( DEBUG_C99_VA_ARGS )
1266 #define DebugNSLog( ... )
1267 #elif( DEBUG_GNU_VA_ARGS )
1268 #define DebugNSLog( ARGS... )
1269 #else
1270 #define DebugNSLog while( 0 )
1271 #endif
1272 #endif
1273
1274 //---------------------------------------------------------------------------------------------------------------------------
1275 /*! @defined DebugLogMsg
1276
1277 @abstract Debug-only macro for the VxWorks logMsg function.
1278 */
1279
1280 #if( TARGET_OS_VXWORKS )
1281 #if( DEBUG )
1282 #define DebugLogMsg( LEVEL, FORMAT, P1, P2, P3, P4, P5, P6 ) \
1283 do \
1284 { \
1285 if( ( inLevel >= gDebugPrintLevelMin ) || ( inLevel <= gDebugPrintLevelMax ) ) \
1286 { \
1287 logMsg( ( FORMAT ), ( P1 ), ( P2 ), ( P3 ), ( P4 ), ( P5 ), ( P6 ) ); \
1288 } \
1289 \
1290 } while( 0 )
1291 #else
1292 #define DebugLogMsg( LEVEL, FORMAT, P1, P2, P3, P4, P5, P6 )
1293 #endif
1294 #else
1295 #define DebugLogMsg dlog
1296 #endif
1297
1298 #if 0
1299 #pragma mark == Routines - General ==
1300 #endif
1301
1302 #ifdef __cplusplus
1303 extern "C" {
1304 #endif
1305
1306 //---------------------------------------------------------------------------------------------------------------------------
1307 /*! @function DebugInitialize
1308
1309 @abstract Initializes the debugging library for a specific kind of output.
1310
1311 @param inType
1312 @param varArg Variable number parameters, controlled by the "inType" parameter.
1313 */
1314
1315 #if( DEBUG )
1316 DEBUG_EXPORT OSStatus DebugInitialize( DebugOutputType inType, ... );
1317 #endif
1318
1319 #if( DEBUG )
1320 #if( DEBUG_C99_VA_ARGS )
1321 #define debug_initialize( ... ) DebugInitialize( __VA_ARGS__ )
1322 #elif( DEBUG_GNU_VA_ARGS )
1323 #define debug_initialize( ARGS... ) DebugInitialize( ## ARGS )
1324 #else
1325 #define debug_initialize DebugInitialize
1326 #endif
1327 #else
1328 #if( DEBUG_C99_VA_ARGS )
1329 #define debug_initialize( ... )
1330 #elif( DEBUG_GNU_VA_ARGS )
1331 #define debug_initialize( ARGS... )
1332 #else
1333 #define debug_initialize while( 0 )
1334 #endif
1335 #endif
1336
1337 //---------------------------------------------------------------------------------------------------------------------------
1338 /*! @function DebugFinalize
1339
1340 @abstract Releases any resources used by the debugging library
1341 */
1342
1343 #if( DEBUG )
1344 DEBUG_EXPORT void DebugFinalize( void );
1345 #endif
1346
1347 #if( DEBUG )
1348 #define debug_terminate() DebugFinalize()
1349 #else
1350 #define debug_terminate()
1351 #endif
1352
1353 //---------------------------------------------------------------------------------------------------------------------------
1354 /*! @function DebugGetProperty
1355
1356 @abstract Gets the specified property from the debugging library.
1357 */
1358
1359 #if( DEBUG )
1360 DEBUG_EXPORT OSStatus DebugGetProperty( DebugPropertyTag inTag, ... );
1361 #endif
1362
1363 #if( DEBUG )
1364 #if( DEBUG_C99_VA_ARGS )
1365 #define debug_get_property( ... ) DebugGetProperty( __VA_ARGS__ )
1366 #elif( DEBUG_GNU_VA_ARGS )
1367 #define debug_get_property( ARGS... ) DebugGetProperty( ## ARGS )
1368 #else
1369 #define debug_get_property DebugGetProperty
1370 #endif
1371 #else
1372 #if( DEBUG_C99_VA_ARGS )
1373 #define debug_get_property( ... )
1374 #elif( DEBUG_GNU_VA_ARGS )
1375 #define debug_get_property( ARGS... )
1376 #else
1377 #define debug_get_property while( 0 )
1378 #endif
1379 #endif
1380
1381 //---------------------------------------------------------------------------------------------------------------------------
1382 /*! @function DebugSetProperty
1383
1384 @abstract Sets the specified property from the debugging library.
1385 */
1386
1387 #if( DEBUG )
1388 DEBUG_EXPORT OSStatus DebugSetProperty( DebugPropertyTag inTag, ... );
1389 #endif
1390
1391 #if( DEBUG )
1392 #if( DEBUG_C99_VA_ARGS )
1393 #define debug_set_property( ... ) DebugSetProperty( __VA_ARGS__ )
1394 #elif( DEBUG_GNU_VA_ARGS )
1395 #define debug_set_property( ARGS... ) DebugSetProperty( ## ARGS )
1396 #else
1397 #define debug_set_property DebugSetProperty
1398 #endif
1399 #else
1400 #if( DEBUG_C99_VA_ARGS )
1401 #define debug_set_property( ... )
1402 #elif( DEBUG_GNU_VA_ARGS )
1403 #define debug_set_property( ARGS... )
1404 #else
1405 #define debug_set_property while( 0 )
1406 #endif
1407 #endif
1408
1409 #if 0
1410 #pragma mark == Routines - Debugging Output ==
1411 #endif
1412
1413 //---------------------------------------------------------------------------------------------------------------------------
1414 /*! @function DebugPrintF
1415
1416 @abstract Prints a debug message with printf-style formatting.
1417
1418 @param inLevel Error that generated this assert or noErr.
1419
1420 @param inFormatString
1421 C string containing assertion text.
1422
1423 @param VAR_ARG
1424 Variable number of arguments depending on the format string.
1425
1426 @result Number of bytes printed or -1 on error.
1427 */
1428
1429 #if( DEBUG )
1430 DEBUG_EXPORT size_t DebugPrintF( DebugLevel inLevel, const char *inFormat, ... );
1431 #endif
1432
1433 //---------------------------------------------------------------------------------------------------------------------------
1434 /*! @function DebugPrintFVAList
1435
1436 @abstract va_list version of DebugPrintF. See DebugPrintF for more info.
1437 */
1438
1439 #if( DEBUG )
1440 DEBUG_EXPORT size_t DebugPrintFVAList( DebugLevel inLevel, const char *inFormat, va_list inArgs );
1441 #endif
1442
1443 //---------------------------------------------------------------------------------------------------------------------------
1444 /*! @function DebugPrintAssert
1445
1446 @abstract Prints a message describing the reason the (e.g. an assert failed), an optional error message,
1447 an optional source filename, an optional source line number.
1448
1449 @param inErrorCode Error that generated this assert or noErr.
1450 @param inAssertString C string containing assertion text.
1451 @param inMessage C string containing a message about the assert.
1452 @param inFileName C string containing path of file where the error occurred.
1453 @param inLineNumber Line number in source file where the error occurred.
1454 @param inFunction C string containing name of function where assert occurred.
1455
1456 @discussion
1457
1458 Example output:
1459
1460 [ASSERT] assert: "dataPtr != NULL" allocate memory for object failed
1461 [ASSERT] where: "MyFile.c", line 123, ("MyFunction")
1462
1463 OR
1464
1465 [ASSERT] error: -6728 (kNoMemoryErr)
1466 [ASSERT] where: "MyFile.c", line 123, ("MyFunction")
1467 */
1468
1469 #if( DEBUG )
1470 DEBUG_EXPORT void
1471 DebugPrintAssert(
1472 int_least32_t inErrorCode,
1473 const char * inAssertString,
1474 const char * inMessage,
1475 const char * inFilename,
1476 int_least32_t inLineNumber,
1477 const char * inFunction );
1478 #endif
1479
1480 #if 0
1481 #pragma mark == Routines - Utilities ==
1482 #endif
1483
1484 //---------------------------------------------------------------------------------------------------------------------------
1485 /*! @function DebugSNPrintF
1486
1487 @abstract Debugging versions of standard C snprintf with extra features.
1488
1489 @param sbuffer Buffer to receive result. Null terminated unless the buffer size is 0.
1490 @param buflen Size of the buffer including space for the null terminator.
1491 @param fmt printf-style format string.
1492 @param VAR_ARG Variable number of arguments depending on the format string.
1493
1494 @result Number of characters written (minus the null terminator).
1495
1496 @discussion
1497
1498 Extra features over the standard C snprintf:
1499 <pre>
1500 64-bit support for %d (%lld), %i (%lli), %u (%llu), %o (%llo), %x (%llx), and %b (%llb).
1501 %@ - Cocoa/CoreFoundation object. Param is the object. Strings are used directly. Others use CFCopyDescription.
1502 %a - Network Address: %.4a=IPv4, %.6a=Ethernet, %.8a Fibre Channel, %.16a=IPv6. Arg=ptr to network address.
1503 %#a - IPv4 or IPv6 mDNSAddr. Arg=ptr to mDNSAddr.
1504 %##a - IPv4 (if AF_INET defined) or IPv6 (if AF_INET6 defined) sockaddr. Arg=ptr to sockaddr.
1505 %b - Binary representation of integer (e.g. 01101011). Modifiers and arg=the same as %d, %x, etc.
1506 %C - Mac-style FourCharCode (e.g. 'APPL'). Arg=32-bit value to print as a Mac-style FourCharCode.
1507 %H - Hex Dump (e.g. "\x6b\xa7" -> "6B A7"). 1st arg=ptr, 2nd arg=size, 3rd arg=max size.
1508 %#H - Hex Dump & ASCII (e.g. "\x41\x62" -> "6B A7 'Ab'"). 1st arg=ptr, 2nd arg=size, 3rd arg=max size.
1509 %m - Error Message (e.g. 0 -> "kNoErr"). Modifiers and error code arg=the same as %d, %x, etc.
1510 %#s - Pascal-style length-prefixed string. Arg=ptr to string.
1511 %##s - DNS label-sequence name. Arg=ptr to name.
1512 %S - UTF-16 string, 0x0000 terminated. Host order if no BOM. Precision is UTF-16 count. Precision includes BOM.
1513 %#S - Big Endian UTF-16 string (unless BOM overrides). Otherwise, the same as %S.
1514 %##S - Little Endian UTF-16 string (unless BOM overrides). Otherwise, the same as %S.
1515 %U - Universally Unique Identifier (UUID) (e.g. 6ba7b810-9dad-11d1-80b4-00c04fd430c8). Arg=ptr to 16-byte UUID.
1516 </pre>
1517 */
1518
1519 #if( DEBUG )
1520 DEBUG_EXPORT size_t DebugSNPrintF(char *sbuffer, size_t buflen, const char *fmt, ...);
1521 #endif
1522
1523 //---------------------------------------------------------------------------------------------------------------------------
1524 /*! @function DebugSNPrintFVAList
1525
1526 @abstract va_list version of DebugSNPrintF. See DebugSNPrintF for more info.
1527 */
1528
1529 #if( DEBUG )
1530 DEBUG_EXPORT size_t DebugSNPrintFVAList(char *sbuffer, size_t buflen, const char *fmt, va_list arg);
1531 #endif
1532
1533 //---------------------------------------------------------------------------------------------------------------------------
1534 /*! @function DebugGetErrorString
1535
1536 @abstract Gets an error string from an error code.
1537
1538 @param inStatus Error code to get the string for.
1539 @param inBuffer Optional buffer to copy the string to for non-static strings. May be null.
1540 @param inBufferSize Size of optional buffer. May be 0.
1541
1542 @result C string containing error string for the error code. Guaranteed to be a valid, static string. If a
1543 buffer is supplied, the return value will always be a pointer to the supplied buffer, which will
1544 contain the best available description of the error code. If a buffer is not supplied, the return
1545 value will be the best available description of the error code that can be represented as a static
1546 string. This allows code that cannot use a temporary buffer to hold the result to still get a useful
1547 error string in most cases, but also allows code that can use a temporary buffer to get the best
1548 available description.
1549 */
1550
1551 #if( DEBUG )
1552 DEBUG_EXPORT const char * DebugGetErrorString( int_least32_t inErrorCode, char *inBuffer, size_t inBufferSize );
1553 #endif
1554
1555 //---------------------------------------------------------------------------------------------------------------------------
1556 /*! @function DebugHexDump
1557
1558 @abstract Hex dumps data to a string or to the output device.
1559 */
1560
1561 #if( DEBUG )
1562 DEBUG_EXPORT size_t
1563 DebugHexDump(
1564 DebugLevel inLevel,
1565 int inIndent,
1566 const char * inLabel,
1567 size_t inLabelSize,
1568 int inLabelMinWidth,
1569 const char * inType,
1570 size_t inTypeSize,
1571 const void * inDataStart,
1572 const void * inData,
1573 size_t inDataSize,
1574 DebugFlags inFlags,
1575 char * outBuffer,
1576 size_t inBufferSize );
1577 #endif
1578
1579 #if( DEBUG )
1580 #define dloghex( LEVEL, INDENT, LABEL, LABEL_SIZE, LABEL_MIN_SIZE, TYPE, TYPE_SIZE, DATA_START, DATA, DATA_SIZE, FLAGS, BUFFER, BUFFER_SIZE ) \
1581 DebugHexDump( ( LEVEL ), (INDENT), ( LABEL ), ( LABEL_SIZE ), ( LABEL_MIN_SIZE ), ( TYPE ), ( TYPE_SIZE ), \
1582 ( DATA_START ), ( DATA ), ( DATA_SIZE ), ( FLAGS ), ( BUFFER ), ( BUFFER_SIZE ) )
1583 #else
1584 #define dloghex( LEVEL, INDENT, LABEL, LABEL_SIZE, LABEL_MIN_SIZE, TYPE, TYPE_SIZE, DATA_START, DATA, DATA_SIZE, FLAGS, BUFFER, BUFFER_SIZE )
1585 #endif
1586
1587 //---------------------------------------------------------------------------------------------------------------------------
1588 /*! @function DebugTaskLevel
1589
1590 @abstract Returns the current task level.
1591
1592 @result Current task level
1593
1594 @discussion
1595
1596 Bit masks to isolate portions of the result (note that some masks may also need bit shifts to right justify):
1597 <pre>
1598 kDebugInterruptLevelMask - Indicates the current interrupt level (> 0 means interrupt time).
1599 kDebugInVBLTaskMask - Indicates if a VBL task is currently being executed.
1600 kDebugInDeferredTaskMask - Indicates if a Deferred Task is currently being executed.
1601 kDebugInSecondaryInterruptHandlerMask - Indicates if a Secondary Interrupt Handler is currently being executed.
1602 kDebugPageFaultFatalMask - Indicates if it is unsafe to cause a page fault (worse than interrupt time).
1603 kDebugMPTaskLevelMask - Indicates if being called from an MP task.
1604 kDebugInterruptDepthMask - 0 means task level, 1 means in interrupt, > 1 means in nested interrupt.
1605 </pre>
1606
1607 Helpers:
1608 <pre>
1609 DebugExtractTaskLevelInterruptDepth() - Macro to extract interrupt depth from task level value.
1610 </pre>
1611 */
1612
1613 #if( DEBUG )
1614 DEBUG_EXPORT uint32_t DebugTaskLevel( void );
1615 #endif
1616
1617 //---------------------------------------------------------------------------------------------------------------------------
1618 /*! @function DebugServicesTest
1619
1620 @abstract Unit test.
1621 */
1622
1623 #if( DEBUG )
1624 DEBUG_EXPORT OSStatus DebugServicesTest( void );
1625 #endif
1626
1627 #ifdef __cplusplus
1628 }
1629 #endif
1630
1631 #endif // __DEBUG_SERVICES__