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