2 * Copyright (c) 1997-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
25 Change History (most recent first):
27 $Log: DebugServices.c,v $
28 Revision 1.4 2004/04/15 08:59:08 bradley
29 Removed deprecated debug and log levels and replaced them with modern equivalents.
31 Revision 1.3 2004/04/08 09:29:55 bradley
32 Manually do host->network byte order conversion to avoid needing libraries for htons/htonl. Changed
33 hex dumps to better separate hex and ASCII. Added support for %.8a syntax in DebugSNPrintF for Fibre
34 Channel addresses (00:11:22:33:44:55:66:77). Fixed a few places where HeaderDoc was incorrect.
36 Revision 1.2 2004/03/07 05:59:34 bradley
37 Sync'd with internal version: Added expect macros, error codes, and CoreServices exclusion.
39 Revision 1.1 2004/01/30 02:27:30 bradley
40 Debugging support for various platforms.
45 - Use StackWalk on Windows to optionally print stack frames.
49 #pragma mark == Includes ==
52 //===========================================================================================================================
54 //===========================================================================================================================
62 #include "CommonServices.h"
64 #include "DebugServices.h"
68 #if( TARGET_OS_VXWORKS )
72 #if( TARGET_OS_WIN32 )
75 #if( !TARGET_OS_WINDOWS_CE )
81 #if( DEBUG_IDEBUG_ENABLED && TARGET_API_MAC_OSX_KERNEL )
82 #include <IOKit/IOLib.h>
85 // If MDNS_DEBUGMSGS is defined (even if defined 0), it is aware of mDNS and it is probably safe to include mDNSClientAPI.h.
87 #if( defined( MDNS_DEBUGMSGS ) )
88 #include "mDNSClientAPI.h"
92 #pragma mark == Macros ==
95 //===========================================================================================================================
97 //===========================================================================================================================
99 #define DebugIsPrint( C ) ( ( ( C ) >= 0x20 ) && ( ( C ) <= 0x7E ) )
102 #pragma mark == Prototypes ==
105 //===========================================================================================================================
107 //===========================================================================================================================
109 static OSStatus
DebugPrint( DebugLevel inLevel
, char *inData
, size_t inSize
);
113 #if( DEBUG_FPRINTF_ENABLED )
114 static OSStatus
DebugFPrintFInit( DebugOutputTypeFlags inFlags
, const char *inFilename
);
115 static void DebugFPrintFPrint( char *inData
, size_t inSize
);
118 // iDebug (Mac OS X user and kernel)
120 #if( DEBUG_IDEBUG_ENABLED )
121 static OSStatus
DebugiDebugInit( void );
122 static void DebugiDebugPrint( char *inData
, size_t inSize
);
125 // kprintf (Mac OS X Kernel)
127 #if( DEBUG_KPRINTF_ENABLED )
128 static void DebugKPrintFPrint( char *inData
, size_t inSize
);
131 // Mac OS X IOLog (Mac OS X Kernel)
133 #if( DEBUG_MAC_OS_X_IOLOG_ENABLED )
134 static void DebugMacOSXIOLogPrint( char *inData
, size_t inSize
);
140 static OSStatus
DebugMacOSXLogInit( void );
141 static void DebugMacOSXLogPrint( char *inData
, size_t inSize
);
146 #if( TARGET_OS_WIN32 )
147 static void DebugWindowsDebuggerPrint( char *inData
, size_t inSize
);
152 #if( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
153 static OSStatus
DebugWindowsEventLogInit( const char *inName
, HMODULE inModule
);
154 static void DebugWindowsEventLogPrint( DebugLevel inLevel
, char *inData
, size_t inSize
);
159 #if( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
161 DebugAssertOutputHandler(
162 OSType inComponentSignature
,
164 const char * inAssertionString
,
165 const char * inExceptionString
,
166 const char * inErrorString
,
167 const char * inFileName
,
170 ConstStr255Param inOutputMsg
);
175 static char * DebugNumVersionToString( uint32_t inVersion
, char *inString
);
177 #if( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
178 static void DebugWinEnableConsole( void );
181 #if( TARGET_OS_WIN32 )
183 DebugWinCharToTCharString(
184 const char * inCharString
,
186 TCHAR
* outTCharString
,
187 size_t inTCharCountMax
,
188 size_t * outTCharCount
);
192 #pragma mark == Globals ==
195 //===========================================================================================================================
197 //===========================================================================================================================
199 #if( TARGET_OS_VXWORKS )
200 // TCP States for inetstatShow.
202 extern char ** pTcpstates
; // defined in tcpLib.c
204 const char * kDebugTCPStates
[] =
209 "(3) TCPS_SYN_RECEIVED",
210 "(4) TCPS_ESTABLISHED",
211 "(5) TCPS_CLOSE_WAIT",
212 "(6) TCPS_FIN_WAIT_1",
215 "(9) TCPS_FIN_WAIT_2",
216 "(10) TCPS_TIME_WAIT",
222 static bool gDebugInitialized
= false;
223 static DebugOutputType gDebugOutputType
= kDebugOutputTypeNone
;
224 static DebugLevel gDebugPrintLevelMin
= kDebugLevelInfo
;
225 static DebugLevel gDebugPrintLevelMax
= kDebugLevelMax
;
226 static DebugLevel gDebugBreakLevel
= kDebugLevelAssert
;
227 #if( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
228 static DebugAssertOutputHandlerUPP gDebugAssertOutputHandlerUPP
= NULL
;
233 static DebugOutputFunctionPtr gDebugCustomOutputFunction
= NULL
;
234 static void * gDebugCustomOutputContext
= NULL
;
238 #if( DEBUG_FPRINTF_ENABLED )
239 static FILE * gDebugFPrintFFile
= NULL
;
245 typedef int ( *DebugMacOSXLogFunctionPtr
)( const char *inFormat
, ... );
247 static DebugMacOSXLogFunctionPtr gDebugMacOSXLogFunction
= NULL
;
253 #if( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
254 static HANDLE gDebugWindowsEventLogEventSource
= NULL
;
259 #pragma mark == General ==
262 //===========================================================================================================================
264 //===========================================================================================================================
266 DEBUG_EXPORT OSStatus
DebugInitialize( DebugOutputType inType
, ... )
269 DebugOutputType type
;
272 va_start( args
, inType
);
274 #if( TARGET_OS_VXWORKS )
275 // Set up the TCP state strings if they are not already set up by VxWorks (normally not set up for some reason).
279 pTcpstates
= (char **) kDebugTCPStates
;
283 // Set up DebugLib stuff (if building with Debugging.h).
285 #if( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
286 if( !gDebugAssertOutputHandlerUPP
)
288 gDebugAssertOutputHandlerUPP
= NewDebugAssertOutputHandlerUPP( DebugAssertOutputHandler
);
289 check( gDebugAssertOutputHandlerUPP
);
290 if( gDebugAssertOutputHandlerUPP
)
292 InstallDebugAssertOutputHandler( gDebugAssertOutputHandlerUPP
);
297 // Pre-process meta-output kind to pick an appropriate output kind for the platform.
300 if( type
== kDebugOutputTypeMetaConsole
)
303 type
= kDebugOutputTypeMacOSXLog
;
304 #elif( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
305 #if( DEBUG_FPRINTF_ENABLED )
306 type
= kDebugOutputTypeFPrintF
;
308 type
= kDebugOutputTypeWindowsDebugger
;
310 #elif( TARGET_API_MAC_OSX_KERNEL )
311 #if( DEBUG_MAC_OS_X_IOLOG_ENABLED )
312 type
= kDebugOutputTypeMacOSXIOLog
;
313 #elif( DEBUG_IDEBUG_ENABLED )
314 type
= kDebugOutputTypeiDebug
;
315 #elif( DEBUG_KPRINTF_ENABLED )
316 type
= kDebugOutputTypeKPrintF
;
318 #elif( TARGET_OS_VXWORKS )
319 #if( DEBUG_FPRINTF_ENABLED )
320 type
= kDebugOutputTypeFPrintF
;
322 #error target is VxWorks, but fprintf output is disabled
325 #if( DEBUG_FPRINTF_ENABLED )
326 type
= kDebugOutputTypeFPrintF
;
331 // Process output kind.
333 gDebugOutputType
= type
;
336 case kDebugOutputTypeNone
:
340 case kDebugOutputTypeCustom
:
341 gDebugCustomOutputFunction
= va_arg( args
, DebugOutputFunctionPtr
);
342 gDebugCustomOutputContext
= va_arg( args
, void * );
346 #if( DEBUG_FPRINTF_ENABLED )
347 case kDebugOutputTypeFPrintF
:
348 if( inType
== kDebugOutputTypeMetaConsole
)
350 err
= DebugFPrintFInit( kDebugOutputTypeFlagsStdErr
, NULL
);
354 DebugOutputTypeFlags flags
;
355 const char * filename
;
357 flags
= (DebugOutputTypeFlags
) va_arg( args
, unsigned int );
358 if( ( flags
& kDebugOutputTypeFlagsTypeMask
) == kDebugOutputTypeFlagsFile
)
360 filename
= va_arg( args
, const char * );
366 err
= DebugFPrintFInit( flags
, filename
);
371 #if( DEBUG_IDEBUG_ENABLED )
372 case kDebugOutputTypeiDebug
:
373 err
= DebugiDebugInit();
377 #if( DEBUG_KPRINTF_ENABLED )
378 case kDebugOutputTypeKPrintF
:
383 #if( DEBUG_MAC_OS_X_IOLOG_ENABLED )
384 case kDebugOutputTypeMacOSXIOLog
:
390 case kDebugOutputTypeMacOSXLog
:
391 err
= DebugMacOSXLogInit();
395 #if( TARGET_OS_WIN32 )
396 case kDebugOutputTypeWindowsDebugger
:
401 #if( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
402 case kDebugOutputTypeWindowsEventLog
:
407 name
= va_arg( args
, const char * );
408 module = va_arg( args
, HMODULE
);
409 err
= DebugWindowsEventLogInit( name
, module );
418 gDebugInitialized
= true;
425 //===========================================================================================================================
427 //===========================================================================================================================
429 DEBUG_EXPORT
void DebugFinalize( void )
431 #if( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
432 check( gDebugAssertOutputHandlerUPP
);
433 if( gDebugAssertOutputHandlerUPP
)
435 InstallDebugAssertOutputHandler( NULL
);
436 DisposeDebugAssertOutputHandlerUPP( gDebugAssertOutputHandlerUPP
);
437 gDebugAssertOutputHandlerUPP
= NULL
;
442 //===========================================================================================================================
444 //===========================================================================================================================
446 DEBUG_EXPORT OSStatus
DebugGetProperty( DebugPropertyTag inTag
, ... )
452 va_start( args
, inTag
);
455 case kDebugPropertyTagPrintLevelMin
:
456 level
= va_arg( args
, DebugLevel
* );
457 *level
= gDebugPrintLevelMin
;
461 case kDebugPropertyTagPrintLevelMax
:
462 level
= va_arg( args
, DebugLevel
* );
463 *level
= gDebugPrintLevelMax
;
467 case kDebugPropertyTagBreakLevel
:
468 level
= va_arg( args
, DebugLevel
* );
469 *level
= gDebugBreakLevel
;
474 err
= kUnsupportedErr
;
481 //===========================================================================================================================
483 //===========================================================================================================================
485 DEBUG_EXPORT OSStatus
DebugSetProperty( DebugPropertyTag inTag
, ... )
491 va_start( args
, inTag
);
494 case kDebugPropertyTagPrintLevelMin
:
495 level
= va_arg( args
, DebugLevel
);
496 gDebugPrintLevelMin
= level
;
500 case kDebugPropertyTagPrintLevelMax
:
501 level
= va_arg( args
, DebugLevel
);
502 gDebugPrintLevelMax
= level
;
506 case kDebugPropertyTagBreakLevel
:
507 level
= va_arg( args
, DebugLevel
);
508 gDebugBreakLevel
= level
;
513 err
= kUnsupportedErr
;
522 #pragma mark == Output ==
525 //===========================================================================================================================
527 //===========================================================================================================================
529 DEBUG_EXPORT
size_t DebugPrintF( DebugLevel inLevel
, const char *inFormat
, ... )
534 // Skip if the level is not in the enabled range..
536 if( ( inLevel
< gDebugPrintLevelMin
) || ( inLevel
> gDebugPrintLevelMax
) )
542 va_start( args
, inFormat
);
543 n
= DebugPrintFVAList( inLevel
, inFormat
, args
);
550 //===========================================================================================================================
552 //===========================================================================================================================
554 DEBUG_EXPORT
size_t DebugPrintFVAList( DebugLevel inLevel
, const char *inFormat
, va_list inArgs
)
559 // Skip if the level is not in the enabled range..
561 if( ( inLevel
< gDebugPrintLevelMin
) || ( inLevel
> gDebugPrintLevelMax
) )
567 n
= DebugSNPrintFVAList( buffer
, sizeof( buffer
), inFormat
, inArgs
);
568 DebugPrint( inLevel
, buffer
, (size_t) n
);
574 //===========================================================================================================================
576 //===========================================================================================================================
578 static OSStatus
DebugPrint( DebugLevel inLevel
, char *inData
, size_t inSize
)
582 // Skip if the level is not in the enabled range..
584 if( ( inLevel
< gDebugPrintLevelMin
) || ( inLevel
> gDebugPrintLevelMax
) )
590 // Printing is not safe at interrupt time so check for this and warn with an interrupt safe mechanism (if available).
592 if( DebugTaskLevel() & kDebugInterruptLevelMask
)
594 #if( TARGET_OS_VXWORKS )
595 logMsg( "\ncannot print at interrupt time\n\n", 1, 2, 3, 4, 5, 6 );
598 err
= kExecutionStateErr
;
602 // Initialize the debugging library if it hasn't already been initialized (allows for zero-config usage).
604 if( !gDebugInitialized
)
606 debug_initialize( kDebugOutputTypeMetaConsole
);
609 // Print based on the current output type.
611 switch( gDebugOutputType
)
613 case kDebugOutputTypeNone
:
616 case kDebugOutputTypeCustom
:
617 if( gDebugCustomOutputFunction
)
619 gDebugCustomOutputFunction( inData
, inSize
, gDebugCustomOutputContext
);
623 #if( DEBUG_FPRINTF_ENABLED )
624 case kDebugOutputTypeFPrintF
:
625 DebugFPrintFPrint( inData
, inSize
);
629 #if( DEBUG_IDEBUG_ENABLED )
630 case kDebugOutputTypeiDebug
:
631 DebugiDebugPrint( inData
, inSize
);
635 #if( DEBUG_KPRINTF_ENABLED )
636 case kDebugOutputTypeKPrintF
:
637 DebugKPrintFPrint( inData
, inSize
);
641 #if( DEBUG_MAC_OS_X_IOLOG_ENABLED )
642 case kDebugOutputTypeMacOSXIOLog
:
643 DebugMacOSXIOLogPrint( inData
, inSize
);
648 case kDebugOutputTypeMacOSXLog
:
649 DebugMacOSXLogPrint( inData
, inSize
);
653 #if( TARGET_OS_WIN32 )
654 case kDebugOutputTypeWindowsDebugger
:
655 DebugWindowsDebuggerPrint( inData
, inSize
);
659 #if( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
660 case kDebugOutputTypeWindowsEventLog
:
661 DebugWindowsEventLogPrint( inLevel
, inData
, inSize
);
674 //===========================================================================================================================
677 // Warning: This routine relies on several of the strings being string constants that will exist forever because the
678 // underlying logMsg API that does the printing is asynchronous so it cannot use temporary/stack-based
679 // pointer variables (e.g. local strings). The debug macros that invoke this function only use constant
680 // constant strings, but if this function is invoked directly from other places, it must use constant strings.
681 //===========================================================================================================================
685 int_least32_t inErrorCode
,
686 const char * inAssertString
,
687 const char * inMessage
,
688 const char * inFilename
,
689 int_least32_t inLineNumber
,
690 const char * inFunction
)
692 // Skip if the level is not in the enabled range..
694 if( ( kDebugLevelAssert
< gDebugPrintLevelMin
) || ( kDebugLevelAssert
> gDebugPrintLevelMax
) )
699 if( inErrorCode
!= 0 )
704 "[ASSERT] error: %ld (%m)\n"
705 "[ASSERT] where: \"%s\", line %ld, \"%s\"\n"
707 inErrorCode
, inErrorCode
,
708 inFilename
? inFilename
: "",
710 inFunction
? inFunction
: "" );
717 "[ASSERT] assert: \"%s\" %s\n"
718 "[ASSERT] where: \"%s\", line %ld, \"%s\"\n"
720 inAssertString
? inAssertString
: "",
721 inMessage
? inMessage
: "",
722 inFilename
? inFilename
: "",
724 inFunction
? inFunction
: "" );
727 // Break into the debugger if enabled.
729 #if( TARGET_OS_WIN32 )
730 if( gDebugBreakLevel
<= kDebugLevelAssert
)
732 if( IsDebuggerPresent() )
744 #if( DEBUG_FPRINTF_ENABLED )
745 //===========================================================================================================================
747 //===========================================================================================================================
749 static OSStatus
DebugFPrintFInit( DebugOutputTypeFlags inFlags
, const char *inFilename
)
752 DebugOutputTypeFlags typeFlags
;
754 typeFlags
= inFlags
& kDebugOutputTypeFlagsTypeMask
;
755 if( typeFlags
== kDebugOutputTypeFlagsStdOut
)
757 #if( TARGET_OS_WIN32 )
758 DebugWinEnableConsole();
761 gDebugFPrintFFile
= stdout
;
763 else if( typeFlags
== kDebugOutputTypeFlagsStdErr
)
765 #if( TARGET_OS_WIN32 )
766 DebugWinEnableConsole();
769 gDebugFPrintFFile
= stdout
;
771 else if( typeFlags
== kDebugOutputTypeFlagsFile
)
773 require_action_quiet( inFilename
&& ( *inFilename
!= '\0' ), exit
, err
= kOpenErr
);
775 gDebugFPrintFFile
= fopen( inFilename
, "a" );
776 require_action_quiet( gDebugFPrintFFile
, exit
, err
= kOpenErr
);
789 //===========================================================================================================================
791 //===========================================================================================================================
793 static void DebugFPrintFPrint( char *inData
, size_t inSize
)
798 // Convert \r to \n. fprintf will interpret \n and convert to whatever is appropriate for the platform.
811 // Write the data and flush.
813 if( gDebugFPrintFFile
)
815 fprintf( gDebugFPrintFFile
, "%.*s", (int) inSize
, inData
);
816 fflush( gDebugFPrintFFile
);
819 #endif // DEBUG_FPRINTF_ENABLED
821 #if( DEBUG_IDEBUG_ENABLED )
822 //===========================================================================================================================
824 //===========================================================================================================================
826 static OSStatus
DebugiDebugInit( void )
830 #if( TARGET_API_MAC_OSX_KERNEL )
832 extern uint32_t * _giDebugReserved1
;
834 // Emulate the iDebugSetOutputType macro in iDebugServices.h.
835 // Note: This is not thread safe, but neither is iDebugServices.h nor iDebugKext.
837 if( !_giDebugReserved1
)
839 _giDebugReserved1
= (uint32_t *) IOMalloc( sizeof( uint32_t ) );
840 require_action_quiet( _giDebugReserved1
, exit
, err
= kNoMemoryErr
);
842 *_giDebugReserved1
= 0x00010000U
;
847 __private_extern__
void iDebugSetOutputTypeInternal( uint32_t inType
);
849 iDebugSetOutputTypeInternal( 0x00010000U
);
857 //===========================================================================================================================
859 //===========================================================================================================================
861 static void DebugiDebugPrint( char *inData
, size_t inSize
)
863 #if( TARGET_API_MAC_OSX_KERNEL )
865 // Locally declared here so we do not need to include iDebugKext.h.
866 // Note: IOKit uses a global namespace for all code and only a partial link occurs at build time. When the
867 // KEXT is loaded, the runtime linker will link in this extern'd symbol (assuming iDebug is present).
868 // _giDebugLogInternal is actually part of IOKit proper so this should link even if iDebug is not present.
870 typedef void ( *iDebugLogFunctionPtr
)( uint32_t inLevel
, uint32_t inTag
, const char *inFormat
, ... );
872 extern iDebugLogFunctionPtr _giDebugLogInternal
;
874 if( _giDebugLogInternal
)
876 _giDebugLogInternal( 0, 0, "%.*s", (int) inSize
, inData
);
881 __private_extern__
void iDebugLogInternal( uint32_t inLevel
, uint32_t inTag
, const char *inFormat
, ... );
883 iDebugLogInternal( 0, 0, "%.*s", (int) inSize
, inData
);
889 #if( DEBUG_KPRINTF_ENABLED )
890 //===========================================================================================================================
892 //===========================================================================================================================
894 static void DebugKPrintFPrint( char *inData
, size_t inSize
)
896 extern void kprintf( const char *inFormat
, ... );
898 kprintf( "%.*s", (int) inSize
, inData
);
902 #if( DEBUG_MAC_OS_X_IOLOG_ENABLED )
903 //===========================================================================================================================
904 // DebugMacOSXIOLogPrint
905 //===========================================================================================================================
907 static void DebugMacOSXIOLogPrint( char *inData
, size_t inSize
)
909 extern void IOLog( const char *inFormat
, ... );
911 IOLog( "%.*s", (int) inSize
, inData
);
916 //===========================================================================================================================
917 // DebugMacOSXLogInit
918 //===========================================================================================================================
920 static OSStatus
DebugMacOSXLogInit( void )
926 CFStringRef functionName
;
931 // Create a bundle reference for System.framework.
933 path
= CFSTR( "/System/Library/Frameworks/System.framework" );
934 url
= CFURLCreateWithFileSystemPath( NULL
, path
, kCFURLPOSIXPathStyle
, true );
935 require_action_quiet( url
, exit
, err
= memFullErr
);
937 bundle
= CFBundleCreate( NULL
, url
);
939 require_action_quiet( bundle
, exit
, err
= memFullErr
);
941 // Get a ptr to the system's "printf" function from System.framework.
943 functionName
= CFSTR( "printf" );
944 functionPtr
= CFBundleGetFunctionPointerForName( bundle
, functionName
);
945 require_action_quiet( functionPtr
, exit
, err
= memFullErr
);
947 // Success! Note: The bundle cannot be released because it would invalidate the function ptr.
949 gDebugMacOSXLogFunction
= (DebugMacOSXLogFunctionPtr
) functionPtr
;
961 //===========================================================================================================================
962 // DebugMacOSXLogPrint
963 //===========================================================================================================================
965 static void DebugMacOSXLogPrint( char *inData
, size_t inSize
)
967 if( gDebugMacOSXLogFunction
)
969 gDebugMacOSXLogFunction( "%.*s", (int) inSize
, inData
);
974 #if( TARGET_OS_WIN32 )
975 //===========================================================================================================================
976 // DebugWindowsDebuggerPrint
977 //===========================================================================================================================
979 void DebugWindowsDebuggerPrint( char *inData
, size_t inSize
)
987 // Copy locally and null terminate the string. This also converts from char to TCHAR in case we are
988 // building with UNICODE enabled since the input is always char. Also convert \r to \n in the process.
991 if( inSize
>= sizeof_array( buffer
) )
993 inSize
= sizeof_array( buffer
) - 1;
1008 // Print out the string to the debugger.
1010 OutputDebugString( buffer
);
1014 #if( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
1015 //===========================================================================================================================
1016 // DebugWindowsEventLogInit
1017 //===========================================================================================================================
1019 static OSStatus
DebugWindowsEventLogInit( const char *inName
, HMODULE inModule
)
1025 TCHAR path
[ MAX_PATH
];
1027 DWORD typesSupported
;
1032 // Use a default name if needed then convert the name to TCHARs so it works on ANSI or Unicode builds.
1034 if( !inName
|| ( *inName
== '\0' ) )
1036 inName
= "DefaultApp";
1038 DebugWinCharToTCharString( inName
, kSizeCString
, name
, sizeof( name
), NULL
);
1040 // Build the path string using the fixed registry path and app name.
1042 src
= "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\";
1043 DebugWinCharToTCharString( src
, kSizeCString
, path
, sizeof_array( path
), &size
);
1044 DebugWinCharToTCharString( inName
, kSizeCString
, path
+ size
, sizeof_array( path
) - size
, NULL
);
1046 // Add/Open the source name as a sub-key under the Application key in the EventLog registry key.
1048 err
= RegCreateKeyEx( HKEY_LOCAL_MACHINE
, path
, 0, NULL
, REG_OPTION_NON_VOLATILE
, KEY_ALL_ACCESS
, NULL
, &key
, NULL
);
1049 require_noerr_quiet( err
, exit
);
1051 // Set the path in the EventMessageFile subkey. Add 1 to the TCHAR count to include the null terminator.
1053 n
= GetModuleFileName( inModule
, path
, sizeof_array( path
) );
1054 err
= translate_errno( n
> 0, (OSStatus
) GetLastError(), kParamErr
);
1055 require_noerr_quiet( err
, exit
);
1057 n
*= sizeof( TCHAR
);
1059 err
= RegSetValueEx( key
, TEXT( "EventMessageFile" ), 0, REG_EXPAND_SZ
, (const LPBYTE
) path
, n
);
1060 require_noerr_quiet( err
, exit
);
1062 // Set the supported event types in the TypesSupported subkey.
1064 typesSupported
= EVENTLOG_SUCCESS
| EVENTLOG_ERROR_TYPE
| EVENTLOG_WARNING_TYPE
| EVENTLOG_INFORMATION_TYPE
|
1065 EVENTLOG_AUDIT_SUCCESS
| EVENTLOG_AUDIT_FAILURE
;
1066 err
= RegSetValueEx( key
, TEXT( "TypesSupported" ), 0, REG_DWORD
, (const LPBYTE
) &typesSupported
, sizeof( DWORD
) );
1067 require_noerr_quiet( err
, exit
);
1069 // Set up the event source.
1071 gDebugWindowsEventLogEventSource
= RegisterEventSource( NULL
, name
);
1072 err
= translate_errno( gDebugWindowsEventLogEventSource
, (OSStatus
) GetLastError(), kParamErr
);
1073 require_noerr_quiet( err
, exit
);
1083 //===========================================================================================================================
1084 // DebugWindowsEventLogPrint
1085 //===========================================================================================================================
1087 static void DebugWindowsEventLogPrint( DebugLevel inLevel
, char *inData
, size_t inSize
)
1090 TCHAR buffer
[ 512 ];
1095 const TCHAR
* array
[ 1 ];
1097 // Map the debug level to a Windows EventLog type.
1099 if( inLevel
<= kDebugLevelNotice
)
1101 type
= EVENTLOG_INFORMATION_TYPE
;
1103 else if( inLevel
<= kDebugLevelWarning
)
1105 type
= EVENTLOG_WARNING_TYPE
;
1109 type
= EVENTLOG_ERROR_TYPE
;
1112 // Copy locally and null terminate the string. This also converts from char to TCHAR in case we are
1113 // building with UNICODE enabled since the input is always char. Also convert \r to \n in the process.
1116 if( inSize
>= sizeof_array( buffer
) )
1118 inSize
= sizeof_array( buffer
) - 1;
1133 // Add the the string to the event log.
1135 array
[ 0 ] = buffer
;
1136 if( gDebugWindowsEventLogEventSource
)
1138 ReportEvent( gDebugWindowsEventLogEventSource
, type
, 0, 0x20000001L
, NULL
, 1, 0, array
, NULL
);
1141 #endif // TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE
1143 #if( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
1144 //===========================================================================================================================
1145 // DebugAssertOutputHandler
1146 //===========================================================================================================================
1149 DebugAssertOutputHandler(
1150 OSType inComponentSignature
,
1152 const char * inAssertString
,
1153 const char * inExceptionString
,
1154 const char * inErrorString
,
1155 const char * inFileName
,
1158 ConstStr255Param inOutputMsg
)
1160 DEBUG_UNUSED( inComponentSignature
);
1161 DEBUG_UNUSED( inOptions
);
1162 DEBUG_UNUSED( inExceptionString
);
1163 DEBUG_UNUSED( inValue
);
1164 DEBUG_UNUSED( inOutputMsg
);
1166 DebugPrintAssert( 0, inAssertString
, inErrorString
, inFileName
, (int_least32_t) inLineNumber
, "" );
1172 #pragma mark == Utilities ==
1175 //===========================================================================================================================
1178 // Stolen from mDNS.c's mDNS_snprintf/mDNS_vsnprintf with the following changes:
1180 // Changed names to avoid name collisions with the mDNS versions.
1181 // Changed types to standard C types since mDNSClientAPI.h may not be available.
1182 // Conditionalized mDNS stuff so it can be used with or with mDNSClientAPI.h.
1183 // Added 64-bit support for %d (%lld), %i (%lli), %u (%llu), %o (%llo), %x (%llx), and %b (%llb).
1184 // Added %@ - Cocoa/CoreFoundation object. Param is the object. Strings are used directly. Others use CFCopyDescription.
1185 // Added %.8a - FIbre Channel address. Arg=ptr to address.
1186 // Added %##a - IPv4 (if AF_INET defined) or IPv6 (if AF_INET6 defined) sockaddr. Arg=ptr to sockaddr.
1187 // Added %b - Binary representation of integer (e.g. 01101011). Modifiers and arg=the same as %d, %x, etc.
1188 // Added %C - Mac-style FourCharCode (e.g. 'APPL'). Arg=32-bit value to print as a Mac-style FourCharCode.
1189 // Added %H - Hex Dump (e.g. "\x6b\xa7" -> "6B A7"). 1st arg=ptr, 2nd arg=size, 3rd arg=max size.
1190 // Added %#H - Hex Dump & ASCII (e.g. "\x41\x62" -> "6B A7 'Ab'"). 1st arg=ptr, 2nd arg=size, 3rd arg=max size.
1191 // Added %m - Error Message (e.g. 0 -> "kNoErr"). Modifiers and error code args are the same as %d, %x, etc.
1192 // Added %S - UTF-16 string. Host order if no BOM. Precision is UTF-16 char count. BOM counts in any precision. Arg=ptr.
1193 // Added %#S - Big Endian UTF-16 string (unless BOM overrides). Otherwise the same as %S.
1194 // Added %##S - Little Endian UTF-16 string (unless BOM overrides). Otherwise the same as %S.
1195 // Added %U - Universally Unique Identifier (UUID) (e.g. 6ba7b810-9dad-11d1-80b4-00c04fd430c8). Arg=ptr to 16-byte UUID.
1196 //===========================================================================================================================
1198 DEBUG_EXPORT
size_t DebugSNPrintF(char *sbuffer
, size_t buflen
, const char *fmt
, ...)
1204 length
= DebugSNPrintFVAList(sbuffer
, buflen
, fmt
, ptr
);
1210 //===========================================================================================================================
1211 // DebugSNPrintFVAList - va_list version of DebugSNPrintF. See DebugSNPrintF for more info.
1212 //===========================================================================================================================
1214 DEBUG_EXPORT
size_t DebugSNPrintFVAList(char *sbuffer
, size_t buflen
, const char *fmt
, va_list arg
)
1216 static const struct DebugSNPrintF_format
1218 unsigned leftJustify
: 1;
1219 unsigned forceSign
: 1;
1220 unsigned zeroPad
: 1;
1221 unsigned havePrecision
: 1;
1225 char sign
; // +, - or space
1226 unsigned int fieldWidth
;
1227 unsigned int precision
;
1228 } DebugSNPrintF_format_default
= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1230 size_t nwritten
= 0;
1232 if (buflen
== 0) return(0);
1233 buflen
--; // Pre-reserve one space in the buffer for the terminating nul
1234 if (buflen
== 0) goto exit
;
1236 for (c
= *fmt
; c
!= 0; c
= *++fmt
)
1240 *sbuffer
++ = (char)c
;
1241 if (++nwritten
>= buflen
) goto exit
;
1246 // The mDNS Vsprintf Argument Conversion Buffer is used as a temporary holding area for
1247 // generating decimal numbers, hexdecimal numbers, IP addresses, domain name strings, etc.
1248 // The size needs to be enough for a 256-byte domain name plus some error text.
1249 #define mDNS_VACB_Size 300
1250 char mDNS_VACB
[mDNS_VACB_Size
];
1251 #define mDNS_VACB_Lim (&mDNS_VACB[mDNS_VACB_Size])
1252 #define mDNS_VACB_Remain(s) ((size_t)(mDNS_VACB_Lim - s))
1253 char *s
= mDNS_VACB_Lim
;
1254 const char *digits
= "0123456789ABCDEF";
1255 struct DebugSNPrintF_format F
= DebugSNPrintF_format_default
;
1257 for(;;) // decode flags
1260 if (c
== '-') F
.leftJustify
= 1;
1261 else if (c
== '+') F
.forceSign
= 1;
1262 else if (c
== ' ') F
.sign
= ' ';
1263 else if (c
== '#') F
.altForm
++;
1264 else if (c
== '0') F
.zeroPad
= 1;
1268 if (c
== '*') // decode field width
1270 int f
= va_arg(arg
, int);
1271 if (f
< 0) { f
= -f
; F
.leftJustify
= 1; }
1272 F
.fieldWidth
= (unsigned int)f
;
1277 for (; c
>= '0' && c
<= '9'; c
= *++fmt
)
1278 F
.fieldWidth
= (10 * F
.fieldWidth
) + (c
- '0');
1281 if (c
== '.') // decode precision
1283 if ((c
= *++fmt
) == '*')
1284 { F
.precision
= va_arg(arg
, unsigned int); c
= *++fmt
; }
1285 else for (; c
>= '0' && c
<= '9'; c
= *++fmt
)
1286 F
.precision
= (10 * F
.precision
) + (c
- '0');
1287 F
.havePrecision
= 1;
1290 if (F
.leftJustify
) F
.zeroPad
= 0;
1293 switch (c
) // perform appropriate conversion
1295 #if TYPE_LONGLONG_NATIVE
1296 unsigned_long_long_compat n
;
1297 unsigned_long_long_compat base
;
1302 case 'h' : F
.hSize
= 1; c
= *++fmt
; goto conv
;
1303 case 'l' : // fall through
1304 case 'L' : F
.lSize
++; c
= *++fmt
; goto conv
;
1306 case 'i' : base
= 10;
1308 case 'u' : base
= 10;
1310 case 'o' : base
= 8;
1312 case 'b' : base
= 2;
1314 case 'p' : n
= va_arg(arg
, uintptr_t);
1315 F
.havePrecision
= 1;
1316 F
.precision
= (sizeof(uintptr_t) == 4) ? 8 : 16;
1321 case 'x' : digits
= "0123456789abcdef";
1322 case 'X' : base
= 16;
1325 #if TYPE_LONGLONG_NATIVE
1326 if (F
.lSize
== 1) n
= (unsigned_long_long_compat
)va_arg(arg
, long);
1327 else if (F
.lSize
== 2) n
= (unsigned_long_long_compat
)va_arg(arg
, long_long_compat
);
1328 else n
= (unsigned_long_long_compat
)va_arg(arg
, int);
1330 if (F
.lSize
== 1) n
= (unsigned long)va_arg(arg
, long);
1331 else if (F
.lSize
== 2) goto exit
;
1332 else n
= (unsigned long)va_arg(arg
, int);
1334 if (F
.hSize
) n
= (short) n
;
1335 #if TYPE_LONGLONG_NATIVE
1336 if ((long_long_compat
) n
< 0) { n
= (unsigned_long_long_compat
)-(long_long_compat
)n
; F
.sign
= '-'; }
1338 if ((long) n
< 0) { n
= (unsigned long)-(long)n
; F
.sign
= '-'; }
1340 else if (F
.forceSign
) F
.sign
= '+';
1343 notSigned
: if (F
.lSize
== 1) n
= va_arg(arg
, unsigned long);
1344 else if (F
.lSize
== 2)
1346 #if TYPE_LONGLONG_NATIVE
1347 n
= va_arg(arg
, unsigned_long_long_compat
);
1352 else n
= va_arg(arg
, unsigned int);
1353 if (F
.hSize
) n
= (unsigned short) n
;
1357 number
: if (!F
.havePrecision
)
1361 F
.precision
= F
.fieldWidth
;
1362 if (F
.altForm
) F
.precision
-= 2;
1363 if (F
.sign
) --F
.precision
;
1365 if (F
.precision
< 1) F
.precision
= 1;
1367 if (F
.precision
> mDNS_VACB_Size
- 1)
1368 F
.precision
= mDNS_VACB_Size
- 1;
1369 for (i
= 0; n
; n
/= base
, i
++) *--s
= (char)(digits
[n
% base
]);
1370 for (; i
< F
.precision
; i
++) *--s
= '0';
1371 if (F
.altForm
) { *--s
= (char)c
; *--s
= '0'; i
+= 2; }
1372 if (F
.sign
) { *--s
= F
.sign
; i
++; }
1376 unsigned char *a
= va_arg(arg
, unsigned char *);
1379 if (!a
) { static char emsg
[] = "<<NULL>>"; s
= emsg
; i
= sizeof(emsg
)-1; }
1382 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1385 #if(defined(MDNS_DEBUGMSGS))
1386 mDNSAddr
*ip
= (mDNSAddr
*)a
;
1389 case mDNSAddrType_IPv4
: F
.precision
= 4; a
= (unsigned char *)&ip
->ip
.v4
; break;
1390 case mDNSAddrType_IPv6
: F
.precision
= 16; a
= (unsigned char *)&ip
->ip
.v6
; break;
1391 default: F
.precision
= 0; break;
1394 F
.precision
= 0; // mDNSClientAPI.h not included so no mDNSAddr support
1397 else if (F
.altForm
== 2)
1400 const struct sockaddr
*sa
;
1401 unsigned char *port
;
1402 sa
= (const struct sockaddr
*)a
;
1403 switch (sa
->sa_family
)
1405 case AF_INET
: F
.precision
= 4; a
= (unsigned char*)&((const struct sockaddr_in
*)a
)->sin_addr
;
1406 port
= (unsigned char*)&((const struct sockaddr_in
*)sa
)->sin_port
;
1407 DebugSNPrintF(post
, sizeof(post
), ":%d", (port
[0] << 8) | port
[1]); break;
1409 case AF_INET6
: F
.precision
= 16; a
= (unsigned char*)&((const struct sockaddr_in6
*)a
)->sin6_addr
;
1410 pre
[0] = '['; pre
[1] = '\0';
1411 port
= (unsigned char*)&((const struct sockaddr_in6
*)sa
)->sin6_port
;
1412 DebugSNPrintF(post
, sizeof(post
), "%%%d]:%d",
1413 (int)((const struct sockaddr_in6
*)sa
)->sin6_scope_id
,
1414 (port
[0] << 8) | port
[1]); break;
1416 default: F
.precision
= 0; break;
1419 F
.precision
= 0; // socket interfaces not included so no sockaddr support
1422 switch (F
.precision
)
1424 case 4: i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "%d.%d.%d.%d%s",
1425 a
[0], a
[1], a
[2], a
[3], post
); break;
1426 case 6: i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "%02X:%02X:%02X:%02X:%02X:%02X",
1427 a
[0], a
[1], a
[2], a
[3], a
[4], a
[5]); break;
1428 case 8: i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
1429 a
[0], a
[1], a
[2], a
[3], a
[4], a
[5], a
[6], a
[7]); break;
1430 case 16: i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
),
1431 "%s%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X%s",
1432 pre
, a
[0], a
[1], a
[2], a
[3], a
[4], a
[5], a
[6], a
[7], a
[8],
1433 a
[9], a
[10], a
[11], a
[12], a
[13], a
[14], a
[15], post
); break;
1434 default: i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "%s", "<< ERROR: Must specify address size "
1435 "(i.e. %.4a=IPv4, %.6a=Ethernet, %.8a=Fibre Channel %.16a=IPv6) >>"); break;
1442 unsigned char *a
= va_arg(arg
, unsigned char *);
1443 if (!a
) { static char emsg
[] = "<<NULL>>"; s
= emsg
; i
= sizeof(emsg
)-1; }
1446 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1447 i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
1448 *((uint32_t*) &a
[0]), *((uint16_t*) &a
[4]), *((uint16_t*) &a
[6]),
1449 a
[8], a
[9], a
[10], a
[11], a
[12], a
[13], a
[14], a
[15]); break;
1454 case 'c' : *--s
= (char)va_arg(arg
, int); i
= 1; break;
1456 case 'C' : if (F
.lSize
) n
= va_arg(arg
, unsigned long);
1457 else n
= va_arg(arg
, unsigned int);
1458 if (F
.hSize
) n
= (unsigned short) n
;
1459 c
= (int)( n
& 0xFF); *--s
= (char)(DebugIsPrint(c
) ? c
: '^');
1460 c
= (int)((n
>> 8) & 0xFF); *--s
= (char)(DebugIsPrint(c
) ? c
: '^');
1461 c
= (int)((n
>> 16) & 0xFF); *--s
= (char)(DebugIsPrint(c
) ? c
: '^');
1462 c
= (int)((n
>> 24) & 0xFF); *--s
= (char)(DebugIsPrint(c
) ? c
: '^');
1466 case 's' : s
= va_arg(arg
, char *);
1467 if (!s
) { static char emsg
[] = "<<NULL>>"; s
= emsg
; i
= sizeof(emsg
)-1; }
1468 else switch (F
.altForm
)
1471 if (F
.havePrecision
) // C string
1473 while((i
< F
.precision
) && s
[i
]) i
++;
1474 // Make sure we don't truncate in the middle of a UTF-8 character.
1475 // If the last character is part of a multi-byte UTF-8 character, back up to the start of it.
1477 while((i
> 0) && ((c
= s
[i
-1]) & 0x80)) { j
++; i
--; if((c
& 0xC0) != 0x80) break; }
1478 // If the actual count of UTF-8 characters matches the encoded UTF-8 count, add it back.
1479 if((j
> 1) && (j
<= 6))
1481 int test
= (0xFF << (8-j
)) & 0xFF;
1482 int mask
= test
| (1 << ((8-j
)-1));
1483 if((c
& mask
) == test
) i
+= j
;
1489 case 1: i
= (unsigned char) *s
++; break; // Pascal string
1490 case 2: { // DNS label-sequence name
1491 unsigned char *a
= (unsigned char *)s
;
1492 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1493 if (*a
== 0) *s
++ = '.'; // Special case for root DNS name
1496 if (*a
> 63) { s
+= DebugSNPrintF(s
, mDNS_VACB_Remain(s
), "<<INVALID LABEL LENGTH %u>>", *a
); break; }
1497 if (s
+ *a
>= &mDNS_VACB
[254]) { s
+= DebugSNPrintF(s
, mDNS_VACB_Remain(s
), "<<NAME TOO LONG>>"); break; }
1498 s
+= DebugSNPrintF(s
, mDNS_VACB_Remain(s
), "%#s.", a
);
1501 i
= (size_t)(s
- mDNS_VACB
);
1502 s
= mDNS_VACB
; // Reset s back to the start of the buffer
1506 if (F
.havePrecision
&& i
> F
.precision
) // Make sure we don't truncate in the middle of a UTF-8 character
1507 { i
= F
.precision
; while (i
>0 && (s
[i
] & 0xC0) == 0x80) i
--; }
1510 case 'S': { // UTF-16 string
1511 unsigned char *a
= va_arg(arg
, unsigned char *);
1512 uint16_t *u
= (uint16_t*)a
;
1513 if (!u
) { static char emsg
[] = "<<NULL>>"; s
= emsg
; i
= sizeof(emsg
)-1; }
1514 if ((!F
.havePrecision
|| F
.precision
))
1516 if ((a
[0] == 0xFE) && (a
[1] == 0xFF)) { F
.altForm
= 1; u
+= 1; a
+= 2; F
.precision
--; } // Big Endian
1517 else if ((a
[0] == 0xFF) && (a
[1] == 0xFE)) { F
.altForm
= 2; u
+= 1; a
+= 2; F
.precision
--; } // Little Endian
1519 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1522 case 0: while ((!F
.havePrecision
|| (i
< F
.precision
)) && u
[i
] && mDNS_VACB_Remain(s
)) // Host Endian
1523 { c
= u
[i
]; *s
++ = (char)(DebugIsPrint(c
) ? c
: '^'); i
++; }
1525 case 1: while ((!F
.havePrecision
|| (i
< F
.precision
)) && u
[i
] && mDNS_VACB_Remain(s
)) // Big Endian
1526 { c
= ((a
[0] << 8) | a
[1]) & 0xFF; *s
++ = (char)(DebugIsPrint(c
) ? c
: '^'); i
++; a
+= 2; }
1528 case 2: while ((!F
.havePrecision
|| (i
< F
.precision
)) && u
[i
] && mDNS_VACB_Remain(s
)) // Little Endian
1529 { c
= ((a
[1] << 8) | a
[0]) & 0xFF; *s
++ = (char)(DebugIsPrint(c
) ? c
: '^'); i
++; a
+= 2; }
1533 s
= mDNS_VACB
; // Reset s back to the start of the buffer
1537 case '@': { // Cocoa/CoreFoundation object
1540 cfObj
= (CFTypeRef
) va_arg(arg
, void *);
1541 cfStr
= (CFGetTypeID(cfObj
) == CFStringGetTypeID()) ? (CFStringRef
)CFRetain(cfObj
) : CFCopyDescription(cfObj
);
1542 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1547 range
= CFRangeMake(0, CFStringGetLength(cfStr
));
1549 CFStringGetBytes(cfStr
, range
, kCFStringEncodingUTF8
, '^', false, (UInt8
*)mDNS_VACB
, (CFIndex
)sizeof(mDNS_VACB
), &m
);
1555 i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "%s", "ERROR: <invalid CF object>" );
1558 if (F
.havePrecision
&& i
> F
.precision
) // Make sure we don't truncate in the middle of a UTF-8 character
1559 { i
= F
.precision
; while (i
>0 && (s
[i
] & 0xC0) == 0x80) i
--; }
1563 case 'm' : { // Error Message
1565 if (F
.lSize
) err
= va_arg(arg
, long);
1566 else err
= va_arg(arg
, int);
1567 if (F
.hSize
) err
= (short)err
;
1568 DebugGetErrorString(err
, mDNS_VACB
, sizeof(mDNS_VACB
));
1569 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1570 for(i
=0;s
[i
];i
++) {}
1574 case 'H' : { // Hex Dump
1575 void *a
= va_arg(arg
, void *);
1576 size_t size
= (size_t)va_arg(arg
, int);
1577 size_t max
= (size_t)va_arg(arg
, int);
1579 kDebugFlagsNoAddress
| kDebugFlagsNoOffset
| kDebugFlagsNoNewLine
|
1580 kDebugFlags8BitSeparator
| kDebugFlagsNo32BitSeparator
|
1581 kDebugFlagsNo16ByteHexPad
| kDebugFlagsNoByteCount
;
1582 if (F
.altForm
== 0) flags
|= kDebugFlagsNoASCII
;
1583 size
= (max
< size
) ? max
: size
;
1584 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1585 i
= DebugHexDump(kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, a
, a
, size
, flags
, mDNS_VACB
, sizeof(mDNS_VACB
));
1589 case 'v' : { // Version
1591 version
= va_arg(arg
, unsigned int);
1592 DebugNumVersionToString(version
, mDNS_VACB
);
1593 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1594 for(i
=0;s
[i
];i
++) {}
1598 case 'n' : s
= va_arg(arg
, char *);
1599 if (F
.hSize
) * (short *) s
= (short)nwritten
;
1600 else if (F
.lSize
) * (long *) s
= (long)nwritten
;
1601 else * (int *) s
= (int)nwritten
;
1604 default: s
= mDNS_VACB
;
1605 i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "<<UNKNOWN FORMAT CONVERSION CODE %%%c>>", c
);
1607 case '%' : *sbuffer
++ = (char)c
;
1608 if (++nwritten
>= buflen
) goto exit
;
1612 if (i
< F
.fieldWidth
&& !F
.leftJustify
) // Pad on the left
1615 if (++nwritten
>= buflen
) goto exit
;
1616 } while (i
< --F
.fieldWidth
);
1618 if (i
> buflen
- nwritten
) // Make sure we don't truncate in the middle of a UTF-8 character
1619 { i
= buflen
- nwritten
; while (i
>0 && (s
[i
] & 0xC0) == 0x80) i
--; }
1620 for (j
=0; j
<i
; j
++) *sbuffer
++ = *s
++; // Write the converted result
1622 if (nwritten
>= buflen
) goto exit
;
1624 for (; i
< F
.fieldWidth
; i
++) // Pad on the right
1627 if (++nwritten
>= buflen
) goto exit
;
1636 //===========================================================================================================================
1637 // DebugGetErrorString
1638 //===========================================================================================================================
1640 DEBUG_EXPORT
const char * DebugGetErrorString( int_least32_t inErrorCode
, char *inBuffer
, size_t inBufferSize
)
1645 #if( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
1649 switch( inErrorCode
)
1651 #define CaseErrorString( X, STR ) case X: s = STR; break
1652 #define CaseErrorStringify( X ) case X: s = # X; break
1653 #define CaseErrorStringifyHardCode( VALUE, X ) case VALUE: s = # X; break
1657 CaseErrorString( 0, "no error" );
1658 CaseErrorString( 1, "in-progress/waiting" );
1659 CaseErrorString( -1, "catch-all unknown error" );
1663 CaseErrorStringifyHardCode( -2, kACPBadRequestErr
);
1664 CaseErrorStringifyHardCode( -3, kACPNoMemoryErr
);
1665 CaseErrorStringifyHardCode( -4, kACPBadParamErr
);
1666 CaseErrorStringifyHardCode( -5, kACPNotFoundErr
);
1667 CaseErrorStringifyHardCode( -6, kACPBadChecksumErr
);
1668 CaseErrorStringifyHardCode( -7, kACPCommandNotHandledErr
);
1669 CaseErrorStringifyHardCode( -8, kACPNetworkErr
);
1670 CaseErrorStringifyHardCode( -9, kACPDuplicateCommandHandlerErr
);
1671 CaseErrorStringifyHardCode( -10, kACPUnknownPropertyErr
);
1672 CaseErrorStringifyHardCode( -11, kACPImmutablePropertyErr
);
1673 CaseErrorStringifyHardCode( -12, kACPBadPropertyValueErr
);
1674 CaseErrorStringifyHardCode( -13, kACPNoResourcesErr
);
1675 CaseErrorStringifyHardCode( -14, kACPBadOptionErr
);
1676 CaseErrorStringifyHardCode( -15, kACPBadSizeErr
);
1677 CaseErrorStringifyHardCode( -16, kACPBadPasswordErr
);
1678 CaseErrorStringifyHardCode( -17, kACPNotInitializedErr
);
1679 CaseErrorStringifyHardCode( -18, kACPNonReadablePropertyErr
);
1680 CaseErrorStringifyHardCode( -19, kACPBadVersionErr
);
1681 CaseErrorStringifyHardCode( -20, kACPBadSignatureErr
);
1682 CaseErrorStringifyHardCode( -21, kACPBadIndexErr
);
1683 CaseErrorStringifyHardCode( -22, kACPUnsupportedErr
);
1684 CaseErrorStringifyHardCode( -23, kACPInUseErr
);
1685 CaseErrorStringifyHardCode( -24, kACPParamCountErr
);
1686 CaseErrorStringifyHardCode( -25, kACPIDErr
);
1687 CaseErrorStringifyHardCode( -26, kACPFormatErr
);
1688 CaseErrorStringifyHardCode( -27, kACPUnknownUserErr
);
1689 CaseErrorStringifyHardCode( -28, kACPAccessDeniedErr
);
1690 CaseErrorStringifyHardCode( -29, kACPIncorrectFWErr
);
1692 // Common Services Errors
1694 CaseErrorStringify( kUnknownErr
);
1695 CaseErrorStringify( kOptionErr
);
1696 CaseErrorStringify( kSelectorErr
);
1697 CaseErrorStringify( kExecutionStateErr
);
1698 CaseErrorStringify( kPathErr
);
1699 CaseErrorStringify( kParamErr
);
1700 CaseErrorStringify( kParamCountErr
);
1701 CaseErrorStringify( kCommandErr
);
1702 CaseErrorStringify( kIDErr
);
1703 CaseErrorStringify( kStateErr
);
1704 CaseErrorStringify( kRangeErr
);
1705 CaseErrorStringify( kRequestErr
);
1706 CaseErrorStringify( kResponseErr
);
1707 CaseErrorStringify( kChecksumErr
);
1708 CaseErrorStringify( kNotHandledErr
);
1709 CaseErrorStringify( kVersionErr
);
1710 CaseErrorStringify( kSignatureErr
);
1711 CaseErrorStringify( kFormatErr
);
1712 CaseErrorStringify( kNotInitializedErr
);
1713 CaseErrorStringify( kAlreadyInitializedErr
);
1714 CaseErrorStringify( kNotInUseErr
);
1715 CaseErrorStringify( kInUseErr
);
1716 CaseErrorStringify( kTimeoutErr
);
1717 CaseErrorStringify( kCanceledErr
);
1718 CaseErrorStringify( kAlreadyCanceledErr
);
1719 CaseErrorStringify( kCannotCancelErr
);
1720 CaseErrorStringify( kDeletedErr
);
1721 CaseErrorStringify( kNotFoundErr
);
1722 CaseErrorStringify( kNoMemoryErr
);
1723 CaseErrorStringify( kNoResourcesErr
);
1724 CaseErrorStringify( kDuplicateErr
);
1725 CaseErrorStringify( kImmutableErr
);
1726 CaseErrorStringify( kUnsupportedDataErr
);
1727 CaseErrorStringify( kIntegrityErr
);
1728 CaseErrorStringify( kIncompatibleErr
);
1729 CaseErrorStringify( kUnsupportedErr
);
1730 CaseErrorStringify( kUnexpectedErr
);
1731 CaseErrorStringify( kValueErr
);
1732 CaseErrorStringify( kNotReadableErr
);
1733 CaseErrorStringify( kNotWritableErr
);
1734 CaseErrorStringify( kBadReferenceErr
);
1735 CaseErrorStringify( kFlagErr
);
1736 CaseErrorStringify( kMalformedErr
);
1737 CaseErrorStringify( kSizeErr
);
1738 CaseErrorStringify( kNameErr
);
1739 CaseErrorStringify( kNotReadyErr
);
1740 CaseErrorStringify( kReadErr
);
1741 CaseErrorStringify( kWriteErr
);
1742 CaseErrorStringify( kMismatchErr
);
1743 CaseErrorStringify( kDateErr
);
1744 CaseErrorStringify( kUnderrunErr
);
1745 CaseErrorStringify( kOverrunErr
);
1746 CaseErrorStringify( kEndingErr
);
1747 CaseErrorStringify( kConnectionErr
);
1748 CaseErrorStringify( kAuthenticationErr
);
1749 CaseErrorStringify( kOpenErr
);
1750 CaseErrorStringify( kTypeErr
);
1751 CaseErrorStringify( kSkipErr
);
1752 CaseErrorStringify( kNoAckErr
);
1753 CaseErrorStringify( kCollisionErr
);
1754 CaseErrorStringify( kBackoffErr
);
1755 CaseErrorStringify( kNoAddressAckErr
);
1756 CaseErrorStringify( kBusyErr
);
1757 CaseErrorStringify( kNoSpaceErr
);
1759 // mDNS/DNS-SD Errors
1761 CaseErrorStringifyHardCode( -65537, mStatus_UnknownErr
);
1762 CaseErrorStringifyHardCode( -65538, mStatus_NoSuchNameErr
);
1763 CaseErrorStringifyHardCode( -65539, mStatus_NoMemoryErr
);
1764 CaseErrorStringifyHardCode( -65540, mStatus_BadParamErr
);
1765 CaseErrorStringifyHardCode( -65541, mStatus_BadReferenceErr
);
1766 CaseErrorStringifyHardCode( -65542, mStatus_BadStateErr
);
1767 CaseErrorStringifyHardCode( -65543, mStatus_BadFlagsErr
);
1768 CaseErrorStringifyHardCode( -65544, mStatus_UnsupportedErr
);
1769 CaseErrorStringifyHardCode( -65545, mStatus_NotInitializedErr
);
1770 CaseErrorStringifyHardCode( -65546, mStatus_NoCache
);
1771 CaseErrorStringifyHardCode( -65547, mStatus_AlreadyRegistered
);
1772 CaseErrorStringifyHardCode( -65548, mStatus_NameConflict
);
1773 CaseErrorStringifyHardCode( -65549, mStatus_Invalid
);
1774 CaseErrorStringifyHardCode( -65550, mStatus_GrowCache
);
1775 CaseErrorStringifyHardCode( -65551, mStatus_BadInterfaceErr
);
1776 CaseErrorStringifyHardCode( -65552, mStatus_Incompatible
);
1777 CaseErrorStringifyHardCode( -65791, mStatus_ConfigChanged
);
1778 CaseErrorStringifyHardCode( -65792, mStatus_MemFree
);
1782 CaseErrorStringifyHardCode( -400000, kRSPUnknownErr
);
1783 CaseErrorStringifyHardCode( -400050, kRSPParamErr
);
1784 CaseErrorStringifyHardCode( -400108, kRSPNoMemoryErr
);
1785 CaseErrorStringifyHardCode( -405246, kRSPRangeErr
);
1786 CaseErrorStringifyHardCode( -409057, kRSPSizeErr
);
1787 CaseErrorStringifyHardCode( -400200, kRSPHardwareErr
);
1788 CaseErrorStringifyHardCode( -401712, kRSPTimeoutErr
);
1789 CaseErrorStringifyHardCode( -402053, kRSPUnsupportedErr
);
1790 CaseErrorStringifyHardCode( -402419, kRSPIDErr
);
1791 CaseErrorStringifyHardCode( -403165, kRSPFlagErr
);
1792 CaseErrorString( -200000, "kRSPControllerStatusBase - 0x50" );
1793 CaseErrorString( -200080, "kRSPCommandSucceededErr - 0x50" );
1794 CaseErrorString( -200001, "kRSPCommandFailedErr - 0x01" );
1795 CaseErrorString( -200051, "kRSPChecksumErr - 0x33" );
1796 CaseErrorString( -200132, "kRSPCommandTimeoutErr - 0x84" );
1797 CaseErrorString( -200034, "kRSPPasswordRequiredErr - 0x22 OBSOLETE" );
1798 CaseErrorString( -200128, "kRSPCanceledErr - 0x02 Async" );
1802 CaseErrorStringifyHardCode( -100043, kXMLNotFoundErr
);
1803 CaseErrorStringifyHardCode( -100050, kXMLParamErr
);
1804 CaseErrorStringifyHardCode( -100108, kXMLNoMemoryErr
);
1805 CaseErrorStringifyHardCode( -100206, kXMLFormatErr
);
1806 CaseErrorStringifyHardCode( -100586, kXMLNoRootElementErr
);
1807 CaseErrorStringifyHardCode( -101703, kXMLWrongDataTypeErr
);
1808 CaseErrorStringifyHardCode( -101726, kXMLKeyErr
);
1809 CaseErrorStringifyHardCode( -102053, kXMLUnsupportedErr
);
1810 CaseErrorStringifyHardCode( -102063, kXMLMissingElementErr
);
1811 CaseErrorStringifyHardCode( -103026, kXMLParseErr
);
1812 CaseErrorStringifyHardCode( -103159, kXMLBadDataErr
);
1813 CaseErrorStringifyHardCode( -103170, kXMLBadNameErr
);
1814 CaseErrorStringifyHardCode( -105246, kXMLRangeErr
);
1815 CaseErrorStringifyHardCode( -105251, kXMLUnknownElementErr
);
1816 CaseErrorStringifyHardCode( -108739, kXMLMalformedInputErr
);
1817 CaseErrorStringifyHardCode( -109057, kXMLBadSizeErr
);
1818 CaseErrorStringifyHardCode( -101730, kXMLMissingChildElementErr
);
1819 CaseErrorStringifyHardCode( -102107, kXMLMissingParentElementErr
);
1820 CaseErrorStringifyHardCode( -130587, kXMLNonRootElementErr
);
1821 CaseErrorStringifyHardCode( -102015, kXMLDateErr
);
1827 CaseErrorStringifyHardCode( 0x00002000, MACH_MSG_IPC_SPACE
);
1828 CaseErrorStringifyHardCode( 0x00001000, MACH_MSG_VM_SPACE
);
1829 CaseErrorStringifyHardCode( 0x00000800, MACH_MSG_IPC_KERNEL
);
1830 CaseErrorStringifyHardCode( 0x00000400, MACH_MSG_VM_KERNEL
);
1831 CaseErrorStringifyHardCode( 0x10000001, MACH_SEND_IN_PROGRESS
);
1832 CaseErrorStringifyHardCode( 0x10000002, MACH_SEND_INVALID_DATA
);
1833 CaseErrorStringifyHardCode( 0x10000003, MACH_SEND_INVALID_DEST
);
1834 CaseErrorStringifyHardCode( 0x10000004, MACH_SEND_TIMED_OUT
);
1835 CaseErrorStringifyHardCode( 0x10000007, MACH_SEND_INTERRUPTED
);
1836 CaseErrorStringifyHardCode( 0x10000008, MACH_SEND_MSG_TOO_SMALL
);
1837 CaseErrorStringifyHardCode( 0x10000009, MACH_SEND_INVALID_REPLY
);
1838 CaseErrorStringifyHardCode( 0x1000000A, MACH_SEND_INVALID_RIGHT
);
1839 CaseErrorStringifyHardCode( 0x1000000B, MACH_SEND_INVALID_NOTIFY
);
1840 CaseErrorStringifyHardCode( 0x1000000C, MACH_SEND_INVALID_MEMORY
);
1841 CaseErrorStringifyHardCode( 0x1000000D, MACH_SEND_NO_BUFFER
);
1842 CaseErrorStringifyHardCode( 0x1000000E, MACH_SEND_TOO_LARGE
);
1843 CaseErrorStringifyHardCode( 0x1000000F, MACH_SEND_INVALID_TYPE
);
1844 CaseErrorStringifyHardCode( 0x10000010, MACH_SEND_INVALID_HEADER
);
1845 CaseErrorStringifyHardCode( 0x10000011, MACH_SEND_INVALID_TRAILER
);
1846 CaseErrorStringifyHardCode( 0x10000015, MACH_SEND_INVALID_RT_OOL_SIZE
);
1847 CaseErrorStringifyHardCode( 0x10004001, MACH_RCV_IN_PROGRESS
);
1848 CaseErrorStringifyHardCode( 0x10004002, MACH_RCV_INVALID_NAME
);
1849 CaseErrorStringifyHardCode( 0x10004003, MACH_RCV_TIMED_OUT
);
1850 CaseErrorStringifyHardCode( 0x10004004, MACH_RCV_TOO_LARGE
);
1851 CaseErrorStringifyHardCode( 0x10004005, MACH_RCV_INTERRUPTED
);
1852 CaseErrorStringifyHardCode( 0x10004006, MACH_RCV_PORT_CHANGED
);
1853 CaseErrorStringifyHardCode( 0x10004007, MACH_RCV_INVALID_NOTIFY
);
1854 CaseErrorStringifyHardCode( 0x10004008, MACH_RCV_INVALID_DATA
);
1855 CaseErrorStringifyHardCode( 0x10004009, MACH_RCV_PORT_DIED
);
1856 CaseErrorStringifyHardCode( 0x1000400A, MACH_RCV_IN_SET
);
1857 CaseErrorStringifyHardCode( 0x1000400B, MACH_RCV_HEADER_ERROR
);
1858 CaseErrorStringifyHardCode( 0x1000400C, MACH_RCV_BODY_ERROR
);
1859 CaseErrorStringifyHardCode( 0x1000400D, MACH_RCV_INVALID_TYPE
);
1860 CaseErrorStringifyHardCode( 0x1000400E, MACH_RCV_SCATTER_SMALL
);
1861 CaseErrorStringifyHardCode( 0x1000400F, MACH_RCV_INVALID_TRAILER
);
1862 CaseErrorStringifyHardCode( 0x10004011, MACH_RCV_IN_PROGRESS_TIMED
);
1864 // Mach OSReturn Errors
1866 CaseErrorStringifyHardCode( 0xDC000001, kOSReturnError
);
1867 CaseErrorStringifyHardCode( 0xDC004001, kOSMetaClassInternal
);
1868 CaseErrorStringifyHardCode( 0xDC004002, kOSMetaClassHasInstances
);
1869 CaseErrorStringifyHardCode( 0xDC004003, kOSMetaClassNoInit
);
1870 CaseErrorStringifyHardCode( 0xDC004004, kOSMetaClassNoTempData
);
1871 CaseErrorStringifyHardCode( 0xDC004005, kOSMetaClassNoDicts
);
1872 CaseErrorStringifyHardCode( 0xDC004006, kOSMetaClassNoKModSet
);
1873 CaseErrorStringifyHardCode( 0xDC004007, kOSMetaClassNoInsKModSet
);
1874 CaseErrorStringifyHardCode( 0xDC004008, kOSMetaClassNoSuper
);
1875 CaseErrorStringifyHardCode( 0xDC004009, kOSMetaClassInstNoSuper
);
1876 CaseErrorStringifyHardCode( 0xDC00400A, kOSMetaClassDuplicateClass
);
1880 CaseErrorStringifyHardCode( 0xE00002BC, kIOReturnError
);
1881 CaseErrorStringifyHardCode( 0xE00002BD, kIOReturnNoMemory
);
1882 CaseErrorStringifyHardCode( 0xE00002BE, kIOReturnNoResources
);
1883 CaseErrorStringifyHardCode( 0xE00002BF, kIOReturnIPCError
);
1884 CaseErrorStringifyHardCode( 0xE00002C0, kIOReturnNoDevice
);
1885 CaseErrorStringifyHardCode( 0xE00002C1, kIOReturnNotPrivileged
);
1886 CaseErrorStringifyHardCode( 0xE00002C2, kIOReturnBadArgument
);
1887 CaseErrorStringifyHardCode( 0xE00002C3, kIOReturnLockedRead
);
1888 CaseErrorStringifyHardCode( 0xE00002C4, kIOReturnLockedWrite
);
1889 CaseErrorStringifyHardCode( 0xE00002C5, kIOReturnExclusiveAccess
);
1890 CaseErrorStringifyHardCode( 0xE00002C6, kIOReturnBadMessageID
);
1891 CaseErrorStringifyHardCode( 0xE00002C7, kIOReturnUnsupported
);
1892 CaseErrorStringifyHardCode( 0xE00002C8, kIOReturnVMError
);
1893 CaseErrorStringifyHardCode( 0xE00002C9, kIOReturnInternalError
);
1894 CaseErrorStringifyHardCode( 0xE00002CA, kIOReturnIOError
);
1895 CaseErrorStringifyHardCode( 0xE00002CC, kIOReturnCannotLock
);
1896 CaseErrorStringifyHardCode( 0xE00002CD, kIOReturnNotOpen
);
1897 CaseErrorStringifyHardCode( 0xE00002CE, kIOReturnNotReadable
);
1898 CaseErrorStringifyHardCode( 0xE00002CF, kIOReturnNotWritable
);
1899 CaseErrorStringifyHardCode( 0xE00002D0, kIOReturnNotAligned
);
1900 CaseErrorStringifyHardCode( 0xE00002D1, kIOReturnBadMedia
);
1901 CaseErrorStringifyHardCode( 0xE00002D2, kIOReturnStillOpen
);
1902 CaseErrorStringifyHardCode( 0xE00002D3, kIOReturnRLDError
);
1903 CaseErrorStringifyHardCode( 0xE00002D4, kIOReturnDMAError
);
1904 CaseErrorStringifyHardCode( 0xE00002D5, kIOReturnBusy
);
1905 CaseErrorStringifyHardCode( 0xE00002D6, kIOReturnTimeout
);
1906 CaseErrorStringifyHardCode( 0xE00002D7, kIOReturnOffline
);
1907 CaseErrorStringifyHardCode( 0xE00002D8, kIOReturnNotReady
);
1908 CaseErrorStringifyHardCode( 0xE00002D9, kIOReturnNotAttached
);
1909 CaseErrorStringifyHardCode( 0xE00002DA, kIOReturnNoChannels
);
1910 CaseErrorStringifyHardCode( 0xE00002DB, kIOReturnNoSpace
);
1911 CaseErrorStringifyHardCode( 0xE00002DD, kIOReturnPortExists
);
1912 CaseErrorStringifyHardCode( 0xE00002DE, kIOReturnCannotWire
);
1913 CaseErrorStringifyHardCode( 0xE00002DF, kIOReturnNoInterrupt
);
1914 CaseErrorStringifyHardCode( 0xE00002E0, kIOReturnNoFrames
);
1915 CaseErrorStringifyHardCode( 0xE00002E1, kIOReturnMessageTooLarge
);
1916 CaseErrorStringifyHardCode( 0xE00002E2, kIOReturnNotPermitted
);
1917 CaseErrorStringifyHardCode( 0xE00002E3, kIOReturnNoPower
);
1918 CaseErrorStringifyHardCode( 0xE00002E4, kIOReturnNoMedia
);
1919 CaseErrorStringifyHardCode( 0xE00002E5, kIOReturnUnformattedMedia
);
1920 CaseErrorStringifyHardCode( 0xE00002E6, kIOReturnUnsupportedMode
);
1921 CaseErrorStringifyHardCode( 0xE00002E7, kIOReturnUnderrun
);
1922 CaseErrorStringifyHardCode( 0xE00002E8, kIOReturnOverrun
);
1923 CaseErrorStringifyHardCode( 0xE00002E9, kIOReturnDeviceError
);
1924 CaseErrorStringifyHardCode( 0xE00002EA, kIOReturnNoCompletion
);
1925 CaseErrorStringifyHardCode( 0xE00002EB, kIOReturnAborted
);
1926 CaseErrorStringifyHardCode( 0xE00002EC, kIOReturnNoBandwidth
);
1927 CaseErrorStringifyHardCode( 0xE00002ED, kIOReturnNotResponding
);
1928 CaseErrorStringifyHardCode( 0xE00002EE, kIOReturnIsoTooOld
);
1929 CaseErrorStringifyHardCode( 0xE00002EF, kIOReturnIsoTooNew
);
1930 CaseErrorStringifyHardCode( 0xE00002F0, kIOReturnNotFound
);
1931 CaseErrorStringifyHardCode( 0xE0000001, kIOReturnInvalid
);
1933 // IOKit FireWire Errors
1935 CaseErrorStringifyHardCode( 0xE0008010, kIOFireWireResponseBase
);
1936 CaseErrorStringifyHardCode( 0xE0008020, kIOFireWireBusReset
);
1937 CaseErrorStringifyHardCode( 0xE0008001, kIOConfigNoEntry
);
1938 CaseErrorStringifyHardCode( 0xE0008002, kIOFireWirePending
);
1939 CaseErrorStringifyHardCode( 0xE0008003, kIOFireWireLastDCLToken
);
1940 CaseErrorStringifyHardCode( 0xE0008004, kIOFireWireConfigROMInvalid
);
1941 CaseErrorStringifyHardCode( 0xE0008005, kIOFireWireAlreadyRegistered
);
1942 CaseErrorStringifyHardCode( 0xE0008006, kIOFireWireMultipleTalkers
);
1943 CaseErrorStringifyHardCode( 0xE0008007, kIOFireWireChannelActive
);
1944 CaseErrorStringifyHardCode( 0xE0008008, kIOFireWireNoListenerOrTalker
);
1945 CaseErrorStringifyHardCode( 0xE0008009, kIOFireWireNoChannels
);
1946 CaseErrorStringifyHardCode( 0xE000800A, kIOFireWireChannelNotAvailable
);
1947 CaseErrorStringifyHardCode( 0xE000800B, kIOFireWireSeparateBus
);
1948 CaseErrorStringifyHardCode( 0xE000800C, kIOFireWireBadSelfIDs
);
1949 CaseErrorStringifyHardCode( 0xE000800D, kIOFireWireLowCableVoltage
);
1950 CaseErrorStringifyHardCode( 0xE000800E, kIOFireWireInsufficientPower
);
1951 CaseErrorStringifyHardCode( 0xE000800F, kIOFireWireOutOfTLabels
);
1952 CaseErrorStringifyHardCode( 0xE0008101, kIOFireWireBogusDCLProgram
);
1953 CaseErrorStringifyHardCode( 0xE0008102, kIOFireWireTalkingAndListening
);
1954 CaseErrorStringifyHardCode( 0xE0008103, kIOFireWireHardwareSlept
);
1955 CaseErrorStringifyHardCode( 0xE00087D0, kIOFWMessageServiceIsRequestingClose
);
1956 CaseErrorStringifyHardCode( 0xE00087D1, kIOFWMessagePowerStateChanged
);
1957 CaseErrorStringifyHardCode( 0xE00087D2, kIOFWMessageTopologyChanged
);
1961 CaseErrorStringifyHardCode( 0xE0004061, kIOUSBUnknownPipeErr
);
1962 CaseErrorStringifyHardCode( 0xE0004060, kIOUSBTooManyPipesErr
);
1963 CaseErrorStringifyHardCode( 0xE000405F, kIOUSBNoAsyncPortErr
);
1964 CaseErrorStringifyHardCode( 0xE000405E, kIOUSBNotEnoughPipesErr
);
1965 CaseErrorStringifyHardCode( 0xE000405D, kIOUSBNotEnoughPowerErr
);
1966 CaseErrorStringifyHardCode( 0xE0004057, kIOUSBEndpointNotFound
);
1967 CaseErrorStringifyHardCode( 0xE0004056, kIOUSBConfigNotFound
);
1968 CaseErrorStringifyHardCode( 0xE0004051, kIOUSBTransactionTimeout
);
1969 CaseErrorStringifyHardCode( 0xE0004050, kIOUSBTransactionReturned
);
1970 CaseErrorStringifyHardCode( 0xE000404F, kIOUSBPipeStalled
);
1971 CaseErrorStringifyHardCode( 0xE000404E, kIOUSBInterfaceNotFound
);
1972 CaseErrorStringifyHardCode( 0xE000404D, kIOUSBLowLatencyBufferNotPreviouslyAllocated
);
1973 CaseErrorStringifyHardCode( 0xE000404C, kIOUSBLowLatencyFrameListNotPreviouslyAllocated
);
1974 CaseErrorStringifyHardCode( 0xE000404B, kIOUSBHighSpeedSplitError
);
1975 CaseErrorStringifyHardCode( 0xE0004010, kIOUSBLinkErr
);
1976 CaseErrorStringifyHardCode( 0xE000400F, kIOUSBNotSent2Err
);
1977 CaseErrorStringifyHardCode( 0xE000400E, kIOUSBNotSent1Err
);
1978 CaseErrorStringifyHardCode( 0xE000400D, kIOUSBBufferUnderrunErr
);
1979 CaseErrorStringifyHardCode( 0xE000400C, kIOUSBBufferOverrunErr
);
1980 CaseErrorStringifyHardCode( 0xE000400B, kIOUSBReserved2Err
);
1981 CaseErrorStringifyHardCode( 0xE000400A, kIOUSBReserved1Err
);
1982 CaseErrorStringifyHardCode( 0xE0004007, kIOUSBWrongPIDErr
);
1983 CaseErrorStringifyHardCode( 0xE0004006, kIOUSBPIDCheckErr
);
1984 CaseErrorStringifyHardCode( 0xE0004003, kIOUSBDataToggleErr
);
1985 CaseErrorStringifyHardCode( 0xE0004002, kIOUSBBitstufErr
);
1986 CaseErrorStringifyHardCode( 0xE0004001, kIOUSBCRCErr
);
1994 #if( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
1995 if( inBuffer
&& ( inBufferSize
> 0 ) )
1999 n
= FormatMessageA( FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_IGNORE_INSERTS
, NULL
, (DWORD
) inErrorCode
,
2000 MAKELANGID( LANG_NEUTRAL
, SUBLANG_DEFAULT
), buffer
, sizeof( buffer
), NULL
);
2003 // Remove any trailing CR's or LF's since some messages have them.
2005 while( ( n
> 0 ) && isspace( ( (unsigned char *) buffer
)[ n
- 1 ] ) )
2007 buffer
[ --n
] = '\0';
2016 #if( !TARGET_API_MAC_OSX_KERNEL && !TARGET_OS_WINDOWS_CE )
2017 s
= strerror( inErrorCode
);
2021 s
= "<unknown error code>";
2027 // Copy the string to the output buffer. If no buffer is supplied or it is empty, return an empty string.
2029 if( inBuffer
&& ( inBufferSize
> 0 ) )
2032 end
= dst
+ ( inBufferSize
- 1 );
2033 while( ( ( end
- dst
) > 0 ) && ( *s
!= '\0' ) )
2043 //===========================================================================================================================
2045 //===========================================================================================================================
2051 const char * inLabel
,
2053 int inLabelMinWidth
,
2054 const char * inType
,
2056 const void * inDataStart
,
2057 const void * inData
,
2061 size_t inBufferSize
)
2063 static const char kHexChars
[] = "0123456789ABCDEF";
2064 const uint8_t * start
;
2065 const uint8_t * src
;
2071 const char * newline
;
2072 char separator
[ 8 ];
2075 DEBUG_UNUSED( inType
);
2076 DEBUG_UNUSED( inTypeSize
);
2078 // Set up the function-wide variables.
2080 if( inLabelSize
== kSizeCString
)
2082 inLabelSize
= strlen( inLabel
);
2084 start
= (const uint8_t *) inData
;
2087 end
= dst
+ inBufferSize
;
2088 offset
= (int)( (intptr_t) inData
- (intptr_t) inDataStart
);
2089 width
= ( (int) inLabelSize
> inLabelMinWidth
) ? (int) inLabelSize
: inLabelMinWidth
;
2090 newline
= ( inFlags
& kDebugFlagsNoNewLine
) ? "" : "\n";
2092 // Set up the separator string. This is used to insert spaces on subsequent "lines" when not using newlines.
2095 if( inFlags
& kDebugFlagsNoNewLine
)
2097 if( inFlags
& kDebugFlags8BitSeparator
)
2101 if( inFlags
& kDebugFlags16BitSeparator
)
2105 if( !( inFlags
& kDebugFlagsNo32BitSeparator
) )
2109 check( ( (size_t)( s
- separator
) ) < sizeof( separator
) );
2115 char prefixString
[ 32 ];
2116 char hexString
[ 64 ];
2117 char asciiString
[ 32 ];
2118 char byteCountString
[ 32 ];
2123 // If this is a label-only item (i.e. no data), print the label (accounting for prefix string spacing) and exit.
2125 if( inDataSize
== 0 )
2127 if( inLabel
&& ( inLabelSize
> 0 ) )
2130 if( !( inFlags
& kDebugFlagsNoAddress
) )
2132 width
+= 8; // "00000000"
2133 if( !( inFlags
& kDebugFlagsNoOffset
) )
2138 if( inFlags
& kDebugFlags32BitOffset
)
2140 width
+= 8; // "00000000"
2142 else if( !( inFlags
& kDebugFlagsNoOffset
) )
2144 width
+= 4; // "0000"
2149 dst
+= DebugSNPrintF( dst
, (size_t)( end
- dst
), "%*s" "%-*.*s" "%.*s" "%s",
2151 ( width
> 0 ) ? ": " : "",
2152 width
, (int) inLabelSize
, inLabel
,
2157 dst
+= DebugPrintF( inLevel
, "%*s" "%-*.*s" "%.*s" "%s",
2159 ( width
> 0 ) ? ": " : "",
2160 width
, (int) inLabelSize
, inLabel
,
2167 // Build the prefix string. It will be in one of the following formats:
2169 // 1) "00000000+0000[0000]" (address and offset)
2170 // 2) "00000000" (address only)
2171 // 3) "0000[0000]" (offset only)
2172 // 4) "" (no address or offset)
2174 // Note: If we're printing multiple "lines", but not printing newlines, a space is used to separate.
2177 if( !( inFlags
& kDebugFlagsNoAddress
) )
2179 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 28 ) & 0xF ];
2180 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 24 ) & 0xF ];
2181 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 20 ) & 0xF ];
2182 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 16 ) & 0xF ];
2183 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 12 ) & 0xF ];
2184 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 8 ) & 0xF ];
2185 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 4 ) & 0xF ];
2186 *s
++ = kHexChars
[ ( (uintptr_t) src
) & 0xF ];
2188 if( !( inFlags
& kDebugFlagsNoOffset
) )
2193 if( !( inFlags
& kDebugFlagsNoOffset
) )
2195 if( inFlags
& kDebugFlags32BitOffset
)
2197 *s
++ = kHexChars
[ ( offset
>> 28 ) & 0xF ];
2198 *s
++ = kHexChars
[ ( offset
>> 24 ) & 0xF ];
2199 *s
++ = kHexChars
[ ( offset
>> 20 ) & 0xF ];
2200 *s
++ = kHexChars
[ ( offset
>> 16 ) & 0xF ];
2202 *s
++ = kHexChars
[ ( offset
>> 12 ) & 0xF ];
2203 *s
++ = kHexChars
[ ( offset
>> 8 ) & 0xF ];
2204 *s
++ = kHexChars
[ ( offset
>> 4 ) & 0xF ];
2205 *s
++ = kHexChars
[ offset
& 0xF ];
2207 if( s
!= prefixString
)
2212 check( ( (size_t)( s
- prefixString
) ) < sizeof( prefixString
) );
2215 // Build a hex string with a optional spaces after every 1, 2, and/or 4 bytes to make it easier to read.
2216 // Optionally pads the hex string with space to fill the full 16 byte range (so it lines up).
2219 chunkSize
= ( inDataSize
< 16 ) ? inDataSize
: 16;
2220 n
= ( inFlags
& kDebugFlagsNo16ByteHexPad
) ? chunkSize
: 16;
2221 for( i
= 0; i
< n
; ++i
)
2223 if( ( inFlags
& kDebugFlags8BitSeparator
) && ( i
> 0 ) )
2227 if( ( inFlags
& kDebugFlags16BitSeparator
) && ( i
> 0 ) && ( ( i
% 2 ) == 0 ) )
2231 if( !( inFlags
& kDebugFlagsNo32BitSeparator
) && ( i
> 0 ) && ( ( i
% 4 ) == 0 ) )
2237 *s
++ = kHexChars
[ src
[ i
] >> 4 ];
2238 *s
++ = kHexChars
[ src
[ i
] & 0xF ];
2246 check( ( (size_t)( s
- hexString
) ) < sizeof( hexString
) );
2249 // Build a string with the ASCII version of the data (replaces non-printable characters with '^').
2250 // Optionally pads the string with '`' to fill the full 16 byte range (so it lines up).
2253 if( !( inFlags
& kDebugFlagsNoASCII
) )
2257 for( i
= 0; i
< n
; ++i
)
2262 if( !DebugIsPrint( c
) )
2274 check( ( (size_t)( s
- asciiString
) ) < sizeof( asciiString
) );
2278 // Build a string indicating how bytes are in the hex dump. Only printed on the first line.
2280 s
= byteCountString
;
2281 if( !( inFlags
& kDebugFlagsNoByteCount
) )
2285 s
+= DebugSNPrintF( s
, sizeof( byteCountString
), " (%d bytes)", (int) inDataSize
);
2288 check( ( (size_t)( s
- byteCountString
) ) < sizeof( byteCountString
) );
2291 // Build the entire line from all the pieces we've previously built.
2297 dst
+= DebugSNPrintF( dst
, (size_t)( end
- dst
),
2299 "%s" // Separator (only if needed)
2308 ( src
!= start
) ? separator
: "",
2310 width
, (int) inLabelSize
, inLabel
? inLabel
: "",
2311 ( width
> 0 ) ? " " : "",
2319 dst
+= DebugSNPrintF( dst
, (size_t)( end
- dst
),
2321 "%s" // Separator (only if needed)
2323 "%*s" // Label Spacing
2330 ( src
!= start
) ? separator
: "",
2333 ( width
> 0 ) ? " " : "",
2344 dst
+= DebugPrintF( inLevel
,
2346 "%s" // Separator (only if needed)
2355 ( src
!= start
) ? separator
: "",
2357 width
, (int) inLabelSize
, inLabel
,
2358 ( width
> 0 ) ? " " : "",
2366 dst
+= DebugPrintF( inLevel
,
2368 "%s" // Separator (only if needed)
2370 "%*s" // Label Spacing
2377 ( src
!= start
) ? separator
: "",
2380 ( width
> 0 ) ? " " : "",
2388 // Move to the next chunk. Exit if there is no more data.
2390 offset
+= (int) chunkSize
;
2392 inDataSize
-= chunkSize
;
2393 if( inDataSize
== 0 )
2399 // Note: The "dst - outBuffer" size calculation works even if "outBuffer" is NULL because it's all relative.
2401 return( (size_t)( dst
- outBuffer
) );
2404 //===========================================================================================================================
2405 // DebugNumVersionToString
2406 //===========================================================================================================================
2408 static char * DebugNumVersionToString( uint32_t inVersion
, char *inString
)
2419 majorRev
= (uint8_t)( ( inVersion
>> 24 ) & 0xFF );
2420 minor
= (uint8_t)( ( inVersion
>> 20 ) & 0x0F );
2421 bugFix
= (uint8_t)( ( inVersion
>> 16 ) & 0x0F );
2422 stage
= (uint8_t)( ( inVersion
>> 8 ) & 0xFF );
2423 revision
= (uint8_t)( inVersion
& 0xFF );
2425 // Convert the major, minor, and bugfix numbers.
2428 s
+= sprintf( s
, "%u", majorRev
);
2429 s
+= sprintf( s
, ".%u", minor
);
2432 s
+= sprintf( s
, ".%u", bugFix
);
2435 // Convert the version stage and non-release revision number.
2439 case kVersionStageDevelopment
:
2440 s
+= sprintf( s
, "d%u", revision
);
2443 case kVersionStageAlpha
:
2444 s
+= sprintf( s
, "a%u", revision
);
2447 case kVersionStageBeta
:
2448 s
+= sprintf( s
, "b%u", revision
);
2451 case kVersionStageFinal
:
2453 // A non-release revision of zero is a special case indicating the software is GM (at the golden master
2454 // stage) and therefore, the non-release revision should not be added to the string.
2458 s
+= sprintf( s
, "f%u", revision
);
2463 dlog( kDebugLevelError
, "invalid NumVersion stage (0x%02X)\n", stage
);
2469 //===========================================================================================================================
2471 //===========================================================================================================================
2473 DEBUG_EXPORT
uint32_t DebugTaskLevel( void )
2479 #if( TARGET_OS_VXWORKS )
2482 level
|= ( ( 1 << kDebugInterruptLevelShift
) & kDebugInterruptLevelMask
);
2489 #if( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
2490 //===========================================================================================================================
2491 // DebugWinEnableConsole
2492 //===========================================================================================================================
2494 #pragma warning( disable:4311 )
2496 static void DebugWinEnableConsole( void )
2498 static bool sConsoleEnabled
= false;
2504 if( sConsoleEnabled
)
2509 // Create console window.
2511 result
= AllocConsole();
2512 require_quiet( result
, exit
);
2514 // Redirect stdin to the console stdin.
2516 fileHandle
= _open_osfhandle( (long) GetStdHandle( STD_INPUT_HANDLE
), _O_TEXT
);
2518 #if( defined( __MWERKS__ ) )
2519 file
= __handle_reopen( (unsigned long) fileHandle
, "r", stdin
);
2520 require_quiet( file
, exit
);
2522 file
= _fdopen( fileHandle
, "r" );
2523 require_quiet( file
, exit
);
2528 err
= setvbuf( stdin
, NULL
, _IONBF
, 0 );
2529 require_noerr_quiet( err
, exit
);
2531 // Redirect stdout to the console stdout.
2533 fileHandle
= _open_osfhandle( (long) GetStdHandle( STD_OUTPUT_HANDLE
), _O_TEXT
);
2535 #if( defined( __MWERKS__ ) )
2536 file
= __handle_reopen( (unsigned long) fileHandle
, "w", stdout
);
2537 require_quiet( file
, exit
);
2539 file
= _fdopen( fileHandle
, "w" );
2540 require_quiet( file
, exit
);
2545 err
= setvbuf( stdout
, NULL
, _IONBF
, 0 );
2546 require_noerr_quiet( err
, exit
);
2548 // Redirect stderr to the console stdout.
2550 fileHandle
= _open_osfhandle( (long) GetStdHandle( STD_OUTPUT_HANDLE
), _O_TEXT
);
2552 #if( defined( __MWERKS__ ) )
2553 file
= __handle_reopen( (unsigned long) fileHandle
, "w", stderr
);
2554 require_quiet( file
, exit
);
2556 file
= _fdopen( fileHandle
, "w" );
2557 require_quiet( file
, exit
);
2562 err
= setvbuf( stderr
, NULL
, _IONBF
, 0 );
2563 require_noerr_quiet( err
, exit
);
2565 sConsoleEnabled
= true;
2571 #pragma warning( default:4311 )
2573 #endif // TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE
2575 #if( TARGET_OS_WIN32 )
2576 //===========================================================================================================================
2577 // DebugWinCharToTCharString
2578 //===========================================================================================================================
2581 DebugWinCharToTCharString(
2582 const char * inCharString
,
2584 TCHAR
* outTCharString
,
2585 size_t inTCharCountMax
,
2586 size_t * outTCharCount
)
2592 if( inCharCount
== kSizeCString
)
2594 inCharCount
= strlen( inCharString
);
2597 dst
= outTCharString
;
2598 if( inTCharCountMax
> 0 )
2600 inTCharCountMax
-= 1;
2601 if( inTCharCountMax
> inCharCount
)
2603 inTCharCountMax
= inCharCount
;
2606 end
= dst
+ inTCharCountMax
;
2609 *dst
++ = (TCHAR
) *src
++;
2615 *outTCharCount
= (size_t)( dst
- outTCharString
);
2617 return( outTCharString
);
2623 #pragma mark == Debugging ==
2626 //===========================================================================================================================
2627 // DebugServicesTest
2628 //===========================================================================================================================
2630 DEBUG_EXPORT OSStatus
DebugServicesTest( void )
2637 0x11, 0x22, 0x33, 0x44,
2639 0x77, 0x88, 0x99, 0xAA,
2643 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
2644 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0,
2645 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71, 0x81, 0x91, 0xA1
2648 debug_initialize( kDebugOutputTypeMetaConsole
);
2652 check( 0 && "SHOULD SEE: check" );
2653 check( 1 && "SHOULD *NOT* SEE: check (valid)" );
2654 check_string( 0, "SHOULD SEE: check_string" );
2655 check_string( 1, "SHOULD *NOT* SEE: check_string (valid)" );
2656 check_noerr( -123 );
2657 check_noerr( 10038 );
2660 check_noerr_string( -6712, "SHOULD SEE: check_noerr_string" );
2661 check_noerr_string( 0, "SHOULD *NOT* SEE: check_noerr_string (valid)" );
2662 check_translated_errno( 0 >= 0 && "SHOULD *NOT* SEE", -384, -999 );
2663 check_translated_errno( -1 >= 0 && "SHOULD SEE", -384, -999 );
2664 check_translated_errno( -1 >= 0 && "SHOULD SEE", 0, -999 );
2665 check_ptr_overlap( "SHOULD *NOT* SEE" ? 10 : 0, 10, 22, 10 );
2666 check_ptr_overlap( "SHOULD SEE" ? 10 : 0, 10, 5, 10 );
2667 check_ptr_overlap( "SHOULD SEE" ? 10 : 0, 10, 12, 6 );
2668 check_ptr_overlap( "SHOULD SEE" ? 12 : 0, 6, 10, 10 );
2669 check_ptr_overlap( "SHOULD SEE" ? 12 : 0, 10, 10, 10 );
2670 check_ptr_overlap( "SHOULD *NOT* SEE" ? 22 : 0, 10, 10, 10 );
2671 check_ptr_overlap( "SHOULD *NOT* SEE" ? 10 : 0, 10, 20, 10 );
2672 check_ptr_overlap( "SHOULD *NOT* SEE" ? 20 : 0, 10, 10, 10 );
2676 require( 0 && "SHOULD SEE", require1
);
2677 { err
= kResponseErr
; goto exit
; }
2679 require( 1 && "SHOULD *NOT* SEE", require2
);
2682 { err
= kResponseErr
; goto exit
; }
2684 require_string( 0 && "SHOULD SEE", require3
, "SHOULD SEE: require_string" );
2685 { err
= kResponseErr
; goto exit
; }
2687 require_string( 1 && "SHOULD *NOT* SEE", require4
, "SHOULD *NOT* SEE: require_string (valid)" );
2690 { err
= kResponseErr
; goto exit
; }
2692 require_quiet( 0 && "SHOULD SEE", require5
);
2693 { err
= kResponseErr
; goto exit
; }
2695 require_quiet( 1 && "SHOULD *NOT* SEE", require6
);
2698 { err
= kResponseErr
; goto exit
; }
2700 require_noerr( -1, require7
);
2701 { err
= kResponseErr
; goto exit
; }
2703 require_noerr( 0, require8
);
2706 { err
= kResponseErr
; goto exit
; }
2708 require_noerr_string( -2, require9
, "SHOULD SEE: require_noerr_string");
2709 { err
= kResponseErr
; goto exit
; }
2711 require_noerr_string( 0, require10
, "SHOULD *NOT* SEE: require_noerr_string (valid)" );
2714 { err
= kResponseErr
; goto exit
; }
2716 require_noerr_action_string( -3, require11
, dlog( kDebugLevelMax
, "action 1 (expected)\n" ), "require_noerr_action_string" );
2717 { err
= kResponseErr
; goto exit
; }
2719 require_noerr_action_string( 0, require12
, dlog( kDebugLevelMax
, "action 2\n" ), "require_noerr_action_string (valid)" );
2722 { err
= kResponseErr
; goto exit
; }
2724 require_noerr_quiet( -4, require13
);
2725 { err
= kResponseErr
; goto exit
; }
2727 require_noerr_quiet( 0, require14
);
2730 { err
= kResponseErr
; goto exit
; }
2732 require_noerr_action( -5, require15
, dlog( kDebugLevelMax
, "SHOULD SEE: action 3 (expected)\n" ) );
2733 { err
= kResponseErr
; goto exit
; }
2735 require_noerr_action( 0, require16
, dlog( kDebugLevelMax
, "SHOULD *NOT* SEE: action 4\n" ) );
2738 { err
= kResponseErr
; goto exit
; }
2740 require_noerr_action_quiet( -4, require17
, dlog( kDebugLevelMax
, "SHOULD SEE: action 5 (expected)\n" ) );
2741 { err
= kResponseErr
; goto exit
; }
2743 require_noerr_action_quiet( 0, require18
, dlog( kDebugLevelMax
, "SHOULD *NOT* SEE: action 6\n" ) );
2746 { err
= kResponseErr
; goto exit
; }
2748 require_action( 0 && "SHOULD SEE", require19
, dlog( kDebugLevelMax
, "SHOULD SEE: action 7 (expected)\n" ) );
2749 { err
= kResponseErr
; goto exit
; }
2751 require_action( 1 && "SHOULD *NOT* SEE", require20
, dlog( kDebugLevelMax
, "SHOULD *NOT* SEE: action 8\n" ) );
2754 { err
= kResponseErr
; goto exit
; }
2756 require_action_quiet( 0, require21
, dlog( kDebugLevelMax
, "SHOULD SEE: action 9 (expected)\n" ) );
2757 { err
= kResponseErr
; goto exit
; }
2759 require_action_quiet( 1, require22
, dlog( kDebugLevelMax
, "SHOULD *NOT* SEE: action 10\n" ) );
2762 { err
= kResponseErr
; goto exit
; }
2764 require_action_string( 0, require23
, dlog( kDebugLevelMax
, "SHOULD SEE: action 11 (expected)\n" ), "SHOULD SEE: require_action_string" );
2765 { err
= kResponseErr
; goto exit
; }
2767 require_action_string( 1, require24
, dlog( kDebugLevelMax
, "SHOULD *NOT* SEE: action 12\n" ), "SHOULD *NOT* SEE: require_action_string" );
2770 { err
= kResponseErr
; goto exit
; }
2773 #if( defined( __MWERKS__ ) )
2774 #if( defined( __cplusplus ) && __option( exceptions ) )
2775 #define COMPILER_HAS_EXCEPTIONS 1
2777 #define COMPILER_HAS_EXCEPTIONS 0
2780 #if( defined( __cplusplus ) )
2781 #define COMPILER_HAS_EXCEPTIONS 1
2783 #define COMPILER_HAS_EXCEPTIONS 0
2787 #if( COMPILER_HAS_EXCEPTIONS )
2790 require_throw( 1 && "SHOULD *NOT* SEE" );
2791 require_throw( 0 && "SHOULD SEE" );
2797 { err
= kResponseErr
; goto exit
; }
2803 err
= translate_errno( 1 != -1, -123, -567 );
2804 require( ( err
== 0 ) && "SHOULD *NOT* SEE", exit
);
2806 err
= translate_errno( -1 != -1, -123, -567 );
2807 require( ( err
== -123 ) && "SHOULD *NOT* SEE", exit
);
2809 err
= translate_errno( -1 != -1, 0, -567 );
2810 require( ( err
== -567 ) && "SHOULD *NOT* SEE", exit
);
2814 debug_string( "debug_string" );
2818 DebugSNPrintF( s
, sizeof( s
), "%d", 1234 );
2819 require_action( strcmp( s
, "1234" ) == 0, exit
, err
= -1 );
2821 DebugSNPrintF( s
, sizeof( s
), "%X", 0x2345 );
2822 require_action( strcmp( s
, "2345" ) == 0, exit
, err
= -1 );
2824 DebugSNPrintF( s
, sizeof( s
), "%#s", "\05test" );
2825 require_action( strcmp( s
, "test" ) == 0, exit
, err
= -1 );
2827 DebugSNPrintF( s
, sizeof( s
), "%##s", "\03www\05apple\03com" );
2828 require_action( strcmp( s
, "www.apple.com." ) == 0, exit
, err
= -1 );
2830 DebugSNPrintF( s
, sizeof( s
), "%ld", (long) INT32_C( 2147483647 ) );
2831 require_action( strcmp( s
, "2147483647" ) == 0, exit
, err
= -1 );
2833 DebugSNPrintF( s
, sizeof( s
), "%lu", (unsigned long) UINT32_C( 4294967295 ) );
2834 require_action( strcmp( s
, "4294967295" ) == 0, exit
, err
= -1 );
2836 #if( TYPE_LONGLONG_NATIVE )
2837 DebugSNPrintF( s
, sizeof( s
), "%lld", (long_long_compat
) INT64_C( 9223372036854775807 ) );
2838 require_action( strcmp( s
, "9223372036854775807" ) == 0, exit
, err
= -1 );
2840 DebugSNPrintF( s
, sizeof( s
), "%lld", (long_long_compat
) INT64_C( -9223372036854775807 ) );
2841 require_action( strcmp( s
, "-9223372036854775807" ) == 0, exit
, err
= -1 );
2843 DebugSNPrintF( s
, sizeof( s
), "%llu", (unsigned_long_long_compat
) UINT64_C( 18446744073709551615 ) );
2844 require_action( strcmp( s
, "18446744073709551615" ) == 0, exit
, err
= -1 );
2847 DebugSNPrintF( s
, sizeof( s
), "%lb", (unsigned long) binary_32( 01111011, 01111011, 01111011, 01111011 ) );
2848 require_action( strcmp( s
, "1111011011110110111101101111011" ) == 0, exit
, err
= -1 );
2850 DebugSNPrintF( s
, sizeof( s
), "%C", 0x41624364 ); // 'AbCd'
2851 require_action( strcmp( s
, "AbCd" ) == 0, exit
, err
= -1 );
2853 #if( defined( MDNS_DEBUGMSGS ) )
2857 memset( &maddr
, 0, sizeof( maddr
) );
2858 maddr
.type
= mDNSAddrType_IPv4
;
2859 maddr
.ip
.v4
.b
[ 0 ] = 127;
2860 maddr
.ip
.v4
.b
[ 1 ] = 0;
2861 maddr
.ip
.v4
.b
[ 2 ] = 0;
2862 maddr
.ip
.v4
.b
[ 3 ] = 1;
2863 DebugSNPrintF( s
, sizeof( s
), "%#a", &maddr
);
2864 require_action( strcmp( s
, "127.0.0.1" ) == 0, exit
, err
= -1 );
2866 memset( &maddr
, 0, sizeof( maddr
) );
2867 maddr
.type
= mDNSAddrType_IPv6
;
2868 maddr
.ip
.v6
.b
[ 0 ] = 0xFE;
2869 maddr
.ip
.v6
.b
[ 1 ] = 0x80;
2870 maddr
.ip
.v6
.b
[ 15 ] = 0x01;
2871 DebugSNPrintF( s
, sizeof( s
), "%#a", &maddr
);
2872 require_action( strcmp( s
, "FE80:0000:0000:0000:0000:0000:0000:0001" ) == 0, exit
, err
= -1 );
2878 struct sockaddr_in sa4
;
2880 memset( &sa4
, 0, sizeof( sa4
) );
2881 sa4
.sin_family
= AF_INET
;
2882 p
= (uint8_t *) &sa4
.sin_port
;
2883 p
[ 0 ] = (uint8_t)( ( 80 >> 8 ) & 0xFF );
2884 p
[ 1 ] = (uint8_t)( 80 & 0xFF );
2885 p
= (uint8_t *) &sa4
.sin_addr
.s_addr
;
2886 p
[ 0 ] = (uint8_t)( ( INADDR_LOOPBACK
>> 24 ) & 0xFF );
2887 p
[ 1 ] = (uint8_t)( ( INADDR_LOOPBACK
>> 16 ) & 0xFF );
2888 p
[ 2 ] = (uint8_t)( ( INADDR_LOOPBACK
>> 8 ) & 0xFF );
2889 p
[ 3 ] = (uint8_t)( INADDR_LOOPBACK
& 0xFF );
2890 DebugSNPrintF( s
, sizeof( s
), "%##a", &sa4
);
2891 require_action( strcmp( s
, "127.0.0.1:80" ) == 0, exit
, err
= -1 );
2897 struct sockaddr_in6 sa6
;
2899 memset( &sa6
, 0, sizeof( sa6
) );
2900 sa6
.sin6_family
= AF_INET6
;
2901 p
= (uint8_t *) &sa6
.sin6_port
;
2902 p
[ 0 ] = (uint8_t)( ( 80 >> 8 ) & 0xFF );
2903 p
[ 1 ] = (uint8_t)( 80 & 0xFF );
2904 sa6
.sin6_addr
.s6_addr
[ 0 ] = 0xFE;
2905 sa6
.sin6_addr
.s6_addr
[ 1 ] = 0x80;
2906 sa6
.sin6_addr
.s6_addr
[ 15 ] = 0x01;
2907 sa6
.sin6_scope_id
= 2;
2908 DebugSNPrintF( s
, sizeof( s
), "%##a", &sa6
);
2909 require_action( strcmp( s
, "[FE80:0000:0000:0000:0000:0000:0000:0001%2]:80" ) == 0, exit
, err
= -1 );
2915 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "tes" );
2916 require_action( strcmp( s
, "tes" ) == 0, exit
, err
= kResponseErr
);
2918 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "test" );
2919 require_action( strcmp( s
, "test" ) == 0, exit
, err
= kResponseErr
);
2921 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "testing" );
2922 require_action( strcmp( s
, "test" ) == 0, exit
, err
= kResponseErr
);
2924 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "te\xC3\xA9" );
2925 require_action( strcmp( s
, "te\xC3\xA9" ) == 0, exit
, err
= kResponseErr
);
2927 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "te\xC3\xA9ing" );
2928 require_action( strcmp( s
, "te\xC3\xA9" ) == 0, exit
, err
= kResponseErr
);
2930 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "tes\xC3\xA9ing" );
2931 require_action( strcmp( s
, "tes" ) == 0, exit
, err
= kResponseErr
);
2933 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "t\xed\x9f\xbf" );
2934 require_action( strcmp( s
, "t\xed\x9f\xbf" ) == 0, exit
, err
= kResponseErr
);
2936 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "t\xed\x9f\xbfing" );
2937 require_action( strcmp( s
, "t\xed\x9f\xbf" ) == 0, exit
, err
= kResponseErr
);
2939 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "te\xed\x9f\xbf" );
2940 require_action( strcmp( s
, "te" ) == 0, exit
, err
= kResponseErr
);
2942 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "te\xed\x9f\xbfing" );
2943 require_action( strcmp( s
, "te" ) == 0, exit
, err
= kResponseErr
);
2945 DebugSNPrintF(s
, sizeof(s
), "%.*s", 7, "te\xC3\xA9\xed\x9f\xbfing" );
2946 require_action( strcmp( s
, "te\xC3\xA9\xed\x9f\xbf" ) == 0, exit
, err
= kResponseErr
);
2948 DebugSNPrintF(s
, sizeof(s
), "%.*s", 6, "te\xC3\xA9\xed\x9f\xbfing" );
2949 require_action( strcmp( s
, "te\xC3\xA9" ) == 0, exit
, err
= kResponseErr
);
2951 DebugSNPrintF(s
, sizeof(s
), "%.*s", 5, "te\xC3\xA9\xed\x9f\xbfing" );
2952 require_action( strcmp( s
, "te\xC3\xA9" ) == 0, exit
, err
= kResponseErr
);
2954 #if( TARGET_RT_BIG_ENDIAN )
2955 DebugSNPrintF( s
, sizeof( s
), "%S", "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" );
2956 require_action( strcmp( s
, "abcd" ) == 0, exit
, err
= -1 );
2958 DebugSNPrintF( s
, sizeof( s
), "%S", "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" "\x00" );
2959 require_action( strcmp( s
, "abcd" ) == 0, exit
, err
= -1 );
2962 DebugSNPrintF( s
, sizeof( s
), "%S",
2963 "\xFE\xFF" "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" ); // Big Endian BOM
2964 require_action( strcmp( s
, "abcd" ) == 0, exit
, err
= -1 );
2966 DebugSNPrintF( s
, sizeof( s
), "%S",
2967 "\xFF\xFE" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" "\x00" ); // Little Endian BOM
2968 require_action( strcmp( s
, "abcd" ) == 0, exit
, err
= -1 );
2970 DebugSNPrintF( s
, sizeof( s
), "%#S", "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" ); // Big Endian
2971 require_action( strcmp( s
, "abcd" ) == 0, exit
, err
= -1 );
2973 DebugSNPrintF( s
, sizeof( s
), "%##S", "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" "\x00" ); // Little Endian
2974 require_action( strcmp( s
, "abcd" ) == 0, exit
, err
= -1 );
2976 DebugSNPrintF( s
, sizeof( s
), "%.*S",
2977 4, "\xFE\xFF" "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" ); // Big Endian BOM
2978 require_action( strcmp( s
, "abc" ) == 0, exit
, err
= -1 );
2980 DebugSNPrintF( s
, sizeof( s
), "%.*S",
2981 4, "\xFF\xFE" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" ); // Little Endian BOM
2982 require_action( strcmp( s
, "abc" ) == 0, exit
, err
= -1 );
2984 #if( TARGET_RT_BIG_ENDIAN )
2985 DebugSNPrintF( s
, sizeof( s
), "%.*S", 3, "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" );
2986 require_action( strcmp( s
, "abc" ) == 0, exit
, err
= -1 );
2988 DebugSNPrintF( s
, sizeof( s
), "%.*S", 3, "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" );
2989 require_action( strcmp( s
, "abc" ) == 0, exit
, err
= -1 );
2992 DebugSNPrintF( s
, sizeof( s
), "%#.*S", 3, "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" ); // Big Endian
2993 require_action( strcmp( s
, "abc" ) == 0, exit
, err
= -1 );
2995 DebugSNPrintF( s
, sizeof( s
), "%##.*S", 3, "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" ); // Little Endian
2996 require_action( strcmp( s
, "abc" ) == 0, exit
, err
= -1 );
3000 DebugSNPrintF( s
, sizeof( s
), "%U", "\x10\xb8\xa7\x6b" "\xad\x9d" "\xd1\x11" "\x80\xb4" "\x00\xc0\x4f\xd4\x30\xc8" );
3001 require_action( strcmp( s
, "6ba7b810-9dad-11d1-80b4-00c04fd430c8" ) == 0, exit
, err
= -1 );
3003 DebugSNPrintF( s
, sizeof( s
), "%m", 0 );
3004 require_action( strcmp( s
, "no error" ) == 0, exit
, err
= -1 );
3006 DebugSNPrintF( s
, sizeof( s
), "%lm", (long) 0 );
3007 require_action( strcmp( s
, "no error" ) == 0, exit
, err
= -1 );
3009 DebugSNPrintF( s
, sizeof( s
), "\"%H\"", "\x6b\xa7\xb8\x10\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8", 16, 16 );
3010 DebugPrintF( kDebugLevelMax
, "%s\n\n", s
);
3012 DebugSNPrintF( s
, sizeof( s
), "\"%H\"",
3013 "\x6b\xa7\xb8\x10\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8"
3014 "\x6b\xa7\xb8\x10\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8",
3016 DebugPrintF( kDebugLevelMax
, "%s\n\n", s
);
3018 DebugSNPrintF( s
, sizeof( s
), "\"%H\"", "\x6b\xa7", 2, 2 );
3019 DebugPrintF( kDebugLevelMax
, "%s\n\n", s
);
3024 DebugHexDump( kDebugLevelMax
, 0, "My Label", kSizeCString
, 0, NULL
, 0, data
, data
, sizeof( data
),
3025 kDebugFlagsNone
, s
, sizeof( s
) );
3026 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3029 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
),
3030 kDebugFlagsNoAddress
| kDebugFlagsNoOffset
, s
, sizeof( s
) );
3031 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3034 DebugHexDump( kDebugLevelMax
, 0, "My Label", kSizeCString
, 0, NULL
, 0, data
, data
, sizeof( data
),
3035 kDebugFlagsNoAddress
| kDebugFlagsNoOffset
, s
, sizeof( s
) );
3036 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3039 DebugHexDump( kDebugLevelMax
, 0, "My Label", kSizeCString
, 0, NULL
, 0, data
, data
, sizeof( data
),
3040 kDebugFlagsNoAddress
, s
, sizeof( s
) );
3041 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3044 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
),
3045 kDebugFlagsNoOffset
, s
, sizeof( s
) );
3046 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3049 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
),
3050 kDebugFlagsNoAddress
, s
, sizeof( s
) );
3051 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3054 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
),
3055 kDebugFlagsNoOffset
, s
, sizeof( s
) );
3056 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3059 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
),
3060 kDebugFlagsNoByteCount
, s
, sizeof( s
) );
3061 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3064 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, "\x41\x62\x43\x64", "\x41\x62\x43\x64", 4, // 'AbCd'
3065 kDebugFlagsNoAddress
| kDebugFlagsNoOffset
| kDebugFlagsNoNewLine
|
3066 kDebugFlagsNo32BitSeparator
| kDebugFlagsNo16ByteHexPad
| kDebugFlagsNoByteCount
,
3068 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3071 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
),
3072 kDebugFlagsNoAddress
| kDebugFlagsNoOffset
| kDebugFlagsNoASCII
| kDebugFlagsNoNewLine
|
3073 kDebugFlags16BitSeparator
| kDebugFlagsNo32BitSeparator
|
3074 kDebugFlagsNo16ByteHexPad
| kDebugFlagsNoByteCount
, s
, sizeof( s
) );
3075 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3078 DebugHexDump( kDebugLevelMax
, 8, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
), kDebugFlagsNone
, s
, sizeof( s
) );
3079 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3083 dlog( kDebugLevelNotice
, "dlog\n" );
3084 dlog( kDebugLevelNotice
, "dlog integer: %d\n", 123 );
3085 dlog( kDebugLevelNotice
, "dlog string: \"%s\"\n", "test string" );
3086 dlogmem( kDebugLevelNotice
, data
, sizeof( data
) );
3090 DebugPrintF( kDebugLevelMax
, "\n\nALL TESTS DONE\n\n" );
3096 DebugPrintF( kDebugLevelMax
, "\n\n### TEST FAILED ###\n\n" );