2 * Copyright (c) 1997-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
23 Change History (most recent first):
25 $Log: DebugServices.c,v $
26 Revision 1.5 2004/09/17 01:08:57 cheshire
27 Renamed mDNSClientAPI.h to mDNSEmbeddedAPI.h
28 The name "mDNSClientAPI.h" is misleading to new developers looking at this code. The interfaces
29 declared in that file are ONLY appropriate to single-address-space embedded applications.
30 For clients on general-purpose computers, the interfaces defined in dns_sd.h should be used.
32 Revision 1.4 2004/04/15 08:59:08 bradley
33 Removed deprecated debug and log levels and replaced them with modern equivalents.
35 Revision 1.3 2004/04/08 09:29:55 bradley
36 Manually do host->network byte order conversion to avoid needing libraries for htons/htonl. Changed
37 hex dumps to better separate hex and ASCII. Added support for %.8a syntax in DebugSNPrintF for Fibre
38 Channel addresses (00:11:22:33:44:55:66:77). Fixed a few places where HeaderDoc was incorrect.
40 Revision 1.2 2004/03/07 05:59:34 bradley
41 Sync'd with internal version: Added expect macros, error codes, and CoreServices exclusion.
43 Revision 1.1 2004/01/30 02:27:30 bradley
44 Debugging support for various platforms.
49 - Use StackWalk on Windows to optionally print stack frames.
53 #pragma mark == Includes ==
56 //===========================================================================================================================
58 //===========================================================================================================================
66 #include "CommonServices.h"
68 #include "DebugServices.h"
72 #if( TARGET_OS_VXWORKS )
76 #if( TARGET_OS_WIN32 )
79 #if( !TARGET_OS_WINDOWS_CE )
85 #if( DEBUG_IDEBUG_ENABLED && TARGET_API_MAC_OSX_KERNEL )
86 #include <IOKit/IOLib.h>
89 // If MDNS_DEBUGMSGS is defined (even if defined 0), it is aware of mDNS and it is probably safe to include mDNSEmbeddedAPI.h.
91 #if( defined( MDNS_DEBUGMSGS ) )
92 #include "mDNSEmbeddedAPI.h"
96 #pragma mark == Macros ==
99 //===========================================================================================================================
101 //===========================================================================================================================
103 #define DebugIsPrint( C ) ( ( ( C ) >= 0x20 ) && ( ( C ) <= 0x7E ) )
106 #pragma mark == Prototypes ==
109 //===========================================================================================================================
111 //===========================================================================================================================
113 static OSStatus
DebugPrint( DebugLevel inLevel
, char *inData
, size_t inSize
);
117 #if( DEBUG_FPRINTF_ENABLED )
118 static OSStatus
DebugFPrintFInit( DebugOutputTypeFlags inFlags
, const char *inFilename
);
119 static void DebugFPrintFPrint( char *inData
, size_t inSize
);
122 // iDebug (Mac OS X user and kernel)
124 #if( DEBUG_IDEBUG_ENABLED )
125 static OSStatus
DebugiDebugInit( void );
126 static void DebugiDebugPrint( char *inData
, size_t inSize
);
129 // kprintf (Mac OS X Kernel)
131 #if( DEBUG_KPRINTF_ENABLED )
132 static void DebugKPrintFPrint( char *inData
, size_t inSize
);
135 // Mac OS X IOLog (Mac OS X Kernel)
137 #if( DEBUG_MAC_OS_X_IOLOG_ENABLED )
138 static void DebugMacOSXIOLogPrint( char *inData
, size_t inSize
);
144 static OSStatus
DebugMacOSXLogInit( void );
145 static void DebugMacOSXLogPrint( char *inData
, size_t inSize
);
150 #if( TARGET_OS_WIN32 )
151 static void DebugWindowsDebuggerPrint( char *inData
, size_t inSize
);
156 #if( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
157 static OSStatus
DebugWindowsEventLogInit( const char *inName
, HMODULE inModule
);
158 static void DebugWindowsEventLogPrint( DebugLevel inLevel
, char *inData
, size_t inSize
);
163 #if( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
165 DebugAssertOutputHandler(
166 OSType inComponentSignature
,
168 const char * inAssertionString
,
169 const char * inExceptionString
,
170 const char * inErrorString
,
171 const char * inFileName
,
174 ConstStr255Param inOutputMsg
);
179 static char * DebugNumVersionToString( uint32_t inVersion
, char *inString
);
181 #if( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
182 static void DebugWinEnableConsole( void );
185 #if( TARGET_OS_WIN32 )
187 DebugWinCharToTCharString(
188 const char * inCharString
,
190 TCHAR
* outTCharString
,
191 size_t inTCharCountMax
,
192 size_t * outTCharCount
);
196 #pragma mark == Globals ==
199 //===========================================================================================================================
201 //===========================================================================================================================
203 #if( TARGET_OS_VXWORKS )
204 // TCP States for inetstatShow.
206 extern char ** pTcpstates
; // defined in tcpLib.c
208 const char * kDebugTCPStates
[] =
213 "(3) TCPS_SYN_RECEIVED",
214 "(4) TCPS_ESTABLISHED",
215 "(5) TCPS_CLOSE_WAIT",
216 "(6) TCPS_FIN_WAIT_1",
219 "(9) TCPS_FIN_WAIT_2",
220 "(10) TCPS_TIME_WAIT",
226 static bool gDebugInitialized
= false;
227 static DebugOutputType gDebugOutputType
= kDebugOutputTypeNone
;
228 static DebugLevel gDebugPrintLevelMin
= kDebugLevelInfo
;
229 static DebugLevel gDebugPrintLevelMax
= kDebugLevelMax
;
230 static DebugLevel gDebugBreakLevel
= kDebugLevelAssert
;
231 #if( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
232 static DebugAssertOutputHandlerUPP gDebugAssertOutputHandlerUPP
= NULL
;
237 static DebugOutputFunctionPtr gDebugCustomOutputFunction
= NULL
;
238 static void * gDebugCustomOutputContext
= NULL
;
242 #if( DEBUG_FPRINTF_ENABLED )
243 static FILE * gDebugFPrintFFile
= NULL
;
249 typedef int ( *DebugMacOSXLogFunctionPtr
)( const char *inFormat
, ... );
251 static DebugMacOSXLogFunctionPtr gDebugMacOSXLogFunction
= NULL
;
257 #if( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
258 static HANDLE gDebugWindowsEventLogEventSource
= NULL
;
263 #pragma mark == General ==
266 //===========================================================================================================================
268 //===========================================================================================================================
270 DEBUG_EXPORT OSStatus
DebugInitialize( DebugOutputType inType
, ... )
273 DebugOutputType type
;
276 va_start( args
, inType
);
278 #if( TARGET_OS_VXWORKS )
279 // Set up the TCP state strings if they are not already set up by VxWorks (normally not set up for some reason).
283 pTcpstates
= (char **) kDebugTCPStates
;
287 // Set up DebugLib stuff (if building with Debugging.h).
289 #if( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
290 if( !gDebugAssertOutputHandlerUPP
)
292 gDebugAssertOutputHandlerUPP
= NewDebugAssertOutputHandlerUPP( DebugAssertOutputHandler
);
293 check( gDebugAssertOutputHandlerUPP
);
294 if( gDebugAssertOutputHandlerUPP
)
296 InstallDebugAssertOutputHandler( gDebugAssertOutputHandlerUPP
);
301 // Pre-process meta-output kind to pick an appropriate output kind for the platform.
304 if( type
== kDebugOutputTypeMetaConsole
)
307 type
= kDebugOutputTypeMacOSXLog
;
308 #elif( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
309 #if( DEBUG_FPRINTF_ENABLED )
310 type
= kDebugOutputTypeFPrintF
;
312 type
= kDebugOutputTypeWindowsDebugger
;
314 #elif( TARGET_API_MAC_OSX_KERNEL )
315 #if( DEBUG_MAC_OS_X_IOLOG_ENABLED )
316 type
= kDebugOutputTypeMacOSXIOLog
;
317 #elif( DEBUG_IDEBUG_ENABLED )
318 type
= kDebugOutputTypeiDebug
;
319 #elif( DEBUG_KPRINTF_ENABLED )
320 type
= kDebugOutputTypeKPrintF
;
322 #elif( TARGET_OS_VXWORKS )
323 #if( DEBUG_FPRINTF_ENABLED )
324 type
= kDebugOutputTypeFPrintF
;
326 #error target is VxWorks, but fprintf output is disabled
329 #if( DEBUG_FPRINTF_ENABLED )
330 type
= kDebugOutputTypeFPrintF
;
335 // Process output kind.
337 gDebugOutputType
= type
;
340 case kDebugOutputTypeNone
:
344 case kDebugOutputTypeCustom
:
345 gDebugCustomOutputFunction
= va_arg( args
, DebugOutputFunctionPtr
);
346 gDebugCustomOutputContext
= va_arg( args
, void * );
350 #if( DEBUG_FPRINTF_ENABLED )
351 case kDebugOutputTypeFPrintF
:
352 if( inType
== kDebugOutputTypeMetaConsole
)
354 err
= DebugFPrintFInit( kDebugOutputTypeFlagsStdErr
, NULL
);
358 DebugOutputTypeFlags flags
;
359 const char * filename
;
361 flags
= (DebugOutputTypeFlags
) va_arg( args
, unsigned int );
362 if( ( flags
& kDebugOutputTypeFlagsTypeMask
) == kDebugOutputTypeFlagsFile
)
364 filename
= va_arg( args
, const char * );
370 err
= DebugFPrintFInit( flags
, filename
);
375 #if( DEBUG_IDEBUG_ENABLED )
376 case kDebugOutputTypeiDebug
:
377 err
= DebugiDebugInit();
381 #if( DEBUG_KPRINTF_ENABLED )
382 case kDebugOutputTypeKPrintF
:
387 #if( DEBUG_MAC_OS_X_IOLOG_ENABLED )
388 case kDebugOutputTypeMacOSXIOLog
:
394 case kDebugOutputTypeMacOSXLog
:
395 err
= DebugMacOSXLogInit();
399 #if( TARGET_OS_WIN32 )
400 case kDebugOutputTypeWindowsDebugger
:
405 #if( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
406 case kDebugOutputTypeWindowsEventLog
:
411 name
= va_arg( args
, const char * );
412 module = va_arg( args
, HMODULE
);
413 err
= DebugWindowsEventLogInit( name
, module );
422 gDebugInitialized
= true;
429 //===========================================================================================================================
431 //===========================================================================================================================
433 DEBUG_EXPORT
void DebugFinalize( void )
435 #if( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
436 check( gDebugAssertOutputHandlerUPP
);
437 if( gDebugAssertOutputHandlerUPP
)
439 InstallDebugAssertOutputHandler( NULL
);
440 DisposeDebugAssertOutputHandlerUPP( gDebugAssertOutputHandlerUPP
);
441 gDebugAssertOutputHandlerUPP
= NULL
;
446 //===========================================================================================================================
448 //===========================================================================================================================
450 DEBUG_EXPORT OSStatus
DebugGetProperty( DebugPropertyTag inTag
, ... )
456 va_start( args
, inTag
);
459 case kDebugPropertyTagPrintLevelMin
:
460 level
= va_arg( args
, DebugLevel
* );
461 *level
= gDebugPrintLevelMin
;
465 case kDebugPropertyTagPrintLevelMax
:
466 level
= va_arg( args
, DebugLevel
* );
467 *level
= gDebugPrintLevelMax
;
471 case kDebugPropertyTagBreakLevel
:
472 level
= va_arg( args
, DebugLevel
* );
473 *level
= gDebugBreakLevel
;
478 err
= kUnsupportedErr
;
485 //===========================================================================================================================
487 //===========================================================================================================================
489 DEBUG_EXPORT OSStatus
DebugSetProperty( DebugPropertyTag inTag
, ... )
495 va_start( args
, inTag
);
498 case kDebugPropertyTagPrintLevelMin
:
499 level
= va_arg( args
, DebugLevel
);
500 gDebugPrintLevelMin
= level
;
504 case kDebugPropertyTagPrintLevelMax
:
505 level
= va_arg( args
, DebugLevel
);
506 gDebugPrintLevelMax
= level
;
510 case kDebugPropertyTagBreakLevel
:
511 level
= va_arg( args
, DebugLevel
);
512 gDebugBreakLevel
= level
;
517 err
= kUnsupportedErr
;
526 #pragma mark == Output ==
529 //===========================================================================================================================
531 //===========================================================================================================================
533 DEBUG_EXPORT
size_t DebugPrintF( DebugLevel inLevel
, const char *inFormat
, ... )
538 // Skip if the level is not in the enabled range..
540 if( ( inLevel
< gDebugPrintLevelMin
) || ( inLevel
> gDebugPrintLevelMax
) )
546 va_start( args
, inFormat
);
547 n
= DebugPrintFVAList( inLevel
, inFormat
, args
);
554 //===========================================================================================================================
556 //===========================================================================================================================
558 DEBUG_EXPORT
size_t DebugPrintFVAList( DebugLevel inLevel
, const char *inFormat
, va_list inArgs
)
563 // Skip if the level is not in the enabled range..
565 if( ( inLevel
< gDebugPrintLevelMin
) || ( inLevel
> gDebugPrintLevelMax
) )
571 n
= DebugSNPrintFVAList( buffer
, sizeof( buffer
), inFormat
, inArgs
);
572 DebugPrint( inLevel
, buffer
, (size_t) n
);
578 //===========================================================================================================================
580 //===========================================================================================================================
582 static OSStatus
DebugPrint( DebugLevel inLevel
, char *inData
, size_t inSize
)
586 // Skip if the level is not in the enabled range..
588 if( ( inLevel
< gDebugPrintLevelMin
) || ( inLevel
> gDebugPrintLevelMax
) )
594 // Printing is not safe at interrupt time so check for this and warn with an interrupt safe mechanism (if available).
596 if( DebugTaskLevel() & kDebugInterruptLevelMask
)
598 #if( TARGET_OS_VXWORKS )
599 logMsg( "\ncannot print at interrupt time\n\n", 1, 2, 3, 4, 5, 6 );
602 err
= kExecutionStateErr
;
606 // Initialize the debugging library if it hasn't already been initialized (allows for zero-config usage).
608 if( !gDebugInitialized
)
610 debug_initialize( kDebugOutputTypeMetaConsole
);
613 // Print based on the current output type.
615 switch( gDebugOutputType
)
617 case kDebugOutputTypeNone
:
620 case kDebugOutputTypeCustom
:
621 if( gDebugCustomOutputFunction
)
623 gDebugCustomOutputFunction( inData
, inSize
, gDebugCustomOutputContext
);
627 #if( DEBUG_FPRINTF_ENABLED )
628 case kDebugOutputTypeFPrintF
:
629 DebugFPrintFPrint( inData
, inSize
);
633 #if( DEBUG_IDEBUG_ENABLED )
634 case kDebugOutputTypeiDebug
:
635 DebugiDebugPrint( inData
, inSize
);
639 #if( DEBUG_KPRINTF_ENABLED )
640 case kDebugOutputTypeKPrintF
:
641 DebugKPrintFPrint( inData
, inSize
);
645 #if( DEBUG_MAC_OS_X_IOLOG_ENABLED )
646 case kDebugOutputTypeMacOSXIOLog
:
647 DebugMacOSXIOLogPrint( inData
, inSize
);
652 case kDebugOutputTypeMacOSXLog
:
653 DebugMacOSXLogPrint( inData
, inSize
);
657 #if( TARGET_OS_WIN32 )
658 case kDebugOutputTypeWindowsDebugger
:
659 DebugWindowsDebuggerPrint( inData
, inSize
);
663 #if( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
664 case kDebugOutputTypeWindowsEventLog
:
665 DebugWindowsEventLogPrint( inLevel
, inData
, inSize
);
678 //===========================================================================================================================
681 // Warning: This routine relies on several of the strings being string constants that will exist forever because the
682 // underlying logMsg API that does the printing is asynchronous so it cannot use temporary/stack-based
683 // pointer variables (e.g. local strings). The debug macros that invoke this function only use constant
684 // constant strings, but if this function is invoked directly from other places, it must use constant strings.
685 //===========================================================================================================================
689 int_least32_t inErrorCode
,
690 const char * inAssertString
,
691 const char * inMessage
,
692 const char * inFilename
,
693 int_least32_t inLineNumber
,
694 const char * inFunction
)
696 // Skip if the level is not in the enabled range..
698 if( ( kDebugLevelAssert
< gDebugPrintLevelMin
) || ( kDebugLevelAssert
> gDebugPrintLevelMax
) )
703 if( inErrorCode
!= 0 )
708 "[ASSERT] error: %ld (%m)\n"
709 "[ASSERT] where: \"%s\", line %ld, \"%s\"\n"
711 inErrorCode
, inErrorCode
,
712 inFilename
? inFilename
: "",
714 inFunction
? inFunction
: "" );
721 "[ASSERT] assert: \"%s\" %s\n"
722 "[ASSERT] where: \"%s\", line %ld, \"%s\"\n"
724 inAssertString
? inAssertString
: "",
725 inMessage
? inMessage
: "",
726 inFilename
? inFilename
: "",
728 inFunction
? inFunction
: "" );
731 // Break into the debugger if enabled.
733 #if( TARGET_OS_WIN32 )
734 if( gDebugBreakLevel
<= kDebugLevelAssert
)
736 if( IsDebuggerPresent() )
748 #if( DEBUG_FPRINTF_ENABLED )
749 //===========================================================================================================================
751 //===========================================================================================================================
753 static OSStatus
DebugFPrintFInit( DebugOutputTypeFlags inFlags
, const char *inFilename
)
756 DebugOutputTypeFlags typeFlags
;
758 typeFlags
= inFlags
& kDebugOutputTypeFlagsTypeMask
;
759 if( typeFlags
== kDebugOutputTypeFlagsStdOut
)
761 #if( TARGET_OS_WIN32 )
762 DebugWinEnableConsole();
765 gDebugFPrintFFile
= stdout
;
767 else if( typeFlags
== kDebugOutputTypeFlagsStdErr
)
769 #if( TARGET_OS_WIN32 )
770 DebugWinEnableConsole();
773 gDebugFPrintFFile
= stdout
;
775 else if( typeFlags
== kDebugOutputTypeFlagsFile
)
777 require_action_quiet( inFilename
&& ( *inFilename
!= '\0' ), exit
, err
= kOpenErr
);
779 gDebugFPrintFFile
= fopen( inFilename
, "a" );
780 require_action_quiet( gDebugFPrintFFile
, exit
, err
= kOpenErr
);
793 //===========================================================================================================================
795 //===========================================================================================================================
797 static void DebugFPrintFPrint( char *inData
, size_t inSize
)
802 // Convert \r to \n. fprintf will interpret \n and convert to whatever is appropriate for the platform.
815 // Write the data and flush.
817 if( gDebugFPrintFFile
)
819 fprintf( gDebugFPrintFFile
, "%.*s", (int) inSize
, inData
);
820 fflush( gDebugFPrintFFile
);
823 #endif // DEBUG_FPRINTF_ENABLED
825 #if( DEBUG_IDEBUG_ENABLED )
826 //===========================================================================================================================
828 //===========================================================================================================================
830 static OSStatus
DebugiDebugInit( void )
834 #if( TARGET_API_MAC_OSX_KERNEL )
836 extern uint32_t * _giDebugReserved1
;
838 // Emulate the iDebugSetOutputType macro in iDebugServices.h.
839 // Note: This is not thread safe, but neither is iDebugServices.h nor iDebugKext.
841 if( !_giDebugReserved1
)
843 _giDebugReserved1
= (uint32_t *) IOMalloc( sizeof( uint32_t ) );
844 require_action_quiet( _giDebugReserved1
, exit
, err
= kNoMemoryErr
);
846 *_giDebugReserved1
= 0x00010000U
;
851 __private_extern__
void iDebugSetOutputTypeInternal( uint32_t inType
);
853 iDebugSetOutputTypeInternal( 0x00010000U
);
861 //===========================================================================================================================
863 //===========================================================================================================================
865 static void DebugiDebugPrint( char *inData
, size_t inSize
)
867 #if( TARGET_API_MAC_OSX_KERNEL )
869 // Locally declared here so we do not need to include iDebugKext.h.
870 // Note: IOKit uses a global namespace for all code and only a partial link occurs at build time. When the
871 // KEXT is loaded, the runtime linker will link in this extern'd symbol (assuming iDebug is present).
872 // _giDebugLogInternal is actually part of IOKit proper so this should link even if iDebug is not present.
874 typedef void ( *iDebugLogFunctionPtr
)( uint32_t inLevel
, uint32_t inTag
, const char *inFormat
, ... );
876 extern iDebugLogFunctionPtr _giDebugLogInternal
;
878 if( _giDebugLogInternal
)
880 _giDebugLogInternal( 0, 0, "%.*s", (int) inSize
, inData
);
885 __private_extern__
void iDebugLogInternal( uint32_t inLevel
, uint32_t inTag
, const char *inFormat
, ... );
887 iDebugLogInternal( 0, 0, "%.*s", (int) inSize
, inData
);
893 #if( DEBUG_KPRINTF_ENABLED )
894 //===========================================================================================================================
896 //===========================================================================================================================
898 static void DebugKPrintFPrint( char *inData
, size_t inSize
)
900 extern void kprintf( const char *inFormat
, ... );
902 kprintf( "%.*s", (int) inSize
, inData
);
906 #if( DEBUG_MAC_OS_X_IOLOG_ENABLED )
907 //===========================================================================================================================
908 // DebugMacOSXIOLogPrint
909 //===========================================================================================================================
911 static void DebugMacOSXIOLogPrint( char *inData
, size_t inSize
)
913 extern void IOLog( const char *inFormat
, ... );
915 IOLog( "%.*s", (int) inSize
, inData
);
920 //===========================================================================================================================
921 // DebugMacOSXLogInit
922 //===========================================================================================================================
924 static OSStatus
DebugMacOSXLogInit( void )
930 CFStringRef functionName
;
935 // Create a bundle reference for System.framework.
937 path
= CFSTR( "/System/Library/Frameworks/System.framework" );
938 url
= CFURLCreateWithFileSystemPath( NULL
, path
, kCFURLPOSIXPathStyle
, true );
939 require_action_quiet( url
, exit
, err
= memFullErr
);
941 bundle
= CFBundleCreate( NULL
, url
);
943 require_action_quiet( bundle
, exit
, err
= memFullErr
);
945 // Get a ptr to the system's "printf" function from System.framework.
947 functionName
= CFSTR( "printf" );
948 functionPtr
= CFBundleGetFunctionPointerForName( bundle
, functionName
);
949 require_action_quiet( functionPtr
, exit
, err
= memFullErr
);
951 // Success! Note: The bundle cannot be released because it would invalidate the function ptr.
953 gDebugMacOSXLogFunction
= (DebugMacOSXLogFunctionPtr
) functionPtr
;
965 //===========================================================================================================================
966 // DebugMacOSXLogPrint
967 //===========================================================================================================================
969 static void DebugMacOSXLogPrint( char *inData
, size_t inSize
)
971 if( gDebugMacOSXLogFunction
)
973 gDebugMacOSXLogFunction( "%.*s", (int) inSize
, inData
);
978 #if( TARGET_OS_WIN32 )
979 //===========================================================================================================================
980 // DebugWindowsDebuggerPrint
981 //===========================================================================================================================
983 void DebugWindowsDebuggerPrint( char *inData
, size_t inSize
)
991 // Copy locally and null terminate the string. This also converts from char to TCHAR in case we are
992 // building with UNICODE enabled since the input is always char. Also convert \r to \n in the process.
995 if( inSize
>= sizeof_array( buffer
) )
997 inSize
= sizeof_array( buffer
) - 1;
1012 // Print out the string to the debugger.
1014 OutputDebugString( buffer
);
1018 #if( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
1019 //===========================================================================================================================
1020 // DebugWindowsEventLogInit
1021 //===========================================================================================================================
1023 static OSStatus
DebugWindowsEventLogInit( const char *inName
, HMODULE inModule
)
1029 TCHAR path
[ MAX_PATH
];
1031 DWORD typesSupported
;
1036 // Use a default name if needed then convert the name to TCHARs so it works on ANSI or Unicode builds.
1038 if( !inName
|| ( *inName
== '\0' ) )
1040 inName
= "DefaultApp";
1042 DebugWinCharToTCharString( inName
, kSizeCString
, name
, sizeof( name
), NULL
);
1044 // Build the path string using the fixed registry path and app name.
1046 src
= "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\";
1047 DebugWinCharToTCharString( src
, kSizeCString
, path
, sizeof_array( path
), &size
);
1048 DebugWinCharToTCharString( inName
, kSizeCString
, path
+ size
, sizeof_array( path
) - size
, NULL
);
1050 // Add/Open the source name as a sub-key under the Application key in the EventLog registry key.
1052 err
= RegCreateKeyEx( HKEY_LOCAL_MACHINE
, path
, 0, NULL
, REG_OPTION_NON_VOLATILE
, KEY_ALL_ACCESS
, NULL
, &key
, NULL
);
1053 require_noerr_quiet( err
, exit
);
1055 // Set the path in the EventMessageFile subkey. Add 1 to the TCHAR count to include the null terminator.
1057 n
= GetModuleFileName( inModule
, path
, sizeof_array( path
) );
1058 err
= translate_errno( n
> 0, (OSStatus
) GetLastError(), kParamErr
);
1059 require_noerr_quiet( err
, exit
);
1061 n
*= sizeof( TCHAR
);
1063 err
= RegSetValueEx( key
, TEXT( "EventMessageFile" ), 0, REG_EXPAND_SZ
, (const LPBYTE
) path
, n
);
1064 require_noerr_quiet( err
, exit
);
1066 // Set the supported event types in the TypesSupported subkey.
1068 typesSupported
= EVENTLOG_SUCCESS
| EVENTLOG_ERROR_TYPE
| EVENTLOG_WARNING_TYPE
| EVENTLOG_INFORMATION_TYPE
|
1069 EVENTLOG_AUDIT_SUCCESS
| EVENTLOG_AUDIT_FAILURE
;
1070 err
= RegSetValueEx( key
, TEXT( "TypesSupported" ), 0, REG_DWORD
, (const LPBYTE
) &typesSupported
, sizeof( DWORD
) );
1071 require_noerr_quiet( err
, exit
);
1073 // Set up the event source.
1075 gDebugWindowsEventLogEventSource
= RegisterEventSource( NULL
, name
);
1076 err
= translate_errno( gDebugWindowsEventLogEventSource
, (OSStatus
) GetLastError(), kParamErr
);
1077 require_noerr_quiet( err
, exit
);
1087 //===========================================================================================================================
1088 // DebugWindowsEventLogPrint
1089 //===========================================================================================================================
1091 static void DebugWindowsEventLogPrint( DebugLevel inLevel
, char *inData
, size_t inSize
)
1094 TCHAR buffer
[ 512 ];
1099 const TCHAR
* array
[ 1 ];
1101 // Map the debug level to a Windows EventLog type.
1103 if( inLevel
<= kDebugLevelNotice
)
1105 type
= EVENTLOG_INFORMATION_TYPE
;
1107 else if( inLevel
<= kDebugLevelWarning
)
1109 type
= EVENTLOG_WARNING_TYPE
;
1113 type
= EVENTLOG_ERROR_TYPE
;
1116 // Copy locally and null terminate the string. This also converts from char to TCHAR in case we are
1117 // building with UNICODE enabled since the input is always char. Also convert \r to \n in the process.
1120 if( inSize
>= sizeof_array( buffer
) )
1122 inSize
= sizeof_array( buffer
) - 1;
1137 // Add the the string to the event log.
1139 array
[ 0 ] = buffer
;
1140 if( gDebugWindowsEventLogEventSource
)
1142 ReportEvent( gDebugWindowsEventLogEventSource
, type
, 0, 0x20000001L
, NULL
, 1, 0, array
, NULL
);
1145 #endif // TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE
1147 #if( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
1148 //===========================================================================================================================
1149 // DebugAssertOutputHandler
1150 //===========================================================================================================================
1153 DebugAssertOutputHandler(
1154 OSType inComponentSignature
,
1156 const char * inAssertString
,
1157 const char * inExceptionString
,
1158 const char * inErrorString
,
1159 const char * inFileName
,
1162 ConstStr255Param inOutputMsg
)
1164 DEBUG_UNUSED( inComponentSignature
);
1165 DEBUG_UNUSED( inOptions
);
1166 DEBUG_UNUSED( inExceptionString
);
1167 DEBUG_UNUSED( inValue
);
1168 DEBUG_UNUSED( inOutputMsg
);
1170 DebugPrintAssert( 0, inAssertString
, inErrorString
, inFileName
, (int_least32_t) inLineNumber
, "" );
1176 #pragma mark == Utilities ==
1179 //===========================================================================================================================
1182 // Stolen from mDNS.c's mDNS_snprintf/mDNS_vsnprintf with the following changes:
1184 // Changed names to avoid name collisions with the mDNS versions.
1185 // Changed types to standard C types since mDNSEmbeddedAPI.h may not be available.
1186 // Conditionalized mDNS stuff so it can be used with or with mDNSEmbeddedAPI.h.
1187 // Added 64-bit support for %d (%lld), %i (%lli), %u (%llu), %o (%llo), %x (%llx), and %b (%llb).
1188 // Added %@ - Cocoa/CoreFoundation object. Param is the object. Strings are used directly. Others use CFCopyDescription.
1189 // Added %.8a - FIbre Channel address. Arg=ptr to address.
1190 // Added %##a - IPv4 (if AF_INET defined) or IPv6 (if AF_INET6 defined) sockaddr. Arg=ptr to sockaddr.
1191 // Added %b - Binary representation of integer (e.g. 01101011). Modifiers and arg=the same as %d, %x, etc.
1192 // Added %C - Mac-style FourCharCode (e.g. 'APPL'). Arg=32-bit value to print as a Mac-style FourCharCode.
1193 // Added %H - Hex Dump (e.g. "\x6b\xa7" -> "6B A7"). 1st arg=ptr, 2nd arg=size, 3rd arg=max size.
1194 // Added %#H - Hex Dump & ASCII (e.g. "\x41\x62" -> "6B A7 'Ab'"). 1st arg=ptr, 2nd arg=size, 3rd arg=max size.
1195 // Added %m - Error Message (e.g. 0 -> "kNoErr"). Modifiers and error code args are the same as %d, %x, etc.
1196 // Added %S - UTF-16 string. Host order if no BOM. Precision is UTF-16 char count. BOM counts in any precision. Arg=ptr.
1197 // Added %#S - Big Endian UTF-16 string (unless BOM overrides). Otherwise the same as %S.
1198 // Added %##S - Little Endian UTF-16 string (unless BOM overrides). Otherwise the same as %S.
1199 // Added %U - Universally Unique Identifier (UUID) (e.g. 6ba7b810-9dad-11d1-80b4-00c04fd430c8). Arg=ptr to 16-byte UUID.
1200 //===========================================================================================================================
1202 DEBUG_EXPORT
size_t DebugSNPrintF(char *sbuffer
, size_t buflen
, const char *fmt
, ...)
1208 length
= DebugSNPrintFVAList(sbuffer
, buflen
, fmt
, ptr
);
1214 //===========================================================================================================================
1215 // DebugSNPrintFVAList - va_list version of DebugSNPrintF. See DebugSNPrintF for more info.
1216 //===========================================================================================================================
1218 DEBUG_EXPORT
size_t DebugSNPrintFVAList(char *sbuffer
, size_t buflen
, const char *fmt
, va_list arg
)
1220 static const struct DebugSNPrintF_format
1222 unsigned leftJustify
: 1;
1223 unsigned forceSign
: 1;
1224 unsigned zeroPad
: 1;
1225 unsigned havePrecision
: 1;
1229 char sign
; // +, - or space
1230 unsigned int fieldWidth
;
1231 unsigned int precision
;
1232 } DebugSNPrintF_format_default
= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1234 size_t nwritten
= 0;
1236 if (buflen
== 0) return(0);
1237 buflen
--; // Pre-reserve one space in the buffer for the terminating nul
1238 if (buflen
== 0) goto exit
;
1240 for (c
= *fmt
; c
!= 0; c
= *++fmt
)
1244 *sbuffer
++ = (char)c
;
1245 if (++nwritten
>= buflen
) goto exit
;
1250 // The mDNS Vsprintf Argument Conversion Buffer is used as a temporary holding area for
1251 // generating decimal numbers, hexdecimal numbers, IP addresses, domain name strings, etc.
1252 // The size needs to be enough for a 256-byte domain name plus some error text.
1253 #define mDNS_VACB_Size 300
1254 char mDNS_VACB
[mDNS_VACB_Size
];
1255 #define mDNS_VACB_Lim (&mDNS_VACB[mDNS_VACB_Size])
1256 #define mDNS_VACB_Remain(s) ((size_t)(mDNS_VACB_Lim - s))
1257 char *s
= mDNS_VACB_Lim
;
1258 const char *digits
= "0123456789ABCDEF";
1259 struct DebugSNPrintF_format F
= DebugSNPrintF_format_default
;
1261 for(;;) // decode flags
1264 if (c
== '-') F
.leftJustify
= 1;
1265 else if (c
== '+') F
.forceSign
= 1;
1266 else if (c
== ' ') F
.sign
= ' ';
1267 else if (c
== '#') F
.altForm
++;
1268 else if (c
== '0') F
.zeroPad
= 1;
1272 if (c
== '*') // decode field width
1274 int f
= va_arg(arg
, int);
1275 if (f
< 0) { f
= -f
; F
.leftJustify
= 1; }
1276 F
.fieldWidth
= (unsigned int)f
;
1281 for (; c
>= '0' && c
<= '9'; c
= *++fmt
)
1282 F
.fieldWidth
= (10 * F
.fieldWidth
) + (c
- '0');
1285 if (c
== '.') // decode precision
1287 if ((c
= *++fmt
) == '*')
1288 { F
.precision
= va_arg(arg
, unsigned int); c
= *++fmt
; }
1289 else for (; c
>= '0' && c
<= '9'; c
= *++fmt
)
1290 F
.precision
= (10 * F
.precision
) + (c
- '0');
1291 F
.havePrecision
= 1;
1294 if (F
.leftJustify
) F
.zeroPad
= 0;
1297 switch (c
) // perform appropriate conversion
1299 #if TYPE_LONGLONG_NATIVE
1300 unsigned_long_long_compat n
;
1301 unsigned_long_long_compat base
;
1306 case 'h' : F
.hSize
= 1; c
= *++fmt
; goto conv
;
1307 case 'l' : // fall through
1308 case 'L' : F
.lSize
++; c
= *++fmt
; goto conv
;
1310 case 'i' : base
= 10;
1312 case 'u' : base
= 10;
1314 case 'o' : base
= 8;
1316 case 'b' : base
= 2;
1318 case 'p' : n
= va_arg(arg
, uintptr_t);
1319 F
.havePrecision
= 1;
1320 F
.precision
= (sizeof(uintptr_t) == 4) ? 8 : 16;
1325 case 'x' : digits
= "0123456789abcdef";
1326 case 'X' : base
= 16;
1329 #if TYPE_LONGLONG_NATIVE
1330 if (F
.lSize
== 1) n
= (unsigned_long_long_compat
)va_arg(arg
, long);
1331 else if (F
.lSize
== 2) n
= (unsigned_long_long_compat
)va_arg(arg
, long_long_compat
);
1332 else n
= (unsigned_long_long_compat
)va_arg(arg
, int);
1334 if (F
.lSize
== 1) n
= (unsigned long)va_arg(arg
, long);
1335 else if (F
.lSize
== 2) goto exit
;
1336 else n
= (unsigned long)va_arg(arg
, int);
1338 if (F
.hSize
) n
= (short) n
;
1339 #if TYPE_LONGLONG_NATIVE
1340 if ((long_long_compat
) n
< 0) { n
= (unsigned_long_long_compat
)-(long_long_compat
)n
; F
.sign
= '-'; }
1342 if ((long) n
< 0) { n
= (unsigned long)-(long)n
; F
.sign
= '-'; }
1344 else if (F
.forceSign
) F
.sign
= '+';
1347 notSigned
: if (F
.lSize
== 1) n
= va_arg(arg
, unsigned long);
1348 else if (F
.lSize
== 2)
1350 #if TYPE_LONGLONG_NATIVE
1351 n
= va_arg(arg
, unsigned_long_long_compat
);
1356 else n
= va_arg(arg
, unsigned int);
1357 if (F
.hSize
) n
= (unsigned short) n
;
1361 number
: if (!F
.havePrecision
)
1365 F
.precision
= F
.fieldWidth
;
1366 if (F
.altForm
) F
.precision
-= 2;
1367 if (F
.sign
) --F
.precision
;
1369 if (F
.precision
< 1) F
.precision
= 1;
1371 if (F
.precision
> mDNS_VACB_Size
- 1)
1372 F
.precision
= mDNS_VACB_Size
- 1;
1373 for (i
= 0; n
; n
/= base
, i
++) *--s
= (char)(digits
[n
% base
]);
1374 for (; i
< F
.precision
; i
++) *--s
= '0';
1375 if (F
.altForm
) { *--s
= (char)c
; *--s
= '0'; i
+= 2; }
1376 if (F
.sign
) { *--s
= F
.sign
; i
++; }
1380 unsigned char *a
= va_arg(arg
, unsigned char *);
1383 if (!a
) { static char emsg
[] = "<<NULL>>"; s
= emsg
; i
= sizeof(emsg
)-1; }
1386 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1389 #if(defined(MDNS_DEBUGMSGS))
1390 mDNSAddr
*ip
= (mDNSAddr
*)a
;
1393 case mDNSAddrType_IPv4
: F
.precision
= 4; a
= (unsigned char *)&ip
->ip
.v4
; break;
1394 case mDNSAddrType_IPv6
: F
.precision
= 16; a
= (unsigned char *)&ip
->ip
.v6
; break;
1395 default: F
.precision
= 0; break;
1398 F
.precision
= 0; // mDNSEmbeddedAPI.h not included so no mDNSAddr support
1401 else if (F
.altForm
== 2)
1404 const struct sockaddr
*sa
;
1405 unsigned char *port
;
1406 sa
= (const struct sockaddr
*)a
;
1407 switch (sa
->sa_family
)
1409 case AF_INET
: F
.precision
= 4; a
= (unsigned char*)&((const struct sockaddr_in
*)a
)->sin_addr
;
1410 port
= (unsigned char*)&((const struct sockaddr_in
*)sa
)->sin_port
;
1411 DebugSNPrintF(post
, sizeof(post
), ":%d", (port
[0] << 8) | port
[1]); break;
1413 case AF_INET6
: F
.precision
= 16; a
= (unsigned char*)&((const struct sockaddr_in6
*)a
)->sin6_addr
;
1414 pre
[0] = '['; pre
[1] = '\0';
1415 port
= (unsigned char*)&((const struct sockaddr_in6
*)sa
)->sin6_port
;
1416 DebugSNPrintF(post
, sizeof(post
), "%%%d]:%d",
1417 (int)((const struct sockaddr_in6
*)sa
)->sin6_scope_id
,
1418 (port
[0] << 8) | port
[1]); break;
1420 default: F
.precision
= 0; break;
1423 F
.precision
= 0; // socket interfaces not included so no sockaddr support
1426 switch (F
.precision
)
1428 case 4: i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "%d.%d.%d.%d%s",
1429 a
[0], a
[1], a
[2], a
[3], post
); break;
1430 case 6: i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "%02X:%02X:%02X:%02X:%02X:%02X",
1431 a
[0], a
[1], a
[2], a
[3], a
[4], a
[5]); break;
1432 case 8: i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
1433 a
[0], a
[1], a
[2], a
[3], a
[4], a
[5], a
[6], a
[7]); break;
1434 case 16: i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
),
1435 "%s%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X%s",
1436 pre
, a
[0], a
[1], a
[2], a
[3], a
[4], a
[5], a
[6], a
[7], a
[8],
1437 a
[9], a
[10], a
[11], a
[12], a
[13], a
[14], a
[15], post
); break;
1438 default: i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "%s", "<< ERROR: Must specify address size "
1439 "(i.e. %.4a=IPv4, %.6a=Ethernet, %.8a=Fibre Channel %.16a=IPv6) >>"); break;
1446 unsigned char *a
= va_arg(arg
, unsigned char *);
1447 if (!a
) { static char emsg
[] = "<<NULL>>"; s
= emsg
; i
= sizeof(emsg
)-1; }
1450 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1451 i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
1452 *((uint32_t*) &a
[0]), *((uint16_t*) &a
[4]), *((uint16_t*) &a
[6]),
1453 a
[8], a
[9], a
[10], a
[11], a
[12], a
[13], a
[14], a
[15]); break;
1458 case 'c' : *--s
= (char)va_arg(arg
, int); i
= 1; break;
1460 case 'C' : if (F
.lSize
) n
= va_arg(arg
, unsigned long);
1461 else n
= va_arg(arg
, unsigned int);
1462 if (F
.hSize
) n
= (unsigned short) n
;
1463 c
= (int)( n
& 0xFF); *--s
= (char)(DebugIsPrint(c
) ? c
: '^');
1464 c
= (int)((n
>> 8) & 0xFF); *--s
= (char)(DebugIsPrint(c
) ? c
: '^');
1465 c
= (int)((n
>> 16) & 0xFF); *--s
= (char)(DebugIsPrint(c
) ? c
: '^');
1466 c
= (int)((n
>> 24) & 0xFF); *--s
= (char)(DebugIsPrint(c
) ? c
: '^');
1470 case 's' : s
= va_arg(arg
, char *);
1471 if (!s
) { static char emsg
[] = "<<NULL>>"; s
= emsg
; i
= sizeof(emsg
)-1; }
1472 else switch (F
.altForm
)
1475 if (F
.havePrecision
) // C string
1477 while((i
< F
.precision
) && s
[i
]) i
++;
1478 // Make sure we don't truncate in the middle of a UTF-8 character.
1479 // If the last character is part of a multi-byte UTF-8 character, back up to the start of it.
1481 while((i
> 0) && ((c
= s
[i
-1]) & 0x80)) { j
++; i
--; if((c
& 0xC0) != 0x80) break; }
1482 // If the actual count of UTF-8 characters matches the encoded UTF-8 count, add it back.
1483 if((j
> 1) && (j
<= 6))
1485 int test
= (0xFF << (8-j
)) & 0xFF;
1486 int mask
= test
| (1 << ((8-j
)-1));
1487 if((c
& mask
) == test
) i
+= j
;
1493 case 1: i
= (unsigned char) *s
++; break; // Pascal string
1494 case 2: { // DNS label-sequence name
1495 unsigned char *a
= (unsigned char *)s
;
1496 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1497 if (*a
== 0) *s
++ = '.'; // Special case for root DNS name
1500 if (*a
> 63) { s
+= DebugSNPrintF(s
, mDNS_VACB_Remain(s
), "<<INVALID LABEL LENGTH %u>>", *a
); break; }
1501 if (s
+ *a
>= &mDNS_VACB
[254]) { s
+= DebugSNPrintF(s
, mDNS_VACB_Remain(s
), "<<NAME TOO LONG>>"); break; }
1502 s
+= DebugSNPrintF(s
, mDNS_VACB_Remain(s
), "%#s.", a
);
1505 i
= (size_t)(s
- mDNS_VACB
);
1506 s
= mDNS_VACB
; // Reset s back to the start of the buffer
1510 if (F
.havePrecision
&& i
> F
.precision
) // Make sure we don't truncate in the middle of a UTF-8 character
1511 { i
= F
.precision
; while (i
>0 && (s
[i
] & 0xC0) == 0x80) i
--; }
1514 case 'S': { // UTF-16 string
1515 unsigned char *a
= va_arg(arg
, unsigned char *);
1516 uint16_t *u
= (uint16_t*)a
;
1517 if (!u
) { static char emsg
[] = "<<NULL>>"; s
= emsg
; i
= sizeof(emsg
)-1; }
1518 if ((!F
.havePrecision
|| F
.precision
))
1520 if ((a
[0] == 0xFE) && (a
[1] == 0xFF)) { F
.altForm
= 1; u
+= 1; a
+= 2; F
.precision
--; } // Big Endian
1521 else if ((a
[0] == 0xFF) && (a
[1] == 0xFE)) { F
.altForm
= 2; u
+= 1; a
+= 2; F
.precision
--; } // Little Endian
1523 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1526 case 0: while ((!F
.havePrecision
|| (i
< F
.precision
)) && u
[i
] && mDNS_VACB_Remain(s
)) // Host Endian
1527 { c
= u
[i
]; *s
++ = (char)(DebugIsPrint(c
) ? c
: '^'); i
++; }
1529 case 1: while ((!F
.havePrecision
|| (i
< F
.precision
)) && u
[i
] && mDNS_VACB_Remain(s
)) // Big Endian
1530 { c
= ((a
[0] << 8) | a
[1]) & 0xFF; *s
++ = (char)(DebugIsPrint(c
) ? c
: '^'); i
++; a
+= 2; }
1532 case 2: while ((!F
.havePrecision
|| (i
< F
.precision
)) && u
[i
] && mDNS_VACB_Remain(s
)) // Little Endian
1533 { c
= ((a
[1] << 8) | a
[0]) & 0xFF; *s
++ = (char)(DebugIsPrint(c
) ? c
: '^'); i
++; a
+= 2; }
1537 s
= mDNS_VACB
; // Reset s back to the start of the buffer
1541 case '@': { // Cocoa/CoreFoundation object
1544 cfObj
= (CFTypeRef
) va_arg(arg
, void *);
1545 cfStr
= (CFGetTypeID(cfObj
) == CFStringGetTypeID()) ? (CFStringRef
)CFRetain(cfObj
) : CFCopyDescription(cfObj
);
1546 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1551 range
= CFRangeMake(0, CFStringGetLength(cfStr
));
1553 CFStringGetBytes(cfStr
, range
, kCFStringEncodingUTF8
, '^', false, (UInt8
*)mDNS_VACB
, (CFIndex
)sizeof(mDNS_VACB
), &m
);
1559 i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "%s", "ERROR: <invalid CF object>" );
1562 if (F
.havePrecision
&& i
> F
.precision
) // Make sure we don't truncate in the middle of a UTF-8 character
1563 { i
= F
.precision
; while (i
>0 && (s
[i
] & 0xC0) == 0x80) i
--; }
1567 case 'm' : { // Error Message
1569 if (F
.lSize
) err
= va_arg(arg
, long);
1570 else err
= va_arg(arg
, int);
1571 if (F
.hSize
) err
= (short)err
;
1572 DebugGetErrorString(err
, mDNS_VACB
, sizeof(mDNS_VACB
));
1573 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1574 for(i
=0;s
[i
];i
++) {}
1578 case 'H' : { // Hex Dump
1579 void *a
= va_arg(arg
, void *);
1580 size_t size
= (size_t)va_arg(arg
, int);
1581 size_t max
= (size_t)va_arg(arg
, int);
1583 kDebugFlagsNoAddress
| kDebugFlagsNoOffset
| kDebugFlagsNoNewLine
|
1584 kDebugFlags8BitSeparator
| kDebugFlagsNo32BitSeparator
|
1585 kDebugFlagsNo16ByteHexPad
| kDebugFlagsNoByteCount
;
1586 if (F
.altForm
== 0) flags
|= kDebugFlagsNoASCII
;
1587 size
= (max
< size
) ? max
: size
;
1588 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1589 i
= DebugHexDump(kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, a
, a
, size
, flags
, mDNS_VACB
, sizeof(mDNS_VACB
));
1593 case 'v' : { // Version
1595 version
= va_arg(arg
, unsigned int);
1596 DebugNumVersionToString(version
, mDNS_VACB
);
1597 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1598 for(i
=0;s
[i
];i
++) {}
1602 case 'n' : s
= va_arg(arg
, char *);
1603 if (F
.hSize
) * (short *) s
= (short)nwritten
;
1604 else if (F
.lSize
) * (long *) s
= (long)nwritten
;
1605 else * (int *) s
= (int)nwritten
;
1608 default: s
= mDNS_VACB
;
1609 i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "<<UNKNOWN FORMAT CONVERSION CODE %%%c>>", c
);
1611 case '%' : *sbuffer
++ = (char)c
;
1612 if (++nwritten
>= buflen
) goto exit
;
1616 if (i
< F
.fieldWidth
&& !F
.leftJustify
) // Pad on the left
1619 if (++nwritten
>= buflen
) goto exit
;
1620 } while (i
< --F
.fieldWidth
);
1622 if (i
> buflen
- nwritten
) // Make sure we don't truncate in the middle of a UTF-8 character
1623 { i
= buflen
- nwritten
; while (i
>0 && (s
[i
] & 0xC0) == 0x80) i
--; }
1624 for (j
=0; j
<i
; j
++) *sbuffer
++ = *s
++; // Write the converted result
1626 if (nwritten
>= buflen
) goto exit
;
1628 for (; i
< F
.fieldWidth
; i
++) // Pad on the right
1631 if (++nwritten
>= buflen
) goto exit
;
1640 //===========================================================================================================================
1641 // DebugGetErrorString
1642 //===========================================================================================================================
1644 DEBUG_EXPORT
const char * DebugGetErrorString( int_least32_t inErrorCode
, char *inBuffer
, size_t inBufferSize
)
1649 #if( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
1653 switch( inErrorCode
)
1655 #define CaseErrorString( X, STR ) case X: s = STR; break
1656 #define CaseErrorStringify( X ) case X: s = # X; break
1657 #define CaseErrorStringifyHardCode( VALUE, X ) case VALUE: s = # X; break
1661 CaseErrorString( 0, "no error" );
1662 CaseErrorString( 1, "in-progress/waiting" );
1663 CaseErrorString( -1, "catch-all unknown error" );
1667 CaseErrorStringifyHardCode( -2, kACPBadRequestErr
);
1668 CaseErrorStringifyHardCode( -3, kACPNoMemoryErr
);
1669 CaseErrorStringifyHardCode( -4, kACPBadParamErr
);
1670 CaseErrorStringifyHardCode( -5, kACPNotFoundErr
);
1671 CaseErrorStringifyHardCode( -6, kACPBadChecksumErr
);
1672 CaseErrorStringifyHardCode( -7, kACPCommandNotHandledErr
);
1673 CaseErrorStringifyHardCode( -8, kACPNetworkErr
);
1674 CaseErrorStringifyHardCode( -9, kACPDuplicateCommandHandlerErr
);
1675 CaseErrorStringifyHardCode( -10, kACPUnknownPropertyErr
);
1676 CaseErrorStringifyHardCode( -11, kACPImmutablePropertyErr
);
1677 CaseErrorStringifyHardCode( -12, kACPBadPropertyValueErr
);
1678 CaseErrorStringifyHardCode( -13, kACPNoResourcesErr
);
1679 CaseErrorStringifyHardCode( -14, kACPBadOptionErr
);
1680 CaseErrorStringifyHardCode( -15, kACPBadSizeErr
);
1681 CaseErrorStringifyHardCode( -16, kACPBadPasswordErr
);
1682 CaseErrorStringifyHardCode( -17, kACPNotInitializedErr
);
1683 CaseErrorStringifyHardCode( -18, kACPNonReadablePropertyErr
);
1684 CaseErrorStringifyHardCode( -19, kACPBadVersionErr
);
1685 CaseErrorStringifyHardCode( -20, kACPBadSignatureErr
);
1686 CaseErrorStringifyHardCode( -21, kACPBadIndexErr
);
1687 CaseErrorStringifyHardCode( -22, kACPUnsupportedErr
);
1688 CaseErrorStringifyHardCode( -23, kACPInUseErr
);
1689 CaseErrorStringifyHardCode( -24, kACPParamCountErr
);
1690 CaseErrorStringifyHardCode( -25, kACPIDErr
);
1691 CaseErrorStringifyHardCode( -26, kACPFormatErr
);
1692 CaseErrorStringifyHardCode( -27, kACPUnknownUserErr
);
1693 CaseErrorStringifyHardCode( -28, kACPAccessDeniedErr
);
1694 CaseErrorStringifyHardCode( -29, kACPIncorrectFWErr
);
1696 // Common Services Errors
1698 CaseErrorStringify( kUnknownErr
);
1699 CaseErrorStringify( kOptionErr
);
1700 CaseErrorStringify( kSelectorErr
);
1701 CaseErrorStringify( kExecutionStateErr
);
1702 CaseErrorStringify( kPathErr
);
1703 CaseErrorStringify( kParamErr
);
1704 CaseErrorStringify( kParamCountErr
);
1705 CaseErrorStringify( kCommandErr
);
1706 CaseErrorStringify( kIDErr
);
1707 CaseErrorStringify( kStateErr
);
1708 CaseErrorStringify( kRangeErr
);
1709 CaseErrorStringify( kRequestErr
);
1710 CaseErrorStringify( kResponseErr
);
1711 CaseErrorStringify( kChecksumErr
);
1712 CaseErrorStringify( kNotHandledErr
);
1713 CaseErrorStringify( kVersionErr
);
1714 CaseErrorStringify( kSignatureErr
);
1715 CaseErrorStringify( kFormatErr
);
1716 CaseErrorStringify( kNotInitializedErr
);
1717 CaseErrorStringify( kAlreadyInitializedErr
);
1718 CaseErrorStringify( kNotInUseErr
);
1719 CaseErrorStringify( kInUseErr
);
1720 CaseErrorStringify( kTimeoutErr
);
1721 CaseErrorStringify( kCanceledErr
);
1722 CaseErrorStringify( kAlreadyCanceledErr
);
1723 CaseErrorStringify( kCannotCancelErr
);
1724 CaseErrorStringify( kDeletedErr
);
1725 CaseErrorStringify( kNotFoundErr
);
1726 CaseErrorStringify( kNoMemoryErr
);
1727 CaseErrorStringify( kNoResourcesErr
);
1728 CaseErrorStringify( kDuplicateErr
);
1729 CaseErrorStringify( kImmutableErr
);
1730 CaseErrorStringify( kUnsupportedDataErr
);
1731 CaseErrorStringify( kIntegrityErr
);
1732 CaseErrorStringify( kIncompatibleErr
);
1733 CaseErrorStringify( kUnsupportedErr
);
1734 CaseErrorStringify( kUnexpectedErr
);
1735 CaseErrorStringify( kValueErr
);
1736 CaseErrorStringify( kNotReadableErr
);
1737 CaseErrorStringify( kNotWritableErr
);
1738 CaseErrorStringify( kBadReferenceErr
);
1739 CaseErrorStringify( kFlagErr
);
1740 CaseErrorStringify( kMalformedErr
);
1741 CaseErrorStringify( kSizeErr
);
1742 CaseErrorStringify( kNameErr
);
1743 CaseErrorStringify( kNotReadyErr
);
1744 CaseErrorStringify( kReadErr
);
1745 CaseErrorStringify( kWriteErr
);
1746 CaseErrorStringify( kMismatchErr
);
1747 CaseErrorStringify( kDateErr
);
1748 CaseErrorStringify( kUnderrunErr
);
1749 CaseErrorStringify( kOverrunErr
);
1750 CaseErrorStringify( kEndingErr
);
1751 CaseErrorStringify( kConnectionErr
);
1752 CaseErrorStringify( kAuthenticationErr
);
1753 CaseErrorStringify( kOpenErr
);
1754 CaseErrorStringify( kTypeErr
);
1755 CaseErrorStringify( kSkipErr
);
1756 CaseErrorStringify( kNoAckErr
);
1757 CaseErrorStringify( kCollisionErr
);
1758 CaseErrorStringify( kBackoffErr
);
1759 CaseErrorStringify( kNoAddressAckErr
);
1760 CaseErrorStringify( kBusyErr
);
1761 CaseErrorStringify( kNoSpaceErr
);
1763 // mDNS/DNS-SD Errors
1765 CaseErrorStringifyHardCode( -65537, mStatus_UnknownErr
);
1766 CaseErrorStringifyHardCode( -65538, mStatus_NoSuchNameErr
);
1767 CaseErrorStringifyHardCode( -65539, mStatus_NoMemoryErr
);
1768 CaseErrorStringifyHardCode( -65540, mStatus_BadParamErr
);
1769 CaseErrorStringifyHardCode( -65541, mStatus_BadReferenceErr
);
1770 CaseErrorStringifyHardCode( -65542, mStatus_BadStateErr
);
1771 CaseErrorStringifyHardCode( -65543, mStatus_BadFlagsErr
);
1772 CaseErrorStringifyHardCode( -65544, mStatus_UnsupportedErr
);
1773 CaseErrorStringifyHardCode( -65545, mStatus_NotInitializedErr
);
1774 CaseErrorStringifyHardCode( -65546, mStatus_NoCache
);
1775 CaseErrorStringifyHardCode( -65547, mStatus_AlreadyRegistered
);
1776 CaseErrorStringifyHardCode( -65548, mStatus_NameConflict
);
1777 CaseErrorStringifyHardCode( -65549, mStatus_Invalid
);
1778 CaseErrorStringifyHardCode( -65550, mStatus_GrowCache
);
1779 CaseErrorStringifyHardCode( -65551, mStatus_BadInterfaceErr
);
1780 CaseErrorStringifyHardCode( -65552, mStatus_Incompatible
);
1781 CaseErrorStringifyHardCode( -65791, mStatus_ConfigChanged
);
1782 CaseErrorStringifyHardCode( -65792, mStatus_MemFree
);
1786 CaseErrorStringifyHardCode( -400000, kRSPUnknownErr
);
1787 CaseErrorStringifyHardCode( -400050, kRSPParamErr
);
1788 CaseErrorStringifyHardCode( -400108, kRSPNoMemoryErr
);
1789 CaseErrorStringifyHardCode( -405246, kRSPRangeErr
);
1790 CaseErrorStringifyHardCode( -409057, kRSPSizeErr
);
1791 CaseErrorStringifyHardCode( -400200, kRSPHardwareErr
);
1792 CaseErrorStringifyHardCode( -401712, kRSPTimeoutErr
);
1793 CaseErrorStringifyHardCode( -402053, kRSPUnsupportedErr
);
1794 CaseErrorStringifyHardCode( -402419, kRSPIDErr
);
1795 CaseErrorStringifyHardCode( -403165, kRSPFlagErr
);
1796 CaseErrorString( -200000, "kRSPControllerStatusBase - 0x50" );
1797 CaseErrorString( -200080, "kRSPCommandSucceededErr - 0x50" );
1798 CaseErrorString( -200001, "kRSPCommandFailedErr - 0x01" );
1799 CaseErrorString( -200051, "kRSPChecksumErr - 0x33" );
1800 CaseErrorString( -200132, "kRSPCommandTimeoutErr - 0x84" );
1801 CaseErrorString( -200034, "kRSPPasswordRequiredErr - 0x22 OBSOLETE" );
1802 CaseErrorString( -200128, "kRSPCanceledErr - 0x02 Async" );
1806 CaseErrorStringifyHardCode( -100043, kXMLNotFoundErr
);
1807 CaseErrorStringifyHardCode( -100050, kXMLParamErr
);
1808 CaseErrorStringifyHardCode( -100108, kXMLNoMemoryErr
);
1809 CaseErrorStringifyHardCode( -100206, kXMLFormatErr
);
1810 CaseErrorStringifyHardCode( -100586, kXMLNoRootElementErr
);
1811 CaseErrorStringifyHardCode( -101703, kXMLWrongDataTypeErr
);
1812 CaseErrorStringifyHardCode( -101726, kXMLKeyErr
);
1813 CaseErrorStringifyHardCode( -102053, kXMLUnsupportedErr
);
1814 CaseErrorStringifyHardCode( -102063, kXMLMissingElementErr
);
1815 CaseErrorStringifyHardCode( -103026, kXMLParseErr
);
1816 CaseErrorStringifyHardCode( -103159, kXMLBadDataErr
);
1817 CaseErrorStringifyHardCode( -103170, kXMLBadNameErr
);
1818 CaseErrorStringifyHardCode( -105246, kXMLRangeErr
);
1819 CaseErrorStringifyHardCode( -105251, kXMLUnknownElementErr
);
1820 CaseErrorStringifyHardCode( -108739, kXMLMalformedInputErr
);
1821 CaseErrorStringifyHardCode( -109057, kXMLBadSizeErr
);
1822 CaseErrorStringifyHardCode( -101730, kXMLMissingChildElementErr
);
1823 CaseErrorStringifyHardCode( -102107, kXMLMissingParentElementErr
);
1824 CaseErrorStringifyHardCode( -130587, kXMLNonRootElementErr
);
1825 CaseErrorStringifyHardCode( -102015, kXMLDateErr
);
1831 CaseErrorStringifyHardCode( 0x00002000, MACH_MSG_IPC_SPACE
);
1832 CaseErrorStringifyHardCode( 0x00001000, MACH_MSG_VM_SPACE
);
1833 CaseErrorStringifyHardCode( 0x00000800, MACH_MSG_IPC_KERNEL
);
1834 CaseErrorStringifyHardCode( 0x00000400, MACH_MSG_VM_KERNEL
);
1835 CaseErrorStringifyHardCode( 0x10000001, MACH_SEND_IN_PROGRESS
);
1836 CaseErrorStringifyHardCode( 0x10000002, MACH_SEND_INVALID_DATA
);
1837 CaseErrorStringifyHardCode( 0x10000003, MACH_SEND_INVALID_DEST
);
1838 CaseErrorStringifyHardCode( 0x10000004, MACH_SEND_TIMED_OUT
);
1839 CaseErrorStringifyHardCode( 0x10000007, MACH_SEND_INTERRUPTED
);
1840 CaseErrorStringifyHardCode( 0x10000008, MACH_SEND_MSG_TOO_SMALL
);
1841 CaseErrorStringifyHardCode( 0x10000009, MACH_SEND_INVALID_REPLY
);
1842 CaseErrorStringifyHardCode( 0x1000000A, MACH_SEND_INVALID_RIGHT
);
1843 CaseErrorStringifyHardCode( 0x1000000B, MACH_SEND_INVALID_NOTIFY
);
1844 CaseErrorStringifyHardCode( 0x1000000C, MACH_SEND_INVALID_MEMORY
);
1845 CaseErrorStringifyHardCode( 0x1000000D, MACH_SEND_NO_BUFFER
);
1846 CaseErrorStringifyHardCode( 0x1000000E, MACH_SEND_TOO_LARGE
);
1847 CaseErrorStringifyHardCode( 0x1000000F, MACH_SEND_INVALID_TYPE
);
1848 CaseErrorStringifyHardCode( 0x10000010, MACH_SEND_INVALID_HEADER
);
1849 CaseErrorStringifyHardCode( 0x10000011, MACH_SEND_INVALID_TRAILER
);
1850 CaseErrorStringifyHardCode( 0x10000015, MACH_SEND_INVALID_RT_OOL_SIZE
);
1851 CaseErrorStringifyHardCode( 0x10004001, MACH_RCV_IN_PROGRESS
);
1852 CaseErrorStringifyHardCode( 0x10004002, MACH_RCV_INVALID_NAME
);
1853 CaseErrorStringifyHardCode( 0x10004003, MACH_RCV_TIMED_OUT
);
1854 CaseErrorStringifyHardCode( 0x10004004, MACH_RCV_TOO_LARGE
);
1855 CaseErrorStringifyHardCode( 0x10004005, MACH_RCV_INTERRUPTED
);
1856 CaseErrorStringifyHardCode( 0x10004006, MACH_RCV_PORT_CHANGED
);
1857 CaseErrorStringifyHardCode( 0x10004007, MACH_RCV_INVALID_NOTIFY
);
1858 CaseErrorStringifyHardCode( 0x10004008, MACH_RCV_INVALID_DATA
);
1859 CaseErrorStringifyHardCode( 0x10004009, MACH_RCV_PORT_DIED
);
1860 CaseErrorStringifyHardCode( 0x1000400A, MACH_RCV_IN_SET
);
1861 CaseErrorStringifyHardCode( 0x1000400B, MACH_RCV_HEADER_ERROR
);
1862 CaseErrorStringifyHardCode( 0x1000400C, MACH_RCV_BODY_ERROR
);
1863 CaseErrorStringifyHardCode( 0x1000400D, MACH_RCV_INVALID_TYPE
);
1864 CaseErrorStringifyHardCode( 0x1000400E, MACH_RCV_SCATTER_SMALL
);
1865 CaseErrorStringifyHardCode( 0x1000400F, MACH_RCV_INVALID_TRAILER
);
1866 CaseErrorStringifyHardCode( 0x10004011, MACH_RCV_IN_PROGRESS_TIMED
);
1868 // Mach OSReturn Errors
1870 CaseErrorStringifyHardCode( 0xDC000001, kOSReturnError
);
1871 CaseErrorStringifyHardCode( 0xDC004001, kOSMetaClassInternal
);
1872 CaseErrorStringifyHardCode( 0xDC004002, kOSMetaClassHasInstances
);
1873 CaseErrorStringifyHardCode( 0xDC004003, kOSMetaClassNoInit
);
1874 CaseErrorStringifyHardCode( 0xDC004004, kOSMetaClassNoTempData
);
1875 CaseErrorStringifyHardCode( 0xDC004005, kOSMetaClassNoDicts
);
1876 CaseErrorStringifyHardCode( 0xDC004006, kOSMetaClassNoKModSet
);
1877 CaseErrorStringifyHardCode( 0xDC004007, kOSMetaClassNoInsKModSet
);
1878 CaseErrorStringifyHardCode( 0xDC004008, kOSMetaClassNoSuper
);
1879 CaseErrorStringifyHardCode( 0xDC004009, kOSMetaClassInstNoSuper
);
1880 CaseErrorStringifyHardCode( 0xDC00400A, kOSMetaClassDuplicateClass
);
1884 CaseErrorStringifyHardCode( 0xE00002BC, kIOReturnError
);
1885 CaseErrorStringifyHardCode( 0xE00002BD, kIOReturnNoMemory
);
1886 CaseErrorStringifyHardCode( 0xE00002BE, kIOReturnNoResources
);
1887 CaseErrorStringifyHardCode( 0xE00002BF, kIOReturnIPCError
);
1888 CaseErrorStringifyHardCode( 0xE00002C0, kIOReturnNoDevice
);
1889 CaseErrorStringifyHardCode( 0xE00002C1, kIOReturnNotPrivileged
);
1890 CaseErrorStringifyHardCode( 0xE00002C2, kIOReturnBadArgument
);
1891 CaseErrorStringifyHardCode( 0xE00002C3, kIOReturnLockedRead
);
1892 CaseErrorStringifyHardCode( 0xE00002C4, kIOReturnLockedWrite
);
1893 CaseErrorStringifyHardCode( 0xE00002C5, kIOReturnExclusiveAccess
);
1894 CaseErrorStringifyHardCode( 0xE00002C6, kIOReturnBadMessageID
);
1895 CaseErrorStringifyHardCode( 0xE00002C7, kIOReturnUnsupported
);
1896 CaseErrorStringifyHardCode( 0xE00002C8, kIOReturnVMError
);
1897 CaseErrorStringifyHardCode( 0xE00002C9, kIOReturnInternalError
);
1898 CaseErrorStringifyHardCode( 0xE00002CA, kIOReturnIOError
);
1899 CaseErrorStringifyHardCode( 0xE00002CC, kIOReturnCannotLock
);
1900 CaseErrorStringifyHardCode( 0xE00002CD, kIOReturnNotOpen
);
1901 CaseErrorStringifyHardCode( 0xE00002CE, kIOReturnNotReadable
);
1902 CaseErrorStringifyHardCode( 0xE00002CF, kIOReturnNotWritable
);
1903 CaseErrorStringifyHardCode( 0xE00002D0, kIOReturnNotAligned
);
1904 CaseErrorStringifyHardCode( 0xE00002D1, kIOReturnBadMedia
);
1905 CaseErrorStringifyHardCode( 0xE00002D2, kIOReturnStillOpen
);
1906 CaseErrorStringifyHardCode( 0xE00002D3, kIOReturnRLDError
);
1907 CaseErrorStringifyHardCode( 0xE00002D4, kIOReturnDMAError
);
1908 CaseErrorStringifyHardCode( 0xE00002D5, kIOReturnBusy
);
1909 CaseErrorStringifyHardCode( 0xE00002D6, kIOReturnTimeout
);
1910 CaseErrorStringifyHardCode( 0xE00002D7, kIOReturnOffline
);
1911 CaseErrorStringifyHardCode( 0xE00002D8, kIOReturnNotReady
);
1912 CaseErrorStringifyHardCode( 0xE00002D9, kIOReturnNotAttached
);
1913 CaseErrorStringifyHardCode( 0xE00002DA, kIOReturnNoChannels
);
1914 CaseErrorStringifyHardCode( 0xE00002DB, kIOReturnNoSpace
);
1915 CaseErrorStringifyHardCode( 0xE00002DD, kIOReturnPortExists
);
1916 CaseErrorStringifyHardCode( 0xE00002DE, kIOReturnCannotWire
);
1917 CaseErrorStringifyHardCode( 0xE00002DF, kIOReturnNoInterrupt
);
1918 CaseErrorStringifyHardCode( 0xE00002E0, kIOReturnNoFrames
);
1919 CaseErrorStringifyHardCode( 0xE00002E1, kIOReturnMessageTooLarge
);
1920 CaseErrorStringifyHardCode( 0xE00002E2, kIOReturnNotPermitted
);
1921 CaseErrorStringifyHardCode( 0xE00002E3, kIOReturnNoPower
);
1922 CaseErrorStringifyHardCode( 0xE00002E4, kIOReturnNoMedia
);
1923 CaseErrorStringifyHardCode( 0xE00002E5, kIOReturnUnformattedMedia
);
1924 CaseErrorStringifyHardCode( 0xE00002E6, kIOReturnUnsupportedMode
);
1925 CaseErrorStringifyHardCode( 0xE00002E7, kIOReturnUnderrun
);
1926 CaseErrorStringifyHardCode( 0xE00002E8, kIOReturnOverrun
);
1927 CaseErrorStringifyHardCode( 0xE00002E9, kIOReturnDeviceError
);
1928 CaseErrorStringifyHardCode( 0xE00002EA, kIOReturnNoCompletion
);
1929 CaseErrorStringifyHardCode( 0xE00002EB, kIOReturnAborted
);
1930 CaseErrorStringifyHardCode( 0xE00002EC, kIOReturnNoBandwidth
);
1931 CaseErrorStringifyHardCode( 0xE00002ED, kIOReturnNotResponding
);
1932 CaseErrorStringifyHardCode( 0xE00002EE, kIOReturnIsoTooOld
);
1933 CaseErrorStringifyHardCode( 0xE00002EF, kIOReturnIsoTooNew
);
1934 CaseErrorStringifyHardCode( 0xE00002F0, kIOReturnNotFound
);
1935 CaseErrorStringifyHardCode( 0xE0000001, kIOReturnInvalid
);
1937 // IOKit FireWire Errors
1939 CaseErrorStringifyHardCode( 0xE0008010, kIOFireWireResponseBase
);
1940 CaseErrorStringifyHardCode( 0xE0008020, kIOFireWireBusReset
);
1941 CaseErrorStringifyHardCode( 0xE0008001, kIOConfigNoEntry
);
1942 CaseErrorStringifyHardCode( 0xE0008002, kIOFireWirePending
);
1943 CaseErrorStringifyHardCode( 0xE0008003, kIOFireWireLastDCLToken
);
1944 CaseErrorStringifyHardCode( 0xE0008004, kIOFireWireConfigROMInvalid
);
1945 CaseErrorStringifyHardCode( 0xE0008005, kIOFireWireAlreadyRegistered
);
1946 CaseErrorStringifyHardCode( 0xE0008006, kIOFireWireMultipleTalkers
);
1947 CaseErrorStringifyHardCode( 0xE0008007, kIOFireWireChannelActive
);
1948 CaseErrorStringifyHardCode( 0xE0008008, kIOFireWireNoListenerOrTalker
);
1949 CaseErrorStringifyHardCode( 0xE0008009, kIOFireWireNoChannels
);
1950 CaseErrorStringifyHardCode( 0xE000800A, kIOFireWireChannelNotAvailable
);
1951 CaseErrorStringifyHardCode( 0xE000800B, kIOFireWireSeparateBus
);
1952 CaseErrorStringifyHardCode( 0xE000800C, kIOFireWireBadSelfIDs
);
1953 CaseErrorStringifyHardCode( 0xE000800D, kIOFireWireLowCableVoltage
);
1954 CaseErrorStringifyHardCode( 0xE000800E, kIOFireWireInsufficientPower
);
1955 CaseErrorStringifyHardCode( 0xE000800F, kIOFireWireOutOfTLabels
);
1956 CaseErrorStringifyHardCode( 0xE0008101, kIOFireWireBogusDCLProgram
);
1957 CaseErrorStringifyHardCode( 0xE0008102, kIOFireWireTalkingAndListening
);
1958 CaseErrorStringifyHardCode( 0xE0008103, kIOFireWireHardwareSlept
);
1959 CaseErrorStringifyHardCode( 0xE00087D0, kIOFWMessageServiceIsRequestingClose
);
1960 CaseErrorStringifyHardCode( 0xE00087D1, kIOFWMessagePowerStateChanged
);
1961 CaseErrorStringifyHardCode( 0xE00087D2, kIOFWMessageTopologyChanged
);
1965 CaseErrorStringifyHardCode( 0xE0004061, kIOUSBUnknownPipeErr
);
1966 CaseErrorStringifyHardCode( 0xE0004060, kIOUSBTooManyPipesErr
);
1967 CaseErrorStringifyHardCode( 0xE000405F, kIOUSBNoAsyncPortErr
);
1968 CaseErrorStringifyHardCode( 0xE000405E, kIOUSBNotEnoughPipesErr
);
1969 CaseErrorStringifyHardCode( 0xE000405D, kIOUSBNotEnoughPowerErr
);
1970 CaseErrorStringifyHardCode( 0xE0004057, kIOUSBEndpointNotFound
);
1971 CaseErrorStringifyHardCode( 0xE0004056, kIOUSBConfigNotFound
);
1972 CaseErrorStringifyHardCode( 0xE0004051, kIOUSBTransactionTimeout
);
1973 CaseErrorStringifyHardCode( 0xE0004050, kIOUSBTransactionReturned
);
1974 CaseErrorStringifyHardCode( 0xE000404F, kIOUSBPipeStalled
);
1975 CaseErrorStringifyHardCode( 0xE000404E, kIOUSBInterfaceNotFound
);
1976 CaseErrorStringifyHardCode( 0xE000404D, kIOUSBLowLatencyBufferNotPreviouslyAllocated
);
1977 CaseErrorStringifyHardCode( 0xE000404C, kIOUSBLowLatencyFrameListNotPreviouslyAllocated
);
1978 CaseErrorStringifyHardCode( 0xE000404B, kIOUSBHighSpeedSplitError
);
1979 CaseErrorStringifyHardCode( 0xE0004010, kIOUSBLinkErr
);
1980 CaseErrorStringifyHardCode( 0xE000400F, kIOUSBNotSent2Err
);
1981 CaseErrorStringifyHardCode( 0xE000400E, kIOUSBNotSent1Err
);
1982 CaseErrorStringifyHardCode( 0xE000400D, kIOUSBBufferUnderrunErr
);
1983 CaseErrorStringifyHardCode( 0xE000400C, kIOUSBBufferOverrunErr
);
1984 CaseErrorStringifyHardCode( 0xE000400B, kIOUSBReserved2Err
);
1985 CaseErrorStringifyHardCode( 0xE000400A, kIOUSBReserved1Err
);
1986 CaseErrorStringifyHardCode( 0xE0004007, kIOUSBWrongPIDErr
);
1987 CaseErrorStringifyHardCode( 0xE0004006, kIOUSBPIDCheckErr
);
1988 CaseErrorStringifyHardCode( 0xE0004003, kIOUSBDataToggleErr
);
1989 CaseErrorStringifyHardCode( 0xE0004002, kIOUSBBitstufErr
);
1990 CaseErrorStringifyHardCode( 0xE0004001, kIOUSBCRCErr
);
1998 #if( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
1999 if( inBuffer
&& ( inBufferSize
> 0 ) )
2003 n
= FormatMessageA( FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_IGNORE_INSERTS
, NULL
, (DWORD
) inErrorCode
,
2004 MAKELANGID( LANG_NEUTRAL
, SUBLANG_DEFAULT
), buffer
, sizeof( buffer
), NULL
);
2007 // Remove any trailing CR's or LF's since some messages have them.
2009 while( ( n
> 0 ) && isspace( ( (unsigned char *) buffer
)[ n
- 1 ] ) )
2011 buffer
[ --n
] = '\0';
2020 #if( !TARGET_API_MAC_OSX_KERNEL && !TARGET_OS_WINDOWS_CE )
2021 s
= strerror( inErrorCode
);
2025 s
= "<unknown error code>";
2031 // Copy the string to the output buffer. If no buffer is supplied or it is empty, return an empty string.
2033 if( inBuffer
&& ( inBufferSize
> 0 ) )
2036 end
= dst
+ ( inBufferSize
- 1 );
2037 while( ( ( end
- dst
) > 0 ) && ( *s
!= '\0' ) )
2047 //===========================================================================================================================
2049 //===========================================================================================================================
2055 const char * inLabel
,
2057 int inLabelMinWidth
,
2058 const char * inType
,
2060 const void * inDataStart
,
2061 const void * inData
,
2065 size_t inBufferSize
)
2067 static const char kHexChars
[] = "0123456789ABCDEF";
2068 const uint8_t * start
;
2069 const uint8_t * src
;
2075 const char * newline
;
2076 char separator
[ 8 ];
2079 DEBUG_UNUSED( inType
);
2080 DEBUG_UNUSED( inTypeSize
);
2082 // Set up the function-wide variables.
2084 if( inLabelSize
== kSizeCString
)
2086 inLabelSize
= strlen( inLabel
);
2088 start
= (const uint8_t *) inData
;
2091 end
= dst
+ inBufferSize
;
2092 offset
= (int)( (intptr_t) inData
- (intptr_t) inDataStart
);
2093 width
= ( (int) inLabelSize
> inLabelMinWidth
) ? (int) inLabelSize
: inLabelMinWidth
;
2094 newline
= ( inFlags
& kDebugFlagsNoNewLine
) ? "" : "\n";
2096 // Set up the separator string. This is used to insert spaces on subsequent "lines" when not using newlines.
2099 if( inFlags
& kDebugFlagsNoNewLine
)
2101 if( inFlags
& kDebugFlags8BitSeparator
)
2105 if( inFlags
& kDebugFlags16BitSeparator
)
2109 if( !( inFlags
& kDebugFlagsNo32BitSeparator
) )
2113 check( ( (size_t)( s
- separator
) ) < sizeof( separator
) );
2119 char prefixString
[ 32 ];
2120 char hexString
[ 64 ];
2121 char asciiString
[ 32 ];
2122 char byteCountString
[ 32 ];
2127 // If this is a label-only item (i.e. no data), print the label (accounting for prefix string spacing) and exit.
2129 if( inDataSize
== 0 )
2131 if( inLabel
&& ( inLabelSize
> 0 ) )
2134 if( !( inFlags
& kDebugFlagsNoAddress
) )
2136 width
+= 8; // "00000000"
2137 if( !( inFlags
& kDebugFlagsNoOffset
) )
2142 if( inFlags
& kDebugFlags32BitOffset
)
2144 width
+= 8; // "00000000"
2146 else if( !( inFlags
& kDebugFlagsNoOffset
) )
2148 width
+= 4; // "0000"
2153 dst
+= DebugSNPrintF( dst
, (size_t)( end
- dst
), "%*s" "%-*.*s" "%.*s" "%s",
2155 ( width
> 0 ) ? ": " : "",
2156 width
, (int) inLabelSize
, inLabel
,
2161 dst
+= DebugPrintF( inLevel
, "%*s" "%-*.*s" "%.*s" "%s",
2163 ( width
> 0 ) ? ": " : "",
2164 width
, (int) inLabelSize
, inLabel
,
2171 // Build the prefix string. It will be in one of the following formats:
2173 // 1) "00000000+0000[0000]" (address and offset)
2174 // 2) "00000000" (address only)
2175 // 3) "0000[0000]" (offset only)
2176 // 4) "" (no address or offset)
2178 // Note: If we're printing multiple "lines", but not printing newlines, a space is used to separate.
2181 if( !( inFlags
& kDebugFlagsNoAddress
) )
2183 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 28 ) & 0xF ];
2184 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 24 ) & 0xF ];
2185 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 20 ) & 0xF ];
2186 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 16 ) & 0xF ];
2187 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 12 ) & 0xF ];
2188 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 8 ) & 0xF ];
2189 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 4 ) & 0xF ];
2190 *s
++ = kHexChars
[ ( (uintptr_t) src
) & 0xF ];
2192 if( !( inFlags
& kDebugFlagsNoOffset
) )
2197 if( !( inFlags
& kDebugFlagsNoOffset
) )
2199 if( inFlags
& kDebugFlags32BitOffset
)
2201 *s
++ = kHexChars
[ ( offset
>> 28 ) & 0xF ];
2202 *s
++ = kHexChars
[ ( offset
>> 24 ) & 0xF ];
2203 *s
++ = kHexChars
[ ( offset
>> 20 ) & 0xF ];
2204 *s
++ = kHexChars
[ ( offset
>> 16 ) & 0xF ];
2206 *s
++ = kHexChars
[ ( offset
>> 12 ) & 0xF ];
2207 *s
++ = kHexChars
[ ( offset
>> 8 ) & 0xF ];
2208 *s
++ = kHexChars
[ ( offset
>> 4 ) & 0xF ];
2209 *s
++ = kHexChars
[ offset
& 0xF ];
2211 if( s
!= prefixString
)
2216 check( ( (size_t)( s
- prefixString
) ) < sizeof( prefixString
) );
2219 // Build a hex string with a optional spaces after every 1, 2, and/or 4 bytes to make it easier to read.
2220 // Optionally pads the hex string with space to fill the full 16 byte range (so it lines up).
2223 chunkSize
= ( inDataSize
< 16 ) ? inDataSize
: 16;
2224 n
= ( inFlags
& kDebugFlagsNo16ByteHexPad
) ? chunkSize
: 16;
2225 for( i
= 0; i
< n
; ++i
)
2227 if( ( inFlags
& kDebugFlags8BitSeparator
) && ( i
> 0 ) )
2231 if( ( inFlags
& kDebugFlags16BitSeparator
) && ( i
> 0 ) && ( ( i
% 2 ) == 0 ) )
2235 if( !( inFlags
& kDebugFlagsNo32BitSeparator
) && ( i
> 0 ) && ( ( i
% 4 ) == 0 ) )
2241 *s
++ = kHexChars
[ src
[ i
] >> 4 ];
2242 *s
++ = kHexChars
[ src
[ i
] & 0xF ];
2250 check( ( (size_t)( s
- hexString
) ) < sizeof( hexString
) );
2253 // Build a string with the ASCII version of the data (replaces non-printable characters with '^').
2254 // Optionally pads the string with '`' to fill the full 16 byte range (so it lines up).
2257 if( !( inFlags
& kDebugFlagsNoASCII
) )
2261 for( i
= 0; i
< n
; ++i
)
2266 if( !DebugIsPrint( c
) )
2278 check( ( (size_t)( s
- asciiString
) ) < sizeof( asciiString
) );
2282 // Build a string indicating how bytes are in the hex dump. Only printed on the first line.
2284 s
= byteCountString
;
2285 if( !( inFlags
& kDebugFlagsNoByteCount
) )
2289 s
+= DebugSNPrintF( s
, sizeof( byteCountString
), " (%d bytes)", (int) inDataSize
);
2292 check( ( (size_t)( s
- byteCountString
) ) < sizeof( byteCountString
) );
2295 // Build the entire line from all the pieces we've previously built.
2301 dst
+= DebugSNPrintF( dst
, (size_t)( end
- dst
),
2303 "%s" // Separator (only if needed)
2312 ( src
!= start
) ? separator
: "",
2314 width
, (int) inLabelSize
, inLabel
? inLabel
: "",
2315 ( width
> 0 ) ? " " : "",
2323 dst
+= DebugSNPrintF( dst
, (size_t)( end
- dst
),
2325 "%s" // Separator (only if needed)
2327 "%*s" // Label Spacing
2334 ( src
!= start
) ? separator
: "",
2337 ( width
> 0 ) ? " " : "",
2348 dst
+= DebugPrintF( inLevel
,
2350 "%s" // Separator (only if needed)
2359 ( src
!= start
) ? separator
: "",
2361 width
, (int) inLabelSize
, inLabel
,
2362 ( width
> 0 ) ? " " : "",
2370 dst
+= DebugPrintF( inLevel
,
2372 "%s" // Separator (only if needed)
2374 "%*s" // Label Spacing
2381 ( src
!= start
) ? separator
: "",
2384 ( width
> 0 ) ? " " : "",
2392 // Move to the next chunk. Exit if there is no more data.
2394 offset
+= (int) chunkSize
;
2396 inDataSize
-= chunkSize
;
2397 if( inDataSize
== 0 )
2403 // Note: The "dst - outBuffer" size calculation works even if "outBuffer" is NULL because it's all relative.
2405 return( (size_t)( dst
- outBuffer
) );
2408 //===========================================================================================================================
2409 // DebugNumVersionToString
2410 //===========================================================================================================================
2412 static char * DebugNumVersionToString( uint32_t inVersion
, char *inString
)
2423 majorRev
= (uint8_t)( ( inVersion
>> 24 ) & 0xFF );
2424 minor
= (uint8_t)( ( inVersion
>> 20 ) & 0x0F );
2425 bugFix
= (uint8_t)( ( inVersion
>> 16 ) & 0x0F );
2426 stage
= (uint8_t)( ( inVersion
>> 8 ) & 0xFF );
2427 revision
= (uint8_t)( inVersion
& 0xFF );
2429 // Convert the major, minor, and bugfix numbers.
2432 s
+= sprintf( s
, "%u", majorRev
);
2433 s
+= sprintf( s
, ".%u", minor
);
2436 s
+= sprintf( s
, ".%u", bugFix
);
2439 // Convert the version stage and non-release revision number.
2443 case kVersionStageDevelopment
:
2444 s
+= sprintf( s
, "d%u", revision
);
2447 case kVersionStageAlpha
:
2448 s
+= sprintf( s
, "a%u", revision
);
2451 case kVersionStageBeta
:
2452 s
+= sprintf( s
, "b%u", revision
);
2455 case kVersionStageFinal
:
2457 // A non-release revision of zero is a special case indicating the software is GM (at the golden master
2458 // stage) and therefore, the non-release revision should not be added to the string.
2462 s
+= sprintf( s
, "f%u", revision
);
2467 dlog( kDebugLevelError
, "invalid NumVersion stage (0x%02X)\n", stage
);
2473 //===========================================================================================================================
2475 //===========================================================================================================================
2477 DEBUG_EXPORT
uint32_t DebugTaskLevel( void )
2483 #if( TARGET_OS_VXWORKS )
2486 level
|= ( ( 1 << kDebugInterruptLevelShift
) & kDebugInterruptLevelMask
);
2493 #if( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
2494 //===========================================================================================================================
2495 // DebugWinEnableConsole
2496 //===========================================================================================================================
2498 #pragma warning( disable:4311 )
2500 static void DebugWinEnableConsole( void )
2502 static bool sConsoleEnabled
= false;
2508 if( sConsoleEnabled
)
2513 // Create console window.
2515 result
= AllocConsole();
2516 require_quiet( result
, exit
);
2518 // Redirect stdin to the console stdin.
2520 fileHandle
= _open_osfhandle( (long) GetStdHandle( STD_INPUT_HANDLE
), _O_TEXT
);
2522 #if( defined( __MWERKS__ ) )
2523 file
= __handle_reopen( (unsigned long) fileHandle
, "r", stdin
);
2524 require_quiet( file
, exit
);
2526 file
= _fdopen( fileHandle
, "r" );
2527 require_quiet( file
, exit
);
2532 err
= setvbuf( stdin
, NULL
, _IONBF
, 0 );
2533 require_noerr_quiet( err
, exit
);
2535 // Redirect stdout to the console stdout.
2537 fileHandle
= _open_osfhandle( (long) GetStdHandle( STD_OUTPUT_HANDLE
), _O_TEXT
);
2539 #if( defined( __MWERKS__ ) )
2540 file
= __handle_reopen( (unsigned long) fileHandle
, "w", stdout
);
2541 require_quiet( file
, exit
);
2543 file
= _fdopen( fileHandle
, "w" );
2544 require_quiet( file
, exit
);
2549 err
= setvbuf( stdout
, NULL
, _IONBF
, 0 );
2550 require_noerr_quiet( err
, exit
);
2552 // Redirect stderr to the console stdout.
2554 fileHandle
= _open_osfhandle( (long) GetStdHandle( STD_OUTPUT_HANDLE
), _O_TEXT
);
2556 #if( defined( __MWERKS__ ) )
2557 file
= __handle_reopen( (unsigned long) fileHandle
, "w", stderr
);
2558 require_quiet( file
, exit
);
2560 file
= _fdopen( fileHandle
, "w" );
2561 require_quiet( file
, exit
);
2566 err
= setvbuf( stderr
, NULL
, _IONBF
, 0 );
2567 require_noerr_quiet( err
, exit
);
2569 sConsoleEnabled
= true;
2575 #pragma warning( default:4311 )
2577 #endif // TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE
2579 #if( TARGET_OS_WIN32 )
2580 //===========================================================================================================================
2581 // DebugWinCharToTCharString
2582 //===========================================================================================================================
2585 DebugWinCharToTCharString(
2586 const char * inCharString
,
2588 TCHAR
* outTCharString
,
2589 size_t inTCharCountMax
,
2590 size_t * outTCharCount
)
2596 if( inCharCount
== kSizeCString
)
2598 inCharCount
= strlen( inCharString
);
2601 dst
= outTCharString
;
2602 if( inTCharCountMax
> 0 )
2604 inTCharCountMax
-= 1;
2605 if( inTCharCountMax
> inCharCount
)
2607 inTCharCountMax
= inCharCount
;
2610 end
= dst
+ inTCharCountMax
;
2613 *dst
++ = (TCHAR
) *src
++;
2619 *outTCharCount
= (size_t)( dst
- outTCharString
);
2621 return( outTCharString
);
2627 #pragma mark == Debugging ==
2630 //===========================================================================================================================
2631 // DebugServicesTest
2632 //===========================================================================================================================
2634 DEBUG_EXPORT OSStatus
DebugServicesTest( void )
2641 0x11, 0x22, 0x33, 0x44,
2643 0x77, 0x88, 0x99, 0xAA,
2647 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
2648 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0,
2649 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71, 0x81, 0x91, 0xA1
2652 debug_initialize( kDebugOutputTypeMetaConsole
);
2656 check( 0 && "SHOULD SEE: check" );
2657 check( 1 && "SHOULD *NOT* SEE: check (valid)" );
2658 check_string( 0, "SHOULD SEE: check_string" );
2659 check_string( 1, "SHOULD *NOT* SEE: check_string (valid)" );
2660 check_noerr( -123 );
2661 check_noerr( 10038 );
2664 check_noerr_string( -6712, "SHOULD SEE: check_noerr_string" );
2665 check_noerr_string( 0, "SHOULD *NOT* SEE: check_noerr_string (valid)" );
2666 check_translated_errno( 0 >= 0 && "SHOULD *NOT* SEE", -384, -999 );
2667 check_translated_errno( -1 >= 0 && "SHOULD SEE", -384, -999 );
2668 check_translated_errno( -1 >= 0 && "SHOULD SEE", 0, -999 );
2669 check_ptr_overlap( "SHOULD *NOT* SEE" ? 10 : 0, 10, 22, 10 );
2670 check_ptr_overlap( "SHOULD SEE" ? 10 : 0, 10, 5, 10 );
2671 check_ptr_overlap( "SHOULD SEE" ? 10 : 0, 10, 12, 6 );
2672 check_ptr_overlap( "SHOULD SEE" ? 12 : 0, 6, 10, 10 );
2673 check_ptr_overlap( "SHOULD SEE" ? 12 : 0, 10, 10, 10 );
2674 check_ptr_overlap( "SHOULD *NOT* SEE" ? 22 : 0, 10, 10, 10 );
2675 check_ptr_overlap( "SHOULD *NOT* SEE" ? 10 : 0, 10, 20, 10 );
2676 check_ptr_overlap( "SHOULD *NOT* SEE" ? 20 : 0, 10, 10, 10 );
2680 require( 0 && "SHOULD SEE", require1
);
2681 { err
= kResponseErr
; goto exit
; }
2683 require( 1 && "SHOULD *NOT* SEE", require2
);
2686 { err
= kResponseErr
; goto exit
; }
2688 require_string( 0 && "SHOULD SEE", require3
, "SHOULD SEE: require_string" );
2689 { err
= kResponseErr
; goto exit
; }
2691 require_string( 1 && "SHOULD *NOT* SEE", require4
, "SHOULD *NOT* SEE: require_string (valid)" );
2694 { err
= kResponseErr
; goto exit
; }
2696 require_quiet( 0 && "SHOULD SEE", require5
);
2697 { err
= kResponseErr
; goto exit
; }
2699 require_quiet( 1 && "SHOULD *NOT* SEE", require6
);
2702 { err
= kResponseErr
; goto exit
; }
2704 require_noerr( -1, require7
);
2705 { err
= kResponseErr
; goto exit
; }
2707 require_noerr( 0, require8
);
2710 { err
= kResponseErr
; goto exit
; }
2712 require_noerr_string( -2, require9
, "SHOULD SEE: require_noerr_string");
2713 { err
= kResponseErr
; goto exit
; }
2715 require_noerr_string( 0, require10
, "SHOULD *NOT* SEE: require_noerr_string (valid)" );
2718 { err
= kResponseErr
; goto exit
; }
2720 require_noerr_action_string( -3, require11
, dlog( kDebugLevelMax
, "action 1 (expected)\n" ), "require_noerr_action_string" );
2721 { err
= kResponseErr
; goto exit
; }
2723 require_noerr_action_string( 0, require12
, dlog( kDebugLevelMax
, "action 2\n" ), "require_noerr_action_string (valid)" );
2726 { err
= kResponseErr
; goto exit
; }
2728 require_noerr_quiet( -4, require13
);
2729 { err
= kResponseErr
; goto exit
; }
2731 require_noerr_quiet( 0, require14
);
2734 { err
= kResponseErr
; goto exit
; }
2736 require_noerr_action( -5, require15
, dlog( kDebugLevelMax
, "SHOULD SEE: action 3 (expected)\n" ) );
2737 { err
= kResponseErr
; goto exit
; }
2739 require_noerr_action( 0, require16
, dlog( kDebugLevelMax
, "SHOULD *NOT* SEE: action 4\n" ) );
2742 { err
= kResponseErr
; goto exit
; }
2744 require_noerr_action_quiet( -4, require17
, dlog( kDebugLevelMax
, "SHOULD SEE: action 5 (expected)\n" ) );
2745 { err
= kResponseErr
; goto exit
; }
2747 require_noerr_action_quiet( 0, require18
, dlog( kDebugLevelMax
, "SHOULD *NOT* SEE: action 6\n" ) );
2750 { err
= kResponseErr
; goto exit
; }
2752 require_action( 0 && "SHOULD SEE", require19
, dlog( kDebugLevelMax
, "SHOULD SEE: action 7 (expected)\n" ) );
2753 { err
= kResponseErr
; goto exit
; }
2755 require_action( 1 && "SHOULD *NOT* SEE", require20
, dlog( kDebugLevelMax
, "SHOULD *NOT* SEE: action 8\n" ) );
2758 { err
= kResponseErr
; goto exit
; }
2760 require_action_quiet( 0, require21
, dlog( kDebugLevelMax
, "SHOULD SEE: action 9 (expected)\n" ) );
2761 { err
= kResponseErr
; goto exit
; }
2763 require_action_quiet( 1, require22
, dlog( kDebugLevelMax
, "SHOULD *NOT* SEE: action 10\n" ) );
2766 { err
= kResponseErr
; goto exit
; }
2768 require_action_string( 0, require23
, dlog( kDebugLevelMax
, "SHOULD SEE: action 11 (expected)\n" ), "SHOULD SEE: require_action_string" );
2769 { err
= kResponseErr
; goto exit
; }
2771 require_action_string( 1, require24
, dlog( kDebugLevelMax
, "SHOULD *NOT* SEE: action 12\n" ), "SHOULD *NOT* SEE: require_action_string" );
2774 { err
= kResponseErr
; goto exit
; }
2777 #if( defined( __MWERKS__ ) )
2778 #if( defined( __cplusplus ) && __option( exceptions ) )
2779 #define COMPILER_HAS_EXCEPTIONS 1
2781 #define COMPILER_HAS_EXCEPTIONS 0
2784 #if( defined( __cplusplus ) )
2785 #define COMPILER_HAS_EXCEPTIONS 1
2787 #define COMPILER_HAS_EXCEPTIONS 0
2791 #if( COMPILER_HAS_EXCEPTIONS )
2794 require_throw( 1 && "SHOULD *NOT* SEE" );
2795 require_throw( 0 && "SHOULD SEE" );
2801 { err
= kResponseErr
; goto exit
; }
2807 err
= translate_errno( 1 != -1, -123, -567 );
2808 require( ( err
== 0 ) && "SHOULD *NOT* SEE", exit
);
2810 err
= translate_errno( -1 != -1, -123, -567 );
2811 require( ( err
== -123 ) && "SHOULD *NOT* SEE", exit
);
2813 err
= translate_errno( -1 != -1, 0, -567 );
2814 require( ( err
== -567 ) && "SHOULD *NOT* SEE", exit
);
2818 debug_string( "debug_string" );
2822 DebugSNPrintF( s
, sizeof( s
), "%d", 1234 );
2823 require_action( strcmp( s
, "1234" ) == 0, exit
, err
= -1 );
2825 DebugSNPrintF( s
, sizeof( s
), "%X", 0x2345 );
2826 require_action( strcmp( s
, "2345" ) == 0, exit
, err
= -1 );
2828 DebugSNPrintF( s
, sizeof( s
), "%#s", "\05test" );
2829 require_action( strcmp( s
, "test" ) == 0, exit
, err
= -1 );
2831 DebugSNPrintF( s
, sizeof( s
), "%##s", "\03www\05apple\03com" );
2832 require_action( strcmp( s
, "www.apple.com." ) == 0, exit
, err
= -1 );
2834 DebugSNPrintF( s
, sizeof( s
), "%ld", (long) INT32_C( 2147483647 ) );
2835 require_action( strcmp( s
, "2147483647" ) == 0, exit
, err
= -1 );
2837 DebugSNPrintF( s
, sizeof( s
), "%lu", (unsigned long) UINT32_C( 4294967295 ) );
2838 require_action( strcmp( s
, "4294967295" ) == 0, exit
, err
= -1 );
2840 #if( TYPE_LONGLONG_NATIVE )
2841 DebugSNPrintF( s
, sizeof( s
), "%lld", (long_long_compat
) INT64_C( 9223372036854775807 ) );
2842 require_action( strcmp( s
, "9223372036854775807" ) == 0, exit
, err
= -1 );
2844 DebugSNPrintF( s
, sizeof( s
), "%lld", (long_long_compat
) INT64_C( -9223372036854775807 ) );
2845 require_action( strcmp( s
, "-9223372036854775807" ) == 0, exit
, err
= -1 );
2847 DebugSNPrintF( s
, sizeof( s
), "%llu", (unsigned_long_long_compat
) UINT64_C( 18446744073709551615 ) );
2848 require_action( strcmp( s
, "18446744073709551615" ) == 0, exit
, err
= -1 );
2851 DebugSNPrintF( s
, sizeof( s
), "%lb", (unsigned long) binary_32( 01111011, 01111011, 01111011, 01111011 ) );
2852 require_action( strcmp( s
, "1111011011110110111101101111011" ) == 0, exit
, err
= -1 );
2854 DebugSNPrintF( s
, sizeof( s
), "%C", 0x41624364 ); // 'AbCd'
2855 require_action( strcmp( s
, "AbCd" ) == 0, exit
, err
= -1 );
2857 #if( defined( MDNS_DEBUGMSGS ) )
2861 memset( &maddr
, 0, sizeof( maddr
) );
2862 maddr
.type
= mDNSAddrType_IPv4
;
2863 maddr
.ip
.v4
.b
[ 0 ] = 127;
2864 maddr
.ip
.v4
.b
[ 1 ] = 0;
2865 maddr
.ip
.v4
.b
[ 2 ] = 0;
2866 maddr
.ip
.v4
.b
[ 3 ] = 1;
2867 DebugSNPrintF( s
, sizeof( s
), "%#a", &maddr
);
2868 require_action( strcmp( s
, "127.0.0.1" ) == 0, exit
, err
= -1 );
2870 memset( &maddr
, 0, sizeof( maddr
) );
2871 maddr
.type
= mDNSAddrType_IPv6
;
2872 maddr
.ip
.v6
.b
[ 0 ] = 0xFE;
2873 maddr
.ip
.v6
.b
[ 1 ] = 0x80;
2874 maddr
.ip
.v6
.b
[ 15 ] = 0x01;
2875 DebugSNPrintF( s
, sizeof( s
), "%#a", &maddr
);
2876 require_action( strcmp( s
, "FE80:0000:0000:0000:0000:0000:0000:0001" ) == 0, exit
, err
= -1 );
2882 struct sockaddr_in sa4
;
2884 memset( &sa4
, 0, sizeof( sa4
) );
2885 sa4
.sin_family
= AF_INET
;
2886 p
= (uint8_t *) &sa4
.sin_port
;
2887 p
[ 0 ] = (uint8_t)( ( 80 >> 8 ) & 0xFF );
2888 p
[ 1 ] = (uint8_t)( 80 & 0xFF );
2889 p
= (uint8_t *) &sa4
.sin_addr
.s_addr
;
2890 p
[ 0 ] = (uint8_t)( ( INADDR_LOOPBACK
>> 24 ) & 0xFF );
2891 p
[ 1 ] = (uint8_t)( ( INADDR_LOOPBACK
>> 16 ) & 0xFF );
2892 p
[ 2 ] = (uint8_t)( ( INADDR_LOOPBACK
>> 8 ) & 0xFF );
2893 p
[ 3 ] = (uint8_t)( INADDR_LOOPBACK
& 0xFF );
2894 DebugSNPrintF( s
, sizeof( s
), "%##a", &sa4
);
2895 require_action( strcmp( s
, "127.0.0.1:80" ) == 0, exit
, err
= -1 );
2901 struct sockaddr_in6 sa6
;
2903 memset( &sa6
, 0, sizeof( sa6
) );
2904 sa6
.sin6_family
= AF_INET6
;
2905 p
= (uint8_t *) &sa6
.sin6_port
;
2906 p
[ 0 ] = (uint8_t)( ( 80 >> 8 ) & 0xFF );
2907 p
[ 1 ] = (uint8_t)( 80 & 0xFF );
2908 sa6
.sin6_addr
.s6_addr
[ 0 ] = 0xFE;
2909 sa6
.sin6_addr
.s6_addr
[ 1 ] = 0x80;
2910 sa6
.sin6_addr
.s6_addr
[ 15 ] = 0x01;
2911 sa6
.sin6_scope_id
= 2;
2912 DebugSNPrintF( s
, sizeof( s
), "%##a", &sa6
);
2913 require_action( strcmp( s
, "[FE80:0000:0000:0000:0000:0000:0000:0001%2]:80" ) == 0, exit
, err
= -1 );
2919 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "tes" );
2920 require_action( strcmp( s
, "tes" ) == 0, exit
, err
= kResponseErr
);
2922 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "test" );
2923 require_action( strcmp( s
, "test" ) == 0, exit
, err
= kResponseErr
);
2925 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "testing" );
2926 require_action( strcmp( s
, "test" ) == 0, exit
, err
= kResponseErr
);
2928 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "te\xC3\xA9" );
2929 require_action( strcmp( s
, "te\xC3\xA9" ) == 0, exit
, err
= kResponseErr
);
2931 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "te\xC3\xA9ing" );
2932 require_action( strcmp( s
, "te\xC3\xA9" ) == 0, exit
, err
= kResponseErr
);
2934 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "tes\xC3\xA9ing" );
2935 require_action( strcmp( s
, "tes" ) == 0, exit
, err
= kResponseErr
);
2937 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "t\xed\x9f\xbf" );
2938 require_action( strcmp( s
, "t\xed\x9f\xbf" ) == 0, exit
, err
= kResponseErr
);
2940 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "t\xed\x9f\xbfing" );
2941 require_action( strcmp( s
, "t\xed\x9f\xbf" ) == 0, exit
, err
= kResponseErr
);
2943 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "te\xed\x9f\xbf" );
2944 require_action( strcmp( s
, "te" ) == 0, exit
, err
= kResponseErr
);
2946 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "te\xed\x9f\xbfing" );
2947 require_action( strcmp( s
, "te" ) == 0, exit
, err
= kResponseErr
);
2949 DebugSNPrintF(s
, sizeof(s
), "%.*s", 7, "te\xC3\xA9\xed\x9f\xbfing" );
2950 require_action( strcmp( s
, "te\xC3\xA9\xed\x9f\xbf" ) == 0, exit
, err
= kResponseErr
);
2952 DebugSNPrintF(s
, sizeof(s
), "%.*s", 6, "te\xC3\xA9\xed\x9f\xbfing" );
2953 require_action( strcmp( s
, "te\xC3\xA9" ) == 0, exit
, err
= kResponseErr
);
2955 DebugSNPrintF(s
, sizeof(s
), "%.*s", 5, "te\xC3\xA9\xed\x9f\xbfing" );
2956 require_action( strcmp( s
, "te\xC3\xA9" ) == 0, exit
, err
= kResponseErr
);
2958 #if( TARGET_RT_BIG_ENDIAN )
2959 DebugSNPrintF( s
, sizeof( s
), "%S", "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" );
2960 require_action( strcmp( s
, "abcd" ) == 0, exit
, err
= -1 );
2962 DebugSNPrintF( s
, sizeof( s
), "%S", "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" "\x00" );
2963 require_action( strcmp( s
, "abcd" ) == 0, exit
, err
= -1 );
2966 DebugSNPrintF( s
, sizeof( s
), "%S",
2967 "\xFE\xFF" "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" ); // Big Endian BOM
2968 require_action( strcmp( s
, "abcd" ) == 0, exit
, err
= -1 );
2970 DebugSNPrintF( s
, sizeof( s
), "%S",
2971 "\xFF\xFE" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" "\x00" ); // Little Endian BOM
2972 require_action( strcmp( s
, "abcd" ) == 0, exit
, err
= -1 );
2974 DebugSNPrintF( s
, sizeof( s
), "%#S", "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" ); // Big Endian
2975 require_action( strcmp( s
, "abcd" ) == 0, exit
, err
= -1 );
2977 DebugSNPrintF( s
, sizeof( s
), "%##S", "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" "\x00" ); // Little Endian
2978 require_action( strcmp( s
, "abcd" ) == 0, exit
, err
= -1 );
2980 DebugSNPrintF( s
, sizeof( s
), "%.*S",
2981 4, "\xFE\xFF" "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" ); // Big Endian BOM
2982 require_action( strcmp( s
, "abc" ) == 0, exit
, err
= -1 );
2984 DebugSNPrintF( s
, sizeof( s
), "%.*S",
2985 4, "\xFF\xFE" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" ); // Little Endian BOM
2986 require_action( strcmp( s
, "abc" ) == 0, exit
, err
= -1 );
2988 #if( TARGET_RT_BIG_ENDIAN )
2989 DebugSNPrintF( s
, sizeof( s
), "%.*S", 3, "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" );
2990 require_action( strcmp( s
, "abc" ) == 0, exit
, err
= -1 );
2992 DebugSNPrintF( s
, sizeof( s
), "%.*S", 3, "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" );
2993 require_action( strcmp( s
, "abc" ) == 0, exit
, err
= -1 );
2996 DebugSNPrintF( s
, sizeof( s
), "%#.*S", 3, "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" ); // Big Endian
2997 require_action( strcmp( s
, "abc" ) == 0, exit
, err
= -1 );
2999 DebugSNPrintF( s
, sizeof( s
), "%##.*S", 3, "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" ); // Little Endian
3000 require_action( strcmp( s
, "abc" ) == 0, exit
, err
= -1 );
3004 DebugSNPrintF( s
, sizeof( s
), "%U", "\x10\xb8\xa7\x6b" "\xad\x9d" "\xd1\x11" "\x80\xb4" "\x00\xc0\x4f\xd4\x30\xc8" );
3005 require_action( strcmp( s
, "6ba7b810-9dad-11d1-80b4-00c04fd430c8" ) == 0, exit
, err
= -1 );
3007 DebugSNPrintF( s
, sizeof( s
), "%m", 0 );
3008 require_action( strcmp( s
, "no error" ) == 0, exit
, err
= -1 );
3010 DebugSNPrintF( s
, sizeof( s
), "%lm", (long) 0 );
3011 require_action( strcmp( s
, "no error" ) == 0, exit
, err
= -1 );
3013 DebugSNPrintF( s
, sizeof( s
), "\"%H\"", "\x6b\xa7\xb8\x10\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8", 16, 16 );
3014 DebugPrintF( kDebugLevelMax
, "%s\n\n", s
);
3016 DebugSNPrintF( s
, sizeof( s
), "\"%H\"",
3017 "\x6b\xa7\xb8\x10\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8"
3018 "\x6b\xa7\xb8\x10\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8",
3020 DebugPrintF( kDebugLevelMax
, "%s\n\n", s
);
3022 DebugSNPrintF( s
, sizeof( s
), "\"%H\"", "\x6b\xa7", 2, 2 );
3023 DebugPrintF( kDebugLevelMax
, "%s\n\n", s
);
3028 DebugHexDump( kDebugLevelMax
, 0, "My Label", kSizeCString
, 0, NULL
, 0, data
, data
, sizeof( data
),
3029 kDebugFlagsNone
, s
, sizeof( s
) );
3030 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3033 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
),
3034 kDebugFlagsNoAddress
| kDebugFlagsNoOffset
, s
, sizeof( s
) );
3035 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3038 DebugHexDump( kDebugLevelMax
, 0, "My Label", kSizeCString
, 0, NULL
, 0, data
, data
, sizeof( data
),
3039 kDebugFlagsNoAddress
| kDebugFlagsNoOffset
, s
, sizeof( s
) );
3040 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3043 DebugHexDump( kDebugLevelMax
, 0, "My Label", kSizeCString
, 0, NULL
, 0, data
, data
, sizeof( data
),
3044 kDebugFlagsNoAddress
, s
, sizeof( s
) );
3045 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3048 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
),
3049 kDebugFlagsNoOffset
, s
, sizeof( s
) );
3050 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3053 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
),
3054 kDebugFlagsNoAddress
, s
, sizeof( s
) );
3055 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3058 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
),
3059 kDebugFlagsNoOffset
, s
, sizeof( s
) );
3060 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3063 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
),
3064 kDebugFlagsNoByteCount
, s
, sizeof( s
) );
3065 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3068 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, "\x41\x62\x43\x64", "\x41\x62\x43\x64", 4, // 'AbCd'
3069 kDebugFlagsNoAddress
| kDebugFlagsNoOffset
| kDebugFlagsNoNewLine
|
3070 kDebugFlagsNo32BitSeparator
| kDebugFlagsNo16ByteHexPad
| kDebugFlagsNoByteCount
,
3072 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3075 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
),
3076 kDebugFlagsNoAddress
| kDebugFlagsNoOffset
| kDebugFlagsNoASCII
| kDebugFlagsNoNewLine
|
3077 kDebugFlags16BitSeparator
| kDebugFlagsNo32BitSeparator
|
3078 kDebugFlagsNo16ByteHexPad
| kDebugFlagsNoByteCount
, s
, sizeof( s
) );
3079 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3082 DebugHexDump( kDebugLevelMax
, 8, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
), kDebugFlagsNone
, s
, sizeof( s
) );
3083 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3087 dlog( kDebugLevelNotice
, "dlog\n" );
3088 dlog( kDebugLevelNotice
, "dlog integer: %d\n", 123 );
3089 dlog( kDebugLevelNotice
, "dlog string: \"%s\"\n", "test string" );
3090 dlogmem( kDebugLevelNotice
, data
, sizeof( data
) );
3094 DebugPrintF( kDebugLevelMax
, "\n\nALL TESTS DONE\n\n" );
3100 DebugPrintF( kDebugLevelMax
, "\n\n### TEST FAILED ###\n\n" );