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