1 /* -*- Mode: C; tab-width: 4 -*-
3 * Copyright (c) 1997-2004 Apple Computer, Inc. All rights reserved.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
19 - Use StackWalk on Windows to optionally print stack frames.
23 #pragma mark == Includes ==
26 //===========================================================================================================================
28 //===========================================================================================================================
36 #include "CommonServices.h"
38 #include "DebugServices.h"
42 #if ( TARGET_OS_WIN32 )
45 #if ( !TARGET_OS_WINDOWS_CE )
51 #if ( DEBUG_IDEBUG_ENABLED && TARGET_API_MAC_OSX_KERNEL )
52 #include <IOKit/IOLib.h>
55 // If MDNS_DEBUGMSGS is defined (even if defined 0), it is aware of mDNS and it is probably safe to include mDNSEmbeddedAPI.h.
57 #if ( defined( MDNS_DEBUGMSGS ) )
58 #include "mDNSEmbeddedAPI.h"
62 #pragma mark == Macros ==
65 //===========================================================================================================================
67 //===========================================================================================================================
69 #define DebugIsPrint( C ) ( ( ( C ) >= 0x20 ) && ( ( C ) <= 0x7E ) )
72 #pragma mark == Prototypes ==
75 //===========================================================================================================================
77 //===========================================================================================================================
79 static OSStatus
DebugPrint( DebugLevel inLevel
, char *inData
, size_t inSize
);
83 #if ( DEBUG_FPRINTF_ENABLED )
84 static OSStatus
DebugFPrintFInit( DebugOutputTypeFlags inFlags
, const char *inFilename
);
85 static void DebugFPrintFPrint( char *inData
, size_t inSize
);
88 // iDebug (Mac OS X user and kernel)
90 #if ( DEBUG_IDEBUG_ENABLED )
91 static OSStatus
DebugiDebugInit( void );
92 static void DebugiDebugPrint( char *inData
, size_t inSize
);
95 // kprintf (Mac OS X Kernel)
97 #if ( DEBUG_KPRINTF_ENABLED )
98 static void DebugKPrintFPrint( char *inData
, size_t inSize
);
101 // Mac OS X IOLog (Mac OS X Kernel)
103 #if ( DEBUG_MAC_OS_X_IOLOG_ENABLED )
104 static void DebugMacOSXIOLogPrint( char *inData
, size_t inSize
);
109 #if ( TARGET_OS_MAC )
110 static OSStatus
DebugMacOSXLogInit( void );
111 static void DebugMacOSXLogPrint( char *inData
, size_t inSize
);
116 #if ( TARGET_OS_WIN32 )
117 static void DebugWindowsDebuggerPrint( char *inData
, size_t inSize
);
122 #if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
123 static OSStatus
DebugWindowsEventLogInit( const char *inName
, HMODULE inModule
);
124 static void DebugWindowsEventLogPrint( DebugLevel inLevel
, char *inData
, size_t inSize
);
129 #if ( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
131 DebugAssertOutputHandler(
132 OSType inComponentSignature
,
134 const char * inAssertionString
,
135 const char * inExceptionString
,
136 const char * inErrorString
,
137 const char * inFileName
,
140 ConstStr255Param inOutputMsg
);
145 static char * DebugNumVersionToString( uint32_t inVersion
, char *inString
);
147 #if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
148 static void DebugWinEnableConsole( void );
151 #if ( TARGET_OS_WIN32 )
153 DebugWinCharToTCharString(
154 const char * inCharString
,
156 TCHAR
* outTCharString
,
157 size_t inTCharCountMax
,
158 size_t * outTCharCount
);
162 #pragma mark == Globals ==
165 //===========================================================================================================================
167 //===========================================================================================================================
171 static bool gDebugInitialized
= false;
172 static DebugOutputType gDebugOutputType
= kDebugOutputTypeNone
;
173 static DebugLevel gDebugPrintLevelMin
= kDebugLevelInfo
;
174 static DebugLevel gDebugPrintLevelMax
= kDebugLevelMax
;
175 static DebugLevel gDebugBreakLevel
= kDebugLevelAssert
;
176 #if ( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
177 static DebugAssertOutputHandlerUPP gDebugAssertOutputHandlerUPP
= NULL
;
182 static DebugOutputFunctionPtr gDebugCustomOutputFunction
= NULL
;
183 static void * gDebugCustomOutputContext
= NULL
;
187 #if ( DEBUG_FPRINTF_ENABLED )
188 static FILE * gDebugFPrintFFile
= NULL
;
193 #if ( TARGET_OS_MAC )
194 typedef int ( *DebugMacOSXLogFunctionPtr
)( const char *inFormat
, ... );
196 static DebugMacOSXLogFunctionPtr gDebugMacOSXLogFunction
= NULL
;
202 #if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
203 static HANDLE gDebugWindowsEventLogEventSource
= NULL
;
208 #pragma mark == General ==
211 //===========================================================================================================================
213 //===========================================================================================================================
215 DEBUG_EXPORT OSStatus
DebugInitialize( DebugOutputType inType
, ... )
218 DebugOutputType type
;
221 va_start( args
, inType
);
223 // Set up DebugLib stuff (if building with Debugging.h).
225 #if ( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
226 if( !gDebugAssertOutputHandlerUPP
)
228 gDebugAssertOutputHandlerUPP
= NewDebugAssertOutputHandlerUPP( DebugAssertOutputHandler
);
229 check( gDebugAssertOutputHandlerUPP
);
230 if( gDebugAssertOutputHandlerUPP
)
232 InstallDebugAssertOutputHandler( gDebugAssertOutputHandlerUPP
);
237 // Pre-process meta-output kind to pick an appropriate output kind for the platform.
240 if( type
== kDebugOutputTypeMetaConsole
)
242 #if ( TARGET_OS_MAC )
243 type
= kDebugOutputTypeMacOSXLog
;
244 #elif ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
245 #if ( DEBUG_FPRINTF_ENABLED )
246 type
= kDebugOutputTypeFPrintF
;
248 type
= kDebugOutputTypeWindowsDebugger
;
250 #elif ( TARGET_API_MAC_OSX_KERNEL )
251 #if ( DEBUG_MAC_OS_X_IOLOG_ENABLED )
252 type
= kDebugOutputTypeMacOSXIOLog
;
253 #elif ( DEBUG_IDEBUG_ENABLED )
254 type
= kDebugOutputTypeiDebug
;
255 #elif ( DEBUG_KPRINTF_ENABLED )
256 type
= kDebugOutputTypeKPrintF
;
259 #if ( DEBUG_FPRINTF_ENABLED )
260 type
= kDebugOutputTypeFPrintF
;
265 // Process output kind.
267 gDebugOutputType
= type
;
270 case kDebugOutputTypeNone
:
274 case kDebugOutputTypeCustom
:
275 gDebugCustomOutputFunction
= va_arg( args
, DebugOutputFunctionPtr
);
276 gDebugCustomOutputContext
= va_arg( args
, void * );
280 #if ( DEBUG_FPRINTF_ENABLED )
281 case kDebugOutputTypeFPrintF
:
282 if( inType
== kDebugOutputTypeMetaConsole
)
284 err
= DebugFPrintFInit( kDebugOutputTypeFlagsStdErr
, NULL
);
288 DebugOutputTypeFlags flags
;
289 const char * filename
;
291 flags
= (DebugOutputTypeFlags
) va_arg( args
, unsigned int );
292 if( ( flags
& kDebugOutputTypeFlagsTypeMask
) == kDebugOutputTypeFlagsFile
)
294 filename
= va_arg( args
, const char * );
300 err
= DebugFPrintFInit( flags
, filename
);
305 #if ( DEBUG_IDEBUG_ENABLED )
306 case kDebugOutputTypeiDebug
:
307 err
= DebugiDebugInit();
311 #if ( DEBUG_KPRINTF_ENABLED )
312 case kDebugOutputTypeKPrintF
:
317 #if ( DEBUG_MAC_OS_X_IOLOG_ENABLED )
318 case kDebugOutputTypeMacOSXIOLog
:
323 #if ( TARGET_OS_MAC )
324 case kDebugOutputTypeMacOSXLog
:
325 err
= DebugMacOSXLogInit();
329 #if ( TARGET_OS_WIN32 )
330 case kDebugOutputTypeWindowsDebugger
:
335 #if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
336 case kDebugOutputTypeWindowsEventLog
:
341 name
= va_arg( args
, const char * );
342 module = va_arg( args
, HMODULE
);
343 err
= DebugWindowsEventLogInit( name
, module );
352 gDebugInitialized
= true;
359 //===========================================================================================================================
361 //===========================================================================================================================
363 DEBUG_EXPORT
void DebugFinalize( void )
365 #if ( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
366 check( gDebugAssertOutputHandlerUPP
);
367 if( gDebugAssertOutputHandlerUPP
)
369 InstallDebugAssertOutputHandler( NULL
);
370 DisposeDebugAssertOutputHandlerUPP( gDebugAssertOutputHandlerUPP
);
371 gDebugAssertOutputHandlerUPP
= NULL
;
376 //===========================================================================================================================
378 //===========================================================================================================================
380 DEBUG_EXPORT OSStatus
DebugGetProperty( DebugPropertyTag inTag
, ... )
386 va_start( args
, inTag
);
389 case kDebugPropertyTagPrintLevelMin
:
390 level
= va_arg( args
, DebugLevel
* );
391 *level
= gDebugPrintLevelMin
;
395 case kDebugPropertyTagPrintLevelMax
:
396 level
= va_arg( args
, DebugLevel
* );
397 *level
= gDebugPrintLevelMax
;
401 case kDebugPropertyTagBreakLevel
:
402 level
= va_arg( args
, DebugLevel
* );
403 *level
= gDebugBreakLevel
;
408 err
= kUnsupportedErr
;
415 //===========================================================================================================================
417 //===========================================================================================================================
419 DEBUG_EXPORT OSStatus
DebugSetProperty( DebugPropertyTag inTag
, ... )
425 va_start( args
, inTag
);
428 case kDebugPropertyTagPrintLevelMin
:
429 level
= va_arg( args
, DebugLevel
);
430 gDebugPrintLevelMin
= level
;
434 case kDebugPropertyTagPrintLevelMax
:
435 level
= va_arg( args
, DebugLevel
);
436 gDebugPrintLevelMax
= level
;
440 case kDebugPropertyTagBreakLevel
:
441 level
= va_arg( args
, DebugLevel
);
442 gDebugBreakLevel
= level
;
447 err
= kUnsupportedErr
;
456 #pragma mark == Output ==
459 //===========================================================================================================================
461 //===========================================================================================================================
463 DEBUG_EXPORT
size_t DebugPrintF( DebugLevel inLevel
, const char *inFormat
, ... )
468 // Skip if the level is not in the enabled range..
470 if( ( inLevel
< gDebugPrintLevelMin
) || ( inLevel
> gDebugPrintLevelMax
) )
476 va_start( args
, inFormat
);
477 n
= DebugPrintFVAList( inLevel
, inFormat
, args
);
484 //===========================================================================================================================
486 //===========================================================================================================================
488 DEBUG_EXPORT
size_t DebugPrintFVAList( DebugLevel inLevel
, const char *inFormat
, va_list inArgs
)
493 // Skip if the level is not in the enabled range..
495 if( ( inLevel
< gDebugPrintLevelMin
) || ( inLevel
> gDebugPrintLevelMax
) )
501 n
= DebugSNPrintFVAList( buffer
, sizeof( buffer
), inFormat
, inArgs
);
502 DebugPrint( inLevel
, buffer
, (size_t) n
);
508 //===========================================================================================================================
510 //===========================================================================================================================
512 static OSStatus
DebugPrint( DebugLevel inLevel
, char *inData
, size_t inSize
)
516 // Skip if the level is not in the enabled range..
518 if( ( inLevel
< gDebugPrintLevelMin
) || ( inLevel
> gDebugPrintLevelMax
) )
524 // Printing is not safe at interrupt time so check for this and warn with an interrupt safe mechanism (if available).
526 if( DebugTaskLevel() & kDebugInterruptLevelMask
)
528 err
= kExecutionStateErr
;
532 // Initialize the debugging library if it hasn't already been initialized (allows for zero-config usage).
534 if( !gDebugInitialized
)
536 debug_initialize( kDebugOutputTypeMetaConsole
);
539 // Print based on the current output type.
541 switch( gDebugOutputType
)
543 case kDebugOutputTypeNone
:
546 case kDebugOutputTypeCustom
:
547 if( gDebugCustomOutputFunction
)
549 gDebugCustomOutputFunction( inData
, inSize
, gDebugCustomOutputContext
);
553 #if ( DEBUG_FPRINTF_ENABLED )
554 case kDebugOutputTypeFPrintF
:
555 DebugFPrintFPrint( inData
, inSize
);
559 #if ( DEBUG_IDEBUG_ENABLED )
560 case kDebugOutputTypeiDebug
:
561 DebugiDebugPrint( inData
, inSize
);
565 #if ( DEBUG_KPRINTF_ENABLED )
566 case kDebugOutputTypeKPrintF
:
567 DebugKPrintFPrint( inData
, inSize
);
571 #if ( DEBUG_MAC_OS_X_IOLOG_ENABLED )
572 case kDebugOutputTypeMacOSXIOLog
:
573 DebugMacOSXIOLogPrint( inData
, inSize
);
577 #if ( TARGET_OS_MAC )
578 case kDebugOutputTypeMacOSXLog
:
579 DebugMacOSXLogPrint( inData
, inSize
);
583 #if ( TARGET_OS_WIN32 )
584 case kDebugOutputTypeWindowsDebugger
:
585 DebugWindowsDebuggerPrint( inData
, inSize
);
589 #if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
590 case kDebugOutputTypeWindowsEventLog
:
591 DebugWindowsEventLogPrint( inLevel
, inData
, inSize
);
604 //===========================================================================================================================
607 // Warning: This routine relies on several of the strings being string constants that will exist forever because the
608 // underlying logMsg API that does the printing is asynchronous so it cannot use temporary/stack-based
609 // pointer variables (e.g. local strings). The debug macros that invoke this function only use constant
610 // constant strings, but if this function is invoked directly from other places, it must use constant strings.
611 //===========================================================================================================================
615 int_least32_t inErrorCode
,
616 const char * inAssertString
,
617 const char * inMessage
,
618 const char * inFilename
,
619 int_least32_t inLineNumber
,
620 const char * inFunction
)
622 // Skip if the level is not in the enabled range..
624 if( ( kDebugLevelAssert
< gDebugPrintLevelMin
) || ( kDebugLevelAssert
> gDebugPrintLevelMax
) )
629 if( inErrorCode
!= 0 )
634 "[ASSERT] error: %ld (%m)\n"
635 "[ASSERT] where: \"%s\", line %ld, \"%s\"\n"
637 inErrorCode
, inErrorCode
,
638 inFilename
? inFilename
: "",
640 inFunction
? inFunction
: "" );
647 "[ASSERT] assert: \"%s\" %s\n"
648 "[ASSERT] where: \"%s\", line %ld, \"%s\"\n"
650 inAssertString
? inAssertString
: "",
651 inMessage
? inMessage
: "",
652 inFilename
? inFilename
: "",
654 inFunction
? inFunction
: "" );
657 // Break into the debugger if enabled.
659 #if ( TARGET_OS_WIN32 )
660 if( gDebugBreakLevel
<= kDebugLevelAssert
)
662 if( IsDebuggerPresent() )
674 #if ( DEBUG_FPRINTF_ENABLED )
675 //===========================================================================================================================
677 //===========================================================================================================================
679 static OSStatus
DebugFPrintFInit( DebugOutputTypeFlags inFlags
, const char *inFilename
)
682 DebugOutputTypeFlags typeFlags
;
684 typeFlags
= inFlags
& kDebugOutputTypeFlagsTypeMask
;
685 if( typeFlags
== kDebugOutputTypeFlagsStdOut
)
687 #if ( TARGET_OS_WIN32 )
688 DebugWinEnableConsole();
691 gDebugFPrintFFile
= stdout
;
693 else if( typeFlags
== kDebugOutputTypeFlagsStdErr
)
695 #if ( TARGET_OS_WIN32 )
696 DebugWinEnableConsole();
699 gDebugFPrintFFile
= stdout
;
701 else if( typeFlags
== kDebugOutputTypeFlagsFile
)
703 require_action_quiet( inFilename
&& ( *inFilename
!= '\0' ), exit
, err
= kOpenErr
);
705 gDebugFPrintFFile
= fopen( inFilename
, "a" );
706 require_action_quiet( gDebugFPrintFFile
, exit
, err
= kOpenErr
);
719 //===========================================================================================================================
721 //===========================================================================================================================
723 static void DebugFPrintFPrint( char *inData
, size_t inSize
)
728 // Convert \r to \n. fprintf will interpret \n and convert to whatever is appropriate for the platform.
741 // Write the data and flush.
743 if( gDebugFPrintFFile
)
745 fprintf( gDebugFPrintFFile
, "%.*s", (int) inSize
, inData
);
746 fflush( gDebugFPrintFFile
);
749 #endif // DEBUG_FPRINTF_ENABLED
751 #if ( DEBUG_IDEBUG_ENABLED )
752 //===========================================================================================================================
754 //===========================================================================================================================
756 static OSStatus
DebugiDebugInit( void )
760 #if ( TARGET_API_MAC_OSX_KERNEL )
762 extern uint32_t * _giDebugReserved1
;
764 // Emulate the iDebugSetOutputType macro in iDebugServices.h.
765 // Note: This is not thread safe, but neither is iDebugServices.h nor iDebugKext.
767 if( !_giDebugReserved1
)
769 _giDebugReserved1
= (uint32_t *) IOMalloc( sizeof( uint32_t ) );
770 require_action_quiet( _giDebugReserved1
, exit
, err
= kNoMemoryErr
);
772 *_giDebugReserved1
= 0x00010000U
;
777 __private_extern__
void iDebugSetOutputTypeInternal( uint32_t inType
);
779 iDebugSetOutputTypeInternal( 0x00010000U
);
787 //===========================================================================================================================
789 //===========================================================================================================================
791 static void DebugiDebugPrint( char *inData
, size_t inSize
)
793 #if ( TARGET_API_MAC_OSX_KERNEL )
795 // Locally declared here so we do not need to include iDebugKext.h.
796 // Note: IOKit uses a global namespace for all code and only a partial link occurs at build time. When the
797 // KEXT is loaded, the runtime linker will link in this extern'd symbol (assuming iDebug is present).
798 // _giDebugLogInternal is actually part of IOKit proper so this should link even if iDebug is not present.
800 typedef void ( *iDebugLogFunctionPtr
)( uint32_t inLevel
, uint32_t inTag
, const char *inFormat
, ... );
802 extern iDebugLogFunctionPtr _giDebugLogInternal
;
804 if( _giDebugLogInternal
)
806 _giDebugLogInternal( 0, 0, "%.*s", (int) inSize
, inData
);
811 __private_extern__
void iDebugLogInternal( uint32_t inLevel
, uint32_t inTag
, const char *inFormat
, ... );
813 iDebugLogInternal( 0, 0, "%.*s", (int) inSize
, inData
);
819 #if ( DEBUG_KPRINTF_ENABLED )
820 //===========================================================================================================================
822 //===========================================================================================================================
824 static void DebugKPrintFPrint( char *inData
, size_t inSize
)
826 extern void kprintf( const char *inFormat
, ... );
828 kprintf( "%.*s", (int) inSize
, inData
);
832 #if ( DEBUG_MAC_OS_X_IOLOG_ENABLED )
833 //===========================================================================================================================
834 // DebugMacOSXIOLogPrint
835 //===========================================================================================================================
837 static void DebugMacOSXIOLogPrint( char *inData
, size_t inSize
)
839 extern void IOLog( const char *inFormat
, ... );
841 IOLog( "%.*s", (int) inSize
, inData
);
845 #if ( TARGET_OS_MAC )
846 //===========================================================================================================================
847 // DebugMacOSXLogInit
848 //===========================================================================================================================
850 static OSStatus
DebugMacOSXLogInit( void )
856 CFStringRef functionName
;
861 // Create a bundle reference for System.framework.
863 path
= CFSTR( "/System/Library/Frameworks/System.framework" );
864 url
= CFURLCreateWithFileSystemPath( NULL
, path
, kCFURLPOSIXPathStyle
, true );
865 require_action_quiet( url
, exit
, err
= memFullErr
);
867 bundle
= CFBundleCreate( NULL
, url
);
869 require_action_quiet( bundle
, exit
, err
= memFullErr
);
871 // Get a ptr to the system's "printf" function from System.framework.
873 functionName
= CFSTR( "printf" );
874 functionPtr
= CFBundleGetFunctionPointerForName( bundle
, functionName
);
875 require_action_quiet( functionPtr
, exit
, err
= memFullErr
);
877 // Success! Note: The bundle cannot be released because it would invalidate the function ptr.
879 gDebugMacOSXLogFunction
= (DebugMacOSXLogFunctionPtr
) functionPtr
;
891 //===========================================================================================================================
892 // DebugMacOSXLogPrint
893 //===========================================================================================================================
895 static void DebugMacOSXLogPrint( char *inData
, size_t inSize
)
897 if( gDebugMacOSXLogFunction
)
899 gDebugMacOSXLogFunction( "%.*s", (int) inSize
, inData
);
904 #if ( TARGET_OS_WIN32 )
905 //===========================================================================================================================
906 // DebugWindowsDebuggerPrint
907 //===========================================================================================================================
909 void DebugWindowsDebuggerPrint( char *inData
, size_t inSize
)
917 // Copy locally and null terminate the string. This also converts from char to TCHAR in case we are
918 // building with UNICODE enabled since the input is always char. Also convert \r to \n in the process.
921 if( inSize
>= sizeof_array( buffer
) )
923 inSize
= sizeof_array( buffer
) - 1;
938 // Print out the string to the debugger.
940 OutputDebugString( buffer
);
944 #if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
945 //===========================================================================================================================
946 // DebugWindowsEventLogInit
947 //===========================================================================================================================
949 static OSStatus
DebugWindowsEventLogInit( const char *inName
, HMODULE inModule
)
955 TCHAR path
[ MAX_PATH
];
957 DWORD typesSupported
;
962 // Use a default name if needed then convert the name to TCHARs so it works on ANSI or Unicode builds.
964 if( !inName
|| ( *inName
== '\0' ) )
966 inName
= "DefaultApp";
968 DebugWinCharToTCharString( inName
, kSizeCString
, name
, sizeof( name
), NULL
);
970 // Build the path string using the fixed registry path and app name.
972 src
= "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\";
973 DebugWinCharToTCharString( src
, kSizeCString
, path
, sizeof_array( path
), &size
);
974 DebugWinCharToTCharString( inName
, kSizeCString
, path
+ size
, sizeof_array( path
) - size
, NULL
);
976 // Add/Open the source name as a sub-key under the Application key in the EventLog registry key.
978 err
= RegCreateKeyEx( HKEY_LOCAL_MACHINE
, path
, 0, NULL
, REG_OPTION_NON_VOLATILE
, KEY_ALL_ACCESS
, NULL
, &key
, NULL
);
979 require_noerr_quiet( err
, exit
);
981 // Set the path in the EventMessageFile subkey. Add 1 to the TCHAR count to include the null terminator.
983 n
= GetModuleFileName( inModule
, path
, sizeof_array( path
) );
984 err
= translate_errno( n
> 0, (OSStatus
) GetLastError(), kParamErr
);
985 require_noerr_quiet( err
, exit
);
987 n
*= sizeof( TCHAR
);
989 err
= RegSetValueEx( key
, TEXT( "EventMessageFile" ), 0, REG_EXPAND_SZ
, (const LPBYTE
) path
, n
);
990 require_noerr_quiet( err
, exit
);
992 // Set the supported event types in the TypesSupported subkey.
994 typesSupported
= EVENTLOG_SUCCESS
| EVENTLOG_ERROR_TYPE
| EVENTLOG_WARNING_TYPE
| EVENTLOG_INFORMATION_TYPE
|
995 EVENTLOG_AUDIT_SUCCESS
| EVENTLOG_AUDIT_FAILURE
;
996 err
= RegSetValueEx( key
, TEXT( "TypesSupported" ), 0, REG_DWORD
, (const LPBYTE
) &typesSupported
, sizeof( DWORD
) );
997 require_noerr_quiet( err
, exit
);
999 // Set up the event source.
1001 gDebugWindowsEventLogEventSource
= RegisterEventSource( NULL
, name
);
1002 err
= translate_errno( gDebugWindowsEventLogEventSource
, (OSStatus
) GetLastError(), kParamErr
);
1003 require_noerr_quiet( err
, exit
);
1013 //===========================================================================================================================
1014 // DebugWindowsEventLogPrint
1015 //===========================================================================================================================
1017 static void DebugWindowsEventLogPrint( DebugLevel inLevel
, char *inData
, size_t inSize
)
1020 TCHAR buffer
[ 512 ];
1025 const TCHAR
* array
[ 1 ];
1027 // Map the debug level to a Windows EventLog type.
1029 if( inLevel
<= kDebugLevelNotice
)
1031 type
= EVENTLOG_INFORMATION_TYPE
;
1033 else if( inLevel
<= kDebugLevelWarning
)
1035 type
= EVENTLOG_WARNING_TYPE
;
1039 type
= EVENTLOG_ERROR_TYPE
;
1042 // Copy locally and null terminate the string. This also converts from char to TCHAR in case we are
1043 // building with UNICODE enabled since the input is always char. Also convert \r to \n in the process.
1046 if( inSize
>= sizeof_array( buffer
) )
1048 inSize
= sizeof_array( buffer
) - 1;
1063 // Add the the string to the event log.
1065 array
[ 0 ] = buffer
;
1066 if( gDebugWindowsEventLogEventSource
)
1068 ReportEvent( gDebugWindowsEventLogEventSource
, type
, 0, 0x20000001L
, NULL
, 1, 0, array
, NULL
);
1071 #endif // TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE
1073 #if ( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
1074 //===========================================================================================================================
1075 // DebugAssertOutputHandler
1076 //===========================================================================================================================
1079 DebugAssertOutputHandler(
1080 OSType inComponentSignature
,
1082 const char * inAssertString
,
1083 const char * inExceptionString
,
1084 const char * inErrorString
,
1085 const char * inFileName
,
1088 ConstStr255Param inOutputMsg
)
1090 DEBUG_UNUSED( inComponentSignature
);
1091 DEBUG_UNUSED( inOptions
);
1092 DEBUG_UNUSED( inExceptionString
);
1093 DEBUG_UNUSED( inValue
);
1094 DEBUG_UNUSED( inOutputMsg
);
1096 DebugPrintAssert( 0, inAssertString
, inErrorString
, inFileName
, (int_least32_t) inLineNumber
, "" );
1102 #pragma mark == Utilities ==
1105 //===========================================================================================================================
1108 // Stolen from mDNS.c's mDNS_snprintf/mDNS_vsnprintf with the following changes:
1110 // Changed names to avoid name collisions with the mDNS versions.
1111 // Changed types to standard C types since mDNSEmbeddedAPI.h may not be available.
1112 // Conditionalized mDNS stuff so it can be used with or with mDNSEmbeddedAPI.h.
1113 // Added 64-bit support for %d (%lld), %i (%lli), %u (%llu), %o (%llo), %x (%llx), and %b (%llb).
1114 // Added %@ - Cocoa/CoreFoundation object. Param is the object. Strings are used directly. Others use CFCopyDescription.
1115 // Added %.8a - FIbre Channel address. Arg=ptr to address.
1116 // Added %##a - IPv4 (if AF_INET defined) or IPv6 (if AF_INET6 defined) sockaddr. Arg=ptr to sockaddr.
1117 // Added %b - Binary representation of integer (e.g. 01101011). Modifiers and arg=the same as %d, %x, etc.
1118 // Added %C - Mac-style FourCharCode (e.g. 'APPL'). Arg=32-bit value to print as a Mac-style FourCharCode.
1119 // Added %H - Hex Dump (e.g. "\x6b\xa7" -> "6B A7"). 1st arg=ptr, 2nd arg=size, 3rd arg=max size.
1120 // Added %#H - Hex Dump & ASCII (e.g. "\x41\x62" -> "6B A7 'Ab'"). 1st arg=ptr, 2nd arg=size, 3rd arg=max size.
1121 // Added %m - Error Message (e.g. 0 -> "kNoErr"). Modifiers and error code args are the same as %d, %x, etc.
1122 // Added %S - UTF-16 string. Host order if no BOM. Precision is UTF-16 char count. BOM counts in any precision. Arg=ptr.
1123 // Added %#S - Big Endian UTF-16 string (unless BOM overrides). Otherwise the same as %S.
1124 // Added %##S - Little Endian UTF-16 string (unless BOM overrides). Otherwise the same as %S.
1125 // Added %U - Universally Unique Identifier (UUID) (e.g. 6ba7b810-9dad-11d1-80b4-00c04fd430c8). Arg=ptr to 16-byte UUID.
1126 //===========================================================================================================================
1128 DEBUG_EXPORT
size_t DebugSNPrintF(char *sbuffer
, size_t buflen
, const char *fmt
, ...)
1134 length
= DebugSNPrintFVAList(sbuffer
, buflen
, fmt
, ptr
);
1140 //===========================================================================================================================
1141 // DebugSNPrintFVAList - va_list version of DebugSNPrintF. See DebugSNPrintF for more info.
1142 //===========================================================================================================================
1144 DEBUG_EXPORT
size_t DebugSNPrintFVAList(char *sbuffer
, size_t buflen
, const char *fmt
, va_list arg
)
1146 static const struct DebugSNPrintF_format
1148 unsigned leftJustify
: 1;
1149 unsigned forceSign
: 1;
1150 unsigned zeroPad
: 1;
1151 unsigned havePrecision
: 1;
1155 char sign
; // +, - or space
1156 unsigned int fieldWidth
;
1157 unsigned int precision
;
1158 } DebugSNPrintF_format_default
= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1160 size_t nwritten
= 0;
1162 if (buflen
== 0) return(0);
1163 buflen
--; // Pre-reserve one space in the buffer for the terminating nul
1164 if (buflen
== 0) goto exit
;
1166 for (c
= *fmt
; c
!= 0; c
= *++fmt
)
1170 *sbuffer
++ = (char)c
;
1171 if (++nwritten
>= buflen
) goto exit
;
1176 // The mDNS Vsprintf Argument Conversion Buffer is used as a temporary holding area for
1177 // generating decimal numbers, hexdecimal numbers, IP addresses, domain name strings, etc.
1178 // The size needs to be enough for a 256-byte domain name plus some error text.
1179 #define mDNS_VACB_Size 300
1180 char mDNS_VACB
[mDNS_VACB_Size
];
1181 #define mDNS_VACB_Lim (&mDNS_VACB[mDNS_VACB_Size])
1182 #define mDNS_VACB_Remain(s) ((size_t)(mDNS_VACB_Lim - s))
1183 char *s
= mDNS_VACB_Lim
;
1184 const char *digits
= "0123456789ABCDEF";
1185 struct DebugSNPrintF_format F
= DebugSNPrintF_format_default
;
1187 for(;;) // decode flags
1190 if (c
== '-') F
.leftJustify
= 1;
1191 else if (c
== '+') F
.forceSign
= 1;
1192 else if (c
== ' ') F
.sign
= ' ';
1193 else if (c
== '#') F
.altForm
++;
1194 else if (c
== '0') F
.zeroPad
= 1;
1198 if (c
== '*') // decode field width
1200 int f
= va_arg(arg
, int);
1201 if (f
< 0) { f
= -f
; F
.leftJustify
= 1; }
1202 F
.fieldWidth
= (unsigned int)f
;
1207 for (; c
>= '0' && c
<= '9'; c
= *++fmt
)
1208 F
.fieldWidth
= (10 * F
.fieldWidth
) + (c
- '0');
1211 if (c
== '.') // decode precision
1213 if ((c
= *++fmt
) == '*')
1214 { F
.precision
= va_arg(arg
, unsigned int); c
= *++fmt
; }
1215 else for (; c
>= '0' && c
<= '9'; c
= *++fmt
)
1216 F
.precision
= (10 * F
.precision
) + (c
- '0');
1217 F
.havePrecision
= 1;
1220 if (F
.leftJustify
) F
.zeroPad
= 0;
1223 switch (c
) // perform appropriate conversion
1225 #if TYPE_LONGLONG_NATIVE
1226 unsigned_long_long_compat n
;
1227 unsigned_long_long_compat base
;
1232 case 'h': F
.hSize
= 1; c
= *++fmt
; goto conv
;
1233 case 'l': // fall through
1234 case 'L': F
.lSize
++; c
= *++fmt
; goto conv
;
1236 case 'i': base
= 10;
1238 case 'u': base
= 10;
1244 case 'p': n
= va_arg(arg
, uintptr_t);
1245 F
.havePrecision
= 1;
1246 F
.precision
= (sizeof(uintptr_t) == 4) ? 8 : 16;
1251 case 'x': digits
= "0123456789abcdef";
1252 case 'X': base
= 16;
1255 #if TYPE_LONGLONG_NATIVE
1256 if (F
.lSize
== 1) n
= (unsigned_long_long_compat
)va_arg(arg
, long);
1257 else if (F
.lSize
== 2) n
= (unsigned_long_long_compat
)va_arg(arg
, long_long_compat
);
1258 else n
= (unsigned_long_long_compat
)va_arg(arg
, int);
1260 if (F
.lSize
== 1) n
= (unsigned long)va_arg(arg
, long);
1261 else if (F
.lSize
== 2) goto exit
;
1262 else n
= (unsigned long)va_arg(arg
, int);
1264 if (F
.hSize
) n
= (short) n
;
1265 #if TYPE_LONGLONG_NATIVE
1266 if ((long_long_compat
) n
< 0) { n
= (unsigned_long_long_compat
)-(long_long_compat
)n
; F
.sign
= '-'; }
1268 if ((long) n
< 0) { n
= (unsigned long)-(long)n
; F
.sign
= '-'; }
1270 else if (F
.forceSign
) F
.sign
= '+';
1273 notSigned
: if (F
.lSize
== 1) n
= va_arg(arg
, unsigned long);
1274 else if (F
.lSize
== 2)
1276 #if TYPE_LONGLONG_NATIVE
1277 n
= va_arg(arg
, unsigned_long_long_compat
);
1282 else n
= va_arg(arg
, unsigned int);
1283 if (F
.hSize
) n
= (unsigned short) n
;
1287 number
: if (!F
.havePrecision
)
1291 F
.precision
= F
.fieldWidth
;
1292 if (F
.altForm
) F
.precision
-= 2;
1293 if (F
.sign
) --F
.precision
;
1295 if (F
.precision
< 1) F
.precision
= 1;
1297 if (F
.precision
> mDNS_VACB_Size
- 1)
1298 F
.precision
= mDNS_VACB_Size
- 1;
1299 for (i
= 0; n
; n
/= base
, i
++) *--s
= (char)(digits
[n
% base
]);
1300 for (; i
< F
.precision
; i
++) *--s
= '0';
1301 if (F
.altForm
) { *--s
= (char)c
; *--s
= '0'; i
+= 2; }
1302 if (F
.sign
) { *--s
= F
.sign
; i
++; }
1306 unsigned char *a
= va_arg(arg
, unsigned char *);
1309 if (!a
) { static char emsg
[] = "<<NULL>>"; s
= emsg
; i
= sizeof(emsg
)-1; }
1312 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1315 #if (defined(MDNS_DEBUGMSGS))
1316 mDNSAddr
*ip
= (mDNSAddr
*)a
;
1319 case mDNSAddrType_IPv4
: F
.precision
= 4; a
= (unsigned char *)&ip
->ip
.v4
; break;
1320 case mDNSAddrType_IPv6
: F
.precision
= 16; a
= (unsigned char *)&ip
->ip
.v6
; break;
1321 default: F
.precision
= 0; break;
1324 F
.precision
= 0; // mDNSEmbeddedAPI.h not included so no mDNSAddr support
1327 else if (F
.altForm
== 2)
1330 const struct sockaddr
*sa
;
1331 unsigned char *port
;
1332 sa
= (const struct sockaddr
*)a
;
1333 switch (sa
->sa_family
)
1335 case AF_INET
: F
.precision
= 4; a
= (unsigned char*)&((const struct sockaddr_in
*)a
)->sin_addr
;
1336 port
= (unsigned char*)&((const struct sockaddr_in
*)sa
)->sin_port
;
1337 DebugSNPrintF(post
, sizeof(post
), ":%d", (port
[0] << 8) | port
[1]); break;
1339 case AF_INET6
: F
.precision
= 16; a
= (unsigned char*)&((const struct sockaddr_in6
*)a
)->sin6_addr
;
1340 pre
[0] = '['; pre
[1] = '\0';
1341 port
= (unsigned char*)&((const struct sockaddr_in6
*)sa
)->sin6_port
;
1342 DebugSNPrintF(post
, sizeof(post
), "%%%d]:%d",
1343 (int)((const struct sockaddr_in6
*)sa
)->sin6_scope_id
,
1344 (port
[0] << 8) | port
[1]); break;
1346 default: F
.precision
= 0; break;
1349 F
.precision
= 0; // socket interfaces not included so no sockaddr support
1352 switch (F
.precision
)
1354 case 4: i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "%d.%d.%d.%d%s",
1355 a
[0], a
[1], a
[2], a
[3], post
); break;
1356 case 6: i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "%02X:%02X:%02X:%02X:%02X:%02X",
1357 a
[0], a
[1], a
[2], a
[3], a
[4], a
[5]); break;
1358 case 8: i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
1359 a
[0], a
[1], a
[2], a
[3], a
[4], a
[5], a
[6], a
[7]); break;
1360 case 16: i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
),
1361 "%s%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X%s",
1362 pre
, a
[0], a
[1], a
[2], a
[3], a
[4], a
[5], a
[6], a
[7], a
[8],
1363 a
[9], a
[10], a
[11], a
[12], a
[13], a
[14], a
[15], post
); break;
1364 default: i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "%s", "<< ERROR: Must specify address size "
1365 "(i.e. %.4a=IPv4, %.6a=Ethernet, %.8a=Fibre Channel %.16a=IPv6) >>"); break;
1372 unsigned char *a
= va_arg(arg
, unsigned char *);
1373 if (!a
) { static char emsg
[] = "<<NULL>>"; s
= emsg
; i
= sizeof(emsg
)-1; }
1376 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1377 i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
1378 *((uint32_t*) &a
[0]), *((uint16_t*) &a
[4]), *((uint16_t*) &a
[6]),
1379 a
[8], a
[9], a
[10], a
[11], a
[12], a
[13], a
[14], a
[15]); break;
1384 case 'c': *--s
= (char)va_arg(arg
, int); i
= 1; break;
1386 case 'C': if (F
.lSize
) n
= va_arg(arg
, unsigned long);
1387 else n
= va_arg(arg
, unsigned int);
1388 if (F
.hSize
) n
= (unsigned short) n
;
1389 c
= (int)( n
& 0xFF); *--s
= (char)(DebugIsPrint(c
) ? c
: '^');
1390 c
= (int)((n
>> 8) & 0xFF); *--s
= (char)(DebugIsPrint(c
) ? c
: '^');
1391 c
= (int)((n
>> 16) & 0xFF); *--s
= (char)(DebugIsPrint(c
) ? c
: '^');
1392 c
= (int)((n
>> 24) & 0xFF); *--s
= (char)(DebugIsPrint(c
) ? c
: '^');
1396 case 's': s
= va_arg(arg
, char *);
1397 if (!s
) { static char emsg
[] = "<<NULL>>"; s
= emsg
; i
= sizeof(emsg
)-1; }
1398 else switch (F
.altForm
)
1401 if (F
.havePrecision
) // C string
1403 while((i
< F
.precision
) && s
[i
]) i
++;
1404 // Make sure we don't truncate in the middle of a UTF-8 character.
1405 // If the last character is part of a multi-byte UTF-8 character, back up to the start of it.
1407 while((i
> 0) && ((c
= s
[i
-1]) & 0x80)) { j
++; i
--; if((c
& 0xC0) != 0x80) break;}
1408 // If the actual count of UTF-8 characters matches the encoded UTF-8 count, add it back.
1409 if((j
> 1) && (j
<= 6))
1411 int test
= (0xFF << (8-j
)) & 0xFF;
1412 int mask
= test
| (1 << ((8-j
)-1));
1413 if((c
& mask
) == test
) i
+= j
;
1419 case 1: i
= (unsigned char) *s
++; break; // Pascal string
1420 case 2: { // DNS label-sequence name
1421 unsigned char *a
= (unsigned char *)s
;
1422 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1423 if (*a
== 0) *s
++ = '.'; // Special case for root DNS name
1426 if (*a
> 63) { s
+= DebugSNPrintF(s
, mDNS_VACB_Remain(s
), "<<INVALID LABEL LENGTH %u>>", *a
); break; }
1427 if (s
+ *a
>= &mDNS_VACB
[254]) { s
+= DebugSNPrintF(s
, mDNS_VACB_Remain(s
), "<<NAME TOO LONG>>"); break; }
1428 s
+= DebugSNPrintF(s
, mDNS_VACB_Remain(s
), "%#s.", a
);
1431 i
= (size_t)(s
- mDNS_VACB
);
1432 s
= mDNS_VACB
; // Reset s back to the start of the buffer
1436 if (F
.havePrecision
&& i
> F
.precision
) // Make sure we don't truncate in the middle of a UTF-8 character
1437 { i
= F
.precision
; while (i
>0 && (s
[i
] & 0xC0) == 0x80) i
--;}
1440 case 'S': { // UTF-16 string
1441 unsigned char *a
= va_arg(arg
, unsigned char *);
1442 uint16_t *u
= (uint16_t*)a
;
1443 if (!u
) { static char emsg
[] = "<<NULL>>"; s
= emsg
; i
= sizeof(emsg
)-1; }
1444 if ((!F
.havePrecision
|| F
.precision
))
1446 if ((a
[0] == 0xFE) && (a
[1] == 0xFF)) { F
.altForm
= 1; u
+= 1; a
+= 2; F
.precision
--; } // Big Endian
1447 else if ((a
[0] == 0xFF) && (a
[1] == 0xFE)) { F
.altForm
= 2; u
+= 1; a
+= 2; F
.precision
--; } // Little Endian
1449 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1452 case 0: while ((!F
.havePrecision
|| (i
< F
.precision
)) && u
[i
] && mDNS_VACB_Remain(s
)) // Host Endian
1453 { c
= u
[i
]; *s
++ = (char)(DebugIsPrint(c
) ? c
: '^'); i
++; }
1455 case 1: while ((!F
.havePrecision
|| (i
< F
.precision
)) && u
[i
] && mDNS_VACB_Remain(s
)) // Big Endian
1456 { c
= ((a
[0] << 8) | a
[1]) & 0xFF; *s
++ = (char)(DebugIsPrint(c
) ? c
: '^'); i
++; a
+= 2; }
1458 case 2: while ((!F
.havePrecision
|| (i
< F
.precision
)) && u
[i
] && mDNS_VACB_Remain(s
)) // Little Endian
1459 { c
= ((a
[1] << 8) | a
[0]) & 0xFF; *s
++ = (char)(DebugIsPrint(c
) ? c
: '^'); i
++; a
+= 2; }
1463 s
= mDNS_VACB
; // Reset s back to the start of the buffer
1467 case '@': { // Cocoa/CoreFoundation object
1470 cfObj
= (CFTypeRef
) va_arg(arg
, void *);
1471 cfStr
= (CFGetTypeID(cfObj
) == CFStringGetTypeID()) ? (CFStringRef
)CFRetain(cfObj
) : CFCopyDescription(cfObj
);
1472 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1477 range
= CFRangeMake(0, CFStringGetLength(cfStr
));
1479 CFStringGetBytes(cfStr
, range
, kCFStringEncodingUTF8
, '^', false, (UInt8
*)mDNS_VACB
, (CFIndex
)sizeof(mDNS_VACB
), &m
);
1485 i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "%s", "ERROR: <invalid CF object>" );
1488 if (F
.havePrecision
&& i
> F
.precision
) // Make sure we don't truncate in the middle of a UTF-8 character
1489 { i
= F
.precision
; while (i
>0 && (s
[i
] & 0xC0) == 0x80) i
--;}
1493 case 'm': { // Error Message
1495 if (F
.lSize
) err
= va_arg(arg
, long);
1496 else err
= va_arg(arg
, int);
1497 if (F
.hSize
) err
= (short)err
;
1498 DebugGetErrorString(err
, mDNS_VACB
, sizeof(mDNS_VACB
));
1499 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1500 for(i
=0; s
[i
]; i
++) {}
1504 case 'H': { // Hex Dump
1505 void *a
= va_arg(arg
, void *);
1506 size_t size
= (size_t)va_arg(arg
, int);
1507 size_t max
= (size_t)va_arg(arg
, int);
1509 kDebugFlagsNoAddress
| kDebugFlagsNoOffset
| kDebugFlagsNoNewLine
|
1510 kDebugFlags8BitSeparator
| kDebugFlagsNo32BitSeparator
|
1511 kDebugFlagsNo16ByteHexPad
| kDebugFlagsNoByteCount
;
1512 if (F
.altForm
== 0) flags
|= kDebugFlagsNoASCII
;
1513 size
= (max
< size
) ? max
: size
;
1514 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1515 i
= DebugHexDump(kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, a
, a
, size
, flags
, mDNS_VACB
, sizeof(mDNS_VACB
));
1519 case 'v': { // Version
1521 version
= va_arg(arg
, unsigned int);
1522 DebugNumVersionToString(version
, mDNS_VACB
);
1523 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1524 for(i
=0; s
[i
]; i
++) {}
1528 case 'n': s
= va_arg(arg
, char *);
1529 if (F
.hSize
) *(short *) s
= (short)nwritten
;
1530 else if (F
.lSize
) *(long *) s
= (long)nwritten
;
1531 else *(int *) s
= (int)nwritten
;
1534 default: s
= mDNS_VACB
;
1535 i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "<<UNKNOWN FORMAT CONVERSION CODE %%%c>>", c
);
1537 case '%': *sbuffer
++ = (char)c
;
1538 if (++nwritten
>= buflen
) goto exit
;
1542 if (i
< F
.fieldWidth
&& !F
.leftJustify
) // Pad on the left
1545 if (++nwritten
>= buflen
) goto exit
;
1546 } while (i
< --F
.fieldWidth
);
1548 if (i
> buflen
- nwritten
) // Make sure we don't truncate in the middle of a UTF-8 character
1549 { i
= buflen
- nwritten
; while (i
>0 && (s
[i
] & 0xC0) == 0x80) i
--;}
1550 for (j
=0; j
<i
; j
++) *sbuffer
++ = *s
++; // Write the converted result
1552 if (nwritten
>= buflen
) goto exit
;
1554 for (; i
< F
.fieldWidth
; i
++) // Pad on the right
1557 if (++nwritten
>= buflen
) goto exit
;
1566 //===========================================================================================================================
1567 // DebugGetErrorString
1568 //===========================================================================================================================
1570 DEBUG_EXPORT
const char * DebugGetErrorString( int_least32_t inErrorCode
, char *inBuffer
, size_t inBufferSize
)
1575 #if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
1579 switch( inErrorCode
)
1581 #define CaseErrorString( X, STR ) case X: s = STR; break
1582 #define CaseErrorStringify( X ) case X: s = # X; break
1583 #define CaseErrorStringifyHardCode( VALUE, X ) case VALUE: s = # X; break
1587 CaseErrorString( 0, "no error" );
1588 CaseErrorString( 1, "in-progress/waiting" );
1589 CaseErrorString( -1, "catch-all unknown error" );
1593 CaseErrorStringifyHardCode( -2, kACPBadRequestErr
);
1594 CaseErrorStringifyHardCode( -3, kACPNoMemoryErr
);
1595 CaseErrorStringifyHardCode( -4, kACPBadParamErr
);
1596 CaseErrorStringifyHardCode( -5, kACPNotFoundErr
);
1597 CaseErrorStringifyHardCode( -6, kACPBadChecksumErr
);
1598 CaseErrorStringifyHardCode( -7, kACPCommandNotHandledErr
);
1599 CaseErrorStringifyHardCode( -8, kACPNetworkErr
);
1600 CaseErrorStringifyHardCode( -9, kACPDuplicateCommandHandlerErr
);
1601 CaseErrorStringifyHardCode( -10, kACPUnknownPropertyErr
);
1602 CaseErrorStringifyHardCode( -11, kACPImmutablePropertyErr
);
1603 CaseErrorStringifyHardCode( -12, kACPBadPropertyValueErr
);
1604 CaseErrorStringifyHardCode( -13, kACPNoResourcesErr
);
1605 CaseErrorStringifyHardCode( -14, kACPBadOptionErr
);
1606 CaseErrorStringifyHardCode( -15, kACPBadSizeErr
);
1607 CaseErrorStringifyHardCode( -16, kACPBadPasswordErr
);
1608 CaseErrorStringifyHardCode( -17, kACPNotInitializedErr
);
1609 CaseErrorStringifyHardCode( -18, kACPNonReadablePropertyErr
);
1610 CaseErrorStringifyHardCode( -19, kACPBadVersionErr
);
1611 CaseErrorStringifyHardCode( -20, kACPBadSignatureErr
);
1612 CaseErrorStringifyHardCode( -21, kACPBadIndexErr
);
1613 CaseErrorStringifyHardCode( -22, kACPUnsupportedErr
);
1614 CaseErrorStringifyHardCode( -23, kACPInUseErr
);
1615 CaseErrorStringifyHardCode( -24, kACPParamCountErr
);
1616 CaseErrorStringifyHardCode( -25, kACPIDErr
);
1617 CaseErrorStringifyHardCode( -26, kACPFormatErr
);
1618 CaseErrorStringifyHardCode( -27, kACPUnknownUserErr
);
1619 CaseErrorStringifyHardCode( -28, kACPAccessDeniedErr
);
1620 CaseErrorStringifyHardCode( -29, kACPIncorrectFWErr
);
1622 // Common Services Errors
1624 CaseErrorStringify( kUnknownErr
);
1625 CaseErrorStringify( kOptionErr
);
1626 CaseErrorStringify( kSelectorErr
);
1627 CaseErrorStringify( kExecutionStateErr
);
1628 CaseErrorStringify( kPathErr
);
1629 CaseErrorStringify( kParamErr
);
1630 CaseErrorStringify( kParamCountErr
);
1631 CaseErrorStringify( kCommandErr
);
1632 CaseErrorStringify( kIDErr
);
1633 CaseErrorStringify( kStateErr
);
1634 CaseErrorStringify( kRangeErr
);
1635 CaseErrorStringify( kRequestErr
);
1636 CaseErrorStringify( kResponseErr
);
1637 CaseErrorStringify( kChecksumErr
);
1638 CaseErrorStringify( kNotHandledErr
);
1639 CaseErrorStringify( kVersionErr
);
1640 CaseErrorStringify( kSignatureErr
);
1641 CaseErrorStringify( kFormatErr
);
1642 CaseErrorStringify( kNotInitializedErr
);
1643 CaseErrorStringify( kAlreadyInitializedErr
);
1644 CaseErrorStringify( kNotInUseErr
);
1645 CaseErrorStringify( kInUseErr
);
1646 CaseErrorStringify( kTimeoutErr
);
1647 CaseErrorStringify( kCanceledErr
);
1648 CaseErrorStringify( kAlreadyCanceledErr
);
1649 CaseErrorStringify( kCannotCancelErr
);
1650 CaseErrorStringify( kDeletedErr
);
1651 CaseErrorStringify( kNotFoundErr
);
1652 CaseErrorStringify( kNoMemoryErr
);
1653 CaseErrorStringify( kNoResourcesErr
);
1654 CaseErrorStringify( kDuplicateErr
);
1655 CaseErrorStringify( kImmutableErr
);
1656 CaseErrorStringify( kUnsupportedDataErr
);
1657 CaseErrorStringify( kIntegrityErr
);
1658 CaseErrorStringify( kIncompatibleErr
);
1659 CaseErrorStringify( kUnsupportedErr
);
1660 CaseErrorStringify( kUnexpectedErr
);
1661 CaseErrorStringify( kValueErr
);
1662 CaseErrorStringify( kNotReadableErr
);
1663 CaseErrorStringify( kNotWritableErr
);
1664 CaseErrorStringify( kBadReferenceErr
);
1665 CaseErrorStringify( kFlagErr
);
1666 CaseErrorStringify( kMalformedErr
);
1667 CaseErrorStringify( kSizeErr
);
1668 CaseErrorStringify( kNameErr
);
1669 CaseErrorStringify( kNotReadyErr
);
1670 CaseErrorStringify( kReadErr
);
1671 CaseErrorStringify( kWriteErr
);
1672 CaseErrorStringify( kMismatchErr
);
1673 CaseErrorStringify( kDateErr
);
1674 CaseErrorStringify( kUnderrunErr
);
1675 CaseErrorStringify( kOverrunErr
);
1676 CaseErrorStringify( kEndingErr
);
1677 CaseErrorStringify( kConnectionErr
);
1678 CaseErrorStringify( kAuthenticationErr
);
1679 CaseErrorStringify( kOpenErr
);
1680 CaseErrorStringify( kTypeErr
);
1681 CaseErrorStringify( kSkipErr
);
1682 CaseErrorStringify( kNoAckErr
);
1683 CaseErrorStringify( kCollisionErr
);
1684 CaseErrorStringify( kBackoffErr
);
1685 CaseErrorStringify( kNoAddressAckErr
);
1686 CaseErrorStringify( kBusyErr
);
1687 CaseErrorStringify( kNoSpaceErr
);
1689 // mDNS/DNS-SD Errors
1691 CaseErrorStringifyHardCode( -65537, mStatus_UnknownErr
);
1692 CaseErrorStringifyHardCode( -65538, mStatus_NoSuchNameErr
);
1693 CaseErrorStringifyHardCode( -65539, mStatus_NoMemoryErr
);
1694 CaseErrorStringifyHardCode( -65540, mStatus_BadParamErr
);
1695 CaseErrorStringifyHardCode( -65541, mStatus_BadReferenceErr
);
1696 CaseErrorStringifyHardCode( -65542, mStatus_BadStateErr
);
1697 CaseErrorStringifyHardCode( -65543, mStatus_BadFlagsErr
);
1698 CaseErrorStringifyHardCode( -65544, mStatus_UnsupportedErr
);
1699 CaseErrorStringifyHardCode( -65545, mStatus_NotInitializedErr
);
1700 CaseErrorStringifyHardCode( -65546, mStatus_NoCache
);
1701 CaseErrorStringifyHardCode( -65547, mStatus_AlreadyRegistered
);
1702 CaseErrorStringifyHardCode( -65548, mStatus_NameConflict
);
1703 CaseErrorStringifyHardCode( -65549, mStatus_Invalid
);
1704 CaseErrorStringifyHardCode( -65550, mStatus_GrowCache
);
1705 CaseErrorStringifyHardCode( -65551, mStatus_Incompatible
);
1706 CaseErrorStringifyHardCode( -65552, mStatus_BadInterfaceErr
);
1707 CaseErrorStringifyHardCode( -65791, mStatus_ConfigChanged
);
1708 CaseErrorStringifyHardCode( -65792, mStatus_MemFree
);
1712 CaseErrorStringifyHardCode( -400000, kRSPUnknownErr
);
1713 CaseErrorStringifyHardCode( -400050, kRSPParamErr
);
1714 CaseErrorStringifyHardCode( -400108, kRSPNoMemoryErr
);
1715 CaseErrorStringifyHardCode( -405246, kRSPRangeErr
);
1716 CaseErrorStringifyHardCode( -409057, kRSPSizeErr
);
1717 CaseErrorStringifyHardCode( -400200, kRSPHardwareErr
);
1718 CaseErrorStringifyHardCode( -401712, kRSPTimeoutErr
);
1719 CaseErrorStringifyHardCode( -402053, kRSPUnsupportedErr
);
1720 CaseErrorStringifyHardCode( -402419, kRSPIDErr
);
1721 CaseErrorStringifyHardCode( -403165, kRSPFlagErr
);
1722 CaseErrorString( -200000, "kRSPControllerStatusBase - 0x50" );
1723 CaseErrorString( -200080, "kRSPCommandSucceededErr - 0x50" );
1724 CaseErrorString( -200001, "kRSPCommandFailedErr - 0x01" );
1725 CaseErrorString( -200051, "kRSPChecksumErr - 0x33" );
1726 CaseErrorString( -200132, "kRSPCommandTimeoutErr - 0x84" );
1727 CaseErrorString( -200034, "kRSPPasswordRequiredErr - 0x22 OBSOLETE" );
1728 CaseErrorString( -200128, "kRSPCanceledErr - 0x02 Async" );
1732 CaseErrorStringifyHardCode( -100043, kXMLNotFoundErr
);
1733 CaseErrorStringifyHardCode( -100050, kXMLParamErr
);
1734 CaseErrorStringifyHardCode( -100108, kXMLNoMemoryErr
);
1735 CaseErrorStringifyHardCode( -100206, kXMLFormatErr
);
1736 CaseErrorStringifyHardCode( -100586, kXMLNoRootElementErr
);
1737 CaseErrorStringifyHardCode( -101703, kXMLWrongDataTypeErr
);
1738 CaseErrorStringifyHardCode( -101726, kXMLKeyErr
);
1739 CaseErrorStringifyHardCode( -102053, kXMLUnsupportedErr
);
1740 CaseErrorStringifyHardCode( -102063, kXMLMissingElementErr
);
1741 CaseErrorStringifyHardCode( -103026, kXMLParseErr
);
1742 CaseErrorStringifyHardCode( -103159, kXMLBadDataErr
);
1743 CaseErrorStringifyHardCode( -103170, kXMLBadNameErr
);
1744 CaseErrorStringifyHardCode( -105246, kXMLRangeErr
);
1745 CaseErrorStringifyHardCode( -105251, kXMLUnknownElementErr
);
1746 CaseErrorStringifyHardCode( -108739, kXMLMalformedInputErr
);
1747 CaseErrorStringifyHardCode( -109057, kXMLBadSizeErr
);
1748 CaseErrorStringifyHardCode( -101730, kXMLMissingChildElementErr
);
1749 CaseErrorStringifyHardCode( -102107, kXMLMissingParentElementErr
);
1750 CaseErrorStringifyHardCode( -130587, kXMLNonRootElementErr
);
1751 CaseErrorStringifyHardCode( -102015, kXMLDateErr
);
1757 CaseErrorStringifyHardCode( 0x00002000, MACH_MSG_IPC_SPACE
);
1758 CaseErrorStringifyHardCode( 0x00001000, MACH_MSG_VM_SPACE
);
1759 CaseErrorStringifyHardCode( 0x00000800, MACH_MSG_IPC_KERNEL
);
1760 CaseErrorStringifyHardCode( 0x00000400, MACH_MSG_VM_KERNEL
);
1761 CaseErrorStringifyHardCode( 0x10000001, MACH_SEND_IN_PROGRESS
);
1762 CaseErrorStringifyHardCode( 0x10000002, MACH_SEND_INVALID_DATA
);
1763 CaseErrorStringifyHardCode( 0x10000003, MACH_SEND_INVALID_DEST
);
1764 CaseErrorStringifyHardCode( 0x10000004, MACH_SEND_TIMED_OUT
);
1765 CaseErrorStringifyHardCode( 0x10000007, MACH_SEND_INTERRUPTED
);
1766 CaseErrorStringifyHardCode( 0x10000008, MACH_SEND_MSG_TOO_SMALL
);
1767 CaseErrorStringifyHardCode( 0x10000009, MACH_SEND_INVALID_REPLY
);
1768 CaseErrorStringifyHardCode( 0x1000000A, MACH_SEND_INVALID_RIGHT
);
1769 CaseErrorStringifyHardCode( 0x1000000B, MACH_SEND_INVALID_NOTIFY
);
1770 CaseErrorStringifyHardCode( 0x1000000C, MACH_SEND_INVALID_MEMORY
);
1771 CaseErrorStringifyHardCode( 0x1000000D, MACH_SEND_NO_BUFFER
);
1772 CaseErrorStringifyHardCode( 0x1000000E, MACH_SEND_TOO_LARGE
);
1773 CaseErrorStringifyHardCode( 0x1000000F, MACH_SEND_INVALID_TYPE
);
1774 CaseErrorStringifyHardCode( 0x10000010, MACH_SEND_INVALID_HEADER
);
1775 CaseErrorStringifyHardCode( 0x10000011, MACH_SEND_INVALID_TRAILER
);
1776 CaseErrorStringifyHardCode( 0x10000015, MACH_SEND_INVALID_RT_OOL_SIZE
);
1777 CaseErrorStringifyHardCode( 0x10004001, MACH_RCV_IN_PROGRESS
);
1778 CaseErrorStringifyHardCode( 0x10004002, MACH_RCV_INVALID_NAME
);
1779 CaseErrorStringifyHardCode( 0x10004003, MACH_RCV_TIMED_OUT
);
1780 CaseErrorStringifyHardCode( 0x10004004, MACH_RCV_TOO_LARGE
);
1781 CaseErrorStringifyHardCode( 0x10004005, MACH_RCV_INTERRUPTED
);
1782 CaseErrorStringifyHardCode( 0x10004006, MACH_RCV_PORT_CHANGED
);
1783 CaseErrorStringifyHardCode( 0x10004007, MACH_RCV_INVALID_NOTIFY
);
1784 CaseErrorStringifyHardCode( 0x10004008, MACH_RCV_INVALID_DATA
);
1785 CaseErrorStringifyHardCode( 0x10004009, MACH_RCV_PORT_DIED
);
1786 CaseErrorStringifyHardCode( 0x1000400A, MACH_RCV_IN_SET
);
1787 CaseErrorStringifyHardCode( 0x1000400B, MACH_RCV_HEADER_ERROR
);
1788 CaseErrorStringifyHardCode( 0x1000400C, MACH_RCV_BODY_ERROR
);
1789 CaseErrorStringifyHardCode( 0x1000400D, MACH_RCV_INVALID_TYPE
);
1790 CaseErrorStringifyHardCode( 0x1000400E, MACH_RCV_SCATTER_SMALL
);
1791 CaseErrorStringifyHardCode( 0x1000400F, MACH_RCV_INVALID_TRAILER
);
1792 CaseErrorStringifyHardCode( 0x10004011, MACH_RCV_IN_PROGRESS_TIMED
);
1794 // Mach OSReturn Errors
1796 CaseErrorStringifyHardCode( 0xDC000001, kOSReturnError
);
1797 CaseErrorStringifyHardCode( 0xDC004001, kOSMetaClassInternal
);
1798 CaseErrorStringifyHardCode( 0xDC004002, kOSMetaClassHasInstances
);
1799 CaseErrorStringifyHardCode( 0xDC004003, kOSMetaClassNoInit
);
1800 CaseErrorStringifyHardCode( 0xDC004004, kOSMetaClassNoTempData
);
1801 CaseErrorStringifyHardCode( 0xDC004005, kOSMetaClassNoDicts
);
1802 CaseErrorStringifyHardCode( 0xDC004006, kOSMetaClassNoKModSet
);
1803 CaseErrorStringifyHardCode( 0xDC004007, kOSMetaClassNoInsKModSet
);
1804 CaseErrorStringifyHardCode( 0xDC004008, kOSMetaClassNoSuper
);
1805 CaseErrorStringifyHardCode( 0xDC004009, kOSMetaClassInstNoSuper
);
1806 CaseErrorStringifyHardCode( 0xDC00400A, kOSMetaClassDuplicateClass
);
1810 CaseErrorStringifyHardCode( 0xE00002BC, kIOReturnError
);
1811 CaseErrorStringifyHardCode( 0xE00002BD, kIOReturnNoMemory
);
1812 CaseErrorStringifyHardCode( 0xE00002BE, kIOReturnNoResources
);
1813 CaseErrorStringifyHardCode( 0xE00002BF, kIOReturnIPCError
);
1814 CaseErrorStringifyHardCode( 0xE00002C0, kIOReturnNoDevice
);
1815 CaseErrorStringifyHardCode( 0xE00002C1, kIOReturnNotPrivileged
);
1816 CaseErrorStringifyHardCode( 0xE00002C2, kIOReturnBadArgument
);
1817 CaseErrorStringifyHardCode( 0xE00002C3, kIOReturnLockedRead
);
1818 CaseErrorStringifyHardCode( 0xE00002C4, kIOReturnLockedWrite
);
1819 CaseErrorStringifyHardCode( 0xE00002C5, kIOReturnExclusiveAccess
);
1820 CaseErrorStringifyHardCode( 0xE00002C6, kIOReturnBadMessageID
);
1821 CaseErrorStringifyHardCode( 0xE00002C7, kIOReturnUnsupported
);
1822 CaseErrorStringifyHardCode( 0xE00002C8, kIOReturnVMError
);
1823 CaseErrorStringifyHardCode( 0xE00002C9, kIOReturnInternalError
);
1824 CaseErrorStringifyHardCode( 0xE00002CA, kIOReturnIOError
);
1825 CaseErrorStringifyHardCode( 0xE00002CC, kIOReturnCannotLock
);
1826 CaseErrorStringifyHardCode( 0xE00002CD, kIOReturnNotOpen
);
1827 CaseErrorStringifyHardCode( 0xE00002CE, kIOReturnNotReadable
);
1828 CaseErrorStringifyHardCode( 0xE00002CF, kIOReturnNotWritable
);
1829 CaseErrorStringifyHardCode( 0xE00002D0, kIOReturnNotAligned
);
1830 CaseErrorStringifyHardCode( 0xE00002D1, kIOReturnBadMedia
);
1831 CaseErrorStringifyHardCode( 0xE00002D2, kIOReturnStillOpen
);
1832 CaseErrorStringifyHardCode( 0xE00002D3, kIOReturnRLDError
);
1833 CaseErrorStringifyHardCode( 0xE00002D4, kIOReturnDMAError
);
1834 CaseErrorStringifyHardCode( 0xE00002D5, kIOReturnBusy
);
1835 CaseErrorStringifyHardCode( 0xE00002D6, kIOReturnTimeout
);
1836 CaseErrorStringifyHardCode( 0xE00002D7, kIOReturnOffline
);
1837 CaseErrorStringifyHardCode( 0xE00002D8, kIOReturnNotReady
);
1838 CaseErrorStringifyHardCode( 0xE00002D9, kIOReturnNotAttached
);
1839 CaseErrorStringifyHardCode( 0xE00002DA, kIOReturnNoChannels
);
1840 CaseErrorStringifyHardCode( 0xE00002DB, kIOReturnNoSpace
);
1841 CaseErrorStringifyHardCode( 0xE00002DD, kIOReturnPortExists
);
1842 CaseErrorStringifyHardCode( 0xE00002DE, kIOReturnCannotWire
);
1843 CaseErrorStringifyHardCode( 0xE00002DF, kIOReturnNoInterrupt
);
1844 CaseErrorStringifyHardCode( 0xE00002E0, kIOReturnNoFrames
);
1845 CaseErrorStringifyHardCode( 0xE00002E1, kIOReturnMessageTooLarge
);
1846 CaseErrorStringifyHardCode( 0xE00002E2, kIOReturnNotPermitted
);
1847 CaseErrorStringifyHardCode( 0xE00002E3, kIOReturnNoPower
);
1848 CaseErrorStringifyHardCode( 0xE00002E4, kIOReturnNoMedia
);
1849 CaseErrorStringifyHardCode( 0xE00002E5, kIOReturnUnformattedMedia
);
1850 CaseErrorStringifyHardCode( 0xE00002E6, kIOReturnUnsupportedMode
);
1851 CaseErrorStringifyHardCode( 0xE00002E7, kIOReturnUnderrun
);
1852 CaseErrorStringifyHardCode( 0xE00002E8, kIOReturnOverrun
);
1853 CaseErrorStringifyHardCode( 0xE00002E9, kIOReturnDeviceError
);
1854 CaseErrorStringifyHardCode( 0xE00002EA, kIOReturnNoCompletion
);
1855 CaseErrorStringifyHardCode( 0xE00002EB, kIOReturnAborted
);
1856 CaseErrorStringifyHardCode( 0xE00002EC, kIOReturnNoBandwidth
);
1857 CaseErrorStringifyHardCode( 0xE00002ED, kIOReturnNotResponding
);
1858 CaseErrorStringifyHardCode( 0xE00002EE, kIOReturnIsoTooOld
);
1859 CaseErrorStringifyHardCode( 0xE00002EF, kIOReturnIsoTooNew
);
1860 CaseErrorStringifyHardCode( 0xE00002F0, kIOReturnNotFound
);
1861 CaseErrorStringifyHardCode( 0xE0000001, kIOReturnInvalid
);
1863 // IOKit FireWire Errors
1865 CaseErrorStringifyHardCode( 0xE0008010, kIOFireWireResponseBase
);
1866 CaseErrorStringifyHardCode( 0xE0008020, kIOFireWireBusReset
);
1867 CaseErrorStringifyHardCode( 0xE0008001, kIOConfigNoEntry
);
1868 CaseErrorStringifyHardCode( 0xE0008002, kIOFireWirePending
);
1869 CaseErrorStringifyHardCode( 0xE0008003, kIOFireWireLastDCLToken
);
1870 CaseErrorStringifyHardCode( 0xE0008004, kIOFireWireConfigROMInvalid
);
1871 CaseErrorStringifyHardCode( 0xE0008005, kIOFireWireAlreadyRegistered
);
1872 CaseErrorStringifyHardCode( 0xE0008006, kIOFireWireMultipleTalkers
);
1873 CaseErrorStringifyHardCode( 0xE0008007, kIOFireWireChannelActive
);
1874 CaseErrorStringifyHardCode( 0xE0008008, kIOFireWireNoListenerOrTalker
);
1875 CaseErrorStringifyHardCode( 0xE0008009, kIOFireWireNoChannels
);
1876 CaseErrorStringifyHardCode( 0xE000800A, kIOFireWireChannelNotAvailable
);
1877 CaseErrorStringifyHardCode( 0xE000800B, kIOFireWireSeparateBus
);
1878 CaseErrorStringifyHardCode( 0xE000800C, kIOFireWireBadSelfIDs
);
1879 CaseErrorStringifyHardCode( 0xE000800D, kIOFireWireLowCableVoltage
);
1880 CaseErrorStringifyHardCode( 0xE000800E, kIOFireWireInsufficientPower
);
1881 CaseErrorStringifyHardCode( 0xE000800F, kIOFireWireOutOfTLabels
);
1882 CaseErrorStringifyHardCode( 0xE0008101, kIOFireWireBogusDCLProgram
);
1883 CaseErrorStringifyHardCode( 0xE0008102, kIOFireWireTalkingAndListening
);
1884 CaseErrorStringifyHardCode( 0xE0008103, kIOFireWireHardwareSlept
);
1885 CaseErrorStringifyHardCode( 0xE00087D0, kIOFWMessageServiceIsRequestingClose
);
1886 CaseErrorStringifyHardCode( 0xE00087D1, kIOFWMessagePowerStateChanged
);
1887 CaseErrorStringifyHardCode( 0xE00087D2, kIOFWMessageTopologyChanged
);
1891 CaseErrorStringifyHardCode( 0xE0004061, kIOUSBUnknownPipeErr
);
1892 CaseErrorStringifyHardCode( 0xE0004060, kIOUSBTooManyPipesErr
);
1893 CaseErrorStringifyHardCode( 0xE000405F, kIOUSBNoAsyncPortErr
);
1894 CaseErrorStringifyHardCode( 0xE000405E, kIOUSBNotEnoughPipesErr
);
1895 CaseErrorStringifyHardCode( 0xE000405D, kIOUSBNotEnoughPowerErr
);
1896 CaseErrorStringifyHardCode( 0xE0004057, kIOUSBEndpointNotFound
);
1897 CaseErrorStringifyHardCode( 0xE0004056, kIOUSBConfigNotFound
);
1898 CaseErrorStringifyHardCode( 0xE0004051, kIOUSBTransactionTimeout
);
1899 CaseErrorStringifyHardCode( 0xE0004050, kIOUSBTransactionReturned
);
1900 CaseErrorStringifyHardCode( 0xE000404F, kIOUSBPipeStalled
);
1901 CaseErrorStringifyHardCode( 0xE000404E, kIOUSBInterfaceNotFound
);
1902 CaseErrorStringifyHardCode( 0xE000404D, kIOUSBLowLatencyBufferNotPreviouslyAllocated
);
1903 CaseErrorStringifyHardCode( 0xE000404C, kIOUSBLowLatencyFrameListNotPreviouslyAllocated
);
1904 CaseErrorStringifyHardCode( 0xE000404B, kIOUSBHighSpeedSplitError
);
1905 CaseErrorStringifyHardCode( 0xE0004010, kIOUSBLinkErr
);
1906 CaseErrorStringifyHardCode( 0xE000400F, kIOUSBNotSent2Err
);
1907 CaseErrorStringifyHardCode( 0xE000400E, kIOUSBNotSent1Err
);
1908 CaseErrorStringifyHardCode( 0xE000400D, kIOUSBBufferUnderrunErr
);
1909 CaseErrorStringifyHardCode( 0xE000400C, kIOUSBBufferOverrunErr
);
1910 CaseErrorStringifyHardCode( 0xE000400B, kIOUSBReserved2Err
);
1911 CaseErrorStringifyHardCode( 0xE000400A, kIOUSBReserved1Err
);
1912 CaseErrorStringifyHardCode( 0xE0004007, kIOUSBWrongPIDErr
);
1913 CaseErrorStringifyHardCode( 0xE0004006, kIOUSBPIDCheckErr
);
1914 CaseErrorStringifyHardCode( 0xE0004003, kIOUSBDataToggleErr
);
1915 CaseErrorStringifyHardCode( 0xE0004002, kIOUSBBitstufErr
);
1916 CaseErrorStringifyHardCode( 0xE0004001, kIOUSBCRCErr
);
1924 #if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
1925 if( inBuffer
&& ( inBufferSize
> 0 ) )
1929 n
= FormatMessageA( FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_IGNORE_INSERTS
, NULL
, (DWORD
) inErrorCode
,
1930 MAKELANGID( LANG_NEUTRAL
, SUBLANG_DEFAULT
), buffer
, sizeof( buffer
), NULL
);
1933 // Remove any trailing CR's or LF's since some messages have them.
1935 while( ( n
> 0 ) && isspace( ( (unsigned char *) buffer
)[ n
- 1 ] ) )
1937 buffer
[ --n
] = '\0';
1946 #if ( !TARGET_API_MAC_OSX_KERNEL && !TARGET_OS_WINDOWS_CE )
1947 s
= strerror( inErrorCode
);
1951 s
= "<unknown error code>";
1957 // Copy the string to the output buffer. If no buffer is supplied or it is empty, return an empty string.
1959 if( inBuffer
&& ( inBufferSize
> 0 ) )
1962 end
= dst
+ ( inBufferSize
- 1 );
1963 while( ( ( end
- dst
) > 0 ) && ( *s
!= '\0' ) )
1973 //===========================================================================================================================
1975 //===========================================================================================================================
1981 const char * inLabel
,
1983 int inLabelMinWidth
,
1984 const char * inType
,
1986 const void * inDataStart
,
1987 const void * inData
,
1991 size_t inBufferSize
)
1993 static const char kHexChars
[] = "0123456789ABCDEF";
1994 const uint8_t * start
;
1995 const uint8_t * src
;
2001 const char * newline
;
2002 char separator
[ 8 ];
2005 DEBUG_UNUSED( inType
);
2006 DEBUG_UNUSED( inTypeSize
);
2008 // Set up the function-wide variables.
2010 if( inLabelSize
== kSizeCString
)
2012 inLabelSize
= strlen( inLabel
);
2014 start
= (const uint8_t *) inData
;
2017 end
= dst
+ inBufferSize
;
2018 offset
= (int)( (intptr_t) inData
- (intptr_t) inDataStart
);
2019 width
= ( (int) inLabelSize
> inLabelMinWidth
) ? (int) inLabelSize
: inLabelMinWidth
;
2020 newline
= ( inFlags
& kDebugFlagsNoNewLine
) ? "" : "\n";
2022 // Set up the separator string. This is used to insert spaces on subsequent "lines" when not using newlines.
2025 if( inFlags
& kDebugFlagsNoNewLine
)
2027 if( inFlags
& kDebugFlags8BitSeparator
)
2031 if( inFlags
& kDebugFlags16BitSeparator
)
2035 if( !( inFlags
& kDebugFlagsNo32BitSeparator
) )
2039 check( ( (size_t)( s
- separator
) ) < sizeof( separator
) );
2045 char prefixString
[ 32 ];
2046 char hexString
[ 64 ];
2047 char asciiString
[ 32 ];
2048 char byteCountString
[ 32 ];
2053 // If this is a label-only item (i.e. no data), print the label (accounting for prefix string spacing) and exit.
2055 if( inDataSize
== 0 )
2057 if( inLabel
&& ( inLabelSize
> 0 ) )
2060 if( !( inFlags
& kDebugFlagsNoAddress
) )
2062 width
+= 8; // "00000000"
2063 if( !( inFlags
& kDebugFlagsNoOffset
) )
2068 if( inFlags
& kDebugFlags32BitOffset
)
2070 width
+= 8; // "00000000"
2072 else if( !( inFlags
& kDebugFlagsNoOffset
) )
2074 width
+= 4; // "0000"
2079 dst
+= DebugSNPrintF( dst
, (size_t)( end
- dst
), "%*s" "%-*.*s" "%.*s" "%s",
2081 ( width
> 0 ) ? ": " : "",
2082 width
, (int) inLabelSize
, inLabel
,
2087 dst
+= DebugPrintF( inLevel
, "%*s" "%-*.*s" "%.*s" "%s",
2089 ( width
> 0 ) ? ": " : "",
2090 width
, (int) inLabelSize
, inLabel
,
2097 // Build the prefix string. It will be in one of the following formats:
2099 // 1) "00000000+0000[0000]" (address and offset)
2100 // 2) "00000000" (address only)
2101 // 3) "0000[0000]" (offset only)
2102 // 4) "" (no address or offset)
2104 // Note: If we're printing multiple "lines", but not printing newlines, a space is used to separate.
2107 if( !( inFlags
& kDebugFlagsNoAddress
) )
2109 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 28 ) & 0xF ];
2110 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 24 ) & 0xF ];
2111 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 20 ) & 0xF ];
2112 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 16 ) & 0xF ];
2113 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 12 ) & 0xF ];
2114 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 8 ) & 0xF ];
2115 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 4 ) & 0xF ];
2116 *s
++ = kHexChars
[ ( (uintptr_t) src
) & 0xF ];
2118 if( !( inFlags
& kDebugFlagsNoOffset
) )
2123 if( !( inFlags
& kDebugFlagsNoOffset
) )
2125 if( inFlags
& kDebugFlags32BitOffset
)
2127 *s
++ = kHexChars
[ ( offset
>> 28 ) & 0xF ];
2128 *s
++ = kHexChars
[ ( offset
>> 24 ) & 0xF ];
2129 *s
++ = kHexChars
[ ( offset
>> 20 ) & 0xF ];
2130 *s
++ = kHexChars
[ ( offset
>> 16 ) & 0xF ];
2132 *s
++ = kHexChars
[ ( offset
>> 12 ) & 0xF ];
2133 *s
++ = kHexChars
[ ( offset
>> 8 ) & 0xF ];
2134 *s
++ = kHexChars
[ ( offset
>> 4 ) & 0xF ];
2135 *s
++ = kHexChars
[ offset
& 0xF ];
2137 if( s
!= prefixString
)
2142 check( ( (size_t)( s
- prefixString
) ) < sizeof( prefixString
) );
2145 // Build a hex string with a optional spaces after every 1, 2, and/or 4 bytes to make it easier to read.
2146 // Optionally pads the hex string with space to fill the full 16 byte range (so it lines up).
2149 chunkSize
= ( inDataSize
< 16 ) ? inDataSize
: 16;
2150 n
= ( inFlags
& kDebugFlagsNo16ByteHexPad
) ? chunkSize
: 16;
2151 for( i
= 0; i
< n
; ++i
)
2153 if( ( inFlags
& kDebugFlags8BitSeparator
) && ( i
> 0 ) )
2157 if( ( inFlags
& kDebugFlags16BitSeparator
) && ( i
> 0 ) && ( ( i
% 2 ) == 0 ) )
2161 if( !( inFlags
& kDebugFlagsNo32BitSeparator
) && ( i
> 0 ) && ( ( i
% 4 ) == 0 ) )
2167 *s
++ = kHexChars
[ src
[ i
] >> 4 ];
2168 *s
++ = kHexChars
[ src
[ i
] & 0xF ];
2176 check( ( (size_t)( s
- hexString
) ) < sizeof( hexString
) );
2179 // Build a string with the ASCII version of the data (replaces non-printable characters with '^').
2180 // Optionally pads the string with '`' to fill the full 16 byte range (so it lines up).
2183 if( !( inFlags
& kDebugFlagsNoASCII
) )
2187 for( i
= 0; i
< n
; ++i
)
2192 if( !DebugIsPrint( c
) )
2204 check( ( (size_t)( s
- asciiString
) ) < sizeof( asciiString
) );
2208 // Build a string indicating how bytes are in the hex dump. Only printed on the first line.
2210 s
= byteCountString
;
2211 if( !( inFlags
& kDebugFlagsNoByteCount
) )
2215 s
+= DebugSNPrintF( s
, sizeof( byteCountString
), " (%d bytes)", (int) inDataSize
);
2218 check( ( (size_t)( s
- byteCountString
) ) < sizeof( byteCountString
) );
2221 // Build the entire line from all the pieces we've previously built.
2227 dst
+= DebugSNPrintF( dst
, (size_t)( end
- dst
),
2229 "%s" // Separator (only if needed)
2238 ( src
!= start
) ? separator
: "",
2240 width
, (int) inLabelSize
, inLabel
? inLabel
: "",
2241 ( width
> 0 ) ? " " : "",
2249 dst
+= DebugSNPrintF( dst
, (size_t)( end
- dst
),
2251 "%s" // Separator (only if needed)
2253 "%*s" // Label Spacing
2260 ( src
!= start
) ? separator
: "",
2263 ( width
> 0 ) ? " " : "",
2274 dst
+= DebugPrintF( inLevel
,
2276 "%s" // Separator (only if needed)
2285 ( src
!= start
) ? separator
: "",
2287 width
, (int) inLabelSize
, inLabel
,
2288 ( width
> 0 ) ? " " : "",
2296 dst
+= DebugPrintF( inLevel
,
2298 "%s" // Separator (only if needed)
2300 "%*s" // Label Spacing
2307 ( src
!= start
) ? separator
: "",
2310 ( width
> 0 ) ? " " : "",
2318 // Move to the next chunk. Exit if there is no more data.
2320 offset
+= (int) chunkSize
;
2322 inDataSize
-= chunkSize
;
2323 if( inDataSize
== 0 )
2329 // Note: The "dst - outBuffer" size calculation works even if "outBuffer" is NULL because it's all relative.
2331 return( (size_t)( dst
- outBuffer
) );
2334 //===========================================================================================================================
2335 // DebugNumVersionToString
2336 //===========================================================================================================================
2338 static char * DebugNumVersionToString( uint32_t inVersion
, char *inString
)
2349 majorRev
= (uint8_t)( ( inVersion
>> 24 ) & 0xFF );
2350 minor
= (uint8_t)( ( inVersion
>> 20 ) & 0x0F );
2351 bugFix
= (uint8_t)( ( inVersion
>> 16 ) & 0x0F );
2352 stage
= (uint8_t)( ( inVersion
>> 8 ) & 0xFF );
2353 revision
= (uint8_t)( inVersion
& 0xFF );
2355 // Convert the major, minor, and bugfix numbers.
2358 s
+= sprintf( s
, "%u", majorRev
);
2359 s
+= sprintf( s
, ".%u", minor
);
2362 s
+= sprintf( s
, ".%u", bugFix
);
2365 // Convert the version stage and non-release revision number.
2369 case kVersionStageDevelopment
:
2370 s
+= sprintf( s
, "d%u", revision
);
2373 case kVersionStageAlpha
:
2374 s
+= sprintf( s
, "a%u", revision
);
2377 case kVersionStageBeta
:
2378 s
+= sprintf( s
, "b%u", revision
);
2381 case kVersionStageFinal
:
2383 // A non-release revision of zero is a special case indicating the software is GM (at the golden master
2384 // stage) and therefore, the non-release revision should not be added to the string.
2388 s
+= sprintf( s
, "f%u", revision
);
2393 dlog( kDebugLevelError
, "invalid NumVersion stage (0x%02X)\n", stage
);
2399 //===========================================================================================================================
2401 //===========================================================================================================================
2403 DEBUG_EXPORT
uint32_t DebugTaskLevel( void )
2412 #if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
2413 //===========================================================================================================================
2414 // DebugWinEnableConsole
2415 //===========================================================================================================================
2417 #pragma warning( disable:4311 )
2419 static void DebugWinEnableConsole( void )
2421 static bool sConsoleEnabled
= false;
2427 if( sConsoleEnabled
)
2432 // Create console window.
2434 result
= AllocConsole();
2435 require_quiet( result
, exit
);
2437 // Redirect stdin to the console stdin.
2439 fileHandle
= _open_osfhandle( (long) GetStdHandle( STD_INPUT_HANDLE
), _O_TEXT
);
2441 #if ( defined( __MWERKS__ ) )
2442 file
= __handle_reopen( (unsigned long) fileHandle
, "r", stdin
);
2443 require_quiet( file
, exit
);
2445 file
= _fdopen( fileHandle
, "r" );
2446 require_quiet( file
, exit
);
2451 err
= setvbuf( stdin
, NULL
, _IONBF
, 0 );
2452 require_noerr_quiet( err
, exit
);
2454 // Redirect stdout to the console stdout.
2456 fileHandle
= _open_osfhandle( (long) GetStdHandle( STD_OUTPUT_HANDLE
), _O_TEXT
);
2458 #if ( defined( __MWERKS__ ) )
2459 file
= __handle_reopen( (unsigned long) fileHandle
, "w", stdout
);
2460 require_quiet( file
, exit
);
2462 file
= _fdopen( fileHandle
, "w" );
2463 require_quiet( file
, exit
);
2468 err
= setvbuf( stdout
, NULL
, _IONBF
, 0 );
2469 require_noerr_quiet( err
, exit
);
2471 // Redirect stderr to the console stdout.
2473 fileHandle
= _open_osfhandle( (long) GetStdHandle( STD_OUTPUT_HANDLE
), _O_TEXT
);
2475 #if ( defined( __MWERKS__ ) )
2476 file
= __handle_reopen( (unsigned long) fileHandle
, "w", stderr
);
2477 require_quiet( file
, exit
);
2479 file
= _fdopen( fileHandle
, "w" );
2480 require_quiet( file
, exit
);
2485 err
= setvbuf( stderr
, NULL
, _IONBF
, 0 );
2486 require_noerr_quiet( err
, exit
);
2488 sConsoleEnabled
= true;
2494 #pragma warning( default:4311 )
2496 #endif // TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE
2498 #if ( TARGET_OS_WIN32 )
2499 //===========================================================================================================================
2500 // DebugWinCharToTCharString
2501 //===========================================================================================================================
2504 DebugWinCharToTCharString(
2505 const char * inCharString
,
2507 TCHAR
* outTCharString
,
2508 size_t inTCharCountMax
,
2509 size_t * outTCharCount
)
2515 if( inCharCount
== kSizeCString
)
2517 inCharCount
= strlen( inCharString
);
2520 dst
= outTCharString
;
2521 if( inTCharCountMax
> 0 )
2523 inTCharCountMax
-= 1;
2524 if( inTCharCountMax
> inCharCount
)
2526 inTCharCountMax
= inCharCount
;
2529 end
= dst
+ inTCharCountMax
;
2532 *dst
++ = (TCHAR
) *src
++;
2538 *outTCharCount
= (size_t)( dst
- outTCharString
);
2540 return( outTCharString
);
2546 #pragma mark == Debugging ==
2549 //===========================================================================================================================
2550 // DebugServicesTest
2551 //===========================================================================================================================
2553 DEBUG_EXPORT OSStatus
DebugServicesTest( void )
2560 0x11, 0x22, 0x33, 0x44,
2562 0x77, 0x88, 0x99, 0xAA,
2566 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
2567 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0,
2568 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71, 0x81, 0x91, 0xA1
2571 debug_initialize( kDebugOutputTypeMetaConsole
);
2575 check( 0 && "SHOULD SEE: check" );
2576 check( 1 && "SHOULD *NOT* SEE: check (valid)" );
2577 check_string( 0, "SHOULD SEE: check_string" );
2578 check_string( 1, "SHOULD *NOT* SEE: check_string (valid)" );
2579 check_noerr( -123 );
2580 check_noerr( 10038 );
2583 check_noerr_string( -6712, "SHOULD SEE: check_noerr_string" );
2584 check_noerr_string( 0, "SHOULD *NOT* SEE: check_noerr_string (valid)" );
2585 check_translated_errno( 0 >= 0 && "SHOULD *NOT* SEE", -384, -999 );
2586 check_translated_errno( -1 >= 0 && "SHOULD SEE", -384, -999 );
2587 check_translated_errno( -1 >= 0 && "SHOULD SEE", 0, -999 );
2588 check_ptr_overlap( "SHOULD *NOT* SEE" ? 10 : 0, 10, 22, 10 );
2589 check_ptr_overlap( "SHOULD SEE" ? 10 : 0, 10, 5, 10 );
2590 check_ptr_overlap( "SHOULD SEE" ? 10 : 0, 10, 12, 6 );
2591 check_ptr_overlap( "SHOULD SEE" ? 12 : 0, 6, 10, 10 );
2592 check_ptr_overlap( "SHOULD SEE" ? 12 : 0, 10, 10, 10 );
2593 check_ptr_overlap( "SHOULD *NOT* SEE" ? 22 : 0, 10, 10, 10 );
2594 check_ptr_overlap( "SHOULD *NOT* SEE" ? 10 : 0, 10, 20, 10 );
2595 check_ptr_overlap( "SHOULD *NOT* SEE" ? 20 : 0, 10, 10, 10 );
2599 require( 0 && "SHOULD SEE", require1
);
2600 { err
= kResponseErr
; goto exit
; }
2602 require( 1 && "SHOULD *NOT* SEE", require2
);
2605 { err
= kResponseErr
; goto exit
; }
2607 require_string( 0 && "SHOULD SEE", require3
, "SHOULD SEE: require_string" );
2608 { err
= kResponseErr
; goto exit
; }
2610 require_string( 1 && "SHOULD *NOT* SEE", require4
, "SHOULD *NOT* SEE: require_string (valid)" );
2613 { err
= kResponseErr
; goto exit
; }
2615 require_quiet( 0 && "SHOULD SEE", require5
);
2616 { err
= kResponseErr
; goto exit
; }
2618 require_quiet( 1 && "SHOULD *NOT* SEE", require6
);
2621 { err
= kResponseErr
; goto exit
; }
2623 require_noerr( -1, require7
);
2624 { err
= kResponseErr
; goto exit
; }
2626 require_noerr( 0, require8
);
2629 { err
= kResponseErr
; goto exit
; }
2631 require_noerr_string( -2, require9
, "SHOULD SEE: require_noerr_string");
2632 { err
= kResponseErr
; goto exit
; }
2634 require_noerr_string( 0, require10
, "SHOULD *NOT* SEE: require_noerr_string (valid)" );
2637 { err
= kResponseErr
; goto exit
; }
2639 require_noerr_action_string( -3, require11
, dlog( kDebugLevelMax
, "action 1 (expected)\n" ), "require_noerr_action_string" );
2640 { err
= kResponseErr
; goto exit
; }
2642 require_noerr_action_string( 0, require12
, dlog( kDebugLevelMax
, "action 2\n" ), "require_noerr_action_string (valid)" );
2645 { err
= kResponseErr
; goto exit
; }
2647 require_noerr_quiet( -4, require13
);
2648 { err
= kResponseErr
; goto exit
; }
2650 require_noerr_quiet( 0, require14
);
2653 { err
= kResponseErr
; goto exit
; }
2655 require_noerr_action( -5, require15
, dlog( kDebugLevelMax
, "SHOULD SEE: action 3 (expected)\n" ) );
2656 { err
= kResponseErr
; goto exit
; }
2658 require_noerr_action( 0, require16
, dlog( kDebugLevelMax
, "SHOULD *NOT* SEE: action 4\n" ) );
2661 { err
= kResponseErr
; goto exit
; }
2663 require_noerr_action_quiet( -4, require17
, dlog( kDebugLevelMax
, "SHOULD SEE: action 5 (expected)\n" ) );
2664 { err
= kResponseErr
; goto exit
; }
2666 require_noerr_action_quiet( 0, require18
, dlog( kDebugLevelMax
, "SHOULD *NOT* SEE: action 6\n" ) );
2669 { err
= kResponseErr
; goto exit
; }
2671 require_action( 0 && "SHOULD SEE", require19
, dlog( kDebugLevelMax
, "SHOULD SEE: action 7 (expected)\n" ) );
2672 { err
= kResponseErr
; goto exit
; }
2674 require_action( 1 && "SHOULD *NOT* SEE", require20
, dlog( kDebugLevelMax
, "SHOULD *NOT* SEE: action 8\n" ) );
2677 { err
= kResponseErr
; goto exit
; }
2679 require_action_quiet( 0, require21
, dlog( kDebugLevelMax
, "SHOULD SEE: action 9 (expected)\n" ) );
2680 { err
= kResponseErr
; goto exit
; }
2682 require_action_quiet( 1, require22
, dlog( kDebugLevelMax
, "SHOULD *NOT* SEE: action 10\n" ) );
2685 { err
= kResponseErr
; goto exit
; }
2687 require_action_string( 0, require23
, dlog( kDebugLevelMax
, "SHOULD SEE: action 11 (expected)\n" ), "SHOULD SEE: require_action_string" );
2688 { err
= kResponseErr
; goto exit
; }
2690 require_action_string( 1, require24
, dlog( kDebugLevelMax
, "SHOULD *NOT* SEE: action 12\n" ), "SHOULD *NOT* SEE: require_action_string" );
2693 { err
= kResponseErr
; goto exit
; }
2696 #if ( defined( __MWERKS__ ) )
2697 #if ( defined( __cplusplus ) && __option( exceptions ) )
2698 #define COMPILER_HAS_EXCEPTIONS 1
2700 #define COMPILER_HAS_EXCEPTIONS 0
2703 #if ( defined( __cplusplus ) )
2704 #define COMPILER_HAS_EXCEPTIONS 1
2706 #define COMPILER_HAS_EXCEPTIONS 0
2710 #if ( COMPILER_HAS_EXCEPTIONS )
2713 require_throw( 1 && "SHOULD *NOT* SEE" );
2714 require_throw( 0 && "SHOULD SEE" );
2720 { err
= kResponseErr
; goto exit
; }
2726 err
= translate_errno( 1 != -1, -123, -567 );
2727 require( ( err
== 0 ) && "SHOULD *NOT* SEE", exit
);
2729 err
= translate_errno( -1 != -1, -123, -567 );
2730 require( ( err
== -123 ) && "SHOULD *NOT* SEE", exit
);
2732 err
= translate_errno( -1 != -1, 0, -567 );
2733 require( ( err
== -567 ) && "SHOULD *NOT* SEE", exit
);
2737 debug_string( "debug_string" );
2741 DebugSNPrintF( s
, sizeof( s
), "%d", 1234 );
2742 require_action( strcmp( s
, "1234" ) == 0, exit
, err
= -1 );
2744 DebugSNPrintF( s
, sizeof( s
), "%X", 0x2345 );
2745 require_action( strcmp( s
, "2345" ) == 0, exit
, err
= -1 );
2747 DebugSNPrintF( s
, sizeof( s
), "%#s", "\05test" );
2748 require_action( strcmp( s
, "test" ) == 0, exit
, err
= -1 );
2750 DebugSNPrintF( s
, sizeof( s
), "%##s", "\03www\05apple\03com" );
2751 require_action( strcmp( s
, "www.apple.com." ) == 0, exit
, err
= -1 );
2753 DebugSNPrintF( s
, sizeof( s
), "%ld", (long) INT32_C( 2147483647 ) );
2754 require_action( strcmp( s
, "2147483647" ) == 0, exit
, err
= -1 );
2756 DebugSNPrintF( s
, sizeof( s
), "%lu", (unsigned long) UINT32_C( 4294967295 ) );
2757 require_action( strcmp( s
, "4294967295" ) == 0, exit
, err
= -1 );
2759 #if ( TYPE_LONGLONG_NATIVE )
2760 DebugSNPrintF( s
, sizeof( s
), "%lld", (long_long_compat
) INT64_C( 9223372036854775807 ) );
2761 require_action( strcmp( s
, "9223372036854775807" ) == 0, exit
, err
= -1 );
2763 DebugSNPrintF( s
, sizeof( s
), "%lld", (long_long_compat
) INT64_C( -9223372036854775807 ) );
2764 require_action( strcmp( s
, "-9223372036854775807" ) == 0, exit
, err
= -1 );
2766 DebugSNPrintF( s
, sizeof( s
), "%llu", (unsigned_long_long_compat
) UINT64_C( 18446744073709551615 ) );
2767 require_action( strcmp( s
, "18446744073709551615" ) == 0, exit
, err
= -1 );
2770 DebugSNPrintF( s
, sizeof( s
), "%lb", (unsigned long) binary_32( 01111011, 01111011, 01111011, 01111011 ) );
2771 require_action( strcmp( s
, "1111011011110110111101101111011" ) == 0, exit
, err
= -1 );
2773 DebugSNPrintF( s
, sizeof( s
), "%C", 0x41624364 ); // 'AbCd'
2774 require_action( strcmp( s
, "AbCd" ) == 0, exit
, err
= -1 );
2776 #if ( defined( MDNS_DEBUGMSGS ) )
2780 memset( &maddr
, 0, sizeof( maddr
) );
2781 maddr
.type
= mDNSAddrType_IPv4
;
2782 maddr
.ip
.v4
.b
[ 0 ] = 127;
2783 maddr
.ip
.v4
.b
[ 1 ] = 0;
2784 maddr
.ip
.v4
.b
[ 2 ] = 0;
2785 maddr
.ip
.v4
.b
[ 3 ] = 1;
2786 DebugSNPrintF( s
, sizeof( s
), "%#a", &maddr
);
2787 require_action( strcmp( s
, "127.0.0.1" ) == 0, exit
, err
= -1 );
2789 memset( &maddr
, 0, sizeof( maddr
) );
2790 maddr
.type
= mDNSAddrType_IPv6
;
2791 maddr
.ip
.v6
.b
[ 0 ] = 0xFE;
2792 maddr
.ip
.v6
.b
[ 1 ] = 0x80;
2793 maddr
.ip
.v6
.b
[ 15 ] = 0x01;
2794 DebugSNPrintF( s
, sizeof( s
), "%#a", &maddr
);
2795 require_action( strcmp( s
, "FE80:0000:0000:0000:0000:0000:0000:0001" ) == 0, exit
, err
= -1 );
2801 struct sockaddr_in sa4
;
2803 memset( &sa4
, 0, sizeof( sa4
) );
2804 sa4
.sin_family
= AF_INET
;
2805 p
= (uint8_t *) &sa4
.sin_port
;
2806 p
[ 0 ] = (uint8_t)( ( 80 >> 8 ) & 0xFF );
2807 p
[ 1 ] = (uint8_t)( 80 & 0xFF );
2808 p
= (uint8_t *) &sa4
.sin_addr
.s_addr
;
2809 p
[ 0 ] = (uint8_t)( ( INADDR_LOOPBACK
>> 24 ) & 0xFF );
2810 p
[ 1 ] = (uint8_t)( ( INADDR_LOOPBACK
>> 16 ) & 0xFF );
2811 p
[ 2 ] = (uint8_t)( ( INADDR_LOOPBACK
>> 8 ) & 0xFF );
2812 p
[ 3 ] = (uint8_t)( INADDR_LOOPBACK
& 0xFF );
2813 DebugSNPrintF( s
, sizeof( s
), "%##a", &sa4
);
2814 require_action( strcmp( s
, "127.0.0.1:80" ) == 0, exit
, err
= -1 );
2820 struct sockaddr_in6 sa6
;
2822 memset( &sa6
, 0, sizeof( sa6
) );
2823 sa6
.sin6_family
= AF_INET6
;
2824 p
= (uint8_t *) &sa6
.sin6_port
;
2825 p
[ 0 ] = (uint8_t)( ( 80 >> 8 ) & 0xFF );
2826 p
[ 1 ] = (uint8_t)( 80 & 0xFF );
2827 sa6
.sin6_addr
.s6_addr
[ 0 ] = 0xFE;
2828 sa6
.sin6_addr
.s6_addr
[ 1 ] = 0x80;
2829 sa6
.sin6_addr
.s6_addr
[ 15 ] = 0x01;
2830 sa6
.sin6_scope_id
= 2;
2831 DebugSNPrintF( s
, sizeof( s
), "%##a", &sa6
);
2832 require_action( strcmp( s
, "[FE80:0000:0000:0000:0000:0000:0000:0001%2]:80" ) == 0, exit
, err
= -1 );
2838 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "tes" );
2839 require_action( strcmp( s
, "tes" ) == 0, exit
, err
= kResponseErr
);
2841 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "test" );
2842 require_action( strcmp( s
, "test" ) == 0, exit
, err
= kResponseErr
);
2844 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "testing" );
2845 require_action( strcmp( s
, "test" ) == 0, exit
, err
= kResponseErr
);
2847 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "te\xC3\xA9" );
2848 require_action( strcmp( s
, "te\xC3\xA9" ) == 0, exit
, err
= kResponseErr
);
2850 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "te\xC3\xA9ing" );
2851 require_action( strcmp( s
, "te\xC3\xA9" ) == 0, exit
, err
= kResponseErr
);
2853 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "tes\xC3\xA9ing" );
2854 require_action( strcmp( s
, "tes" ) == 0, exit
, err
= kResponseErr
);
2856 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "t\xed\x9f\xbf" );
2857 require_action( strcmp( s
, "t\xed\x9f\xbf" ) == 0, exit
, err
= kResponseErr
);
2859 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "t\xed\x9f\xbfing" );
2860 require_action( strcmp( s
, "t\xed\x9f\xbf" ) == 0, exit
, err
= kResponseErr
);
2862 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "te\xed\x9f\xbf" );
2863 require_action( strcmp( s
, "te" ) == 0, exit
, err
= kResponseErr
);
2865 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "te\xed\x9f\xbfing" );
2866 require_action( strcmp( s
, "te" ) == 0, exit
, err
= kResponseErr
);
2868 DebugSNPrintF(s
, sizeof(s
), "%.*s", 7, "te\xC3\xA9\xed\x9f\xbfing" );
2869 require_action( strcmp( s
, "te\xC3\xA9\xed\x9f\xbf" ) == 0, exit
, err
= kResponseErr
);
2871 DebugSNPrintF(s
, sizeof(s
), "%.*s", 6, "te\xC3\xA9\xed\x9f\xbfing" );
2872 require_action( strcmp( s
, "te\xC3\xA9" ) == 0, exit
, err
= kResponseErr
);
2874 DebugSNPrintF(s
, sizeof(s
), "%.*s", 5, "te\xC3\xA9\xed\x9f\xbfing" );
2875 require_action( strcmp( s
, "te\xC3\xA9" ) == 0, exit
, err
= kResponseErr
);
2877 #if ( TARGET_RT_BIG_ENDIAN )
2878 DebugSNPrintF( s
, sizeof( s
), "%S", "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" );
2879 require_action( strcmp( s
, "abcd" ) == 0, exit
, err
= -1 );
2881 DebugSNPrintF( s
, sizeof( s
), "%S", "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" "\x00" );
2882 require_action( strcmp( s
, "abcd" ) == 0, exit
, err
= -1 );
2885 DebugSNPrintF( s
, sizeof( s
), "%S",
2886 "\xFE\xFF" "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" ); // Big Endian BOM
2887 require_action( strcmp( s
, "abcd" ) == 0, exit
, err
= -1 );
2889 DebugSNPrintF( s
, sizeof( s
), "%S",
2890 "\xFF\xFE" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" "\x00" ); // Little Endian BOM
2891 require_action( strcmp( s
, "abcd" ) == 0, exit
, err
= -1 );
2893 DebugSNPrintF( s
, sizeof( s
), "%#S", "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" ); // Big Endian
2894 require_action( strcmp( s
, "abcd" ) == 0, exit
, err
= -1 );
2896 DebugSNPrintF( s
, sizeof( s
), "%##S", "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" "\x00" ); // Little Endian
2897 require_action( strcmp( s
, "abcd" ) == 0, exit
, err
= -1 );
2899 DebugSNPrintF( s
, sizeof( s
), "%.*S",
2900 4, "\xFE\xFF" "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" ); // Big Endian BOM
2901 require_action( strcmp( s
, "abc" ) == 0, exit
, err
= -1 );
2903 DebugSNPrintF( s
, sizeof( s
), "%.*S",
2904 4, "\xFF\xFE" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" ); // Little Endian BOM
2905 require_action( strcmp( s
, "abc" ) == 0, exit
, err
= -1 );
2907 #if ( TARGET_RT_BIG_ENDIAN )
2908 DebugSNPrintF( s
, sizeof( s
), "%.*S", 3, "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" );
2909 require_action( strcmp( s
, "abc" ) == 0, exit
, err
= -1 );
2911 DebugSNPrintF( s
, sizeof( s
), "%.*S", 3, "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" );
2912 require_action( strcmp( s
, "abc" ) == 0, exit
, err
= -1 );
2915 DebugSNPrintF( s
, sizeof( s
), "%#.*S", 3, "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" ); // Big Endian
2916 require_action( strcmp( s
, "abc" ) == 0, exit
, err
= -1 );
2918 DebugSNPrintF( s
, sizeof( s
), "%##.*S", 3, "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" ); // Little Endian
2919 require_action( strcmp( s
, "abc" ) == 0, exit
, err
= -1 );
2923 DebugSNPrintF( s
, sizeof( s
), "%U", "\x10\xb8\xa7\x6b" "\xad\x9d" "\xd1\x11" "\x80\xb4" "\x00\xc0\x4f\xd4\x30\xc8" );
2924 require_action( strcmp( s
, "6ba7b810-9dad-11d1-80b4-00c04fd430c8" ) == 0, exit
, err
= -1 );
2926 DebugSNPrintF( s
, sizeof( s
), "%m", 0 );
2927 require_action( strcmp( s
, "no error" ) == 0, exit
, err
= -1 );
2929 DebugSNPrintF( s
, sizeof( s
), "%lm", (long) 0 );
2930 require_action( strcmp( s
, "no error" ) == 0, exit
, err
= -1 );
2932 DebugSNPrintF( s
, sizeof( s
), "\"%H\"", "\x6b\xa7\xb8\x10\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8", 16, 16 );
2933 DebugPrintF( kDebugLevelMax
, "%s\n\n", s
);
2935 DebugSNPrintF( s
, sizeof( s
), "\"%H\"",
2936 "\x6b\xa7\xb8\x10\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8"
2937 "\x6b\xa7\xb8\x10\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8",
2939 DebugPrintF( kDebugLevelMax
, "%s\n\n", s
);
2941 DebugSNPrintF( s
, sizeof( s
), "\"%H\"", "\x6b\xa7", 2, 2 );
2942 DebugPrintF( kDebugLevelMax
, "%s\n\n", s
);
2947 DebugHexDump( kDebugLevelMax
, 0, "My Label", kSizeCString
, 0, NULL
, 0, data
, data
, sizeof( data
),
2948 kDebugFlagsNone
, s
, sizeof( s
) );
2949 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
2952 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
),
2953 kDebugFlagsNoAddress
| kDebugFlagsNoOffset
, s
, sizeof( s
) );
2954 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
2957 DebugHexDump( kDebugLevelMax
, 0, "My Label", kSizeCString
, 0, NULL
, 0, data
, data
, sizeof( data
),
2958 kDebugFlagsNoAddress
| kDebugFlagsNoOffset
, s
, sizeof( s
) );
2959 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
2962 DebugHexDump( kDebugLevelMax
, 0, "My Label", kSizeCString
, 0, NULL
, 0, data
, data
, sizeof( data
),
2963 kDebugFlagsNoAddress
, s
, sizeof( s
) );
2964 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
2967 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
),
2968 kDebugFlagsNoOffset
, s
, sizeof( s
) );
2969 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
2972 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
),
2973 kDebugFlagsNoAddress
, s
, sizeof( s
) );
2974 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
2977 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
),
2978 kDebugFlagsNoOffset
, s
, sizeof( s
) );
2979 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
2982 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
),
2983 kDebugFlagsNoByteCount
, s
, sizeof( s
) );
2984 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
2987 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, "\x41\x62\x43\x64", "\x41\x62\x43\x64", 4, // 'AbCd'
2988 kDebugFlagsNoAddress
| kDebugFlagsNoOffset
| kDebugFlagsNoNewLine
|
2989 kDebugFlagsNo32BitSeparator
| kDebugFlagsNo16ByteHexPad
| kDebugFlagsNoByteCount
,
2991 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
2994 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
),
2995 kDebugFlagsNoAddress
| kDebugFlagsNoOffset
| kDebugFlagsNoASCII
| kDebugFlagsNoNewLine
|
2996 kDebugFlags16BitSeparator
| kDebugFlagsNo32BitSeparator
|
2997 kDebugFlagsNo16ByteHexPad
| kDebugFlagsNoByteCount
, s
, sizeof( s
) );
2998 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3001 DebugHexDump( kDebugLevelMax
, 8, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
), kDebugFlagsNone
, s
, sizeof( s
) );
3002 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3006 dlog( kDebugLevelNotice
, "dlog\n" );
3007 dlog( kDebugLevelNotice
, "dlog integer: %d\n", 123 );
3008 dlog( kDebugLevelNotice
, "dlog string: \"%s\"\n", "test string" );
3009 dlogmem( kDebugLevelNotice
, data
, sizeof( data
) );
3013 DebugPrintF( kDebugLevelMax
, "\n\nALL TESTS DONE\n\n" );
3019 DebugPrintF( kDebugLevelMax
, "\n\n### TEST FAILED ###\n\n" );