bump product version to 5.0.4.1
[LibreOffice.git] / sd / source / ui / remotecontrol / mDNSResponder / DebugServices.c
blob7f57d88705aa4680550940a9342eccf71a3a0fe6
1 /* -*- Mode: C; tab-width: 4 -*-
3 * Copyright (c) 1997-2004 Apple Computer, Inc. All rights reserved.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 To Do:
19 - Use StackWalk on Windows to optionally print stack frames.
22 #if 0
23 #pragma mark == Includes ==
24 #endif
27 // Includes
28 #if ( !KERNEL )
29 #include <ctype.h>
30 #include <stdio.h>
31 #include <string.h>
32 #endif
34 #include "CommonServices.h"
36 #include "DebugServices.h"
38 #if ( DEBUG )
40 #if ( TARGET_OS_VXWORKS )
41 #include "intLib.h"
42 #endif
44 #if ( TARGET_OS_WIN32 )
45 #include <time.h>
47 #if ( !TARGET_OS_WINDOWS_CE )
48 #include <fcntl.h>
49 #include <io.h>
50 #endif
51 #endif
53 #if ( DEBUG_IDEBUG_ENABLED && TARGET_API_MAC_OSX_KERNEL )
54 #include <IOKit/IOLib.h>
55 #endif
57 // If MDNS_DEBUGMSGS is defined (even if defined 0), it is aware of mDNS and it is probably safe to include mDNSEmbeddedAPI.h.
58 #if ( defined( MDNS_DEBUGMSGS ) )
59 #include "mDNSEmbeddedAPI.h"
60 #endif
62 #if 0
63 #pragma mark == Macros ==
64 #endif
67 // Macros
68 #define DebugIsPrint( C ) ( ( ( C ) >= 0x20 ) && ( ( C ) <= 0x7E ) )
70 #if 0
71 #pragma mark == Prototypes ==
72 #endif
75 // Prototypes
76 static OSStatus DebugPrint( DebugLevel inLevel, char *inData, size_t inSize );
78 // fprintf
79 #if ( DEBUG_FPRINTF_ENABLED )
80 static OSStatus DebugFPrintFInit( DebugOutputTypeFlags inFlags, const char *inFilename );
81 static void DebugFPrintFPrint( char *inData, size_t inSize );
82 #endif
84 // iDebug (Mac OS X user and kernel)
85 #if ( DEBUG_IDEBUG_ENABLED )
86 static OSStatus DebugiDebugInit( void );
87 static void DebugiDebugPrint( char *inData, size_t inSize );
88 #endif
90 // kprintf (Mac OS X Kernel)
91 #if ( DEBUG_KPRINTF_ENABLED )
92 static void DebugKPrintFPrint( char *inData, size_t inSize );
93 #endif
95 // Mac OS X IOLog (Mac OS X Kernel)
96 #if ( DEBUG_MAC_OS_X_IOLOG_ENABLED )
97 static void DebugMacOSXIOLogPrint( char *inData, size_t inSize );
98 #endif
100 // Mac OS X Log
101 #if ( TARGET_OS_MAC )
102 static OSStatus DebugMacOSXLogInit( void );
103 static void DebugMacOSXLogPrint( char *inData, size_t inSize );
104 #endif
106 // Windows Debugger
107 #if ( TARGET_OS_WIN32 )
108 static void DebugWindowsDebuggerPrint( char *inData, size_t inSize );
109 #endif
111 // Windows Event Log
112 #if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
113 static OSStatus DebugWindowsEventLogInit( const char *inName, HMODULE inModule );
114 static void DebugWindowsEventLogPrint( DebugLevel inLevel, char *inData, size_t inSize );
115 #endif
117 // DebugLib support
118 #if ( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
119 static pascal void
120 DebugAssertOutputHandler(
121 OSType inComponentSignature,
122 UInt32 inOptions,
123 const char * inAssertionString,
124 const char * inExceptionString,
125 const char * inErrorString,
126 const char * inFileName,
127 long inLineNumber,
128 void * inValue,
129 ConstStr255Param inOutputMsg );
130 #endif
132 // Utilities
133 static char * DebugNumVersionToString( uint32_t inVersion, char *inString );
135 #if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
136 static void DebugWinEnableConsole( void );
137 #endif
139 #if ( TARGET_OS_WIN32 )
140 static TCHAR *
141 DebugWinCharToTCharString(
142 const char * inCharString,
143 size_t inCharCount,
144 TCHAR * outTCharString,
145 size_t inTCharCountMax,
146 size_t * outTCharCount );
147 #endif
149 #if 0
150 #pragma mark == Globals ==
151 #endif
154 // Private Globals
155 #if ( TARGET_OS_VXWORKS )
156 // TCP States for inetstatShow.
158 extern char ** pTcpstates; // defined in tcpLib.c
160 const char * kDebugTCPStates[] =
162 "(0) TCPS_CLOSED",
163 "(1) TCPS_LISTEN",
164 "(2) TCPS_SYN_SENT",
165 "(3) TCPS_SYN_RECEIVED",
166 "(4) TCPS_ESTABLISHED",
167 "(5) TCPS_CLOSE_WAIT",
168 "(6) TCPS_FIN_WAIT_1",
169 "(7) TCPS_CLOSING",
170 "(8) TCPS_LAST_ACK",
171 "(9) TCPS_FIN_WAIT_2",
172 "(10) TCPS_TIME_WAIT",
174 #endif
176 // General
177 static bool gDebugInitialized = false;
178 static DebugOutputType gDebugOutputType = kDebugOutputTypeNone;
179 static DebugLevel gDebugPrintLevelMin = kDebugLevelInfo;
180 static DebugLevel gDebugPrintLevelMax = kDebugLevelMax;
181 static DebugLevel gDebugBreakLevel = kDebugLevelAssert;
182 #if ( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
183 static DebugAssertOutputHandlerUPP gDebugAssertOutputHandlerUPP = NULL;
184 #endif
186 // Custom
187 static DebugOutputFunctionPtr gDebugCustomOutputFunction = NULL;
188 static void * gDebugCustomOutputContext = NULL;
190 // fprintf
192 #if ( DEBUG_FPRINTF_ENABLED )
193 static FILE * gDebugFPrintFFile = NULL;
194 #endif
196 // MacOSXLog
197 #if ( TARGET_OS_MAC )
198 typedef int ( *DebugMacOSXLogFunctionPtr )( const char *inFormat, ... );
200 static DebugMacOSXLogFunctionPtr gDebugMacOSXLogFunction = NULL;
201 #endif
203 // WindowsEventLog
204 #if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
205 static HANDLE gDebugWindowsEventLogEventSource = NULL;
206 #endif
208 #if 0
209 #pragma mark -
210 #pragma mark == General ==
211 #endif
214 // DebugInitialize
215 DEBUG_EXPORT OSStatus DebugInitialize( DebugOutputType inType, ... )
217 OSStatus err;
218 DebugOutputType type;
219 va_list args;
221 va_start( args, inType );
223 #if ( TARGET_OS_VXWORKS )
224 // Set up the TCP state strings if they are not already set up by VxWorks (normally not set up for some reason).
226 if( !pTcpstates )
228 pTcpstates = (char **) kDebugTCPStates;
230 #endif
232 // Set up DebugLib stuff (if building with Debugging.h).
234 #if ( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
235 if( !gDebugAssertOutputHandlerUPP )
237 gDebugAssertOutputHandlerUPP = NewDebugAssertOutputHandlerUPP( DebugAssertOutputHandler );
238 check( gDebugAssertOutputHandlerUPP );
239 if( gDebugAssertOutputHandlerUPP )
241 InstallDebugAssertOutputHandler( gDebugAssertOutputHandlerUPP );
244 #endif
246 // Pre-process meta-output kind to pick an appropriate output kind for the platform.
248 type = inType;
249 if( type == kDebugOutputTypeMetaConsole )
251 #if ( TARGET_OS_MAC )
252 type = kDebugOutputTypeMacOSXLog;
253 #elif ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
254 #if ( DEBUG_FPRINTF_ENABLED )
255 type = kDebugOutputTypeFPrintF;
256 #else
257 type = kDebugOutputTypeWindowsDebugger;
258 #endif
259 #elif ( TARGET_API_MAC_OSX_KERNEL )
260 #if ( DEBUG_MAC_OS_X_IOLOG_ENABLED )
261 type = kDebugOutputTypeMacOSXIOLog;
262 #elif ( DEBUG_IDEBUG_ENABLED )
263 type = kDebugOutputTypeiDebug;
264 #elif ( DEBUG_KPRINTF_ENABLED )
265 type = kDebugOutputTypeKPrintF;
266 #endif
267 #elif ( TARGET_OS_VXWORKS )
268 #if ( DEBUG_FPRINTF_ENABLED )
269 type = kDebugOutputTypeFPrintF;
270 #else
271 #error target is VxWorks, but fprintf output is disabled
272 #endif
273 #else
274 #if ( DEBUG_FPRINTF_ENABLED )
275 type = kDebugOutputTypeFPrintF;
276 #endif
277 #endif
280 // Process output kind
281 gDebugOutputType = type;
282 switch( type )
284 case kDebugOutputTypeNone:
285 err = kNoErr;
286 break;
288 case kDebugOutputTypeCustom:
289 gDebugCustomOutputFunction = va_arg( args, DebugOutputFunctionPtr );
290 gDebugCustomOutputContext = va_arg( args, void * );
291 err = kNoErr;
292 break;
294 #if ( DEBUG_FPRINTF_ENABLED )
295 case kDebugOutputTypeFPrintF:
296 if( inType == kDebugOutputTypeMetaConsole )
298 err = DebugFPrintFInit( kDebugOutputTypeFlagsStdErr, NULL );
300 else
302 DebugOutputTypeFlags flags;
303 const char * filename;
305 flags = (DebugOutputTypeFlags) va_arg( args, unsigned int );
306 if( ( flags & kDebugOutputTypeFlagsTypeMask ) == kDebugOutputTypeFlagsFile )
308 filename = va_arg( args, const char * );
310 else
312 filename = NULL;
314 err = DebugFPrintFInit( flags, filename );
316 break;
317 #endif
319 #if ( DEBUG_IDEBUG_ENABLED )
320 case kDebugOutputTypeiDebug:
321 err = DebugiDebugInit();
322 break;
323 #endif
325 #if ( DEBUG_KPRINTF_ENABLED )
326 case kDebugOutputTypeKPrintF:
327 err = kNoErr;
328 break;
329 #endif
331 #if ( DEBUG_MAC_OS_X_IOLOG_ENABLED )
332 case kDebugOutputTypeMacOSXIOLog:
333 err = kNoErr;
334 break;
335 #endif
337 #if ( TARGET_OS_MAC )
338 case kDebugOutputTypeMacOSXLog:
339 err = DebugMacOSXLogInit();
340 break;
341 #endif
343 #if ( TARGET_OS_WIN32 )
344 case kDebugOutputTypeWindowsDebugger:
345 err = kNoErr;
346 break;
347 #endif
349 #if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
350 case kDebugOutputTypeWindowsEventLog:
352 const char * name;
353 HMODULE module;
355 name = va_arg( args, const char * );
356 module = va_arg( args, HMODULE );
357 err = DebugWindowsEventLogInit( name, module );
359 break;
360 #endif
362 default:
363 err = kParamErr;
364 goto exit;
366 gDebugInitialized = true;
368 exit:
369 va_end( args );
370 return err;
374 // DebugFinalize
375 DEBUG_EXPORT void DebugFinalize( void )
377 #if ( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
378 check( gDebugAssertOutputHandlerUPP );
379 if( gDebugAssertOutputHandlerUPP )
381 InstallDebugAssertOutputHandler( NULL );
382 DisposeDebugAssertOutputHandlerUPP( gDebugAssertOutputHandlerUPP );
383 gDebugAssertOutputHandlerUPP = NULL;
385 #endif
389 // DebugGetProperty
390 DEBUG_EXPORT OSStatus DebugGetProperty( DebugPropertyTag inTag, ... )
392 OSStatus err;
393 va_list args;
394 DebugLevel * level;
396 va_start( args, inTag );
397 switch( inTag )
399 case kDebugPropertyTagPrintLevelMin:
400 level = va_arg( args, DebugLevel * );
401 *level = gDebugPrintLevelMin;
402 err = kNoErr;
403 break;
405 case kDebugPropertyTagPrintLevelMax:
406 level = va_arg( args, DebugLevel * );
407 *level = gDebugPrintLevelMax;
408 err = kNoErr;
409 break;
411 case kDebugPropertyTagBreakLevel:
412 level = va_arg( args, DebugLevel * );
413 *level = gDebugBreakLevel;
414 err = kNoErr;
415 break;
417 default:
418 err = kUnsupportedErr;
419 break;
421 va_end( args );
422 return err;
426 // DebugSetProperty
427 DEBUG_EXPORT OSStatus DebugSetProperty( DebugPropertyTag inTag, ... )
429 OSStatus err;
430 va_list args;
431 DebugLevel level;
433 va_start( args, inTag );
434 switch( inTag )
436 case kDebugPropertyTagPrintLevelMin:
437 level = va_arg( args, DebugLevel );
438 gDebugPrintLevelMin = level;
439 err = kNoErr;
440 break;
442 case kDebugPropertyTagPrintLevelMax:
443 level = va_arg( args, DebugLevel );
444 gDebugPrintLevelMax = level;
445 err = kNoErr;
446 break;
448 case kDebugPropertyTagBreakLevel:
449 level = va_arg( args, DebugLevel );
450 gDebugBreakLevel = level;
451 err = kNoErr;
452 break;
454 default:
455 err = kUnsupportedErr;
456 break;
458 va_end( args );
459 return err;
462 #if 0
463 #pragma mark -
464 #pragma mark == Output ==
465 #endif
468 // DebugPrintF
469 DEBUG_EXPORT size_t DebugPrintF( DebugLevel inLevel, const char *inFormat, ... )
471 va_list args;
472 size_t n;
474 // Skip if the level is not in the enabled range..
476 if( ( inLevel < gDebugPrintLevelMin ) || ( inLevel > gDebugPrintLevelMax ) )
478 n = 0;
479 goto exit;
482 va_start( args, inFormat );
483 n = DebugPrintFVAList( inLevel, inFormat, args );
484 va_end( args );
486 exit:
487 return n;
491 // DebugPrintFVAList
492 DEBUG_EXPORT size_t DebugPrintFVAList( DebugLevel inLevel, const char *inFormat, va_list inArgs )
494 size_t n;
495 char buffer[ 512 ];
497 // Skip if the level is not in the enabled range..
499 if( ( inLevel < gDebugPrintLevelMin ) || ( inLevel > gDebugPrintLevelMax ) )
501 n = 0;
502 goto exit;
505 n = DebugSNPrintFVAList( buffer, sizeof( buffer ), inFormat, inArgs );
506 DebugPrint( inLevel, buffer, (size_t) n );
508 exit:
509 return n;
513 // DebugPrint
514 static OSStatus DebugPrint( DebugLevel inLevel, char *inData, size_t inSize )
516 OSStatus err;
518 // Skip if the level is not in the enabled range..
520 if( ( inLevel < gDebugPrintLevelMin ) || ( inLevel > gDebugPrintLevelMax ) )
522 err = kRangeErr;
523 goto exit;
526 // Printing is not safe at interrupt time so check for this and warn with an interrupt safe mechanism (if available).
528 if( DebugTaskLevel() & kDebugInterruptLevelMask )
530 #if ( TARGET_OS_VXWORKS )
531 logMsg( "\ncannot print at interrupt time\n\n", 1, 2, 3, 4, 5, 6 );
532 #endif
534 err = kExecutionStateErr;
535 goto exit;
538 // Initialize the debugging library if it hasn't already been initialized (allows for zero-config usage).
540 if( !gDebugInitialized )
542 debug_initialize( kDebugOutputTypeMetaConsole );
545 // Print based on the current output type.
547 switch( gDebugOutputType )
549 case kDebugOutputTypeNone:
550 break;
552 case kDebugOutputTypeCustom:
553 if( gDebugCustomOutputFunction )
555 gDebugCustomOutputFunction( inData, inSize, gDebugCustomOutputContext );
557 break;
559 #if ( DEBUG_FPRINTF_ENABLED )
560 case kDebugOutputTypeFPrintF:
561 DebugFPrintFPrint( inData, inSize );
562 break;
563 #endif
565 #if ( DEBUG_IDEBUG_ENABLED )
566 case kDebugOutputTypeiDebug:
567 DebugiDebugPrint( inData, inSize );
568 break;
569 #endif
571 #if ( DEBUG_KPRINTF_ENABLED )
572 case kDebugOutputTypeKPrintF:
573 DebugKPrintFPrint( inData, inSize );
574 break;
575 #endif
577 #if ( DEBUG_MAC_OS_X_IOLOG_ENABLED )
578 case kDebugOutputTypeMacOSXIOLog:
579 DebugMacOSXIOLogPrint( inData, inSize );
580 break;
581 #endif
583 #if ( TARGET_OS_MAC )
584 case kDebugOutputTypeMacOSXLog:
585 DebugMacOSXLogPrint( inData, inSize );
586 break;
587 #endif
589 #if ( TARGET_OS_WIN32 )
590 case kDebugOutputTypeWindowsDebugger:
591 DebugWindowsDebuggerPrint( inData, inSize );
592 break;
593 #endif
595 #if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
596 case kDebugOutputTypeWindowsEventLog:
597 DebugWindowsEventLogPrint( inLevel, inData, inSize );
598 break;
599 #endif
601 default:
602 break;
604 err = kNoErr;
606 exit:
607 return err;
611 // DebugPrintAssert
613 // Warning: This routine relies on several of the strings being string constants that will exist forever because the
614 // underlying logMsg API that does the printing is asynchronous so it cannot use temporary/stack-based
615 // pointer variables (e.g. local strings). The debug macros that invoke this function only use constant
616 // constant strings, but if this function is invoked directly from other places, it must use constant strings.
617 DEBUG_EXPORT void
618 DebugPrintAssert(
619 int_least32_t inErrorCode,
620 const char * inAssertString,
621 const char * inMessage,
622 const char * inFilename,
623 int_least32_t inLineNumber,
624 const char * inFunction )
626 // Skip if the level is not in the enabled range..
627 if( ( kDebugLevelAssert < gDebugPrintLevelMin ) || ( kDebugLevelAssert > gDebugPrintLevelMax ) )
629 return;
632 if( inErrorCode != 0 )
634 DebugPrintF(
635 kDebugLevelAssert,
636 "\n"
637 "[ASSERT] error: %ld (%m)\n"
638 "[ASSERT] where: \"%s\", line %ld, \"%s\"\n"
639 "\n",
640 inErrorCode, inErrorCode,
641 inFilename ? inFilename : "",
642 inLineNumber,
643 inFunction ? inFunction : "" );
645 else
647 DebugPrintF(
648 kDebugLevelAssert,
649 "\n"
650 "[ASSERT] assert: \"%s\" %s\n"
651 "[ASSERT] where: \"%s\", line %ld, \"%s\"\n"
652 "\n",
653 inAssertString ? inAssertString : "",
654 inMessage ? inMessage : "",
655 inFilename ? inFilename : "",
656 inLineNumber,
657 inFunction ? inFunction : "" );
660 // Break into the debugger if enabled
661 #if ( TARGET_OS_WIN32 )
662 if( gDebugBreakLevel <= kDebugLevelAssert )
664 if( IsDebuggerPresent() )
666 DebugBreak();
669 #endif
672 #if 0
673 #pragma mark -
674 #endif
676 #if ( DEBUG_FPRINTF_ENABLED )
678 // DebugFPrintFInit
679 static OSStatus DebugFPrintFInit( DebugOutputTypeFlags inFlags, const char *inFilename )
681 OSStatus err;
682 DebugOutputTypeFlags typeFlags;
684 typeFlags = inFlags & kDebugOutputTypeFlagsTypeMask;
685 if( typeFlags == kDebugOutputTypeFlagsStdOut )
687 #if ( TARGET_OS_WIN32 )
688 DebugWinEnableConsole();
689 #endif
691 gDebugFPrintFFile = stdout;
693 else if( typeFlags == kDebugOutputTypeFlagsStdErr )
695 #if ( TARGET_OS_WIN32 )
696 DebugWinEnableConsole();
697 #endif
699 gDebugFPrintFFile = stdout;
701 else if( typeFlags == kDebugOutputTypeFlagsFile )
703 require_action_quiet( inFilename && ( *inFilename != '\0' ), exit, err = kOpenErr );
705 gDebugFPrintFFile = fopen( inFilename, "a" );
706 require_action_quiet( gDebugFPrintFFile, exit, err = kOpenErr );
708 else
710 err = kParamErr;
711 goto exit;
713 err = kNoErr;
715 exit:
716 return err;
720 // DebugFPrintFPrint
721 static void DebugFPrintFPrint( char *inData, size_t inSize )
723 char * p;
724 char * q;
726 // Convert \r to \n. fprintf will interpret \n and convert to whatever is appropriate for the platform.
727 p = inData;
728 q = p + inSize;
729 while( p < q )
731 if( *p == '\r' )
733 *p = '\n';
735 ++p;
738 // Write the data and flush.
739 if( gDebugFPrintFFile )
741 fprintf( gDebugFPrintFFile, "%.*s", (int) inSize, inData );
742 fflush( gDebugFPrintFFile );
745 #endif // DEBUG_FPRINTF_ENABLED
747 #if ( DEBUG_IDEBUG_ENABLED )
749 // DebugiDebugInit
750 static OSStatus DebugiDebugInit( void )
752 OSStatus err;
754 #if ( TARGET_API_MAC_OSX_KERNEL )
756 extern uint32_t * _giDebugReserved1;
758 // Emulate the iDebugSetOutputType macro in iDebugServices.h.
759 // Note: This is not thread safe, but neither is iDebugServices.h nor iDebugKext.
760 if( !_giDebugReserved1 )
762 _giDebugReserved1 = (uint32_t *) IOMalloc( sizeof( uint32_t ) );
763 require_action_quiet( _giDebugReserved1, exit, err = kNoMemoryErr );
765 *_giDebugReserved1 = 0x00010000U;
766 err = kNoErr;
767 exit:
768 #else
770 __private_extern__ void iDebugSetOutputTypeInternal( uint32_t inType );
772 iDebugSetOutputTypeInternal( 0x00010000U );
773 err = kNoErr;
775 #endif
777 return err;
781 // DebugiDebugPrint
782 static void DebugiDebugPrint( char *inData, size_t inSize )
784 #if ( TARGET_API_MAC_OSX_KERNEL )
786 // Locally declared here so we do not need to include iDebugKext.h.
787 // Note: IOKit uses a global namespace for all code and only a partial link occurs at build time. When the
788 // KEXT is loaded, the runtime linker will link in this extern'd symbol (assuming iDebug is present).
789 // _giDebugLogInternal is actually part of IOKit proper so this should link even if iDebug is not present.
791 typedef void ( *iDebugLogFunctionPtr )( uint32_t inLevel, uint32_t inTag, const char *inFormat, ... );
793 extern iDebugLogFunctionPtr _giDebugLogInternal;
795 if( _giDebugLogInternal )
797 _giDebugLogInternal( 0, 0, "%.*s", (int) inSize, inData );
800 #else
802 __private_extern__ void iDebugLogInternal( uint32_t inLevel, uint32_t inTag, const char *inFormat, ... );
804 iDebugLogInternal( 0, 0, "%.*s", (int) inSize, inData );
806 #endif
808 #endif
810 #if ( DEBUG_KPRINTF_ENABLED )
812 // DebugKPrintFPrint
813 static void DebugKPrintFPrint( char *inData, size_t inSize )
815 extern void kprintf( const char *inFormat, ... );
817 kprintf( "%.*s", (int) inSize, inData );
819 #endif
821 #if ( DEBUG_MAC_OS_X_IOLOG_ENABLED )
823 // DebugMacOSXIOLogPrint
824 static void DebugMacOSXIOLogPrint( char *inData, size_t inSize )
826 extern void IOLog( const char *inFormat, ... );
828 IOLog( "%.*s", (int) inSize, inData );
830 #endif
832 #if ( TARGET_OS_MAC )
834 // DebugMacOSXLogInit
835 static OSStatus DebugMacOSXLogInit( void )
837 OSStatus err;
838 CFStringRef path;
839 CFURLRef url;
840 CFBundleRef bundle;
841 CFStringRef functionName;
842 void * functionPtr;
844 bundle = NULL;
846 // Create a bundle reference for System.framework.
848 path = CFSTR( "/System/Library/Frameworks/System.framework" );
849 url = CFURLCreateWithFileSystemPath( NULL, path, kCFURLPOSIXPathStyle, true );
850 require_action_quiet( url, exit, err = memFullErr );
852 bundle = CFBundleCreate( NULL, url );
853 CFRelease( url );
854 require_action_quiet( bundle, exit, err = memFullErr );
856 // Get a ptr to the system's "printf" function from System.framework.
858 functionName = CFSTR( "printf" );
859 functionPtr = CFBundleGetFunctionPointerForName( bundle, functionName );
860 require_action_quiet( functionPtr, exit, err = memFullErr );
862 // Success! Note: The bundle cannot be released because it would invalidate the function ptr.
864 gDebugMacOSXLogFunction = (DebugMacOSXLogFunctionPtr) functionPtr;
865 bundle = NULL;
866 err = noErr;
868 exit:
869 if( bundle )
871 CFRelease( bundle );
873 return err;
876 // DebugMacOSXLogPrint
877 static void DebugMacOSXLogPrint( char *inData, size_t inSize )
879 if( gDebugMacOSXLogFunction )
881 gDebugMacOSXLogFunction( "%.*s", (int) inSize, inData );
884 #endif
886 #if ( TARGET_OS_WIN32 )
888 // DebugWindowsDebuggerPrint
889 void DebugWindowsDebuggerPrint( char *inData, size_t inSize )
891 TCHAR buffer[ 512 ];
892 const char * src;
893 const char * end;
894 TCHAR * dst;
895 char c;
897 // Copy locally and null terminate the string. This also converts from char to TCHAR in case we are
898 // building with UNICODE enabled since the input is always char. Also convert \r to \n in the process.
899 src = inData;
900 if( inSize >= sizeof_array( buffer ) )
902 inSize = sizeof_array( buffer ) - 1;
904 end = src + inSize;
905 dst = buffer;
906 while( src < end )
908 c = *src++;
909 if( c == '\r' )
911 c = '\n';
913 *dst++ = (TCHAR) c;
915 *dst = 0;
917 // Print out the string to the debugger.
918 OutputDebugString( buffer );
920 #endif
922 #if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
924 // DebugWindowsEventLogInit
925 static OSStatus DebugWindowsEventLogInit( const char *inName, HMODULE inModule )
927 OSStatus err;
928 HKEY key;
929 TCHAR name[ 128 ];
930 const char * src;
931 TCHAR path[ MAX_PATH ];
932 size_t size;
933 DWORD typesSupported;
934 DWORD n;
936 key = NULL;
938 // Use a default name if needed then convert the name to TCHARs so it works on ANSI or Unicode builds.
939 if( !inName || ( *inName == '\0' ) )
941 inName = "DefaultApp";
943 DebugWinCharToTCharString( inName, kSizeCString, name, sizeof( name ), NULL );
945 // Build the path string using the fixed registry path and app name.
946 src = "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\";
947 DebugWinCharToTCharString( src, kSizeCString, path, sizeof_array( path ), &size );
948 DebugWinCharToTCharString( inName, kSizeCString, path + size, sizeof_array( path ) - size, NULL );
950 // Add/Open the source name as a sub-key under the Application key in the EventLog registry key.
951 err = RegCreateKeyEx( HKEY_LOCAL_MACHINE, path, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, NULL );
952 require_noerr_quiet( err, exit );
954 // Set the path in the EventMessageFile subkey. Add 1 to the TCHAR count to include the null terminator.
955 n = GetModuleFileName( inModule, path, sizeof_array( path ) );
956 err = translate_errno( n > 0, (OSStatus) GetLastError(), kParamErr );
957 require_noerr_quiet( err, exit );
958 n += 1;
959 n *= sizeof( TCHAR );
961 err = RegSetValueEx( key, TEXT( "EventMessageFile" ), 0, REG_EXPAND_SZ, (const LPBYTE) path, n );
962 require_noerr_quiet( err, exit );
964 // Set the supported event types in the TypesSupported subkey.
965 typesSupported = EVENTLOG_SUCCESS | EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE |
966 EVENTLOG_AUDIT_SUCCESS | EVENTLOG_AUDIT_FAILURE;
967 err = RegSetValueEx( key, TEXT( "TypesSupported" ), 0, REG_DWORD, (const LPBYTE) &typesSupported, sizeof( DWORD ) );
968 require_noerr_quiet( err, exit );
970 // Set up the event source.
971 gDebugWindowsEventLogEventSource = RegisterEventSource( NULL, name );
972 err = translate_errno( gDebugWindowsEventLogEventSource, (OSStatus) GetLastError(), kParamErr );
973 require_noerr_quiet( err, exit );
975 exit:
976 if( key )
978 RegCloseKey( key );
980 return err;
984 // DebugWindowsEventLogPrint
985 static void DebugWindowsEventLogPrint( DebugLevel inLevel, char *inData, size_t inSize )
987 WORD type;
988 TCHAR buffer[ 512 ];
989 const char * src;
990 const char * end;
991 TCHAR * dst;
992 char c;
993 const TCHAR * array[ 1 ];
995 // Map the debug level to a Windows EventLog type
996 if( inLevel <= kDebugLevelNotice )
998 type = EVENTLOG_INFORMATION_TYPE;
1000 else if( inLevel <= kDebugLevelWarning )
1002 type = EVENTLOG_WARNING_TYPE;
1004 else
1006 type = EVENTLOG_ERROR_TYPE;
1009 // Copy locally and null terminate the string. This also converts from char to TCHAR in case we are
1010 // building with UNICODE enabled since the input is always char. Also convert \r to \n in the process.
1011 src = inData;
1012 if( inSize >= sizeof_array( buffer ) )
1014 inSize = sizeof_array( buffer ) - 1;
1016 end = src + inSize;
1017 dst = buffer;
1018 while( src < end )
1020 c = *src++;
1021 if( c == '\r' )
1023 c = '\n';
1025 *dst++ = (TCHAR) c;
1027 *dst = 0;
1029 // Add the string to the event log.
1030 array[ 0 ] = buffer;
1031 if( gDebugWindowsEventLogEventSource )
1033 ReportEvent( gDebugWindowsEventLogEventSource, type, 0, 0x20000001L, NULL, 1, 0, array, NULL );
1036 #endif // TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE
1038 #if ( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
1040 // DebugAssertOutputHandler
1041 static pascal void
1042 DebugAssertOutputHandler(
1043 OSType inComponentSignature,
1044 UInt32 inOptions,
1045 const char * inAssertString,
1046 const char * inExceptionString,
1047 const char * inErrorString,
1048 const char * inFileName,
1049 long inLineNumber,
1050 void * inValue,
1051 ConstStr255Param inOutputMsg )
1053 DEBUG_UNUSED( inComponentSignature );
1054 DEBUG_UNUSED( inOptions );
1055 DEBUG_UNUSED( inExceptionString );
1056 DEBUG_UNUSED( inValue );
1057 DEBUG_UNUSED( inOutputMsg );
1059 DebugPrintAssert( 0, inAssertString, inErrorString, inFileName, (int_least32_t) inLineNumber, "" );
1061 #endif
1063 #if 0
1064 #pragma mark -
1065 #pragma mark == Utilities ==
1066 #endif
1069 // DebugSNPrintF
1071 // Stolen from mDNS.c's mDNS_snprintf/mDNS_vsnprintf with the following changes:
1073 // Changed names to avoid name collisions with the mDNS versions.
1074 // Changed types to standard C types since mDNSEmbeddedAPI.h may not be available.
1075 // Conditionalized mDNS stuff so it can be used with or with mDNSEmbeddedAPI.h.
1076 // Added 64-bit support for %d (%lld), %i (%lli), %u (%llu), %o (%llo), %x (%llx), and %b (%llb).
1077 // Added %@ - Cocoa/CoreFoundation object. Param is the object. Strings are used directly. Others use CFCopyDescription.
1078 // Added %.8a - FIbre Channel address. Arg=ptr to address.
1079 // Added %##a - IPv4 (if AF_INET defined) or IPv6 (if AF_INET6 defined) sockaddr. Arg=ptr to sockaddr.
1080 // Added %b - Binary representation of integer (e.g. 01101011). Modifiers and arg=the same as %d, %x, etc.
1081 // Added %C - Mac-style FourCharCode (e.g. 'APPL'). Arg=32-bit value to print as a Mac-style FourCharCode.
1082 // Added %H - Hex Dump (e.g. "\x6b\xa7" -> "6B A7"). 1st arg=ptr, 2nd arg=size, 3rd arg=max size.
1083 // Added %#H - Hex Dump & ASCII (e.g. "\x41\x62" -> "6B A7 'Ab'"). 1st arg=ptr, 2nd arg=size, 3rd arg=max size.
1084 // Added %m - Error Message (e.g. 0 -> "kNoErr"). Modifiers and error code args are the same as %d, %x, etc.
1085 // Added %S - UTF-16 string. Host order if no BOM. Precision is UTF-16 char count. BOM counts in any precision. Arg=ptr.
1086 // Added %#S - Big Endian UTF-16 string (unless BOM overrides). Otherwise the same as %S.
1087 // Added %##S - Little Endian UTF-16 string (unless BOM overrides). Otherwise the same as %S.
1088 // Added %U - Universally Unique Identifier (UUID) (e.g. 6ba7b810-9dad-11d1-80b4-00c04fd430c8). Arg=ptr to 16-byte UUID.
1091 DEBUG_EXPORT size_t DebugSNPrintF(char *sbuffer, size_t buflen, const char *fmt, ...)
1093 size_t length;
1095 va_list ptr;
1096 va_start(ptr,fmt);
1097 length = DebugSNPrintFVAList(sbuffer, buflen, fmt, ptr);
1098 va_end(ptr);
1100 return length;
1104 // DebugSNPrintFVAList - va_list version of DebugSNPrintF. See DebugSNPrintF for more info.
1105 DEBUG_EXPORT size_t DebugSNPrintFVAList(char *sbuffer, size_t buflen, const char *fmt, va_list arg)
1107 static const struct DebugSNPrintF_format
1109 unsigned leftJustify : 1;
1110 unsigned forceSign : 1;
1111 unsigned zeroPad : 1;
1112 unsigned havePrecision : 1;
1113 unsigned hSize : 1;
1114 char lSize;
1115 char altForm;
1116 char sign; // +, - or space
1117 unsigned int fieldWidth;
1118 unsigned int precision;
1119 } DebugSNPrintF_format_default = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1121 size_t nwritten = 0;
1122 int c;
1123 if (buflen == 0) return 0;
1124 buflen--; // Pre-reserve one space in the buffer for the terminating nul
1125 if (buflen == 0) goto exit;
1127 for (c = *fmt; c != 0; c = *++fmt)
1129 if (c != '%')
1131 *sbuffer++ = (char)c;
1132 if (++nwritten >= buflen) goto exit;
1134 else
1136 size_t i=0, j;
1137 // The mDNS Vsprintf Argument Conversion Buffer is used as a temporary holding area for
1138 // generating decimal numbers, hexdecimal numbers, IP addresses, domain name strings, etc.
1139 // The size needs to be enough for a 256-byte domain name plus some error text.
1140 #define mDNS_VACB_Size 300
1141 char mDNS_VACB[mDNS_VACB_Size];
1142 #define mDNS_VACB_Lim (&mDNS_VACB[mDNS_VACB_Size])
1143 #define mDNS_VACB_Remain(s) ((size_t)(mDNS_VACB_Lim - s))
1144 char *s = mDNS_VACB_Lim;
1145 const char *digits = "0123456789ABCDEF";
1146 struct DebugSNPrintF_format F = DebugSNPrintF_format_default;
1148 for(;;) // decode flags
1150 c = *++fmt;
1151 if (c == '-') F.leftJustify = 1;
1152 else if (c == '+') F.forceSign = 1;
1153 else if (c == ' ') F.sign = ' ';
1154 else if (c == '#') F.altForm++;
1155 else if (c == '0') F.zeroPad = 1;
1156 else break;
1159 if (c == '*') // decode field width
1161 int f = va_arg(arg, int);
1162 if (f < 0) { f = -f; F.leftJustify = 1; }
1163 F.fieldWidth = (unsigned int)f;
1164 c = *++fmt;
1166 else
1168 for (; c >= '0' && c <= '9'; c = *++fmt)
1169 F.fieldWidth = (10 * F.fieldWidth) + (c - '0');
1172 if (c == '.') // decode precision
1174 if ((c = *++fmt) == '*')
1175 { F.precision = va_arg(arg, unsigned int); c = *++fmt; }
1176 else for (; c >= '0' && c <= '9'; c = *++fmt)
1177 F.precision = (10 * F.precision) + (c - '0');
1178 F.havePrecision = 1;
1181 if (F.leftJustify) F.zeroPad = 0;
1183 conv:
1184 switch (c) // perform appropriate conversion
1186 #if TYPE_LONGLONG_NATIVE
1187 unsigned_long_long_compat n;
1188 unsigned_long_long_compat base;
1189 #else
1190 unsigned long n;
1191 unsigned long base;
1192 #endif
1193 case 'h': F.hSize = 1; c = *++fmt; goto conv;
1194 case 'l': // fall through
1195 case 'L': F.lSize++; c = *++fmt; goto conv;
1196 case 'd':
1197 case 'i': base = 10;
1198 goto canBeSigned;
1199 case 'u': base = 10;
1200 goto notSigned;
1201 case 'o': base = 8;
1202 goto notSigned;
1203 case 'b': base = 2;
1204 goto notSigned;
1205 case 'p': n = va_arg(arg, uintptr_t);
1206 F.havePrecision = 1;
1207 F.precision = (sizeof(uintptr_t) == 4) ? 8 : 16;
1208 F.sign = 0;
1209 base = 16;
1210 c = 'x';
1211 goto number;
1212 case 'x': digits = "0123456789abcdef";
1213 case 'X': base = 16;
1214 goto notSigned;
1215 canBeSigned:
1216 #if TYPE_LONGLONG_NATIVE
1217 if (F.lSize == 1) n = (unsigned_long_long_compat)va_arg(arg, long);
1218 else if (F.lSize == 2) n = (unsigned_long_long_compat)va_arg(arg, long_long_compat);
1219 else n = (unsigned_long_long_compat)va_arg(arg, int);
1220 #else
1221 if (F.lSize == 1) n = (unsigned long)va_arg(arg, long);
1222 else if (F.lSize == 2) goto exit;
1223 else n = (unsigned long)va_arg(arg, int);
1224 #endif
1225 if (F.hSize) n = (short) n;
1226 #if TYPE_LONGLONG_NATIVE
1227 if ((long_long_compat) n < 0) { n = (unsigned_long_long_compat)-(long_long_compat)n; F.sign = '-'; }
1228 #else
1229 if ((long) n < 0) { n = (unsigned long)-(long)n; F.sign = '-'; }
1230 #endif
1231 else if (F.forceSign) F.sign = '+';
1232 goto number;
1234 notSigned: if (F.lSize == 1) n = va_arg(arg, unsigned long);
1235 else if (F.lSize == 2)
1237 #if TYPE_LONGLONG_NATIVE
1238 n = va_arg(arg, unsigned_long_long_compat);
1239 #else
1240 goto exit;
1241 #endif
1243 else n = va_arg(arg, unsigned int);
1244 if (F.hSize) n = (unsigned short) n;
1245 F.sign = 0;
1246 goto number;
1248 number: if (!F.havePrecision)
1250 if (F.zeroPad)
1252 F.precision = F.fieldWidth;
1253 if (F.altForm) F.precision -= 2;
1254 if (F.sign) --F.precision;
1256 if (F.precision < 1) F.precision = 1;
1258 if (F.precision > mDNS_VACB_Size - 1)
1259 F.precision = mDNS_VACB_Size - 1;
1260 for (i = 0; n; n /= base, i++) *--s = (char)(digits[n % base]);
1261 for (; i < F.precision; i++) *--s = '0';
1262 if (F.altForm) { *--s = (char)c; *--s = '0'; i += 2; }
1263 if (F.sign) { *--s = F.sign; i++; }
1264 break;
1266 case 'a': {
1267 unsigned char *a = va_arg(arg, unsigned char *);
1268 char pre[4] = "";
1269 char post[32] = "";
1270 if (!a) { static char emsg[] = "<<NULL>>"; s = emsg; i = sizeof(emsg)-1; }
1271 else
1273 s = mDNS_VACB; // Adjust s to point to the start of the buffer, not the end
1274 if (F.altForm == 1)
1276 #if (defined(MDNS_DEBUGMSGS))
1277 mDNSAddr *ip = (mDNSAddr*)a;
1278 switch (ip->type)
1280 case mDNSAddrType_IPv4: F.precision = 4; a = (unsigned char *)&ip->ip.v4; break;
1281 case mDNSAddrType_IPv6: F.precision = 16; a = (unsigned char *)&ip->ip.v6; break;
1282 default: F.precision = 0; break;
1284 #else
1285 F.precision = 0; // mDNSEmbeddedAPI.h not included so no mDNSAddr support
1286 #endif
1288 else if (F.altForm == 2)
1290 #ifdef AF_INET
1291 const struct sockaddr *sa;
1292 unsigned char *port;
1293 sa = (const struct sockaddr*)a;
1294 switch (sa->sa_family)
1296 case AF_INET: F.precision = 4; a = (unsigned char*)&((const struct sockaddr_in *)a)->sin_addr;
1297 port = (unsigned char*)&((const struct sockaddr_in *)sa)->sin_port;
1298 DebugSNPrintF(post, sizeof(post), ":%d", (port[0] << 8) | port[1]); break;
1299 #ifdef AF_INET6
1300 case AF_INET6: F.precision = 16; a = (unsigned char*)&((const struct sockaddr_in6 *)a)->sin6_addr;
1301 pre[0] = '['; pre[1] = '\0';
1302 port = (unsigned char*)&((const struct sockaddr_in6 *)sa)->sin6_port;
1303 DebugSNPrintF(post, sizeof(post), "%%%d]:%d",
1304 (int)((const struct sockaddr_in6 *)sa)->sin6_scope_id,
1305 (port[0] << 8) | port[1]); break;
1306 #endif
1307 default: F.precision = 0; break;
1309 #else
1310 F.precision = 0; // socket interfaces not included so no sockaddr support
1311 #endif
1313 switch (F.precision)
1315 case 4: i = DebugSNPrintF(mDNS_VACB, sizeof(mDNS_VACB), "%d.%d.%d.%d%s",
1316 a[0], a[1], a[2], a[3], post); break;
1317 case 6: i = DebugSNPrintF(mDNS_VACB, sizeof(mDNS_VACB), "%02X:%02X:%02X:%02X:%02X:%02X",
1318 a[0], a[1], a[2], a[3], a[4], a[5]); break;
1319 case 8: i = DebugSNPrintF(mDNS_VACB, sizeof(mDNS_VACB), "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
1320 a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]); break;
1321 case 16: i = DebugSNPrintF(mDNS_VACB, sizeof(mDNS_VACB),
1322 "%s%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X%s",
1323 pre, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8],
1324 a[9], a[10], a[11], a[12], a[13], a[14], a[15], post); break;
1325 default: i = DebugSNPrintF(mDNS_VACB, sizeof(mDNS_VACB), "%s", "<< ERROR: Must specify address size "
1326 "(i.e. %.4a=IPv4, %.6a=Ethernet, %.8a=Fibre Channel %.16a=IPv6) >>"); break;
1330 break;
1332 case 'U': {
1333 unsigned char *a = va_arg(arg, unsigned char *);
1334 if (!a) { static char emsg[] = "<<NULL>>"; s = emsg; i = sizeof(emsg)-1; }
1335 else
1337 s = mDNS_VACB; // Adjust s to point to the start of the buffer, not the end
1338 i = DebugSNPrintF(mDNS_VACB, sizeof(mDNS_VACB), "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
1339 *((uint32_t*) &a[0]), *((uint16_t*) &a[4]), *((uint16_t*) &a[6]),
1340 a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); break;
1343 break;
1345 case 'c': *--s = (char)va_arg(arg, int); i = 1; break;
1347 case 'C': if (F.lSize) n = va_arg(arg, unsigned long);
1348 else n = va_arg(arg, unsigned int);
1349 if (F.hSize) n = (unsigned short) n;
1350 c = (int)( n & 0xFF); *--s = (char)(DebugIsPrint(c) ? c : '^');
1351 c = (int)((n >> 8) & 0xFF); *--s = (char)(DebugIsPrint(c) ? c : '^');
1352 c = (int)((n >> 16) & 0xFF); *--s = (char)(DebugIsPrint(c) ? c : '^');
1353 c = (int)((n >> 24) & 0xFF); *--s = (char)(DebugIsPrint(c) ? c : '^');
1354 i = 4;
1355 break;
1357 case 's': s = va_arg(arg, char *);
1358 if (!s) { static char emsg[] = "<<NULL>>"; s = emsg; i = sizeof(emsg)-1; }
1359 else switch (F.altForm)
1361 case 0: i=0;
1362 if (F.havePrecision) // C string
1364 while((i < F.precision) && s[i]) i++;
1365 // Make sure we don't truncate in the middle of a UTF-8 character.
1366 // If the last character is part of a multi-byte UTF-8 character, back up to the start of it.
1367 j=0;
1368 while((i > 0) && ((c = s[i-1]) & 0x80)) { j++; i--; if((c & 0xC0) != 0x80) break;}
1369 // If the actual count of UTF-8 characters matches the encoded UTF-8 count, add it back.
1370 if((j > 1) && (j <= 6))
1372 int test = (0xFF << (8-j)) & 0xFF;
1373 int mask = test | (1 << ((8-j)-1));
1374 if((c & mask) == test) i += j;
1377 else
1378 while(s[i]) i++;
1379 break;
1380 case 1: i = (unsigned char) *s++; break; // Pascal string
1381 case 2: { // DNS label-sequence name
1382 unsigned char *a = (unsigned char *)s;
1383 s = mDNS_VACB; // Adjust s to point to the start of the buffer, not the end
1384 if (*a == 0) *s++ = '.'; // Special case for root DNS name
1385 while (*a)
1387 if (*a > 63) { s += DebugSNPrintF(s, mDNS_VACB_Remain(s), "<<INVALID LABEL LENGTH %u>>", *a); break; }
1388 if (s + *a >= &mDNS_VACB[254]) { s += DebugSNPrintF(s, mDNS_VACB_Remain(s), "<<NAME TOO LONG>>"); break; }
1389 s += DebugSNPrintF(s, mDNS_VACB_Remain(s), "%#s.", a);
1390 a += 1 + *a;
1392 i = (size_t)(s - mDNS_VACB);
1393 s = mDNS_VACB; // Reset s back to the start of the buffer
1394 break;
1397 if (F.havePrecision && i > F.precision) // Make sure we don't truncate in the middle of a UTF-8 character
1398 { i = F.precision; while (i>0 && (s[i] & 0xC0) == 0x80) i--;}
1399 break;
1401 case 'S': { // UTF-16 string
1402 unsigned char *a = va_arg(arg, unsigned char *);
1403 uint16_t *u = (uint16_t*)a;
1404 if (!u) { static char emsg[] = "<<NULL>>"; s = emsg; i = sizeof(emsg)-1; }
1405 if ((!F.havePrecision || F.precision))
1407 if ((a[0] == 0xFE) && (a[1] == 0xFF)) { F.altForm = 1; u += 1; a += 2; F.precision--; } // Big Endian
1408 else if ((a[0] == 0xFF) && (a[1] == 0xFE)) { F.altForm = 2; u += 1; a += 2; F.precision--; } // Little Endian
1410 s = mDNS_VACB; // Adjust s to point to the start of the buffer, not the end
1411 switch (F.altForm)
1413 case 0: while ((!F.havePrecision || (i < F.precision)) && u[i] && mDNS_VACB_Remain(s)) // Host Endian
1414 { c = u[i]; *s++ = (char)(DebugIsPrint(c) ? c : '^'); i++; }
1415 break;
1416 case 1: while ((!F.havePrecision || (i < F.precision)) && u[i] && mDNS_VACB_Remain(s)) // Big Endian
1417 { c = ((a[0] << 8) | a[1]) & 0xFF; *s++ = (char)(DebugIsPrint(c) ? c : '^'); i++; a += 2; }
1418 break;
1419 case 2: while ((!F.havePrecision || (i < F.precision)) && u[i] && mDNS_VACB_Remain(s)) // Little Endian
1420 { c = ((a[1] << 8) | a[0]) & 0xFF; *s++ = (char)(DebugIsPrint(c) ? c : '^'); i++; a += 2; }
1421 break;
1424 s = mDNS_VACB; // Reset s back to the start of the buffer
1425 break;
1427 #if TARGET_OS_MAC
1428 case '@': { // Cocoa/CoreFoundation object
1429 CFTypeRef cfObj;
1430 CFStringRef cfStr;
1431 cfObj = (CFTypeRef) va_arg(arg, void *);
1432 cfStr = (CFGetTypeID(cfObj) == CFStringGetTypeID()) ? (CFStringRef)CFRetain(cfObj) : CFCopyDescription(cfObj);
1433 s = mDNS_VACB; // Adjust s to point to the start of the buffer, not the end
1434 if (cfStr)
1436 CFRange range;
1437 CFIndex m;
1438 range = CFRangeMake(0, CFStringGetLength(cfStr));
1439 m = 0;
1440 CFStringGetBytes(cfStr, range, kCFStringEncodingUTF8, '^', false, (UInt8*)mDNS_VACB, (CFIndex)sizeof(mDNS_VACB), &m);
1441 CFRelease(cfStr);
1442 i = (size_t) m;
1444 else
1446 i = DebugSNPrintF(mDNS_VACB, sizeof(mDNS_VACB), "%s", "ERROR: <invalid CF object>" );
1449 if (F.havePrecision && i > F.precision) // Make sure we don't truncate in the middle of a UTF-8 character
1450 { i = F.precision; while (i>0 && (s[i] & 0xC0) == 0x80) i--;}
1451 break;
1452 #endif
1454 case 'm': { // Error Message
1455 long err;
1456 if (F.lSize) err = va_arg(arg, long);
1457 else err = va_arg(arg, int);
1458 if (F.hSize) err = (short)err;
1459 DebugGetErrorString(err, mDNS_VACB, sizeof(mDNS_VACB));
1460 s = mDNS_VACB; // Adjust s to point to the start of the buffer, not the end
1461 for(i=0; s[i]; i++) {}
1463 break;
1465 case 'H': { // Hex Dump
1466 void *a = va_arg(arg, void *);
1467 size_t size = (size_t)va_arg(arg, int);
1468 size_t max = (size_t)va_arg(arg, int);
1469 DebugFlags flags =
1470 kDebugFlagsNoAddress | kDebugFlagsNoOffset | kDebugFlagsNoNewLine |
1471 kDebugFlags8BitSeparator | kDebugFlagsNo32BitSeparator |
1472 kDebugFlagsNo16ByteHexPad | kDebugFlagsNoByteCount;
1473 if (F.altForm == 0) flags |= kDebugFlagsNoASCII;
1474 size = (max < size) ? max : size;
1475 s = mDNS_VACB; // Adjust s to point to the start of the buffer, not the end
1476 i = DebugHexDump(kDebugLevelMax, 0, NULL, 0, 0, NULL, 0, a, a, size, flags, mDNS_VACB, sizeof(mDNS_VACB));
1478 break;
1480 case 'v': { // Version
1481 uint32_t version;
1482 version = va_arg(arg, unsigned int);
1483 DebugNumVersionToString(version, mDNS_VACB);
1484 s = mDNS_VACB; // Adjust s to point to the start of the buffer, not the end
1485 for(i=0; s[i]; i++) {}
1487 break;
1489 case 'n': s = va_arg(arg, char *);
1490 if (F.hSize) *(short *) s = (short)nwritten;
1491 else if (F.lSize) *(long *) s = (long)nwritten;
1492 else *(int *) s = (int)nwritten;
1493 continue;
1495 default: s = mDNS_VACB;
1496 i = DebugSNPrintF(mDNS_VACB, sizeof(mDNS_VACB), "<<UNKNOWN FORMAT CONVERSION CODE %%%c>>", c);
1498 case '%': *sbuffer++ = (char)c;
1499 if (++nwritten >= buflen) goto exit;
1500 break;
1503 if (i < F.fieldWidth && !F.leftJustify) // Pad on the left
1504 do {
1505 *sbuffer++ = ' ';
1506 if (++nwritten >= buflen) goto exit;
1507 } while (i < --F.fieldWidth);
1509 if (i > buflen - nwritten) // Make sure we don't truncate in the middle of a UTF-8 character
1510 { i = buflen - nwritten; while (i>0 && (s[i] & 0xC0) == 0x80) i--;}
1511 for (j=0; j<i; j++) *sbuffer++ = *s++; // Write the converted result
1512 nwritten += i;
1513 if (nwritten >= buflen) goto exit;
1515 for (; i < F.fieldWidth; i++) // Pad on the right
1517 *sbuffer++ = ' ';
1518 if (++nwritten >= buflen) goto exit;
1522 exit:
1523 *sbuffer++ = 0;
1524 return nwritten;
1528 // DebugGetErrorString
1529 DEBUG_EXPORT const char * DebugGetErrorString( int_least32_t inErrorCode, char *inBuffer, size_t inBufferSize )
1531 const char * s;
1532 char * dst;
1533 char * end;
1534 #if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
1535 char buffer[ 256 ];
1536 #endif
1538 switch( inErrorCode )
1540 #define CaseErrorString( X, STR ) case X: s = STR; break
1541 #define CaseErrorStringify( X ) case X: s = # X; break
1542 #define CaseErrorStringifyHardCode( VALUE, X ) case VALUE: s = # X; break
1544 // General Errors
1546 CaseErrorString( 0, "no error" );
1547 CaseErrorString( 1, "in-progress/waiting" );
1548 CaseErrorString( -1, "catch-all unknown error" );
1550 // ACP Errors
1552 CaseErrorStringifyHardCode( -2, kACPBadRequestErr );
1553 CaseErrorStringifyHardCode( -3, kACPNoMemoryErr );
1554 CaseErrorStringifyHardCode( -4, kACPBadParamErr );
1555 CaseErrorStringifyHardCode( -5, kACPNotFoundErr );
1556 CaseErrorStringifyHardCode( -6, kACPBadChecksumErr );
1557 CaseErrorStringifyHardCode( -7, kACPCommandNotHandledErr );
1558 CaseErrorStringifyHardCode( -8, kACPNetworkErr );
1559 CaseErrorStringifyHardCode( -9, kACPDuplicateCommandHandlerErr );
1560 CaseErrorStringifyHardCode( -10, kACPUnknownPropertyErr );
1561 CaseErrorStringifyHardCode( -11, kACPImmutablePropertyErr );
1562 CaseErrorStringifyHardCode( -12, kACPBadPropertyValueErr );
1563 CaseErrorStringifyHardCode( -13, kACPNoResourcesErr );
1564 CaseErrorStringifyHardCode( -14, kACPBadOptionErr );
1565 CaseErrorStringifyHardCode( -15, kACPBadSizeErr );
1566 CaseErrorStringifyHardCode( -16, kACPBadPasswordErr );
1567 CaseErrorStringifyHardCode( -17, kACPNotInitializedErr );
1568 CaseErrorStringifyHardCode( -18, kACPNonReadablePropertyErr );
1569 CaseErrorStringifyHardCode( -19, kACPBadVersionErr );
1570 CaseErrorStringifyHardCode( -20, kACPBadSignatureErr );
1571 CaseErrorStringifyHardCode( -21, kACPBadIndexErr );
1572 CaseErrorStringifyHardCode( -22, kACPUnsupportedErr );
1573 CaseErrorStringifyHardCode( -23, kACPInUseErr );
1574 CaseErrorStringifyHardCode( -24, kACPParamCountErr );
1575 CaseErrorStringifyHardCode( -25, kACPIDErr );
1576 CaseErrorStringifyHardCode( -26, kACPFormatErr );
1577 CaseErrorStringifyHardCode( -27, kACPUnknownUserErr );
1578 CaseErrorStringifyHardCode( -28, kACPAccessDeniedErr );
1579 CaseErrorStringifyHardCode( -29, kACPIncorrectFWErr );
1581 // Common Services Errors
1583 CaseErrorStringify( kUnknownErr );
1584 CaseErrorStringify( kOptionErr );
1585 CaseErrorStringify( kSelectorErr );
1586 CaseErrorStringify( kExecutionStateErr );
1587 CaseErrorStringify( kPathErr );
1588 CaseErrorStringify( kParamErr );
1589 CaseErrorStringify( kParamCountErr );
1590 CaseErrorStringify( kCommandErr );
1591 CaseErrorStringify( kIDErr );
1592 CaseErrorStringify( kStateErr );
1593 CaseErrorStringify( kRangeErr );
1594 CaseErrorStringify( kRequestErr );
1595 CaseErrorStringify( kResponseErr );
1596 CaseErrorStringify( kChecksumErr );
1597 CaseErrorStringify( kNotHandledErr );
1598 CaseErrorStringify( kVersionErr );
1599 CaseErrorStringify( kSignatureErr );
1600 CaseErrorStringify( kFormatErr );
1601 CaseErrorStringify( kNotInitializedErr );
1602 CaseErrorStringify( kAlreadyInitializedErr );
1603 CaseErrorStringify( kNotInUseErr );
1604 CaseErrorStringify( kInUseErr );
1605 CaseErrorStringify( kTimeoutErr );
1606 CaseErrorStringify( kCanceledErr );
1607 CaseErrorStringify( kAlreadyCanceledErr );
1608 CaseErrorStringify( kCannotCancelErr );
1609 CaseErrorStringify( kDeletedErr );
1610 CaseErrorStringify( kNotFoundErr );
1611 CaseErrorStringify( kNoMemoryErr );
1612 CaseErrorStringify( kNoResourcesErr );
1613 CaseErrorStringify( kDuplicateErr );
1614 CaseErrorStringify( kImmutableErr );
1615 CaseErrorStringify( kUnsupportedDataErr );
1616 CaseErrorStringify( kIntegrityErr );
1617 CaseErrorStringify( kIncompatibleErr );
1618 CaseErrorStringify( kUnsupportedErr );
1619 CaseErrorStringify( kUnexpectedErr );
1620 CaseErrorStringify( kValueErr );
1621 CaseErrorStringify( kNotReadableErr );
1622 CaseErrorStringify( kNotWritableErr );
1623 CaseErrorStringify( kBadReferenceErr );
1624 CaseErrorStringify( kFlagErr );
1625 CaseErrorStringify( kMalformedErr );
1626 CaseErrorStringify( kSizeErr );
1627 CaseErrorStringify( kNameErr );
1628 CaseErrorStringify( kNotReadyErr );
1629 CaseErrorStringify( kReadErr );
1630 CaseErrorStringify( kWriteErr );
1631 CaseErrorStringify( kMismatchErr );
1632 CaseErrorStringify( kDateErr );
1633 CaseErrorStringify( kUnderrunErr );
1634 CaseErrorStringify( kOverrunErr );
1635 CaseErrorStringify( kEndingErr );
1636 CaseErrorStringify( kConnectionErr );
1637 CaseErrorStringify( kAuthenticationErr );
1638 CaseErrorStringify( kOpenErr );
1639 CaseErrorStringify( kTypeErr );
1640 CaseErrorStringify( kSkipErr );
1641 CaseErrorStringify( kNoAckErr );
1642 CaseErrorStringify( kCollisionErr );
1643 CaseErrorStringify( kBackoffErr );
1644 CaseErrorStringify( kNoAddressAckErr );
1645 CaseErrorStringify( kBusyErr );
1646 CaseErrorStringify( kNoSpaceErr );
1648 // mDNS/DNS-SD Errors
1650 CaseErrorStringifyHardCode( -65537, mStatus_UnknownErr );
1651 CaseErrorStringifyHardCode( -65538, mStatus_NoSuchNameErr );
1652 CaseErrorStringifyHardCode( -65539, mStatus_NoMemoryErr );
1653 CaseErrorStringifyHardCode( -65540, mStatus_BadParamErr );
1654 CaseErrorStringifyHardCode( -65541, mStatus_BadReferenceErr );
1655 CaseErrorStringifyHardCode( -65542, mStatus_BadStateErr );
1656 CaseErrorStringifyHardCode( -65543, mStatus_BadFlagsErr );
1657 CaseErrorStringifyHardCode( -65544, mStatus_UnsupportedErr );
1658 CaseErrorStringifyHardCode( -65545, mStatus_NotInitializedErr );
1659 CaseErrorStringifyHardCode( -65546, mStatus_NoCache );
1660 CaseErrorStringifyHardCode( -65547, mStatus_AlreadyRegistered );
1661 CaseErrorStringifyHardCode( -65548, mStatus_NameConflict );
1662 CaseErrorStringifyHardCode( -65549, mStatus_Invalid );
1663 CaseErrorStringifyHardCode( -65550, mStatus_GrowCache );
1664 CaseErrorStringifyHardCode( -65551, mStatus_BadInterfaceErr );
1665 CaseErrorStringifyHardCode( -65552, mStatus_Incompatible );
1666 CaseErrorStringifyHardCode( -65791, mStatus_ConfigChanged );
1667 CaseErrorStringifyHardCode( -65792, mStatus_MemFree );
1669 // RSP Errors
1671 CaseErrorStringifyHardCode( -400000, kRSPUnknownErr );
1672 CaseErrorStringifyHardCode( -400050, kRSPParamErr );
1673 CaseErrorStringifyHardCode( -400108, kRSPNoMemoryErr );
1674 CaseErrorStringifyHardCode( -405246, kRSPRangeErr );
1675 CaseErrorStringifyHardCode( -409057, kRSPSizeErr );
1676 CaseErrorStringifyHardCode( -400200, kRSPHardwareErr );
1677 CaseErrorStringifyHardCode( -401712, kRSPTimeoutErr );
1678 CaseErrorStringifyHardCode( -402053, kRSPUnsupportedErr );
1679 CaseErrorStringifyHardCode( -402419, kRSPIDErr );
1680 CaseErrorStringifyHardCode( -403165, kRSPFlagErr );
1681 CaseErrorString( -200000, "kRSPControllerStatusBase - 0x50" );
1682 CaseErrorString( -200080, "kRSPCommandSucceededErr - 0x50" );
1683 CaseErrorString( -200001, "kRSPCommandFailedErr - 0x01" );
1684 CaseErrorString( -200051, "kRSPChecksumErr - 0x33" );
1685 CaseErrorString( -200132, "kRSPCommandTimeoutErr - 0x84" );
1686 CaseErrorString( -200034, "kRSPPasswordRequiredErr - 0x22 OBSOLETE" );
1687 CaseErrorString( -200128, "kRSPCanceledErr - 0x02 Async" );
1689 // XML Errors
1691 CaseErrorStringifyHardCode( -100043, kXMLNotFoundErr );
1692 CaseErrorStringifyHardCode( -100050, kXMLParamErr );
1693 CaseErrorStringifyHardCode( -100108, kXMLNoMemoryErr );
1694 CaseErrorStringifyHardCode( -100206, kXMLFormatErr );
1695 CaseErrorStringifyHardCode( -100586, kXMLNoRootElementErr );
1696 CaseErrorStringifyHardCode( -101703, kXMLWrongDataTypeErr );
1697 CaseErrorStringifyHardCode( -101726, kXMLKeyErr );
1698 CaseErrorStringifyHardCode( -102053, kXMLUnsupportedErr );
1699 CaseErrorStringifyHardCode( -102063, kXMLMissingElementErr );
1700 CaseErrorStringifyHardCode( -103026, kXMLParseErr );
1701 CaseErrorStringifyHardCode( -103159, kXMLBadDataErr );
1702 CaseErrorStringifyHardCode( -103170, kXMLBadNameErr );
1703 CaseErrorStringifyHardCode( -105246, kXMLRangeErr );
1704 CaseErrorStringifyHardCode( -105251, kXMLUnknownElementErr );
1705 CaseErrorStringifyHardCode( -108739, kXMLMalformedInputErr );
1706 CaseErrorStringifyHardCode( -109057, kXMLBadSizeErr );
1707 CaseErrorStringifyHardCode( -101730, kXMLMissingChildElementErr );
1708 CaseErrorStringifyHardCode( -102107, kXMLMissingParentElementErr );
1709 CaseErrorStringifyHardCode( -130587, kXMLNonRootElementErr );
1710 CaseErrorStringifyHardCode( -102015, kXMLDateErr );
1712 #if ( __MACH__ )
1714 // Mach Errors
1716 CaseErrorStringifyHardCode( 0x00002000, MACH_MSG_IPC_SPACE );
1717 CaseErrorStringifyHardCode( 0x00001000, MACH_MSG_VM_SPACE );
1718 CaseErrorStringifyHardCode( 0x00000800, MACH_MSG_IPC_KERNEL );
1719 CaseErrorStringifyHardCode( 0x00000400, MACH_MSG_VM_KERNEL );
1720 CaseErrorStringifyHardCode( 0x10000001, MACH_SEND_IN_PROGRESS );
1721 CaseErrorStringifyHardCode( 0x10000002, MACH_SEND_INVALID_DATA );
1722 CaseErrorStringifyHardCode( 0x10000003, MACH_SEND_INVALID_DEST );
1723 CaseErrorStringifyHardCode( 0x10000004, MACH_SEND_TIMED_OUT );
1724 CaseErrorStringifyHardCode( 0x10000007, MACH_SEND_INTERRUPTED );
1725 CaseErrorStringifyHardCode( 0x10000008, MACH_SEND_MSG_TOO_SMALL );
1726 CaseErrorStringifyHardCode( 0x10000009, MACH_SEND_INVALID_REPLY );
1727 CaseErrorStringifyHardCode( 0x1000000A, MACH_SEND_INVALID_RIGHT );
1728 CaseErrorStringifyHardCode( 0x1000000B, MACH_SEND_INVALID_NOTIFY );
1729 CaseErrorStringifyHardCode( 0x1000000C, MACH_SEND_INVALID_MEMORY );
1730 CaseErrorStringifyHardCode( 0x1000000D, MACH_SEND_NO_BUFFER );
1731 CaseErrorStringifyHardCode( 0x1000000E, MACH_SEND_TOO_LARGE );
1732 CaseErrorStringifyHardCode( 0x1000000F, MACH_SEND_INVALID_TYPE );
1733 CaseErrorStringifyHardCode( 0x10000010, MACH_SEND_INVALID_HEADER );
1734 CaseErrorStringifyHardCode( 0x10000011, MACH_SEND_INVALID_TRAILER );
1735 CaseErrorStringifyHardCode( 0x10000015, MACH_SEND_INVALID_RT_OOL_SIZE );
1736 CaseErrorStringifyHardCode( 0x10004001, MACH_RCV_IN_PROGRESS );
1737 CaseErrorStringifyHardCode( 0x10004002, MACH_RCV_INVALID_NAME );
1738 CaseErrorStringifyHardCode( 0x10004003, MACH_RCV_TIMED_OUT );
1739 CaseErrorStringifyHardCode( 0x10004004, MACH_RCV_TOO_LARGE );
1740 CaseErrorStringifyHardCode( 0x10004005, MACH_RCV_INTERRUPTED );
1741 CaseErrorStringifyHardCode( 0x10004006, MACH_RCV_PORT_CHANGED );
1742 CaseErrorStringifyHardCode( 0x10004007, MACH_RCV_INVALID_NOTIFY );
1743 CaseErrorStringifyHardCode( 0x10004008, MACH_RCV_INVALID_DATA );
1744 CaseErrorStringifyHardCode( 0x10004009, MACH_RCV_PORT_DIED );
1745 CaseErrorStringifyHardCode( 0x1000400A, MACH_RCV_IN_SET );
1746 CaseErrorStringifyHardCode( 0x1000400B, MACH_RCV_HEADER_ERROR );
1747 CaseErrorStringifyHardCode( 0x1000400C, MACH_RCV_BODY_ERROR );
1748 CaseErrorStringifyHardCode( 0x1000400D, MACH_RCV_INVALID_TYPE );
1749 CaseErrorStringifyHardCode( 0x1000400E, MACH_RCV_SCATTER_SMALL );
1750 CaseErrorStringifyHardCode( 0x1000400F, MACH_RCV_INVALID_TRAILER );
1751 CaseErrorStringifyHardCode( 0x10004011, MACH_RCV_IN_PROGRESS_TIMED );
1753 // Mach OSReturn Errors
1755 CaseErrorStringifyHardCode( 0xDC000001, kOSReturnError );
1756 CaseErrorStringifyHardCode( 0xDC004001, kOSMetaClassInternal );
1757 CaseErrorStringifyHardCode( 0xDC004002, kOSMetaClassHasInstances );
1758 CaseErrorStringifyHardCode( 0xDC004003, kOSMetaClassNoInit );
1759 CaseErrorStringifyHardCode( 0xDC004004, kOSMetaClassNoTempData );
1760 CaseErrorStringifyHardCode( 0xDC004005, kOSMetaClassNoDicts );
1761 CaseErrorStringifyHardCode( 0xDC004006, kOSMetaClassNoKModSet );
1762 CaseErrorStringifyHardCode( 0xDC004007, kOSMetaClassNoInsKModSet );
1763 CaseErrorStringifyHardCode( 0xDC004008, kOSMetaClassNoSuper );
1764 CaseErrorStringifyHardCode( 0xDC004009, kOSMetaClassInstNoSuper );
1765 CaseErrorStringifyHardCode( 0xDC00400A, kOSMetaClassDuplicateClass );
1767 // IOKit Errors
1769 CaseErrorStringifyHardCode( 0xE00002BC, kIOReturnError );
1770 CaseErrorStringifyHardCode( 0xE00002BD, kIOReturnNoMemory );
1771 CaseErrorStringifyHardCode( 0xE00002BE, kIOReturnNoResources );
1772 CaseErrorStringifyHardCode( 0xE00002BF, kIOReturnIPCError );
1773 CaseErrorStringifyHardCode( 0xE00002C0, kIOReturnNoDevice );
1774 CaseErrorStringifyHardCode( 0xE00002C1, kIOReturnNotPrivileged );
1775 CaseErrorStringifyHardCode( 0xE00002C2, kIOReturnBadArgument );
1776 CaseErrorStringifyHardCode( 0xE00002C3, kIOReturnLockedRead );
1777 CaseErrorStringifyHardCode( 0xE00002C4, kIOReturnLockedWrite );
1778 CaseErrorStringifyHardCode( 0xE00002C5, kIOReturnExclusiveAccess );
1779 CaseErrorStringifyHardCode( 0xE00002C6, kIOReturnBadMessageID );
1780 CaseErrorStringifyHardCode( 0xE00002C7, kIOReturnUnsupported );
1781 CaseErrorStringifyHardCode( 0xE00002C8, kIOReturnVMError );
1782 CaseErrorStringifyHardCode( 0xE00002C9, kIOReturnInternalError );
1783 CaseErrorStringifyHardCode( 0xE00002CA, kIOReturnIOError );
1784 CaseErrorStringifyHardCode( 0xE00002CC, kIOReturnCannotLock );
1785 CaseErrorStringifyHardCode( 0xE00002CD, kIOReturnNotOpen );
1786 CaseErrorStringifyHardCode( 0xE00002CE, kIOReturnNotReadable );
1787 CaseErrorStringifyHardCode( 0xE00002CF, kIOReturnNotWritable );
1788 CaseErrorStringifyHardCode( 0xE00002D0, kIOReturnNotAligned );
1789 CaseErrorStringifyHardCode( 0xE00002D1, kIOReturnBadMedia );
1790 CaseErrorStringifyHardCode( 0xE00002D2, kIOReturnStillOpen );
1791 CaseErrorStringifyHardCode( 0xE00002D3, kIOReturnRLDError );
1792 CaseErrorStringifyHardCode( 0xE00002D4, kIOReturnDMAError );
1793 CaseErrorStringifyHardCode( 0xE00002D5, kIOReturnBusy );
1794 CaseErrorStringifyHardCode( 0xE00002D6, kIOReturnTimeout );
1795 CaseErrorStringifyHardCode( 0xE00002D7, kIOReturnOffline );
1796 CaseErrorStringifyHardCode( 0xE00002D8, kIOReturnNotReady );
1797 CaseErrorStringifyHardCode( 0xE00002D9, kIOReturnNotAttached );
1798 CaseErrorStringifyHardCode( 0xE00002DA, kIOReturnNoChannels );
1799 CaseErrorStringifyHardCode( 0xE00002DB, kIOReturnNoSpace );
1800 CaseErrorStringifyHardCode( 0xE00002DD, kIOReturnPortExists );
1801 CaseErrorStringifyHardCode( 0xE00002DE, kIOReturnCannotWire );
1802 CaseErrorStringifyHardCode( 0xE00002DF, kIOReturnNoInterrupt );
1803 CaseErrorStringifyHardCode( 0xE00002E0, kIOReturnNoFrames );
1804 CaseErrorStringifyHardCode( 0xE00002E1, kIOReturnMessageTooLarge );
1805 CaseErrorStringifyHardCode( 0xE00002E2, kIOReturnNotPermitted );
1806 CaseErrorStringifyHardCode( 0xE00002E3, kIOReturnNoPower );
1807 CaseErrorStringifyHardCode( 0xE00002E4, kIOReturnNoMedia );
1808 CaseErrorStringifyHardCode( 0xE00002E5, kIOReturnUnformattedMedia );
1809 CaseErrorStringifyHardCode( 0xE00002E6, kIOReturnUnsupportedMode );
1810 CaseErrorStringifyHardCode( 0xE00002E7, kIOReturnUnderrun );
1811 CaseErrorStringifyHardCode( 0xE00002E8, kIOReturnOverrun );
1812 CaseErrorStringifyHardCode( 0xE00002E9, kIOReturnDeviceError );
1813 CaseErrorStringifyHardCode( 0xE00002EA, kIOReturnNoCompletion );
1814 CaseErrorStringifyHardCode( 0xE00002EB, kIOReturnAborted );
1815 CaseErrorStringifyHardCode( 0xE00002EC, kIOReturnNoBandwidth );
1816 CaseErrorStringifyHardCode( 0xE00002ED, kIOReturnNotResponding );
1817 CaseErrorStringifyHardCode( 0xE00002EE, kIOReturnIsoTooOld );
1818 CaseErrorStringifyHardCode( 0xE00002EF, kIOReturnIsoTooNew );
1819 CaseErrorStringifyHardCode( 0xE00002F0, kIOReturnNotFound );
1820 CaseErrorStringifyHardCode( 0xE0000001, kIOReturnInvalid );
1822 // IOKit FireWire Errors
1824 CaseErrorStringifyHardCode( 0xE0008010, kIOFireWireResponseBase );
1825 CaseErrorStringifyHardCode( 0xE0008020, kIOFireWireBusReset );
1826 CaseErrorStringifyHardCode( 0xE0008001, kIOConfigNoEntry );
1827 CaseErrorStringifyHardCode( 0xE0008002, kIOFireWirePending );
1828 CaseErrorStringifyHardCode( 0xE0008003, kIOFireWireLastDCLToken );
1829 CaseErrorStringifyHardCode( 0xE0008004, kIOFireWireConfigROMInvalid );
1830 CaseErrorStringifyHardCode( 0xE0008005, kIOFireWireAlreadyRegistered );
1831 CaseErrorStringifyHardCode( 0xE0008006, kIOFireWireMultipleTalkers );
1832 CaseErrorStringifyHardCode( 0xE0008007, kIOFireWireChannelActive );
1833 CaseErrorStringifyHardCode( 0xE0008008, kIOFireWireNoListenerOrTalker );
1834 CaseErrorStringifyHardCode( 0xE0008009, kIOFireWireNoChannels );
1835 CaseErrorStringifyHardCode( 0xE000800A, kIOFireWireChannelNotAvailable );
1836 CaseErrorStringifyHardCode( 0xE000800B, kIOFireWireSeparateBus );
1837 CaseErrorStringifyHardCode( 0xE000800C, kIOFireWireBadSelfIDs );
1838 CaseErrorStringifyHardCode( 0xE000800D, kIOFireWireLowCableVoltage );
1839 CaseErrorStringifyHardCode( 0xE000800E, kIOFireWireInsufficientPower );
1840 CaseErrorStringifyHardCode( 0xE000800F, kIOFireWireOutOfTLabels );
1841 CaseErrorStringifyHardCode( 0xE0008101, kIOFireWireBogusDCLProgram );
1842 CaseErrorStringifyHardCode( 0xE0008102, kIOFireWireTalkingAndListening );
1843 CaseErrorStringifyHardCode( 0xE0008103, kIOFireWireHardwareSlept );
1844 CaseErrorStringifyHardCode( 0xE00087D0, kIOFWMessageServiceIsRequestingClose );
1845 CaseErrorStringifyHardCode( 0xE00087D1, kIOFWMessagePowerStateChanged );
1846 CaseErrorStringifyHardCode( 0xE00087D2, kIOFWMessageTopologyChanged );
1848 // IOKit USB Errors
1850 CaseErrorStringifyHardCode( 0xE0004061, kIOUSBUnknownPipeErr );
1851 CaseErrorStringifyHardCode( 0xE0004060, kIOUSBTooManyPipesErr );
1852 CaseErrorStringifyHardCode( 0xE000405F, kIOUSBNoAsyncPortErr );
1853 CaseErrorStringifyHardCode( 0xE000405E, kIOUSBNotEnoughPipesErr );
1854 CaseErrorStringifyHardCode( 0xE000405D, kIOUSBNotEnoughPowerErr );
1855 CaseErrorStringifyHardCode( 0xE0004057, kIOUSBEndpointNotFound );
1856 CaseErrorStringifyHardCode( 0xE0004056, kIOUSBConfigNotFound );
1857 CaseErrorStringifyHardCode( 0xE0004051, kIOUSBTransactionTimeout );
1858 CaseErrorStringifyHardCode( 0xE0004050, kIOUSBTransactionReturned );
1859 CaseErrorStringifyHardCode( 0xE000404F, kIOUSBPipeStalled );
1860 CaseErrorStringifyHardCode( 0xE000404E, kIOUSBInterfaceNotFound );
1861 CaseErrorStringifyHardCode( 0xE000404D, kIOUSBLowLatencyBufferNotPreviouslyAllocated );
1862 CaseErrorStringifyHardCode( 0xE000404C, kIOUSBLowLatencyFrameListNotPreviouslyAllocated );
1863 CaseErrorStringifyHardCode( 0xE000404B, kIOUSBHighSpeedSplitError );
1864 CaseErrorStringifyHardCode( 0xE0004010, kIOUSBLinkErr );
1865 CaseErrorStringifyHardCode( 0xE000400F, kIOUSBNotSent2Err );
1866 CaseErrorStringifyHardCode( 0xE000400E, kIOUSBNotSent1Err );
1867 CaseErrorStringifyHardCode( 0xE000400D, kIOUSBBufferUnderrunErr );
1868 CaseErrorStringifyHardCode( 0xE000400C, kIOUSBBufferOverrunErr );
1869 CaseErrorStringifyHardCode( 0xE000400B, kIOUSBReserved2Err );
1870 CaseErrorStringifyHardCode( 0xE000400A, kIOUSBReserved1Err );
1871 CaseErrorStringifyHardCode( 0xE0004007, kIOUSBWrongPIDErr );
1872 CaseErrorStringifyHardCode( 0xE0004006, kIOUSBPIDCheckErr );
1873 CaseErrorStringifyHardCode( 0xE0004003, kIOUSBDataToggleErr );
1874 CaseErrorStringifyHardCode( 0xE0004002, kIOUSBBitstufErr );
1875 CaseErrorStringifyHardCode( 0xE0004001, kIOUSBCRCErr );
1877 #endif // __MACH__
1879 // Other Errors
1881 default:
1882 s = NULL;
1883 #if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
1884 if( inBuffer && ( inBufferSize > 0 ) )
1886 DWORD n;
1888 n = FormatMessageA( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, (DWORD) inErrorCode,
1889 MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), buffer, sizeof( buffer ), NULL );
1890 if( n > 0 )
1892 // Remove any trailing CR's or LF's since some messages have them.
1894 while( ( n > 0 ) && isspace( ( (unsigned char *) buffer )[ n - 1 ] ) )
1896 buffer[ --n ] = '\0';
1898 s = buffer;
1901 #endif
1903 if( !s )
1905 #if ( !TARGET_API_MAC_OSX_KERNEL && !TARGET_OS_WINDOWS_CE )
1906 s = strerror( inErrorCode );
1907 #endif
1908 if( !s )
1910 s = "<unknown error code>";
1913 break;
1916 // Copy the string to the output buffer. If no buffer is supplied or it is empty, return an empty string.
1918 if( inBuffer && ( inBufferSize > 0 ) )
1920 dst = inBuffer;
1921 end = dst + ( inBufferSize - 1 );
1922 while( ( ( end - dst ) > 0 ) && ( *s != '\0' ) )
1924 *dst++ = *s++;
1926 *dst = '\0';
1927 s = inBuffer;
1929 return s;
1933 // DebugHexDump
1934 DEBUG_EXPORT size_t
1935 DebugHexDump(
1936 DebugLevel inLevel,
1937 int inIndent,
1938 const char * inLabel,
1939 size_t inLabelSize,
1940 int inLabelMinWidth,
1941 const char * inType,
1942 size_t inTypeSize,
1943 const void * inDataStart,
1944 const void * inData,
1945 size_t inDataSize,
1946 DebugFlags inFlags,
1947 char * outBuffer,
1948 size_t inBufferSize )
1950 static const char kHexChars[] = "0123456789ABCDEF";
1951 const uint8_t * start;
1952 const uint8_t * src;
1953 char * dst;
1954 char * end;
1955 size_t n;
1956 int offset;
1957 int width;
1958 const char * newline;
1959 char separator[ 8 ];
1960 char * s;
1962 DEBUG_UNUSED( inType );
1963 DEBUG_UNUSED( inTypeSize );
1965 // Set up the function-wide variables.
1967 if( inLabelSize == kSizeCString )
1969 inLabelSize = strlen( inLabel );
1971 start = (const uint8_t *) inData;
1972 src = start;
1973 dst = outBuffer;
1974 end = dst + inBufferSize;
1975 offset = (int)( (intptr_t) inData - (intptr_t) inDataStart );
1976 width = ( (int) inLabelSize > inLabelMinWidth ) ? (int) inLabelSize : inLabelMinWidth;
1977 newline = ( inFlags & kDebugFlagsNoNewLine ) ? "" : "\n";
1979 // Set up the separator string. This is used to insert spaces on subsequent "lines" when not using newlines.
1981 s = separator;
1982 if( inFlags & kDebugFlagsNoNewLine )
1984 if( inFlags & kDebugFlags8BitSeparator )
1986 *s++ = ' ';
1988 if( inFlags & kDebugFlags16BitSeparator )
1990 *s++ = ' ';
1992 if( !( inFlags & kDebugFlagsNo32BitSeparator ) )
1994 *s++ = ' ';
1996 check( ( (size_t)( s - separator ) ) < sizeof( separator ) );
1998 *s = '\0';
2000 for( ;; )
2002 char prefixString[ 32 ];
2003 char hexString[ 64 ];
2004 char asciiString[ 32 ];
2005 char byteCountString[ 32 ];
2006 int c;
2007 size_t chunkSize;
2008 size_t i;
2010 // If this is a label-only item (i.e. no data), print the label (accounting for prefix string spacing) and exit.
2012 if( inDataSize == 0 )
2014 if( inLabel && ( inLabelSize > 0 ) )
2016 width = 0;
2017 if( !( inFlags & kDebugFlagsNoAddress ) )
2019 width += 8; // "00000000"
2020 if( !( inFlags & kDebugFlagsNoOffset ) )
2022 width += 1; // "+"
2025 if( inFlags & kDebugFlags32BitOffset )
2027 width += 8; // "00000000"
2029 else if( !( inFlags & kDebugFlagsNoOffset ) )
2031 width += 4; // "0000"
2034 if( outBuffer )
2036 dst += DebugSNPrintF( dst, (size_t)( end - dst ), "%*s" "%-*.*s" "%.*s" "%s",
2037 width, "",
2038 ( width > 0 ) ? ": " : "",
2039 width, (int) inLabelSize, inLabel,
2040 newline );
2042 else
2044 dst += DebugPrintF( inLevel, "%*s" "%-*.*s" "%.*s" "%s",
2045 width, "",
2046 ( width > 0 ) ? ": " : "",
2047 width, (int) inLabelSize, inLabel,
2048 newline );
2051 break;
2054 // Build the prefix string. It will be in one of the following formats:
2056 // 1) "00000000+0000[0000]" (address and offset)
2057 // 2) "00000000" (address only)
2058 // 3) "0000[0000]" (offset only)
2059 // 4) "" (no address or offset)
2061 // Note: If we're printing multiple "lines", but not printing newlines, a space is used to separate.
2063 s = prefixString;
2064 if( !( inFlags & kDebugFlagsNoAddress ) )
2066 *s++ = kHexChars[ ( ( (uintptr_t) src ) >> 28 ) & 0xF ];
2067 *s++ = kHexChars[ ( ( (uintptr_t) src ) >> 24 ) & 0xF ];
2068 *s++ = kHexChars[ ( ( (uintptr_t) src ) >> 20 ) & 0xF ];
2069 *s++ = kHexChars[ ( ( (uintptr_t) src ) >> 16 ) & 0xF ];
2070 *s++ = kHexChars[ ( ( (uintptr_t) src ) >> 12 ) & 0xF ];
2071 *s++ = kHexChars[ ( ( (uintptr_t) src ) >> 8 ) & 0xF ];
2072 *s++ = kHexChars[ ( ( (uintptr_t) src ) >> 4 ) & 0xF ];
2073 *s++ = kHexChars[ ( (uintptr_t) src ) & 0xF ];
2075 if( !( inFlags & kDebugFlagsNoOffset ) )
2077 *s++ = '+';
2080 if( !( inFlags & kDebugFlagsNoOffset ) )
2082 if( inFlags & kDebugFlags32BitOffset )
2084 *s++ = kHexChars[ ( offset >> 28 ) & 0xF ];
2085 *s++ = kHexChars[ ( offset >> 24 ) & 0xF ];
2086 *s++ = kHexChars[ ( offset >> 20 ) & 0xF ];
2087 *s++ = kHexChars[ ( offset >> 16 ) & 0xF ];
2089 *s++ = kHexChars[ ( offset >> 12 ) & 0xF ];
2090 *s++ = kHexChars[ ( offset >> 8 ) & 0xF ];
2091 *s++ = kHexChars[ ( offset >> 4 ) & 0xF ];
2092 *s++ = kHexChars[ offset & 0xF ];
2094 if( s != prefixString )
2096 *s++ = ':';
2097 *s++ = ' ';
2099 check( ( (size_t)( s - prefixString ) ) < sizeof( prefixString ) );
2100 *s = '\0';
2102 // Build a hex string with a optional spaces after every 1, 2, and/or 4 bytes to make it easier to read.
2103 // Optionally pads the hex string with space to fill the full 16 byte range (so it lines up).
2105 s = hexString;
2106 chunkSize = ( inDataSize < 16 ) ? inDataSize : 16;
2107 n = ( inFlags & kDebugFlagsNo16ByteHexPad ) ? chunkSize : 16;
2108 for( i = 0; i < n; ++i )
2110 if( ( inFlags & kDebugFlags8BitSeparator ) && ( i > 0 ) )
2112 *s++ = ' ';
2114 if( ( inFlags & kDebugFlags16BitSeparator ) && ( i > 0 ) && ( ( i % 2 ) == 0 ) )
2116 *s++ = ' ';
2118 if( !( inFlags & kDebugFlagsNo32BitSeparator ) && ( i > 0 ) && ( ( i % 4 ) == 0 ) )
2120 *s++ = ' ';
2122 if( i < chunkSize )
2124 *s++ = kHexChars[ src[ i ] >> 4 ];
2125 *s++ = kHexChars[ src[ i ] & 0xF ];
2127 else
2129 *s++ = ' ';
2130 *s++ = ' ';
2133 check( ( (size_t)( s - hexString ) ) < sizeof( hexString ) );
2134 *s = '\0';
2136 // Build a string with the ASCII version of the data (replaces non-printable characters with '^').
2137 // Optionally pads the string with '`' to fill the full 16 byte range (so it lines up).
2139 s = asciiString;
2140 if( !( inFlags & kDebugFlagsNoASCII ) )
2142 *s++ = ' ';
2143 *s++ = '|';
2144 for( i = 0; i < n; ++i )
2146 if( i < chunkSize )
2148 c = src[ i ];
2149 if( !DebugIsPrint( c ) )
2151 c = '^';
2154 else
2156 c = '`';
2158 *s++ = (char) c;
2160 *s++ = '|';
2161 check( ( (size_t)( s - asciiString ) ) < sizeof( asciiString ) );
2163 *s = '\0';
2165 // Build a string indicating how bytes are in the hex dump. Only printed on the first line.
2167 s = byteCountString;
2168 if( !( inFlags & kDebugFlagsNoByteCount ) )
2170 if( src == start )
2172 s += DebugSNPrintF( s, sizeof( byteCountString ), " (%d bytes)", (int) inDataSize );
2175 check( ( (size_t)( s - byteCountString ) ) < sizeof( byteCountString ) );
2176 *s = '\0';
2178 // Build the entire line from all the pieces we've previously built.
2180 if( outBuffer )
2182 if( src == start )
2184 dst += DebugSNPrintF( dst, (size_t)( end - dst ),
2185 "%*s" // Indention
2186 "%s" // Separator (only if needed)
2187 "%s" // Prefix
2188 "%-*.*s" // Label
2189 "%s" // Separator
2190 "%s" // Hex
2191 "%s" // ASCII
2192 "%s" // Byte Count
2193 "%s", // Newline
2194 inIndent, "",
2195 ( src != start ) ? separator : "",
2196 prefixString,
2197 width, (int) inLabelSize, inLabel ? inLabel : "",
2198 ( width > 0 ) ? " " : "",
2199 hexString,
2200 asciiString,
2201 byteCountString,
2202 newline );
2204 else
2206 dst += DebugSNPrintF( dst, (size_t)( end - dst ),
2207 "%*s" // Indention
2208 "%s" // Separator (only if needed)
2209 "%s" // Prefix
2210 "%*s" // Label Spacing
2211 "%s" // Separator
2212 "%s" // Hex
2213 "%s" // ASCII
2214 "%s" // Byte Count
2215 "%s", // Newline
2216 inIndent, "",
2217 ( src != start ) ? separator : "",
2218 prefixString,
2219 width, "",
2220 ( width > 0 ) ? " " : "",
2221 hexString,
2222 asciiString,
2223 byteCountString,
2224 newline );
2227 else
2229 if( src == start )
2231 dst += DebugPrintF( inLevel,
2232 "%*s" // Indention
2233 "%s" // Separator (only if needed)
2234 "%s" // Prefix
2235 "%-*.*s" // Label
2236 "%s" // Separator
2237 "%s" // Hex
2238 "%s" // ASCII
2239 "%s" // Byte Count
2240 "%s", // Newline
2241 inIndent, "",
2242 ( src != start ) ? separator : "",
2243 prefixString,
2244 width, (int) inLabelSize, inLabel,
2245 ( width > 0 ) ? " " : "",
2246 hexString,
2247 asciiString,
2248 byteCountString,
2249 newline );
2251 else
2253 dst += DebugPrintF( inLevel,
2254 "%*s" // Indention
2255 "%s" // Separator (only if needed)
2256 "%s" // Prefix
2257 "%*s" // Label Spacing
2258 "%s" // Separator
2259 "%s" // Hex
2260 "%s" // ASCII
2261 "%s" // Byte Count
2262 "%s", // Newline
2263 inIndent, "",
2264 ( src != start ) ? separator : "",
2265 prefixString,
2266 width, "",
2267 ( width > 0 ) ? " " : "",
2268 hexString,
2269 asciiString,
2270 byteCountString,
2271 newline );
2275 // Move to the next chunk. Exit if there is no more data.
2277 offset += (int) chunkSize;
2278 src += chunkSize;
2279 inDataSize -= chunkSize;
2280 if( inDataSize == 0 )
2282 break;
2286 // Note: The "dst - outBuffer" size calculation works even if "outBuffer" is NULL because it's all relative.
2288 return (size_t)( dst - outBuffer );
2292 // DebugNumVersionToString
2293 static char * DebugNumVersionToString( uint32_t inVersion, char *inString )
2295 char * s;
2296 uint8_t majorRev;
2297 uint8_t minor;
2298 uint8_t bugFix;
2299 uint8_t stage;
2300 uint8_t revision;
2302 check( inString );
2304 majorRev = (uint8_t)( ( inVersion >> 24 ) & 0xFF );
2305 minor = (uint8_t)( ( inVersion >> 20 ) & 0x0F );
2306 bugFix = (uint8_t)( ( inVersion >> 16 ) & 0x0F );
2307 stage = (uint8_t)( ( inVersion >> 8 ) & 0xFF );
2308 revision = (uint8_t)( inVersion & 0xFF );
2310 // Convert the major, minor, and bugfix numbers.
2312 s = inString;
2313 s += sprintf( s, "%u", majorRev );
2314 s += sprintf( s, ".%u", minor );
2315 if( bugFix != 0 )
2317 s += sprintf( s, ".%u", bugFix );
2320 // Convert the version stage and non-release revision number.
2322 switch( stage )
2324 case kVersionStageDevelopment:
2325 s += sprintf( s, "d%u", revision );
2326 break;
2328 case kVersionStageAlpha:
2329 s += sprintf( s, "a%u", revision );
2330 break;
2332 case kVersionStageBeta:
2333 s += sprintf( s, "b%u", revision );
2334 break;
2336 case kVersionStageFinal:
2338 // A non-release revision of zero is a special case indicating the software is GM (at the golden master
2339 // stage) and therefore, the non-release revision should not be added to the string.
2341 if( revision != 0 )
2343 s += sprintf( s, "f%u", revision );
2345 break;
2347 default:
2348 dlog( kDebugLevelError, "invalid NumVersion stage (0x%02X)\n", stage );
2349 break;
2351 return inString;
2355 // DebugTaskLevel
2356 DEBUG_EXPORT uint32_t DebugTaskLevel( void )
2358 uint32_t level;
2360 level = 0;
2362 #if ( TARGET_OS_VXWORKS )
2363 if( intContext() )
2365 level |= ( ( 1 << kDebugInterruptLevelShift ) & kDebugInterruptLevelMask );
2367 #endif
2369 return level;
2372 #if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
2374 // DebugWinEnableConsole
2375 #pragma warning( disable:4311 )
2377 static void DebugWinEnableConsole( void )
2379 static bool sConsoleEnabled = false;
2380 BOOL result;
2381 int fileHandle;
2382 FILE * file;
2383 int err;
2385 if( sConsoleEnabled )
2387 goto exit;
2390 // Create console window.
2392 result = AllocConsole();
2393 require_quiet( result, exit );
2395 // Redirect stdin to the console stdin.
2397 fileHandle = _open_osfhandle( (long) GetStdHandle( STD_INPUT_HANDLE ), _O_TEXT );
2399 #if ( defined( __MWERKS__ ) )
2400 file = __handle_reopen( (unsigned long) fileHandle, "r", stdin );
2401 require_quiet( file, exit );
2402 #else
2403 file = _fdopen( fileHandle, "r" );
2404 require_quiet( file, exit );
2406 *stdin = *file;
2407 #endif
2409 err = setvbuf( stdin, NULL, _IONBF, 0 );
2410 require_noerr_quiet( err, exit );
2412 // Redirect stdout to the console stdout.
2414 fileHandle = _open_osfhandle( (long) GetStdHandle( STD_OUTPUT_HANDLE ), _O_TEXT );
2416 #if ( defined( __MWERKS__ ) )
2417 file = __handle_reopen( (unsigned long) fileHandle, "w", stdout );
2418 require_quiet( file, exit );
2419 #else
2420 file = _fdopen( fileHandle, "w" );
2421 require_quiet( file, exit );
2423 *stdout = *file;
2424 #endif
2426 err = setvbuf( stdout, NULL, _IONBF, 0 );
2427 require_noerr_quiet( err, exit );
2429 // Redirect stderr to the console stdout.
2431 fileHandle = _open_osfhandle( (long) GetStdHandle( STD_OUTPUT_HANDLE ), _O_TEXT );
2433 #if ( defined( __MWERKS__ ) )
2434 file = __handle_reopen( (unsigned long) fileHandle, "w", stderr );
2435 require_quiet( file, exit );
2436 #else
2437 file = _fdopen( fileHandle, "w" );
2438 require_quiet( file, exit );
2440 *stderr = *file;
2441 #endif
2443 err = setvbuf( stderr, NULL, _IONBF, 0 );
2444 require_noerr_quiet( err, exit );
2446 sConsoleEnabled = true;
2448 exit:
2449 return;
2452 #pragma warning( default:4311 )
2454 #endif // TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE
2456 #if ( TARGET_OS_WIN32 )
2458 // DebugWinCharToTCharString
2459 static TCHAR *
2460 DebugWinCharToTCharString(
2461 const char * inCharString,
2462 size_t inCharCount,
2463 TCHAR * outTCharString,
2464 size_t inTCharCountMax,
2465 size_t * outTCharCount )
2467 const char * src;
2468 TCHAR * dst;
2469 TCHAR * end;
2471 if( inCharCount == kSizeCString )
2473 inCharCount = strlen( inCharString );
2475 src = inCharString;
2476 dst = outTCharString;
2477 if( inTCharCountMax > 0 )
2479 inTCharCountMax -= 1;
2480 if( inTCharCountMax > inCharCount )
2482 inTCharCountMax = inCharCount;
2485 end = dst + inTCharCountMax;
2486 while( dst < end )
2488 *dst++ = (TCHAR) *src++;
2490 *dst = 0;
2492 if( outTCharCount )
2494 *outTCharCount = (size_t)( dst - outTCharString );
2496 return outTCharString;
2498 #endif
2500 #if 0
2501 #pragma mark -
2502 #pragma mark == Debugging ==
2503 #endif
2506 // DebugServicesTest
2507 DEBUG_EXPORT OSStatus DebugServicesTest( void )
2509 OSStatus err;
2510 char s[ 512 ];
2511 uint8_t * p;
2512 uint8_t data[] =
2514 0x11, 0x22, 0x33, 0x44,
2515 0x55, 0x66,
2516 0x77, 0x88, 0x99, 0xAA,
2517 0xBB, 0xCC, 0xDD,
2518 0xEE,
2519 0xFF,
2520 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
2521 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0,
2522 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71, 0x81, 0x91, 0xA1
2525 debug_initialize( kDebugOutputTypeMetaConsole );
2527 // check's
2529 check( 0 && "SHOULD SEE: check" );
2530 check( 1 && "SHOULD *NOT* SEE: check (valid)" );
2531 check_string( 0, "SHOULD SEE: check_string" );
2532 check_string( 1, "SHOULD *NOT* SEE: check_string (valid)" );
2533 check_noerr( -123 );
2534 check_noerr( 10038 );
2535 check_noerr( 22 );
2536 check_noerr( 0 );
2537 check_noerr_string( -6712, "SHOULD SEE: check_noerr_string" );
2538 check_noerr_string( 0, "SHOULD *NOT* SEE: check_noerr_string (valid)" );
2539 check_translated_errno( 0 >= 0 && "SHOULD *NOT* SEE", -384, -999 );
2540 check_translated_errno( -1 >= 0 && "SHOULD SEE", -384, -999 );
2541 check_translated_errno( -1 >= 0 && "SHOULD SEE", 0, -999 );
2542 check_ptr_overlap( "SHOULD *NOT* SEE" ? 10 : 0, 10, 22, 10 );
2543 check_ptr_overlap( "SHOULD SEE" ? 10 : 0, 10, 5, 10 );
2544 check_ptr_overlap( "SHOULD SEE" ? 10 : 0, 10, 12, 6 );
2545 check_ptr_overlap( "SHOULD SEE" ? 12 : 0, 6, 10, 10 );
2546 check_ptr_overlap( "SHOULD SEE" ? 12 : 0, 10, 10, 10 );
2547 check_ptr_overlap( "SHOULD *NOT* SEE" ? 22 : 0, 10, 10, 10 );
2548 check_ptr_overlap( "SHOULD *NOT* SEE" ? 10 : 0, 10, 20, 10 );
2549 check_ptr_overlap( "SHOULD *NOT* SEE" ? 20 : 0, 10, 10, 10 );
2551 // require's
2553 require( 0 && "SHOULD SEE", require1 );
2554 { err = kResponseErr; goto exit; }
2555 require1:
2556 require( 1 && "SHOULD *NOT* SEE", require2 );
2557 goto require2Good;
2558 require2:
2559 { err = kResponseErr; goto exit; }
2560 require2Good:
2561 require_string( 0 && "SHOULD SEE", require3, "SHOULD SEE: require_string" );
2562 { err = kResponseErr; goto exit; }
2563 require3:
2564 require_string( 1 && "SHOULD *NOT* SEE", require4, "SHOULD *NOT* SEE: require_string (valid)" );
2565 goto require4Good;
2566 require4:
2567 { err = kResponseErr; goto exit; }
2568 require4Good:
2569 require_quiet( 0 && "SHOULD SEE", require5 );
2570 { err = kResponseErr; goto exit; }
2571 require5:
2572 require_quiet( 1 && "SHOULD *NOT* SEE", require6 );
2573 goto require6Good;
2574 require6:
2575 { err = kResponseErr; goto exit; }
2576 require6Good:
2577 require_noerr( -1, require7 );
2578 { err = kResponseErr; goto exit; }
2579 require7:
2580 require_noerr( 0, require8 );
2581 goto require8Good;
2582 require8:
2583 { err = kResponseErr; goto exit; }
2584 require8Good:
2585 require_noerr_string( -2, require9, "SHOULD SEE: require_noerr_string");
2586 { err = kResponseErr; goto exit; }
2587 require9:
2588 require_noerr_string( 0, require10, "SHOULD *NOT* SEE: require_noerr_string (valid)" );
2589 goto require10Good;
2590 require10:
2591 { err = kResponseErr; goto exit; }
2592 require10Good:
2593 require_noerr_action_string( -3, require11, dlog( kDebugLevelMax, "action 1 (expected)\n" ), "require_noerr_action_string" );
2594 { err = kResponseErr; goto exit; }
2595 require11:
2596 require_noerr_action_string( 0, require12, dlog( kDebugLevelMax, "action 2\n" ), "require_noerr_action_string (valid)" );
2597 goto require12Good;
2598 require12:
2599 { err = kResponseErr; goto exit; }
2600 require12Good:
2601 require_noerr_quiet( -4, require13 );
2602 { err = kResponseErr; goto exit; }
2603 require13:
2604 require_noerr_quiet( 0, require14 );
2605 goto require14Good;
2606 require14:
2607 { err = kResponseErr; goto exit; }
2608 require14Good:
2609 require_noerr_action( -5, require15, dlog( kDebugLevelMax, "SHOULD SEE: action 3 (expected)\n" ) );
2610 { err = kResponseErr; goto exit; }
2611 require15:
2612 require_noerr_action( 0, require16, dlog( kDebugLevelMax, "SHOULD *NOT* SEE: action 4\n" ) );
2613 goto require16Good;
2614 require16:
2615 { err = kResponseErr; goto exit; }
2616 require16Good:
2617 require_noerr_action_quiet( -4, require17, dlog( kDebugLevelMax, "SHOULD SEE: action 5 (expected)\n" ) );
2618 { err = kResponseErr; goto exit; }
2619 require17:
2620 require_noerr_action_quiet( 0, require18, dlog( kDebugLevelMax, "SHOULD *NOT* SEE: action 6\n" ) );
2621 goto require18Good;
2622 require18:
2623 { err = kResponseErr; goto exit; }
2624 require18Good:
2625 require_action( 0 && "SHOULD SEE", require19, dlog( kDebugLevelMax, "SHOULD SEE: action 7 (expected)\n" ) );
2626 { err = kResponseErr; goto exit; }
2627 require19:
2628 require_action( 1 && "SHOULD *NOT* SEE", require20, dlog( kDebugLevelMax, "SHOULD *NOT* SEE: action 8\n" ) );
2629 goto require20Good;
2630 require20:
2631 { err = kResponseErr; goto exit; }
2632 require20Good:
2633 require_action_quiet( 0, require21, dlog( kDebugLevelMax, "SHOULD SEE: action 9 (expected)\n" ) );
2634 { err = kResponseErr; goto exit; }
2635 require21:
2636 require_action_quiet( 1, require22, dlog( kDebugLevelMax, "SHOULD *NOT* SEE: action 10\n" ) );
2637 goto require22Good;
2638 require22:
2639 { err = kResponseErr; goto exit; }
2640 require22Good:
2641 require_action_string( 0, require23, dlog( kDebugLevelMax, "SHOULD SEE: action 11 (expected)\n" ), "SHOULD SEE: require_action_string" );
2642 { err = kResponseErr; goto exit; }
2643 require23:
2644 require_action_string( 1, require24, dlog( kDebugLevelMax, "SHOULD *NOT* SEE: action 12\n" ), "SHOULD *NOT* SEE: require_action_string" );
2645 goto require24Good;
2646 require24:
2647 { err = kResponseErr; goto exit; }
2648 require24Good:
2650 #if ( defined( __MWERKS__ ) )
2651 #if ( defined( __cplusplus ) && __option( exceptions ) )
2652 #define COMPILER_HAS_EXCEPTIONS 1
2653 #else
2654 #define COMPILER_HAS_EXCEPTIONS 0
2655 #endif
2656 #else
2657 #if ( defined( __cplusplus ) )
2658 #define COMPILER_HAS_EXCEPTIONS 1
2659 #else
2660 #define COMPILER_HAS_EXCEPTIONS 0
2661 #endif
2662 #endif
2664 #if ( COMPILER_HAS_EXCEPTIONS )
2667 require_throw( 1 && "SHOULD *NOT* SEE" );
2668 require_throw( 0 && "SHOULD SEE" );
2670 catch(... )
2672 goto require26Good;
2674 { err = kResponseErr; goto exit; }
2675 require26Good:
2676 #endif
2678 // translate_errno
2680 err = translate_errno( 1 != -1, -123, -567 );
2681 require( ( err == 0 ) && "SHOULD *NOT* SEE", exit );
2683 err = translate_errno( -1 != -1, -123, -567 );
2684 require( ( err == -123 ) && "SHOULD *NOT* SEE", exit );
2686 err = translate_errno( -1 != -1, 0, -567 );
2687 require( ( err == -567 ) && "SHOULD *NOT* SEE", exit );
2689 // debug_string
2691 debug_string( "debug_string" );
2693 // DebugSNPrintF
2695 DebugSNPrintF( s, sizeof( s ), "%d", 1234 );
2696 require_action( strcmp( s, "1234" ) == 0, exit, err = -1 );
2698 DebugSNPrintF( s, sizeof( s ), "%X", 0x2345 );
2699 require_action( strcmp( s, "2345" ) == 0, exit, err = -1 );
2701 DebugSNPrintF( s, sizeof( s ), "%#s", "\05test" );
2702 require_action( strcmp( s, "test" ) == 0, exit, err = -1 );
2704 DebugSNPrintF( s, sizeof( s ), "%##s", "\03www\05apple\03com" );
2705 require_action( strcmp( s, "www.apple.com." ) == 0, exit, err = -1 );
2707 DebugSNPrintF( s, sizeof( s ), "%ld", (long) INT32_C( 2147483647 ) );
2708 require_action( strcmp( s, "2147483647" ) == 0, exit, err = -1 );
2710 DebugSNPrintF( s, sizeof( s ), "%lu", (unsigned long) UINT32_C( 4294967295 ) );
2711 require_action( strcmp( s, "4294967295" ) == 0, exit, err = -1 );
2713 #if ( TYPE_LONGLONG_NATIVE )
2714 DebugSNPrintF( s, sizeof( s ), "%lld", (long_long_compat) INT64_C( 9223372036854775807 ) );
2715 require_action( strcmp( s, "9223372036854775807" ) == 0, exit, err = -1 );
2717 DebugSNPrintF( s, sizeof( s ), "%lld", (long_long_compat) INT64_C( -9223372036854775807 ) );
2718 require_action( strcmp( s, "-9223372036854775807" ) == 0, exit, err = -1 );
2720 DebugSNPrintF( s, sizeof( s ), "%llu", (unsigned_long_long_compat) UINT64_C( 18446744073709551615 ) );
2721 require_action( strcmp( s, "18446744073709551615" ) == 0, exit, err = -1 );
2722 #endif
2724 DebugSNPrintF( s, sizeof( s ), "%lb", (unsigned long) binary_32( 01111011, 01111011, 01111011, 01111011 ) );
2725 require_action( strcmp( s, "1111011011110110111101101111011" ) == 0, exit, err = -1 );
2727 DebugSNPrintF( s, sizeof( s ), "%C", 0x41624364 ); // 'AbCd'
2728 require_action( strcmp( s, "AbCd" ) == 0, exit, err = -1 );
2730 #if ( defined( MDNS_DEBUGMSGS ) )
2732 mDNSAddr maddr;
2734 memset( &maddr, 0, sizeof( maddr ) );
2735 maddr.type = mDNSAddrType_IPv4;
2736 maddr.ip.v4.b[ 0 ] = 127;
2737 maddr.ip.v4.b[ 1 ] = 0;
2738 maddr.ip.v4.b[ 2 ] = 0;
2739 maddr.ip.v4.b[ 3 ] = 1;
2740 DebugSNPrintF( s, sizeof( s ), "%#a", &maddr );
2741 require_action( strcmp( s, "127.0.0.1" ) == 0, exit, err = -1 );
2743 memset( &maddr, 0, sizeof( maddr ) );
2744 maddr.type = mDNSAddrType_IPv6;
2745 maddr.ip.v6.b[ 0 ] = 0xFE;
2746 maddr.ip.v6.b[ 1 ] = 0x80;
2747 maddr.ip.v6.b[ 15 ] = 0x01;
2748 DebugSNPrintF( s, sizeof( s ), "%#a", &maddr );
2749 require_action( strcmp( s, "FE80:0000:0000:0000:0000:0000:0000:0001" ) == 0, exit, err = -1 );
2751 #endif
2753 #if ( AF_INET )
2755 struct sockaddr_in sa4;
2757 memset( &sa4, 0, sizeof( sa4 ) );
2758 sa4.sin_family = AF_INET;
2759 p = (uint8_t *) &sa4.sin_port;
2760 p[ 0 ] = (uint8_t)( ( 80 >> 8 ) & 0xFF );
2761 p[ 1 ] = (uint8_t)( 80 & 0xFF );
2762 p = (uint8_t *) &sa4.sin_addr.s_addr;
2763 p[ 0 ] = (uint8_t)( ( INADDR_LOOPBACK >> 24 ) & 0xFF );
2764 p[ 1 ] = (uint8_t)( ( INADDR_LOOPBACK >> 16 ) & 0xFF );
2765 p[ 2 ] = (uint8_t)( ( INADDR_LOOPBACK >> 8 ) & 0xFF );
2766 p[ 3 ] = (uint8_t)( INADDR_LOOPBACK & 0xFF );
2767 DebugSNPrintF( s, sizeof( s ), "%##a", &sa4 );
2768 require_action( strcmp( s, "127.0.0.1:80" ) == 0, exit, err = -1 );
2770 #endif
2772 #if ( AF_INET6 )
2774 struct sockaddr_in6 sa6;
2776 memset( &sa6, 0, sizeof( sa6 ) );
2777 sa6.sin6_family = AF_INET6;
2778 p = (uint8_t *) &sa6.sin6_port;
2779 p[ 0 ] = (uint8_t)( ( 80 >> 8 ) & 0xFF );
2780 p[ 1 ] = (uint8_t)( 80 & 0xFF );
2781 sa6.sin6_addr.s6_addr[ 0 ] = 0xFE;
2782 sa6.sin6_addr.s6_addr[ 1 ] = 0x80;
2783 sa6.sin6_addr.s6_addr[ 15 ] = 0x01;
2784 sa6.sin6_scope_id = 2;
2785 DebugSNPrintF( s, sizeof( s ), "%##a", &sa6 );
2786 require_action( strcmp( s, "[FE80:0000:0000:0000:0000:0000:0000:0001%2]:80" ) == 0, exit, err = -1 );
2788 #endif
2790 // Unicode
2792 DebugSNPrintF(s, sizeof(s), "%.*s", 4, "tes" );
2793 require_action( strcmp( s, "tes" ) == 0, exit, err = kResponseErr );
2795 DebugSNPrintF(s, sizeof(s), "%.*s", 4, "test" );
2796 require_action( strcmp( s, "test" ) == 0, exit, err = kResponseErr );
2798 DebugSNPrintF(s, sizeof(s), "%.*s", 4, "testing" );
2799 require_action( strcmp( s, "test" ) == 0, exit, err = kResponseErr );
2801 DebugSNPrintF(s, sizeof(s), "%.*s", 4, "te\xC3\xA9" );
2802 require_action( strcmp( s, "te\xC3\xA9" ) == 0, exit, err = kResponseErr );
2804 DebugSNPrintF(s, sizeof(s), "%.*s", 4, "te\xC3\xA9ing" );
2805 require_action( strcmp( s, "te\xC3\xA9" ) == 0, exit, err = kResponseErr );
2807 DebugSNPrintF(s, sizeof(s), "%.*s", 4, "tes\xC3\xA9ing" );
2808 require_action( strcmp( s, "tes" ) == 0, exit, err = kResponseErr );
2810 DebugSNPrintF(s, sizeof(s), "%.*s", 4, "t\xed\x9f\xbf" );
2811 require_action( strcmp( s, "t\xed\x9f\xbf" ) == 0, exit, err = kResponseErr );
2813 DebugSNPrintF(s, sizeof(s), "%.*s", 4, "t\xed\x9f\xbfing" );
2814 require_action( strcmp( s, "t\xed\x9f\xbf" ) == 0, exit, err = kResponseErr );
2816 DebugSNPrintF(s, sizeof(s), "%.*s", 4, "te\xed\x9f\xbf" );
2817 require_action( strcmp( s, "te" ) == 0, exit, err = kResponseErr );
2819 DebugSNPrintF(s, sizeof(s), "%.*s", 4, "te\xed\x9f\xbfing" );
2820 require_action( strcmp( s, "te" ) == 0, exit, err = kResponseErr );
2822 DebugSNPrintF(s, sizeof(s), "%.*s", 7, "te\xC3\xA9\xed\x9f\xbfing" );
2823 require_action( strcmp( s, "te\xC3\xA9\xed\x9f\xbf" ) == 0, exit, err = kResponseErr );
2825 DebugSNPrintF(s, sizeof(s), "%.*s", 6, "te\xC3\xA9\xed\x9f\xbfing" );
2826 require_action( strcmp( s, "te\xC3\xA9" ) == 0, exit, err = kResponseErr );
2828 DebugSNPrintF(s, sizeof(s), "%.*s", 5, "te\xC3\xA9\xed\x9f\xbfing" );
2829 require_action( strcmp( s, "te\xC3\xA9" ) == 0, exit, err = kResponseErr );
2831 #if ( TARGET_RT_BIG_ENDIAN )
2832 DebugSNPrintF( s, sizeof( s ), "%S", "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" );
2833 require_action( strcmp( s, "abcd" ) == 0, exit, err = -1 );
2834 #else
2835 DebugSNPrintF( s, sizeof( s ), "%S", "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" "\x00" );
2836 require_action( strcmp( s, "abcd" ) == 0, exit, err = -1 );
2837 #endif
2839 DebugSNPrintF( s, sizeof( s ), "%S",
2840 "\xFE\xFF" "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" ); // Big Endian BOM
2841 require_action( strcmp( s, "abcd" ) == 0, exit, err = -1 );
2843 DebugSNPrintF( s, sizeof( s ), "%S",
2844 "\xFF\xFE" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" "\x00" ); // Little Endian BOM
2845 require_action( strcmp( s, "abcd" ) == 0, exit, err = -1 );
2847 DebugSNPrintF( s, sizeof( s ), "%#S", "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" ); // Big Endian
2848 require_action( strcmp( s, "abcd" ) == 0, exit, err = -1 );
2850 DebugSNPrintF( s, sizeof( s ), "%##S", "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" "\x00" ); // Little Endian
2851 require_action( strcmp( s, "abcd" ) == 0, exit, err = -1 );
2853 DebugSNPrintF( s, sizeof( s ), "%.*S",
2854 4, "\xFE\xFF" "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" ); // Big Endian BOM
2855 require_action( strcmp( s, "abc" ) == 0, exit, err = -1 );
2857 DebugSNPrintF( s, sizeof( s ), "%.*S",
2858 4, "\xFF\xFE" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" ); // Little Endian BOM
2859 require_action( strcmp( s, "abc" ) == 0, exit, err = -1 );
2861 #if ( TARGET_RT_BIG_ENDIAN )
2862 DebugSNPrintF( s, sizeof( s ), "%.*S", 3, "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" );
2863 require_action( strcmp( s, "abc" ) == 0, exit, err = -1 );
2864 #else
2865 DebugSNPrintF( s, sizeof( s ), "%.*S", 3, "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" );
2866 require_action( strcmp( s, "abc" ) == 0, exit, err = -1 );
2867 #endif
2869 DebugSNPrintF( s, sizeof( s ), "%#.*S", 3, "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" ); // Big Endian
2870 require_action( strcmp( s, "abc" ) == 0, exit, err = -1 );
2872 DebugSNPrintF( s, sizeof( s ), "%##.*S", 3, "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" ); // Little Endian
2873 require_action( strcmp( s, "abc" ) == 0, exit, err = -1 );
2875 // Misc
2877 DebugSNPrintF( s, sizeof( s ), "%U", "\x10\xb8\xa7\x6b" "\xad\x9d" "\xd1\x11" "\x80\xb4" "\x00\xc0\x4f\xd4\x30\xc8" );
2878 require_action( strcmp( s, "6ba7b810-9dad-11d1-80b4-00c04fd430c8" ) == 0, exit, err = -1 );
2880 DebugSNPrintF( s, sizeof( s ), "%m", 0 );
2881 require_action( strcmp( s, "no error" ) == 0, exit, err = -1 );
2883 DebugSNPrintF( s, sizeof( s ), "%lm", (long) 0 );
2884 require_action( strcmp( s, "no error" ) == 0, exit, err = -1 );
2886 DebugSNPrintF( s, sizeof( s ), "\"%H\"", "\x6b\xa7\xb8\x10\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8", 16, 16 );
2887 DebugPrintF( kDebugLevelMax, "%s\n\n", s );
2889 DebugSNPrintF( s, sizeof( s ), "\"%H\"",
2890 "\x6b\xa7\xb8\x10\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8"
2891 "\x6b\xa7\xb8\x10\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8",
2892 32, 32 );
2893 DebugPrintF( kDebugLevelMax, "%s\n\n", s );
2895 DebugSNPrintF( s, sizeof( s ), "\"%H\"", "\x6b\xa7", 2, 2 );
2896 DebugPrintF( kDebugLevelMax, "%s\n\n", s );
2898 // Hex Dumps
2900 s[ 0 ] = '\0';
2901 DebugHexDump( kDebugLevelMax, 0, "My Label", kSizeCString, 0, NULL, 0, data, data, sizeof( data ),
2902 kDebugFlagsNone, s, sizeof( s ) );
2903 DebugPrintF( kDebugLevelMax, "%s\n", s );
2905 s[ 0 ] = '\0';
2906 DebugHexDump( kDebugLevelMax, 0, NULL, 0, 0, NULL, 0, data, data, sizeof( data ),
2907 kDebugFlagsNoAddress | kDebugFlagsNoOffset, s, sizeof( s ) );
2908 DebugPrintF( kDebugLevelMax, "%s\n", s );
2910 s[ 0 ] = '\0';
2911 DebugHexDump( kDebugLevelMax, 0, "My Label", kSizeCString, 0, NULL, 0, data, data, sizeof( data ),
2912 kDebugFlagsNoAddress | kDebugFlagsNoOffset, s, sizeof( s ) );
2913 DebugPrintF( kDebugLevelMax, "%s\n", s );
2915 s[ 0 ] = '\0';
2916 DebugHexDump( kDebugLevelMax, 0, "My Label", kSizeCString, 0, NULL, 0, data, data, sizeof( data ),
2917 kDebugFlagsNoAddress, s, sizeof( s ) );
2918 DebugPrintF( kDebugLevelMax, "%s\n", s );
2920 s[ 0 ] = '\0';
2921 DebugHexDump( kDebugLevelMax, 0, NULL, 0, 0, NULL, 0, data, data, sizeof( data ),
2922 kDebugFlagsNoOffset, s, sizeof( s ) );
2923 DebugPrintF( kDebugLevelMax, "%s\n", s );
2925 s[ 0 ] = '\0';
2926 DebugHexDump( kDebugLevelMax, 0, NULL, 0, 0, NULL, 0, data, data, sizeof( data ),
2927 kDebugFlagsNoAddress, s, sizeof( s ) );
2928 DebugPrintF( kDebugLevelMax, "%s\n", s );
2930 s[ 0 ] = '\0';
2931 DebugHexDump( kDebugLevelMax, 0, NULL, 0, 0, NULL, 0, data, data, sizeof( data ),
2932 kDebugFlagsNoOffset, s, sizeof( s ) );
2933 DebugPrintF( kDebugLevelMax, "%s\n", s );
2935 s[ 0 ] = '\0';
2936 DebugHexDump( kDebugLevelMax, 0, NULL, 0, 0, NULL, 0, data, data, sizeof( data ),
2937 kDebugFlagsNoByteCount, s, sizeof( s ) );
2938 DebugPrintF( kDebugLevelMax, "%s\n", s );
2940 s[ 0 ] = '\0';
2941 DebugHexDump( kDebugLevelMax, 0, NULL, 0, 0, NULL, 0, "\x41\x62\x43\x64", "\x41\x62\x43\x64", 4, // 'AbCd'
2942 kDebugFlagsNoAddress | kDebugFlagsNoOffset | kDebugFlagsNoNewLine |
2943 kDebugFlagsNo32BitSeparator | kDebugFlagsNo16ByteHexPad | kDebugFlagsNoByteCount,
2944 s, sizeof( s ) );
2945 DebugPrintF( kDebugLevelMax, "%s\n", s );
2947 s[ 0 ] = '\0';
2948 DebugHexDump( kDebugLevelMax, 0, NULL, 0, 0, NULL, 0, data, data, sizeof( data ),
2949 kDebugFlagsNoAddress | kDebugFlagsNoOffset | kDebugFlagsNoASCII | kDebugFlagsNoNewLine |
2950 kDebugFlags16BitSeparator | kDebugFlagsNo32BitSeparator |
2951 kDebugFlagsNo16ByteHexPad | kDebugFlagsNoByteCount, s, sizeof( s ) );
2952 DebugPrintF( kDebugLevelMax, "%s\n", s );
2954 s[ 0 ] = '\0';
2955 DebugHexDump( kDebugLevelMax, 8, NULL, 0, 0, NULL, 0, data, data, sizeof( data ), kDebugFlagsNone, s, sizeof( s ) );
2956 DebugPrintF( kDebugLevelMax, "%s\n", s );
2958 // dlog's
2960 dlog( kDebugLevelNotice, "dlog\n" );
2961 dlog( kDebugLevelNotice, "dlog integer: %d\n", 123 );
2962 dlog( kDebugLevelNotice, "dlog string: \"%s\"\n", "test string" );
2963 dlogmem( kDebugLevelNotice, data, sizeof( data ) );
2965 // Done
2967 DebugPrintF( kDebugLevelMax, "\n\nALL TESTS DONE\n\n" );
2968 err = kNoErr;
2970 exit:
2971 if( err )
2973 DebugPrintF( kDebugLevelMax, "\n\n### TEST FAILED ###\n\n" );
2975 return err;
2978 #endif // DEBUG