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 ==
34 #include "CommonServices.h"
36 #include "DebugServices.h"
40 #if ( TARGET_OS_VXWORKS )
44 #if ( TARGET_OS_WIN32 )
47 #if ( !TARGET_OS_WINDOWS_CE )
53 #if ( DEBUG_IDEBUG_ENABLED && TARGET_API_MAC_OSX_KERNEL )
54 #include <IOKit/IOLib.h>
57 // If MDNS_DEBUGMSGS is defined (even if defined 0), it is aware of mDNS and it is probably safe to include mDNSEmbeddedAPI.h.
58 #if ( defined( MDNS_DEBUGMSGS ) )
59 #include "mDNSEmbeddedAPI.h"
63 #pragma mark == Macros ==
68 #define DebugIsPrint( C ) ( ( ( C ) >= 0x20 ) && ( ( C ) <= 0x7E ) )
71 #pragma mark == Prototypes ==
76 static OSStatus
DebugPrint( DebugLevel inLevel
, char *inData
, size_t inSize
);
79 #if ( DEBUG_FPRINTF_ENABLED )
80 static OSStatus
DebugFPrintFInit( DebugOutputTypeFlags inFlags
, const char *inFilename
);
81 static void DebugFPrintFPrint( char *inData
, size_t inSize
);
84 // iDebug (Mac OS X user and kernel)
85 #if ( DEBUG_IDEBUG_ENABLED )
86 static OSStatus
DebugiDebugInit( void );
87 static void DebugiDebugPrint( char *inData
, size_t inSize
);
90 // kprintf (Mac OS X Kernel)
91 #if ( DEBUG_KPRINTF_ENABLED )
92 static void DebugKPrintFPrint( char *inData
, size_t inSize
);
95 // Mac OS X IOLog (Mac OS X Kernel)
96 #if ( DEBUG_MAC_OS_X_IOLOG_ENABLED )
97 static void DebugMacOSXIOLogPrint( char *inData
, size_t inSize
);
101 #if ( TARGET_OS_MAC )
102 static OSStatus
DebugMacOSXLogInit( void );
103 static void DebugMacOSXLogPrint( char *inData
, size_t inSize
);
107 #if ( TARGET_OS_WIN32 )
108 static void DebugWindowsDebuggerPrint( char *inData
, size_t inSize
);
112 #if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
113 static OSStatus
DebugWindowsEventLogInit( const char *inName
, HMODULE inModule
);
114 static void DebugWindowsEventLogPrint( DebugLevel inLevel
, char *inData
, size_t inSize
);
118 #if ( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
120 DebugAssertOutputHandler(
121 OSType inComponentSignature
,
123 const char * inAssertionString
,
124 const char * inExceptionString
,
125 const char * inErrorString
,
126 const char * inFileName
,
129 ConstStr255Param inOutputMsg
);
133 static char * DebugNumVersionToString( uint32_t inVersion
, char *inString
);
135 #if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
136 static void DebugWinEnableConsole( void );
139 #if ( TARGET_OS_WIN32 )
141 DebugWinCharToTCharString(
142 const char * inCharString
,
144 TCHAR
* outTCharString
,
145 size_t inTCharCountMax
,
146 size_t * outTCharCount
);
150 #pragma mark == Globals ==
155 #if ( TARGET_OS_VXWORKS )
156 // TCP States for inetstatShow.
158 extern char ** pTcpstates
; // defined in tcpLib.c
160 const char * kDebugTCPStates
[] =
165 "(3) TCPS_SYN_RECEIVED",
166 "(4) TCPS_ESTABLISHED",
167 "(5) TCPS_CLOSE_WAIT",
168 "(6) TCPS_FIN_WAIT_1",
171 "(9) TCPS_FIN_WAIT_2",
172 "(10) TCPS_TIME_WAIT",
177 static bool gDebugInitialized
= false;
178 static DebugOutputType gDebugOutputType
= kDebugOutputTypeNone
;
179 static DebugLevel gDebugPrintLevelMin
= kDebugLevelInfo
;
180 static DebugLevel gDebugPrintLevelMax
= kDebugLevelMax
;
181 static DebugLevel gDebugBreakLevel
= kDebugLevelAssert
;
182 #if ( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
183 static DebugAssertOutputHandlerUPP gDebugAssertOutputHandlerUPP
= NULL
;
187 static DebugOutputFunctionPtr gDebugCustomOutputFunction
= NULL
;
188 static void * gDebugCustomOutputContext
= NULL
;
192 #if ( DEBUG_FPRINTF_ENABLED )
193 static FILE * gDebugFPrintFFile
= NULL
;
197 #if ( TARGET_OS_MAC )
198 typedef int ( *DebugMacOSXLogFunctionPtr
)( const char *inFormat
, ... );
200 static DebugMacOSXLogFunctionPtr gDebugMacOSXLogFunction
= NULL
;
204 #if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
205 static HANDLE gDebugWindowsEventLogEventSource
= NULL
;
210 #pragma mark == General ==
215 DEBUG_EXPORT OSStatus
DebugInitialize( DebugOutputType inType
, ... )
218 DebugOutputType type
;
221 va_start( args
, inType
);
223 #if ( TARGET_OS_VXWORKS )
224 // Set up the TCP state strings if they are not already set up by VxWorks (normally not set up for some reason).
228 pTcpstates
= (char **) kDebugTCPStates
;
232 // Set up DebugLib stuff (if building with Debugging.h).
234 #if ( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
235 if( !gDebugAssertOutputHandlerUPP
)
237 gDebugAssertOutputHandlerUPP
= NewDebugAssertOutputHandlerUPP( DebugAssertOutputHandler
);
238 check( gDebugAssertOutputHandlerUPP
);
239 if( gDebugAssertOutputHandlerUPP
)
241 InstallDebugAssertOutputHandler( gDebugAssertOutputHandlerUPP
);
246 // Pre-process meta-output kind to pick an appropriate output kind for the platform.
249 if( type
== kDebugOutputTypeMetaConsole
)
251 #if ( TARGET_OS_MAC )
252 type
= kDebugOutputTypeMacOSXLog
;
253 #elif ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
254 #if ( DEBUG_FPRINTF_ENABLED )
255 type
= kDebugOutputTypeFPrintF
;
257 type
= kDebugOutputTypeWindowsDebugger
;
259 #elif ( TARGET_API_MAC_OSX_KERNEL )
260 #if ( DEBUG_MAC_OS_X_IOLOG_ENABLED )
261 type
= kDebugOutputTypeMacOSXIOLog
;
262 #elif ( DEBUG_IDEBUG_ENABLED )
263 type
= kDebugOutputTypeiDebug
;
264 #elif ( DEBUG_KPRINTF_ENABLED )
265 type
= kDebugOutputTypeKPrintF
;
267 #elif ( TARGET_OS_VXWORKS )
268 #if ( DEBUG_FPRINTF_ENABLED )
269 type
= kDebugOutputTypeFPrintF
;
271 #error target is VxWorks, but fprintf output is disabled
274 #if ( DEBUG_FPRINTF_ENABLED )
275 type
= kDebugOutputTypeFPrintF
;
280 // Process output kind
281 gDebugOutputType
= type
;
284 case kDebugOutputTypeNone
:
288 case kDebugOutputTypeCustom
:
289 gDebugCustomOutputFunction
= va_arg( args
, DebugOutputFunctionPtr
);
290 gDebugCustomOutputContext
= va_arg( args
, void * );
294 #if ( DEBUG_FPRINTF_ENABLED )
295 case kDebugOutputTypeFPrintF
:
296 if( inType
== kDebugOutputTypeMetaConsole
)
298 err
= DebugFPrintFInit( kDebugOutputTypeFlagsStdErr
, NULL
);
302 DebugOutputTypeFlags flags
;
303 const char * filename
;
305 flags
= (DebugOutputTypeFlags
) va_arg( args
, unsigned int );
306 if( ( flags
& kDebugOutputTypeFlagsTypeMask
) == kDebugOutputTypeFlagsFile
)
308 filename
= va_arg( args
, const char * );
314 err
= DebugFPrintFInit( flags
, filename
);
319 #if ( DEBUG_IDEBUG_ENABLED )
320 case kDebugOutputTypeiDebug
:
321 err
= DebugiDebugInit();
325 #if ( DEBUG_KPRINTF_ENABLED )
326 case kDebugOutputTypeKPrintF
:
331 #if ( DEBUG_MAC_OS_X_IOLOG_ENABLED )
332 case kDebugOutputTypeMacOSXIOLog
:
337 #if ( TARGET_OS_MAC )
338 case kDebugOutputTypeMacOSXLog
:
339 err
= DebugMacOSXLogInit();
343 #if ( TARGET_OS_WIN32 )
344 case kDebugOutputTypeWindowsDebugger
:
349 #if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
350 case kDebugOutputTypeWindowsEventLog
:
355 name
= va_arg( args
, const char * );
356 module
= va_arg( args
, HMODULE
);
357 err
= DebugWindowsEventLogInit( name
, module
);
366 gDebugInitialized
= true;
375 DEBUG_EXPORT
void DebugFinalize( void )
377 #if ( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
378 check( gDebugAssertOutputHandlerUPP
);
379 if( gDebugAssertOutputHandlerUPP
)
381 InstallDebugAssertOutputHandler( NULL
);
382 DisposeDebugAssertOutputHandlerUPP( gDebugAssertOutputHandlerUPP
);
383 gDebugAssertOutputHandlerUPP
= NULL
;
390 DEBUG_EXPORT OSStatus
DebugGetProperty( DebugPropertyTag inTag
, ... )
396 va_start( args
, inTag
);
399 case kDebugPropertyTagPrintLevelMin
:
400 level
= va_arg( args
, DebugLevel
* );
401 *level
= gDebugPrintLevelMin
;
405 case kDebugPropertyTagPrintLevelMax
:
406 level
= va_arg( args
, DebugLevel
* );
407 *level
= gDebugPrintLevelMax
;
411 case kDebugPropertyTagBreakLevel
:
412 level
= va_arg( args
, DebugLevel
* );
413 *level
= gDebugBreakLevel
;
418 err
= kUnsupportedErr
;
427 DEBUG_EXPORT OSStatus
DebugSetProperty( DebugPropertyTag inTag
, ... )
433 va_start( args
, inTag
);
436 case kDebugPropertyTagPrintLevelMin
:
437 level
= va_arg( args
, DebugLevel
);
438 gDebugPrintLevelMin
= level
;
442 case kDebugPropertyTagPrintLevelMax
:
443 level
= va_arg( args
, DebugLevel
);
444 gDebugPrintLevelMax
= level
;
448 case kDebugPropertyTagBreakLevel
:
449 level
= va_arg( args
, DebugLevel
);
450 gDebugBreakLevel
= level
;
455 err
= kUnsupportedErr
;
464 #pragma mark == Output ==
469 DEBUG_EXPORT
size_t DebugPrintF( DebugLevel inLevel
, const char *inFormat
, ... )
474 // Skip if the level is not in the enabled range..
476 if( ( inLevel
< gDebugPrintLevelMin
) || ( inLevel
> gDebugPrintLevelMax
) )
482 va_start( args
, inFormat
);
483 n
= DebugPrintFVAList( inLevel
, inFormat
, args
);
492 DEBUG_EXPORT
size_t DebugPrintFVAList( DebugLevel inLevel
, const char *inFormat
, va_list inArgs
)
497 // Skip if the level is not in the enabled range..
499 if( ( inLevel
< gDebugPrintLevelMin
) || ( inLevel
> gDebugPrintLevelMax
) )
505 n
= DebugSNPrintFVAList( buffer
, sizeof( buffer
), inFormat
, inArgs
);
506 DebugPrint( inLevel
, buffer
, (size_t) n
);
514 static OSStatus
DebugPrint( DebugLevel inLevel
, char *inData
, size_t inSize
)
518 // Skip if the level is not in the enabled range..
520 if( ( inLevel
< gDebugPrintLevelMin
) || ( inLevel
> gDebugPrintLevelMax
) )
526 // Printing is not safe at interrupt time so check for this and warn with an interrupt safe mechanism (if available).
528 if( DebugTaskLevel() & kDebugInterruptLevelMask
)
530 #if ( TARGET_OS_VXWORKS )
531 logMsg( "\ncannot print at interrupt time\n\n", 1, 2, 3, 4, 5, 6 );
534 err
= kExecutionStateErr
;
538 // Initialize the debugging library if it hasn't already been initialized (allows for zero-config usage).
540 if( !gDebugInitialized
)
542 debug_initialize( kDebugOutputTypeMetaConsole
);
545 // Print based on the current output type.
547 switch( gDebugOutputType
)
549 case kDebugOutputTypeNone
:
552 case kDebugOutputTypeCustom
:
553 if( gDebugCustomOutputFunction
)
555 gDebugCustomOutputFunction( inData
, inSize
, gDebugCustomOutputContext
);
559 #if ( DEBUG_FPRINTF_ENABLED )
560 case kDebugOutputTypeFPrintF
:
561 DebugFPrintFPrint( inData
, inSize
);
565 #if ( DEBUG_IDEBUG_ENABLED )
566 case kDebugOutputTypeiDebug
:
567 DebugiDebugPrint( inData
, inSize
);
571 #if ( DEBUG_KPRINTF_ENABLED )
572 case kDebugOutputTypeKPrintF
:
573 DebugKPrintFPrint( inData
, inSize
);
577 #if ( DEBUG_MAC_OS_X_IOLOG_ENABLED )
578 case kDebugOutputTypeMacOSXIOLog
:
579 DebugMacOSXIOLogPrint( inData
, inSize
);
583 #if ( TARGET_OS_MAC )
584 case kDebugOutputTypeMacOSXLog
:
585 DebugMacOSXLogPrint( inData
, inSize
);
589 #if ( TARGET_OS_WIN32 )
590 case kDebugOutputTypeWindowsDebugger
:
591 DebugWindowsDebuggerPrint( inData
, inSize
);
595 #if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
596 case kDebugOutputTypeWindowsEventLog
:
597 DebugWindowsEventLogPrint( inLevel
, inData
, inSize
);
613 // Warning: This routine relies on several of the strings being string constants that will exist forever because the
614 // underlying logMsg API that does the printing is asynchronous so it cannot use temporary/stack-based
615 // pointer variables (e.g. local strings). The debug macros that invoke this function only use constant
616 // constant strings, but if this function is invoked directly from other places, it must use constant strings.
619 int_least32_t inErrorCode
,
620 const char * inAssertString
,
621 const char * inMessage
,
622 const char * inFilename
,
623 int_least32_t inLineNumber
,
624 const char * inFunction
)
626 // Skip if the level is not in the enabled range..
627 if( ( kDebugLevelAssert
< gDebugPrintLevelMin
) || ( kDebugLevelAssert
> gDebugPrintLevelMax
) )
632 if( inErrorCode
!= 0 )
637 "[ASSERT] error: %ld (%m)\n"
638 "[ASSERT] where: \"%s\", line %ld, \"%s\"\n"
640 inErrorCode
, inErrorCode
,
641 inFilename
? inFilename
: "",
643 inFunction
? inFunction
: "" );
650 "[ASSERT] assert: \"%s\" %s\n"
651 "[ASSERT] where: \"%s\", line %ld, \"%s\"\n"
653 inAssertString
? inAssertString
: "",
654 inMessage
? inMessage
: "",
655 inFilename
? inFilename
: "",
657 inFunction
? inFunction
: "" );
660 // Break into the debugger if enabled
661 #if ( TARGET_OS_WIN32 )
662 if( gDebugBreakLevel
<= kDebugLevelAssert
)
664 if( IsDebuggerPresent() )
676 #if ( DEBUG_FPRINTF_ENABLED )
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
);
721 static void DebugFPrintFPrint( char *inData
, size_t inSize
)
726 // Convert \r to \n. fprintf will interpret \n and convert to whatever is appropriate for the platform.
738 // Write the data and flush.
739 if( gDebugFPrintFFile
)
741 fprintf( gDebugFPrintFFile
, "%.*s", (int) inSize
, inData
);
742 fflush( gDebugFPrintFFile
);
745 #endif // DEBUG_FPRINTF_ENABLED
747 #if ( DEBUG_IDEBUG_ENABLED )
750 static OSStatus
DebugiDebugInit( void )
754 #if ( TARGET_API_MAC_OSX_KERNEL )
756 extern uint32_t * _giDebugReserved1
;
758 // Emulate the iDebugSetOutputType macro in iDebugServices.h.
759 // Note: This is not thread safe, but neither is iDebugServices.h nor iDebugKext.
760 if( !_giDebugReserved1
)
762 _giDebugReserved1
= (uint32_t *) IOMalloc( sizeof( uint32_t ) );
763 require_action_quiet( _giDebugReserved1
, exit
, err
= kNoMemoryErr
);
765 *_giDebugReserved1
= 0x00010000U
;
770 __private_extern__
void iDebugSetOutputTypeInternal( uint32_t inType
);
772 iDebugSetOutputTypeInternal( 0x00010000U
);
782 static void DebugiDebugPrint( char *inData
, size_t inSize
)
784 #if ( TARGET_API_MAC_OSX_KERNEL )
786 // Locally declared here so we do not need to include iDebugKext.h.
787 // Note: IOKit uses a global namespace for all code and only a partial link occurs at build time. When the
788 // KEXT is loaded, the runtime linker will link in this extern'd symbol (assuming iDebug is present).
789 // _giDebugLogInternal is actually part of IOKit proper so this should link even if iDebug is not present.
791 typedef void ( *iDebugLogFunctionPtr
)( uint32_t inLevel
, uint32_t inTag
, const char *inFormat
, ... );
793 extern iDebugLogFunctionPtr _giDebugLogInternal
;
795 if( _giDebugLogInternal
)
797 _giDebugLogInternal( 0, 0, "%.*s", (int) inSize
, inData
);
802 __private_extern__
void iDebugLogInternal( uint32_t inLevel
, uint32_t inTag
, const char *inFormat
, ... );
804 iDebugLogInternal( 0, 0, "%.*s", (int) inSize
, inData
);
810 #if ( DEBUG_KPRINTF_ENABLED )
813 static void DebugKPrintFPrint( char *inData
, size_t inSize
)
815 extern void kprintf( const char *inFormat
, ... );
817 kprintf( "%.*s", (int) inSize
, inData
);
821 #if ( DEBUG_MAC_OS_X_IOLOG_ENABLED )
823 // DebugMacOSXIOLogPrint
824 static void DebugMacOSXIOLogPrint( char *inData
, size_t inSize
)
826 extern void IOLog( const char *inFormat
, ... );
828 IOLog( "%.*s", (int) inSize
, inData
);
832 #if ( TARGET_OS_MAC )
834 // DebugMacOSXLogInit
835 static OSStatus
DebugMacOSXLogInit( void )
841 CFStringRef functionName
;
846 // Create a bundle reference for System.framework.
848 path
= CFSTR( "/System/Library/Frameworks/System.framework" );
849 url
= CFURLCreateWithFileSystemPath( NULL
, path
, kCFURLPOSIXPathStyle
, true );
850 require_action_quiet( url
, exit
, err
= memFullErr
);
852 bundle
= CFBundleCreate( NULL
, url
);
854 require_action_quiet( bundle
, exit
, err
= memFullErr
);
856 // Get a ptr to the system's "printf" function from System.framework.
858 functionName
= CFSTR( "printf" );
859 functionPtr
= CFBundleGetFunctionPointerForName( bundle
, functionName
);
860 require_action_quiet( functionPtr
, exit
, err
= memFullErr
);
862 // Success! Note: The bundle cannot be released because it would invalidate the function ptr.
864 gDebugMacOSXLogFunction
= (DebugMacOSXLogFunctionPtr
) functionPtr
;
876 // DebugMacOSXLogPrint
877 static void DebugMacOSXLogPrint( char *inData
, size_t inSize
)
879 if( gDebugMacOSXLogFunction
)
881 gDebugMacOSXLogFunction( "%.*s", (int) inSize
, inData
);
886 #if ( TARGET_OS_WIN32 )
888 // DebugWindowsDebuggerPrint
889 void DebugWindowsDebuggerPrint( char *inData
, size_t inSize
)
897 // Copy locally and null terminate the string. This also converts from char to TCHAR in case we are
898 // building with UNICODE enabled since the input is always char. Also convert \r to \n in the process.
900 if( inSize
>= sizeof_array( buffer
) )
902 inSize
= sizeof_array( buffer
) - 1;
917 // Print out the string to the debugger.
918 OutputDebugString( buffer
);
922 #if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
924 // DebugWindowsEventLogInit
925 static OSStatus
DebugWindowsEventLogInit( const char *inName
, HMODULE inModule
)
931 TCHAR path
[ MAX_PATH
];
933 DWORD typesSupported
;
938 // Use a default name if needed then convert the name to TCHARs so it works on ANSI or Unicode builds.
939 if( !inName
|| ( *inName
== '\0' ) )
941 inName
= "DefaultApp";
943 DebugWinCharToTCharString( inName
, kSizeCString
, name
, sizeof( name
), NULL
);
945 // Build the path string using the fixed registry path and app name.
946 src
= "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\";
947 DebugWinCharToTCharString( src
, kSizeCString
, path
, sizeof_array( path
), &size
);
948 DebugWinCharToTCharString( inName
, kSizeCString
, path
+ size
, sizeof_array( path
) - size
, NULL
);
950 // Add/Open the source name as a sub-key under the Application key in the EventLog registry key.
951 err
= RegCreateKeyEx( HKEY_LOCAL_MACHINE
, path
, 0, NULL
, REG_OPTION_NON_VOLATILE
, KEY_ALL_ACCESS
, NULL
, &key
, NULL
);
952 require_noerr_quiet( err
, exit
);
954 // Set the path in the EventMessageFile subkey. Add 1 to the TCHAR count to include the null terminator.
955 n
= GetModuleFileName( inModule
, path
, sizeof_array( path
) );
956 err
= translate_errno( n
> 0, (OSStatus
) GetLastError(), kParamErr
);
957 require_noerr_quiet( err
, exit
);
959 n
*= sizeof( TCHAR
);
961 err
= RegSetValueEx( key
, TEXT( "EventMessageFile" ), 0, REG_EXPAND_SZ
, (const LPBYTE
) path
, n
);
962 require_noerr_quiet( err
, exit
);
964 // Set the supported event types in the TypesSupported subkey.
965 typesSupported
= EVENTLOG_SUCCESS
| EVENTLOG_ERROR_TYPE
| EVENTLOG_WARNING_TYPE
| EVENTLOG_INFORMATION_TYPE
|
966 EVENTLOG_AUDIT_SUCCESS
| EVENTLOG_AUDIT_FAILURE
;
967 err
= RegSetValueEx( key
, TEXT( "TypesSupported" ), 0, REG_DWORD
, (const LPBYTE
) &typesSupported
, sizeof( DWORD
) );
968 require_noerr_quiet( err
, exit
);
970 // Set up the event source.
971 gDebugWindowsEventLogEventSource
= RegisterEventSource( NULL
, name
);
972 err
= translate_errno( gDebugWindowsEventLogEventSource
, (OSStatus
) GetLastError(), kParamErr
);
973 require_noerr_quiet( err
, exit
);
984 // DebugWindowsEventLogPrint
985 static void DebugWindowsEventLogPrint( DebugLevel inLevel
, char *inData
, size_t inSize
)
993 const TCHAR
* array
[ 1 ];
995 // Map the debug level to a Windows EventLog type
996 if( inLevel
<= kDebugLevelNotice
)
998 type
= EVENTLOG_INFORMATION_TYPE
;
1000 else if( inLevel
<= kDebugLevelWarning
)
1002 type
= EVENTLOG_WARNING_TYPE
;
1006 type
= EVENTLOG_ERROR_TYPE
;
1009 // Copy locally and null terminate the string. This also converts from char to TCHAR in case we are
1010 // building with UNICODE enabled since the input is always char. Also convert \r to \n in the process.
1012 if( inSize
>= sizeof_array( buffer
) )
1014 inSize
= sizeof_array( buffer
) - 1;
1029 // Add the string to the event log.
1030 array
[ 0 ] = buffer
;
1031 if( gDebugWindowsEventLogEventSource
)
1033 ReportEvent( gDebugWindowsEventLogEventSource
, type
, 0, 0x20000001L
, NULL
, 1, 0, array
, NULL
);
1036 #endif // TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE
1038 #if ( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
1040 // DebugAssertOutputHandler
1042 DebugAssertOutputHandler(
1043 OSType inComponentSignature
,
1045 const char * inAssertString
,
1046 const char * inExceptionString
,
1047 const char * inErrorString
,
1048 const char * inFileName
,
1051 ConstStr255Param inOutputMsg
)
1053 DEBUG_UNUSED( inComponentSignature
);
1054 DEBUG_UNUSED( inOptions
);
1055 DEBUG_UNUSED( inExceptionString
);
1056 DEBUG_UNUSED( inValue
);
1057 DEBUG_UNUSED( inOutputMsg
);
1059 DebugPrintAssert( 0, inAssertString
, inErrorString
, inFileName
, (int_least32_t) inLineNumber
, "" );
1065 #pragma mark == Utilities ==
1071 // Stolen from mDNS.c's mDNS_snprintf/mDNS_vsnprintf with the following changes:
1073 // Changed names to avoid name collisions with the mDNS versions.
1074 // Changed types to standard C types since mDNSEmbeddedAPI.h may not be available.
1075 // Conditionalized mDNS stuff so it can be used with or with mDNSEmbeddedAPI.h.
1076 // Added 64-bit support for %d (%lld), %i (%lli), %u (%llu), %o (%llo), %x (%llx), and %b (%llb).
1077 // Added %@ - Cocoa/CoreFoundation object. Param is the object. Strings are used directly. Others use CFCopyDescription.
1078 // Added %.8a - FIbre Channel address. Arg=ptr to address.
1079 // Added %##a - IPv4 (if AF_INET defined) or IPv6 (if AF_INET6 defined) sockaddr. Arg=ptr to sockaddr.
1080 // Added %b - Binary representation of integer (e.g. 01101011). Modifiers and arg=the same as %d, %x, etc.
1081 // Added %C - Mac-style FourCharCode (e.g. 'APPL'). Arg=32-bit value to print as a Mac-style FourCharCode.
1082 // Added %H - Hex Dump (e.g. "\x6b\xa7" -> "6B A7"). 1st arg=ptr, 2nd arg=size, 3rd arg=max size.
1083 // Added %#H - Hex Dump & ASCII (e.g. "\x41\x62" -> "6B A7 'Ab'"). 1st arg=ptr, 2nd arg=size, 3rd arg=max size.
1084 // Added %m - Error Message (e.g. 0 -> "kNoErr"). Modifiers and error code args are the same as %d, %x, etc.
1085 // Added %S - UTF-16 string. Host order if no BOM. Precision is UTF-16 char count. BOM counts in any precision. Arg=ptr.
1086 // Added %#S - Big Endian UTF-16 string (unless BOM overrides). Otherwise the same as %S.
1087 // Added %##S - Little Endian UTF-16 string (unless BOM overrides). Otherwise the same as %S.
1088 // Added %U - Universally Unique Identifier (UUID) (e.g. 6ba7b810-9dad-11d1-80b4-00c04fd430c8). Arg=ptr to 16-byte UUID.
1091 DEBUG_EXPORT
size_t DebugSNPrintF(char *sbuffer
, size_t buflen
, const char *fmt
, ...)
1097 length
= DebugSNPrintFVAList(sbuffer
, buflen
, fmt
, ptr
);
1104 // DebugSNPrintFVAList - va_list version of DebugSNPrintF. See DebugSNPrintF for more info.
1105 DEBUG_EXPORT
size_t DebugSNPrintFVAList(char *sbuffer
, size_t buflen
, const char *fmt
, va_list arg
)
1107 static const struct DebugSNPrintF_format
1109 unsigned leftJustify
: 1;
1110 unsigned forceSign
: 1;
1111 unsigned zeroPad
: 1;
1112 unsigned havePrecision
: 1;
1116 char sign
; // +, - or space
1117 unsigned int fieldWidth
;
1118 unsigned int precision
;
1119 } DebugSNPrintF_format_default
= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1121 size_t nwritten
= 0;
1123 if (buflen
== 0) return 0;
1124 buflen
--; // Pre-reserve one space in the buffer for the terminating nul
1125 if (buflen
== 0) goto exit
;
1127 for (c
= *fmt
; c
!= 0; c
= *++fmt
)
1131 *sbuffer
++ = (char)c
;
1132 if (++nwritten
>= buflen
) goto exit
;
1137 // The mDNS Vsprintf Argument Conversion Buffer is used as a temporary holding area for
1138 // generating decimal numbers, hexdecimal numbers, IP addresses, domain name strings, etc.
1139 // The size needs to be enough for a 256-byte domain name plus some error text.
1140 #define mDNS_VACB_Size 300
1141 char mDNS_VACB
[mDNS_VACB_Size
];
1142 #define mDNS_VACB_Lim (&mDNS_VACB[mDNS_VACB_Size])
1143 #define mDNS_VACB_Remain(s) ((size_t)(mDNS_VACB_Lim - s))
1144 char *s
= mDNS_VACB_Lim
;
1145 const char *digits
= "0123456789ABCDEF";
1146 struct DebugSNPrintF_format F
= DebugSNPrintF_format_default
;
1148 for(;;) // decode flags
1151 if (c
== '-') F
.leftJustify
= 1;
1152 else if (c
== '+') F
.forceSign
= 1;
1153 else if (c
== ' ') F
.sign
= ' ';
1154 else if (c
== '#') F
.altForm
++;
1155 else if (c
== '0') F
.zeroPad
= 1;
1159 if (c
== '*') // decode field width
1161 int f
= va_arg(arg
, int);
1162 if (f
< 0) { f
= -f
; F
.leftJustify
= 1; }
1163 F
.fieldWidth
= (unsigned int)f
;
1168 for (; c
>= '0' && c
<= '9'; c
= *++fmt
)
1169 F
.fieldWidth
= (10 * F
.fieldWidth
) + (c
- '0');
1172 if (c
== '.') // decode precision
1174 if ((c
= *++fmt
) == '*')
1175 { F
.precision
= va_arg(arg
, unsigned int); c
= *++fmt
; }
1176 else for (; c
>= '0' && c
<= '9'; c
= *++fmt
)
1177 F
.precision
= (10 * F
.precision
) + (c
- '0');
1178 F
.havePrecision
= 1;
1181 if (F
.leftJustify
) F
.zeroPad
= 0;
1184 switch (c
) // perform appropriate conversion
1186 #if TYPE_LONGLONG_NATIVE
1187 unsigned_long_long_compat n
;
1188 unsigned_long_long_compat base
;
1193 case 'h': F
.hSize
= 1; c
= *++fmt
; goto conv
;
1194 case 'l': // fall through
1195 case 'L': F
.lSize
++; c
= *++fmt
; goto conv
;
1197 case 'i': base
= 10;
1199 case 'u': base
= 10;
1205 case 'p': n
= va_arg(arg
, uintptr_t);
1206 F
.havePrecision
= 1;
1207 F
.precision
= (sizeof(uintptr_t) == 4) ? 8 : 16;
1212 case 'x': digits
= "0123456789abcdef";
1213 case 'X': base
= 16;
1216 #if TYPE_LONGLONG_NATIVE
1217 if (F
.lSize
== 1) n
= (unsigned_long_long_compat
)va_arg(arg
, long);
1218 else if (F
.lSize
== 2) n
= (unsigned_long_long_compat
)va_arg(arg
, long_long_compat
);
1219 else n
= (unsigned_long_long_compat
)va_arg(arg
, int);
1221 if (F
.lSize
== 1) n
= (unsigned long)va_arg(arg
, long);
1222 else if (F
.lSize
== 2) goto exit
;
1223 else n
= (unsigned long)va_arg(arg
, int);
1225 if (F
.hSize
) n
= (short) n
;
1226 #if TYPE_LONGLONG_NATIVE
1227 if ((long_long_compat
) n
< 0) { n
= (unsigned_long_long_compat
)-(long_long_compat
)n
; F
.sign
= '-'; }
1229 if ((long) n
< 0) { n
= (unsigned long)-(long)n
; F
.sign
= '-'; }
1231 else if (F
.forceSign
) F
.sign
= '+';
1234 notSigned
: if (F
.lSize
== 1) n
= va_arg(arg
, unsigned long);
1235 else if (F
.lSize
== 2)
1237 #if TYPE_LONGLONG_NATIVE
1238 n
= va_arg(arg
, unsigned_long_long_compat
);
1243 else n
= va_arg(arg
, unsigned int);
1244 if (F
.hSize
) n
= (unsigned short) n
;
1248 number
: if (!F
.havePrecision
)
1252 F
.precision
= F
.fieldWidth
;
1253 if (F
.altForm
) F
.precision
-= 2;
1254 if (F
.sign
) --F
.precision
;
1256 if (F
.precision
< 1) F
.precision
= 1;
1258 if (F
.precision
> mDNS_VACB_Size
- 1)
1259 F
.precision
= mDNS_VACB_Size
- 1;
1260 for (i
= 0; n
; n
/= base
, i
++) *--s
= (char)(digits
[n
% base
]);
1261 for (; i
< F
.precision
; i
++) *--s
= '0';
1262 if (F
.altForm
) { *--s
= (char)c
; *--s
= '0'; i
+= 2; }
1263 if (F
.sign
) { *--s
= F
.sign
; i
++; }
1267 unsigned char *a
= va_arg(arg
, unsigned char *);
1270 if (!a
) { static char emsg
[] = "<<NULL>>"; s
= emsg
; i
= sizeof(emsg
)-1; }
1273 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1276 #if (defined(MDNS_DEBUGMSGS))
1277 mDNSAddr
*ip
= (mDNSAddr
*)a
;
1280 case mDNSAddrType_IPv4
: F
.precision
= 4; a
= (unsigned char *)&ip
->ip
.v4
; break;
1281 case mDNSAddrType_IPv6
: F
.precision
= 16; a
= (unsigned char *)&ip
->ip
.v6
; break;
1282 default: F
.precision
= 0; break;
1285 F
.precision
= 0; // mDNSEmbeddedAPI.h not included so no mDNSAddr support
1288 else if (F
.altForm
== 2)
1291 const struct sockaddr
*sa
;
1292 unsigned char *port
;
1293 sa
= (const struct sockaddr
*)a
;
1294 switch (sa
->sa_family
)
1296 case AF_INET
: F
.precision
= 4; a
= (unsigned char*)&((const struct sockaddr_in
*)a
)->sin_addr
;
1297 port
= (unsigned char*)&((const struct sockaddr_in
*)sa
)->sin_port
;
1298 DebugSNPrintF(post
, sizeof(post
), ":%d", (port
[0] << 8) | port
[1]); break;
1300 case AF_INET6
: F
.precision
= 16; a
= (unsigned char*)&((const struct sockaddr_in6
*)a
)->sin6_addr
;
1301 pre
[0] = '['; pre
[1] = '\0';
1302 port
= (unsigned char*)&((const struct sockaddr_in6
*)sa
)->sin6_port
;
1303 DebugSNPrintF(post
, sizeof(post
), "%%%d]:%d",
1304 (int)((const struct sockaddr_in6
*)sa
)->sin6_scope_id
,
1305 (port
[0] << 8) | port
[1]); break;
1307 default: F
.precision
= 0; break;
1310 F
.precision
= 0; // socket interfaces not included so no sockaddr support
1313 switch (F
.precision
)
1315 case 4: i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "%d.%d.%d.%d%s",
1316 a
[0], a
[1], a
[2], a
[3], post
); break;
1317 case 6: i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "%02X:%02X:%02X:%02X:%02X:%02X",
1318 a
[0], a
[1], a
[2], a
[3], a
[4], a
[5]); break;
1319 case 8: i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
1320 a
[0], a
[1], a
[2], a
[3], a
[4], a
[5], a
[6], a
[7]); break;
1321 case 16: i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
),
1322 "%s%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X%s",
1323 pre
, a
[0], a
[1], a
[2], a
[3], a
[4], a
[5], a
[6], a
[7], a
[8],
1324 a
[9], a
[10], a
[11], a
[12], a
[13], a
[14], a
[15], post
); break;
1325 default: i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "%s", "<< ERROR: Must specify address size "
1326 "(i.e. %.4a=IPv4, %.6a=Ethernet, %.8a=Fibre Channel %.16a=IPv6) >>"); break;
1333 unsigned char *a
= va_arg(arg
, unsigned char *);
1334 if (!a
) { static char emsg
[] = "<<NULL>>"; s
= emsg
; i
= sizeof(emsg
)-1; }
1337 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1338 i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
1339 *((uint32_t*) &a
[0]), *((uint16_t*) &a
[4]), *((uint16_t*) &a
[6]),
1340 a
[8], a
[9], a
[10], a
[11], a
[12], a
[13], a
[14], a
[15]); break;
1345 case 'c': *--s
= (char)va_arg(arg
, int); i
= 1; break;
1347 case 'C': if (F
.lSize
) n
= va_arg(arg
, unsigned long);
1348 else n
= va_arg(arg
, unsigned int);
1349 if (F
.hSize
) n
= (unsigned short) n
;
1350 c
= (int)( n
& 0xFF); *--s
= (char)(DebugIsPrint(c
) ? c
: '^');
1351 c
= (int)((n
>> 8) & 0xFF); *--s
= (char)(DebugIsPrint(c
) ? c
: '^');
1352 c
= (int)((n
>> 16) & 0xFF); *--s
= (char)(DebugIsPrint(c
) ? c
: '^');
1353 c
= (int)((n
>> 24) & 0xFF); *--s
= (char)(DebugIsPrint(c
) ? c
: '^');
1357 case 's': s
= va_arg(arg
, char *);
1358 if (!s
) { static char emsg
[] = "<<NULL>>"; s
= emsg
; i
= sizeof(emsg
)-1; }
1359 else switch (F
.altForm
)
1362 if (F
.havePrecision
) // C string
1364 while((i
< F
.precision
) && s
[i
]) i
++;
1365 // Make sure we don't truncate in the middle of a UTF-8 character.
1366 // If the last character is part of a multi-byte UTF-8 character, back up to the start of it.
1368 while((i
> 0) && ((c
= s
[i
-1]) & 0x80)) { j
++; i
--; if((c
& 0xC0) != 0x80) break;}
1369 // If the actual count of UTF-8 characters matches the encoded UTF-8 count, add it back.
1370 if((j
> 1) && (j
<= 6))
1372 int test
= (0xFF << (8-j
)) & 0xFF;
1373 int mask
= test
| (1 << ((8-j
)-1));
1374 if((c
& mask
) == test
) i
+= j
;
1380 case 1: i
= (unsigned char) *s
++; break; // Pascal string
1381 case 2: { // DNS label-sequence name
1382 unsigned char *a
= (unsigned char *)s
;
1383 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1384 if (*a
== 0) *s
++ = '.'; // Special case for root DNS name
1387 if (*a
> 63) { s
+= DebugSNPrintF(s
, mDNS_VACB_Remain(s
), "<<INVALID LABEL LENGTH %u>>", *a
); break; }
1388 if (s
+ *a
>= &mDNS_VACB
[254]) { s
+= DebugSNPrintF(s
, mDNS_VACB_Remain(s
), "<<NAME TOO LONG>>"); break; }
1389 s
+= DebugSNPrintF(s
, mDNS_VACB_Remain(s
), "%#s.", a
);
1392 i
= (size_t)(s
- mDNS_VACB
);
1393 s
= mDNS_VACB
; // Reset s back to the start of the buffer
1397 if (F
.havePrecision
&& i
> F
.precision
) // Make sure we don't truncate in the middle of a UTF-8 character
1398 { i
= F
.precision
; while (i
>0 && (s
[i
] & 0xC0) == 0x80) i
--;}
1401 case 'S': { // UTF-16 string
1402 unsigned char *a
= va_arg(arg
, unsigned char *);
1403 uint16_t *u
= (uint16_t*)a
;
1404 if (!u
) { static char emsg
[] = "<<NULL>>"; s
= emsg
; i
= sizeof(emsg
)-1; }
1405 if ((!F
.havePrecision
|| F
.precision
))
1407 if ((a
[0] == 0xFE) && (a
[1] == 0xFF)) { F
.altForm
= 1; u
+= 1; a
+= 2; F
.precision
--; } // Big Endian
1408 else if ((a
[0] == 0xFF) && (a
[1] == 0xFE)) { F
.altForm
= 2; u
+= 1; a
+= 2; F
.precision
--; } // Little Endian
1410 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1413 case 0: while ((!F
.havePrecision
|| (i
< F
.precision
)) && u
[i
] && mDNS_VACB_Remain(s
)) // Host Endian
1414 { c
= u
[i
]; *s
++ = (char)(DebugIsPrint(c
) ? c
: '^'); i
++; }
1416 case 1: while ((!F
.havePrecision
|| (i
< F
.precision
)) && u
[i
] && mDNS_VACB_Remain(s
)) // Big Endian
1417 { c
= ((a
[0] << 8) | a
[1]) & 0xFF; *s
++ = (char)(DebugIsPrint(c
) ? c
: '^'); i
++; a
+= 2; }
1419 case 2: while ((!F
.havePrecision
|| (i
< F
.precision
)) && u
[i
] && mDNS_VACB_Remain(s
)) // Little Endian
1420 { c
= ((a
[1] << 8) | a
[0]) & 0xFF; *s
++ = (char)(DebugIsPrint(c
) ? c
: '^'); i
++; a
+= 2; }
1424 s
= mDNS_VACB
; // Reset s back to the start of the buffer
1428 case '@': { // Cocoa/CoreFoundation object
1431 cfObj
= (CFTypeRef
) va_arg(arg
, void *);
1432 cfStr
= (CFGetTypeID(cfObj
) == CFStringGetTypeID()) ? (CFStringRef
)CFRetain(cfObj
) : CFCopyDescription(cfObj
);
1433 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1438 range
= CFRangeMake(0, CFStringGetLength(cfStr
));
1440 CFStringGetBytes(cfStr
, range
, kCFStringEncodingUTF8
, '^', false, (UInt8
*)mDNS_VACB
, (CFIndex
)sizeof(mDNS_VACB
), &m
);
1446 i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "%s", "ERROR: <invalid CF object>" );
1449 if (F
.havePrecision
&& i
> F
.precision
) // Make sure we don't truncate in the middle of a UTF-8 character
1450 { i
= F
.precision
; while (i
>0 && (s
[i
] & 0xC0) == 0x80) i
--;}
1454 case 'm': { // Error Message
1456 if (F
.lSize
) err
= va_arg(arg
, long);
1457 else err
= va_arg(arg
, int);
1458 if (F
.hSize
) err
= (short)err
;
1459 DebugGetErrorString(err
, mDNS_VACB
, sizeof(mDNS_VACB
));
1460 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1461 for(i
=0; s
[i
]; i
++) {}
1465 case 'H': { // Hex Dump
1466 void *a
= va_arg(arg
, void *);
1467 size_t size
= (size_t)va_arg(arg
, int);
1468 size_t max
= (size_t)va_arg(arg
, int);
1470 kDebugFlagsNoAddress
| kDebugFlagsNoOffset
| kDebugFlagsNoNewLine
|
1471 kDebugFlags8BitSeparator
| kDebugFlagsNo32BitSeparator
|
1472 kDebugFlagsNo16ByteHexPad
| kDebugFlagsNoByteCount
;
1473 if (F
.altForm
== 0) flags
|= kDebugFlagsNoASCII
;
1474 size
= (max
< size
) ? max
: size
;
1475 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1476 i
= DebugHexDump(kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, a
, a
, size
, flags
, mDNS_VACB
, sizeof(mDNS_VACB
));
1480 case 'v': { // Version
1482 version
= va_arg(arg
, unsigned int);
1483 DebugNumVersionToString(version
, mDNS_VACB
);
1484 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1485 for(i
=0; s
[i
]; i
++) {}
1489 case 'n': s
= va_arg(arg
, char *);
1490 if (F
.hSize
) *(short *) s
= (short)nwritten
;
1491 else if (F
.lSize
) *(long *) s
= (long)nwritten
;
1492 else *(int *) s
= (int)nwritten
;
1495 default: s
= mDNS_VACB
;
1496 i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "<<UNKNOWN FORMAT CONVERSION CODE %%%c>>", c
);
1498 case '%': *sbuffer
++ = (char)c
;
1499 if (++nwritten
>= buflen
) goto exit
;
1503 if (i
< F
.fieldWidth
&& !F
.leftJustify
) // Pad on the left
1506 if (++nwritten
>= buflen
) goto exit
;
1507 } while (i
< --F
.fieldWidth
);
1509 if (i
> buflen
- nwritten
) // Make sure we don't truncate in the middle of a UTF-8 character
1510 { i
= buflen
- nwritten
; while (i
>0 && (s
[i
] & 0xC0) == 0x80) i
--;}
1511 for (j
=0; j
<i
; j
++) *sbuffer
++ = *s
++; // Write the converted result
1513 if (nwritten
>= buflen
) goto exit
;
1515 for (; i
< F
.fieldWidth
; i
++) // Pad on the right
1518 if (++nwritten
>= buflen
) goto exit
;
1528 // DebugGetErrorString
1529 DEBUG_EXPORT
const char * DebugGetErrorString( int_least32_t inErrorCode
, char *inBuffer
, size_t inBufferSize
)
1534 #if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
1538 switch( inErrorCode
)
1540 #define CaseErrorString( X, STR ) case X: s = STR; break
1541 #define CaseErrorStringify( X ) case X: s = # X; break
1542 #define CaseErrorStringifyHardCode( VALUE, X ) case VALUE: s = # X; break
1546 CaseErrorString( 0, "no error" );
1547 CaseErrorString( 1, "in-progress/waiting" );
1548 CaseErrorString( -1, "catch-all unknown error" );
1552 CaseErrorStringifyHardCode( -2, kACPBadRequestErr
);
1553 CaseErrorStringifyHardCode( -3, kACPNoMemoryErr
);
1554 CaseErrorStringifyHardCode( -4, kACPBadParamErr
);
1555 CaseErrorStringifyHardCode( -5, kACPNotFoundErr
);
1556 CaseErrorStringifyHardCode( -6, kACPBadChecksumErr
);
1557 CaseErrorStringifyHardCode( -7, kACPCommandNotHandledErr
);
1558 CaseErrorStringifyHardCode( -8, kACPNetworkErr
);
1559 CaseErrorStringifyHardCode( -9, kACPDuplicateCommandHandlerErr
);
1560 CaseErrorStringifyHardCode( -10, kACPUnknownPropertyErr
);
1561 CaseErrorStringifyHardCode( -11, kACPImmutablePropertyErr
);
1562 CaseErrorStringifyHardCode( -12, kACPBadPropertyValueErr
);
1563 CaseErrorStringifyHardCode( -13, kACPNoResourcesErr
);
1564 CaseErrorStringifyHardCode( -14, kACPBadOptionErr
);
1565 CaseErrorStringifyHardCode( -15, kACPBadSizeErr
);
1566 CaseErrorStringifyHardCode( -16, kACPBadPasswordErr
);
1567 CaseErrorStringifyHardCode( -17, kACPNotInitializedErr
);
1568 CaseErrorStringifyHardCode( -18, kACPNonReadablePropertyErr
);
1569 CaseErrorStringifyHardCode( -19, kACPBadVersionErr
);
1570 CaseErrorStringifyHardCode( -20, kACPBadSignatureErr
);
1571 CaseErrorStringifyHardCode( -21, kACPBadIndexErr
);
1572 CaseErrorStringifyHardCode( -22, kACPUnsupportedErr
);
1573 CaseErrorStringifyHardCode( -23, kACPInUseErr
);
1574 CaseErrorStringifyHardCode( -24, kACPParamCountErr
);
1575 CaseErrorStringifyHardCode( -25, kACPIDErr
);
1576 CaseErrorStringifyHardCode( -26, kACPFormatErr
);
1577 CaseErrorStringifyHardCode( -27, kACPUnknownUserErr
);
1578 CaseErrorStringifyHardCode( -28, kACPAccessDeniedErr
);
1579 CaseErrorStringifyHardCode( -29, kACPIncorrectFWErr
);
1581 // Common Services Errors
1583 CaseErrorStringify( kUnknownErr
);
1584 CaseErrorStringify( kOptionErr
);
1585 CaseErrorStringify( kSelectorErr
);
1586 CaseErrorStringify( kExecutionStateErr
);
1587 CaseErrorStringify( kPathErr
);
1588 CaseErrorStringify( kParamErr
);
1589 CaseErrorStringify( kParamCountErr
);
1590 CaseErrorStringify( kCommandErr
);
1591 CaseErrorStringify( kIDErr
);
1592 CaseErrorStringify( kStateErr
);
1593 CaseErrorStringify( kRangeErr
);
1594 CaseErrorStringify( kRequestErr
);
1595 CaseErrorStringify( kResponseErr
);
1596 CaseErrorStringify( kChecksumErr
);
1597 CaseErrorStringify( kNotHandledErr
);
1598 CaseErrorStringify( kVersionErr
);
1599 CaseErrorStringify( kSignatureErr
);
1600 CaseErrorStringify( kFormatErr
);
1601 CaseErrorStringify( kNotInitializedErr
);
1602 CaseErrorStringify( kAlreadyInitializedErr
);
1603 CaseErrorStringify( kNotInUseErr
);
1604 CaseErrorStringify( kInUseErr
);
1605 CaseErrorStringify( kTimeoutErr
);
1606 CaseErrorStringify( kCanceledErr
);
1607 CaseErrorStringify( kAlreadyCanceledErr
);
1608 CaseErrorStringify( kCannotCancelErr
);
1609 CaseErrorStringify( kDeletedErr
);
1610 CaseErrorStringify( kNotFoundErr
);
1611 CaseErrorStringify( kNoMemoryErr
);
1612 CaseErrorStringify( kNoResourcesErr
);
1613 CaseErrorStringify( kDuplicateErr
);
1614 CaseErrorStringify( kImmutableErr
);
1615 CaseErrorStringify( kUnsupportedDataErr
);
1616 CaseErrorStringify( kIntegrityErr
);
1617 CaseErrorStringify( kIncompatibleErr
);
1618 CaseErrorStringify( kUnsupportedErr
);
1619 CaseErrorStringify( kUnexpectedErr
);
1620 CaseErrorStringify( kValueErr
);
1621 CaseErrorStringify( kNotReadableErr
);
1622 CaseErrorStringify( kNotWritableErr
);
1623 CaseErrorStringify( kBadReferenceErr
);
1624 CaseErrorStringify( kFlagErr
);
1625 CaseErrorStringify( kMalformedErr
);
1626 CaseErrorStringify( kSizeErr
);
1627 CaseErrorStringify( kNameErr
);
1628 CaseErrorStringify( kNotReadyErr
);
1629 CaseErrorStringify( kReadErr
);
1630 CaseErrorStringify( kWriteErr
);
1631 CaseErrorStringify( kMismatchErr
);
1632 CaseErrorStringify( kDateErr
);
1633 CaseErrorStringify( kUnderrunErr
);
1634 CaseErrorStringify( kOverrunErr
);
1635 CaseErrorStringify( kEndingErr
);
1636 CaseErrorStringify( kConnectionErr
);
1637 CaseErrorStringify( kAuthenticationErr
);
1638 CaseErrorStringify( kOpenErr
);
1639 CaseErrorStringify( kTypeErr
);
1640 CaseErrorStringify( kSkipErr
);
1641 CaseErrorStringify( kNoAckErr
);
1642 CaseErrorStringify( kCollisionErr
);
1643 CaseErrorStringify( kBackoffErr
);
1644 CaseErrorStringify( kNoAddressAckErr
);
1645 CaseErrorStringify( kBusyErr
);
1646 CaseErrorStringify( kNoSpaceErr
);
1648 // mDNS/DNS-SD Errors
1650 CaseErrorStringifyHardCode( -65537, mStatus_UnknownErr
);
1651 CaseErrorStringifyHardCode( -65538, mStatus_NoSuchNameErr
);
1652 CaseErrorStringifyHardCode( -65539, mStatus_NoMemoryErr
);
1653 CaseErrorStringifyHardCode( -65540, mStatus_BadParamErr
);
1654 CaseErrorStringifyHardCode( -65541, mStatus_BadReferenceErr
);
1655 CaseErrorStringifyHardCode( -65542, mStatus_BadStateErr
);
1656 CaseErrorStringifyHardCode( -65543, mStatus_BadFlagsErr
);
1657 CaseErrorStringifyHardCode( -65544, mStatus_UnsupportedErr
);
1658 CaseErrorStringifyHardCode( -65545, mStatus_NotInitializedErr
);
1659 CaseErrorStringifyHardCode( -65546, mStatus_NoCache
);
1660 CaseErrorStringifyHardCode( -65547, mStatus_AlreadyRegistered
);
1661 CaseErrorStringifyHardCode( -65548, mStatus_NameConflict
);
1662 CaseErrorStringifyHardCode( -65549, mStatus_Invalid
);
1663 CaseErrorStringifyHardCode( -65550, mStatus_GrowCache
);
1664 CaseErrorStringifyHardCode( -65551, mStatus_BadInterfaceErr
);
1665 CaseErrorStringifyHardCode( -65552, mStatus_Incompatible
);
1666 CaseErrorStringifyHardCode( -65791, mStatus_ConfigChanged
);
1667 CaseErrorStringifyHardCode( -65792, mStatus_MemFree
);
1671 CaseErrorStringifyHardCode( -400000, kRSPUnknownErr
);
1672 CaseErrorStringifyHardCode( -400050, kRSPParamErr
);
1673 CaseErrorStringifyHardCode( -400108, kRSPNoMemoryErr
);
1674 CaseErrorStringifyHardCode( -405246, kRSPRangeErr
);
1675 CaseErrorStringifyHardCode( -409057, kRSPSizeErr
);
1676 CaseErrorStringifyHardCode( -400200, kRSPHardwareErr
);
1677 CaseErrorStringifyHardCode( -401712, kRSPTimeoutErr
);
1678 CaseErrorStringifyHardCode( -402053, kRSPUnsupportedErr
);
1679 CaseErrorStringifyHardCode( -402419, kRSPIDErr
);
1680 CaseErrorStringifyHardCode( -403165, kRSPFlagErr
);
1681 CaseErrorString( -200000, "kRSPControllerStatusBase - 0x50" );
1682 CaseErrorString( -200080, "kRSPCommandSucceededErr - 0x50" );
1683 CaseErrorString( -200001, "kRSPCommandFailedErr - 0x01" );
1684 CaseErrorString( -200051, "kRSPChecksumErr - 0x33" );
1685 CaseErrorString( -200132, "kRSPCommandTimeoutErr - 0x84" );
1686 CaseErrorString( -200034, "kRSPPasswordRequiredErr - 0x22 OBSOLETE" );
1687 CaseErrorString( -200128, "kRSPCanceledErr - 0x02 Async" );
1691 CaseErrorStringifyHardCode( -100043, kXMLNotFoundErr
);
1692 CaseErrorStringifyHardCode( -100050, kXMLParamErr
);
1693 CaseErrorStringifyHardCode( -100108, kXMLNoMemoryErr
);
1694 CaseErrorStringifyHardCode( -100206, kXMLFormatErr
);
1695 CaseErrorStringifyHardCode( -100586, kXMLNoRootElementErr
);
1696 CaseErrorStringifyHardCode( -101703, kXMLWrongDataTypeErr
);
1697 CaseErrorStringifyHardCode( -101726, kXMLKeyErr
);
1698 CaseErrorStringifyHardCode( -102053, kXMLUnsupportedErr
);
1699 CaseErrorStringifyHardCode( -102063, kXMLMissingElementErr
);
1700 CaseErrorStringifyHardCode( -103026, kXMLParseErr
);
1701 CaseErrorStringifyHardCode( -103159, kXMLBadDataErr
);
1702 CaseErrorStringifyHardCode( -103170, kXMLBadNameErr
);
1703 CaseErrorStringifyHardCode( -105246, kXMLRangeErr
);
1704 CaseErrorStringifyHardCode( -105251, kXMLUnknownElementErr
);
1705 CaseErrorStringifyHardCode( -108739, kXMLMalformedInputErr
);
1706 CaseErrorStringifyHardCode( -109057, kXMLBadSizeErr
);
1707 CaseErrorStringifyHardCode( -101730, kXMLMissingChildElementErr
);
1708 CaseErrorStringifyHardCode( -102107, kXMLMissingParentElementErr
);
1709 CaseErrorStringifyHardCode( -130587, kXMLNonRootElementErr
);
1710 CaseErrorStringifyHardCode( -102015, kXMLDateErr
);
1716 CaseErrorStringifyHardCode( 0x00002000, MACH_MSG_IPC_SPACE
);
1717 CaseErrorStringifyHardCode( 0x00001000, MACH_MSG_VM_SPACE
);
1718 CaseErrorStringifyHardCode( 0x00000800, MACH_MSG_IPC_KERNEL
);
1719 CaseErrorStringifyHardCode( 0x00000400, MACH_MSG_VM_KERNEL
);
1720 CaseErrorStringifyHardCode( 0x10000001, MACH_SEND_IN_PROGRESS
);
1721 CaseErrorStringifyHardCode( 0x10000002, MACH_SEND_INVALID_DATA
);
1722 CaseErrorStringifyHardCode( 0x10000003, MACH_SEND_INVALID_DEST
);
1723 CaseErrorStringifyHardCode( 0x10000004, MACH_SEND_TIMED_OUT
);
1724 CaseErrorStringifyHardCode( 0x10000007, MACH_SEND_INTERRUPTED
);
1725 CaseErrorStringifyHardCode( 0x10000008, MACH_SEND_MSG_TOO_SMALL
);
1726 CaseErrorStringifyHardCode( 0x10000009, MACH_SEND_INVALID_REPLY
);
1727 CaseErrorStringifyHardCode( 0x1000000A, MACH_SEND_INVALID_RIGHT
);
1728 CaseErrorStringifyHardCode( 0x1000000B, MACH_SEND_INVALID_NOTIFY
);
1729 CaseErrorStringifyHardCode( 0x1000000C, MACH_SEND_INVALID_MEMORY
);
1730 CaseErrorStringifyHardCode( 0x1000000D, MACH_SEND_NO_BUFFER
);
1731 CaseErrorStringifyHardCode( 0x1000000E, MACH_SEND_TOO_LARGE
);
1732 CaseErrorStringifyHardCode( 0x1000000F, MACH_SEND_INVALID_TYPE
);
1733 CaseErrorStringifyHardCode( 0x10000010, MACH_SEND_INVALID_HEADER
);
1734 CaseErrorStringifyHardCode( 0x10000011, MACH_SEND_INVALID_TRAILER
);
1735 CaseErrorStringifyHardCode( 0x10000015, MACH_SEND_INVALID_RT_OOL_SIZE
);
1736 CaseErrorStringifyHardCode( 0x10004001, MACH_RCV_IN_PROGRESS
);
1737 CaseErrorStringifyHardCode( 0x10004002, MACH_RCV_INVALID_NAME
);
1738 CaseErrorStringifyHardCode( 0x10004003, MACH_RCV_TIMED_OUT
);
1739 CaseErrorStringifyHardCode( 0x10004004, MACH_RCV_TOO_LARGE
);
1740 CaseErrorStringifyHardCode( 0x10004005, MACH_RCV_INTERRUPTED
);
1741 CaseErrorStringifyHardCode( 0x10004006, MACH_RCV_PORT_CHANGED
);
1742 CaseErrorStringifyHardCode( 0x10004007, MACH_RCV_INVALID_NOTIFY
);
1743 CaseErrorStringifyHardCode( 0x10004008, MACH_RCV_INVALID_DATA
);
1744 CaseErrorStringifyHardCode( 0x10004009, MACH_RCV_PORT_DIED
);
1745 CaseErrorStringifyHardCode( 0x1000400A, MACH_RCV_IN_SET
);
1746 CaseErrorStringifyHardCode( 0x1000400B, MACH_RCV_HEADER_ERROR
);
1747 CaseErrorStringifyHardCode( 0x1000400C, MACH_RCV_BODY_ERROR
);
1748 CaseErrorStringifyHardCode( 0x1000400D, MACH_RCV_INVALID_TYPE
);
1749 CaseErrorStringifyHardCode( 0x1000400E, MACH_RCV_SCATTER_SMALL
);
1750 CaseErrorStringifyHardCode( 0x1000400F, MACH_RCV_INVALID_TRAILER
);
1751 CaseErrorStringifyHardCode( 0x10004011, MACH_RCV_IN_PROGRESS_TIMED
);
1753 // Mach OSReturn Errors
1755 CaseErrorStringifyHardCode( 0xDC000001, kOSReturnError
);
1756 CaseErrorStringifyHardCode( 0xDC004001, kOSMetaClassInternal
);
1757 CaseErrorStringifyHardCode( 0xDC004002, kOSMetaClassHasInstances
);
1758 CaseErrorStringifyHardCode( 0xDC004003, kOSMetaClassNoInit
);
1759 CaseErrorStringifyHardCode( 0xDC004004, kOSMetaClassNoTempData
);
1760 CaseErrorStringifyHardCode( 0xDC004005, kOSMetaClassNoDicts
);
1761 CaseErrorStringifyHardCode( 0xDC004006, kOSMetaClassNoKModSet
);
1762 CaseErrorStringifyHardCode( 0xDC004007, kOSMetaClassNoInsKModSet
);
1763 CaseErrorStringifyHardCode( 0xDC004008, kOSMetaClassNoSuper
);
1764 CaseErrorStringifyHardCode( 0xDC004009, kOSMetaClassInstNoSuper
);
1765 CaseErrorStringifyHardCode( 0xDC00400A, kOSMetaClassDuplicateClass
);
1769 CaseErrorStringifyHardCode( 0xE00002BC, kIOReturnError
);
1770 CaseErrorStringifyHardCode( 0xE00002BD, kIOReturnNoMemory
);
1771 CaseErrorStringifyHardCode( 0xE00002BE, kIOReturnNoResources
);
1772 CaseErrorStringifyHardCode( 0xE00002BF, kIOReturnIPCError
);
1773 CaseErrorStringifyHardCode( 0xE00002C0, kIOReturnNoDevice
);
1774 CaseErrorStringifyHardCode( 0xE00002C1, kIOReturnNotPrivileged
);
1775 CaseErrorStringifyHardCode( 0xE00002C2, kIOReturnBadArgument
);
1776 CaseErrorStringifyHardCode( 0xE00002C3, kIOReturnLockedRead
);
1777 CaseErrorStringifyHardCode( 0xE00002C4, kIOReturnLockedWrite
);
1778 CaseErrorStringifyHardCode( 0xE00002C5, kIOReturnExclusiveAccess
);
1779 CaseErrorStringifyHardCode( 0xE00002C6, kIOReturnBadMessageID
);
1780 CaseErrorStringifyHardCode( 0xE00002C7, kIOReturnUnsupported
);
1781 CaseErrorStringifyHardCode( 0xE00002C8, kIOReturnVMError
);
1782 CaseErrorStringifyHardCode( 0xE00002C9, kIOReturnInternalError
);
1783 CaseErrorStringifyHardCode( 0xE00002CA, kIOReturnIOError
);
1784 CaseErrorStringifyHardCode( 0xE00002CC, kIOReturnCannotLock
);
1785 CaseErrorStringifyHardCode( 0xE00002CD, kIOReturnNotOpen
);
1786 CaseErrorStringifyHardCode( 0xE00002CE, kIOReturnNotReadable
);
1787 CaseErrorStringifyHardCode( 0xE00002CF, kIOReturnNotWritable
);
1788 CaseErrorStringifyHardCode( 0xE00002D0, kIOReturnNotAligned
);
1789 CaseErrorStringifyHardCode( 0xE00002D1, kIOReturnBadMedia
);
1790 CaseErrorStringifyHardCode( 0xE00002D2, kIOReturnStillOpen
);
1791 CaseErrorStringifyHardCode( 0xE00002D3, kIOReturnRLDError
);
1792 CaseErrorStringifyHardCode( 0xE00002D4, kIOReturnDMAError
);
1793 CaseErrorStringifyHardCode( 0xE00002D5, kIOReturnBusy
);
1794 CaseErrorStringifyHardCode( 0xE00002D6, kIOReturnTimeout
);
1795 CaseErrorStringifyHardCode( 0xE00002D7, kIOReturnOffline
);
1796 CaseErrorStringifyHardCode( 0xE00002D8, kIOReturnNotReady
);
1797 CaseErrorStringifyHardCode( 0xE00002D9, kIOReturnNotAttached
);
1798 CaseErrorStringifyHardCode( 0xE00002DA, kIOReturnNoChannels
);
1799 CaseErrorStringifyHardCode( 0xE00002DB, kIOReturnNoSpace
);
1800 CaseErrorStringifyHardCode( 0xE00002DD, kIOReturnPortExists
);
1801 CaseErrorStringifyHardCode( 0xE00002DE, kIOReturnCannotWire
);
1802 CaseErrorStringifyHardCode( 0xE00002DF, kIOReturnNoInterrupt
);
1803 CaseErrorStringifyHardCode( 0xE00002E0, kIOReturnNoFrames
);
1804 CaseErrorStringifyHardCode( 0xE00002E1, kIOReturnMessageTooLarge
);
1805 CaseErrorStringifyHardCode( 0xE00002E2, kIOReturnNotPermitted
);
1806 CaseErrorStringifyHardCode( 0xE00002E3, kIOReturnNoPower
);
1807 CaseErrorStringifyHardCode( 0xE00002E4, kIOReturnNoMedia
);
1808 CaseErrorStringifyHardCode( 0xE00002E5, kIOReturnUnformattedMedia
);
1809 CaseErrorStringifyHardCode( 0xE00002E6, kIOReturnUnsupportedMode
);
1810 CaseErrorStringifyHardCode( 0xE00002E7, kIOReturnUnderrun
);
1811 CaseErrorStringifyHardCode( 0xE00002E8, kIOReturnOverrun
);
1812 CaseErrorStringifyHardCode( 0xE00002E9, kIOReturnDeviceError
);
1813 CaseErrorStringifyHardCode( 0xE00002EA, kIOReturnNoCompletion
);
1814 CaseErrorStringifyHardCode( 0xE00002EB, kIOReturnAborted
);
1815 CaseErrorStringifyHardCode( 0xE00002EC, kIOReturnNoBandwidth
);
1816 CaseErrorStringifyHardCode( 0xE00002ED, kIOReturnNotResponding
);
1817 CaseErrorStringifyHardCode( 0xE00002EE, kIOReturnIsoTooOld
);
1818 CaseErrorStringifyHardCode( 0xE00002EF, kIOReturnIsoTooNew
);
1819 CaseErrorStringifyHardCode( 0xE00002F0, kIOReturnNotFound
);
1820 CaseErrorStringifyHardCode( 0xE0000001, kIOReturnInvalid
);
1822 // IOKit FireWire Errors
1824 CaseErrorStringifyHardCode( 0xE0008010, kIOFireWireResponseBase
);
1825 CaseErrorStringifyHardCode( 0xE0008020, kIOFireWireBusReset
);
1826 CaseErrorStringifyHardCode( 0xE0008001, kIOConfigNoEntry
);
1827 CaseErrorStringifyHardCode( 0xE0008002, kIOFireWirePending
);
1828 CaseErrorStringifyHardCode( 0xE0008003, kIOFireWireLastDCLToken
);
1829 CaseErrorStringifyHardCode( 0xE0008004, kIOFireWireConfigROMInvalid
);
1830 CaseErrorStringifyHardCode( 0xE0008005, kIOFireWireAlreadyRegistered
);
1831 CaseErrorStringifyHardCode( 0xE0008006, kIOFireWireMultipleTalkers
);
1832 CaseErrorStringifyHardCode( 0xE0008007, kIOFireWireChannelActive
);
1833 CaseErrorStringifyHardCode( 0xE0008008, kIOFireWireNoListenerOrTalker
);
1834 CaseErrorStringifyHardCode( 0xE0008009, kIOFireWireNoChannels
);
1835 CaseErrorStringifyHardCode( 0xE000800A, kIOFireWireChannelNotAvailable
);
1836 CaseErrorStringifyHardCode( 0xE000800B, kIOFireWireSeparateBus
);
1837 CaseErrorStringifyHardCode( 0xE000800C, kIOFireWireBadSelfIDs
);
1838 CaseErrorStringifyHardCode( 0xE000800D, kIOFireWireLowCableVoltage
);
1839 CaseErrorStringifyHardCode( 0xE000800E, kIOFireWireInsufficientPower
);
1840 CaseErrorStringifyHardCode( 0xE000800F, kIOFireWireOutOfTLabels
);
1841 CaseErrorStringifyHardCode( 0xE0008101, kIOFireWireBogusDCLProgram
);
1842 CaseErrorStringifyHardCode( 0xE0008102, kIOFireWireTalkingAndListening
);
1843 CaseErrorStringifyHardCode( 0xE0008103, kIOFireWireHardwareSlept
);
1844 CaseErrorStringifyHardCode( 0xE00087D0, kIOFWMessageServiceIsRequestingClose
);
1845 CaseErrorStringifyHardCode( 0xE00087D1, kIOFWMessagePowerStateChanged
);
1846 CaseErrorStringifyHardCode( 0xE00087D2, kIOFWMessageTopologyChanged
);
1850 CaseErrorStringifyHardCode( 0xE0004061, kIOUSBUnknownPipeErr
);
1851 CaseErrorStringifyHardCode( 0xE0004060, kIOUSBTooManyPipesErr
);
1852 CaseErrorStringifyHardCode( 0xE000405F, kIOUSBNoAsyncPortErr
);
1853 CaseErrorStringifyHardCode( 0xE000405E, kIOUSBNotEnoughPipesErr
);
1854 CaseErrorStringifyHardCode( 0xE000405D, kIOUSBNotEnoughPowerErr
);
1855 CaseErrorStringifyHardCode( 0xE0004057, kIOUSBEndpointNotFound
);
1856 CaseErrorStringifyHardCode( 0xE0004056, kIOUSBConfigNotFound
);
1857 CaseErrorStringifyHardCode( 0xE0004051, kIOUSBTransactionTimeout
);
1858 CaseErrorStringifyHardCode( 0xE0004050, kIOUSBTransactionReturned
);
1859 CaseErrorStringifyHardCode( 0xE000404F, kIOUSBPipeStalled
);
1860 CaseErrorStringifyHardCode( 0xE000404E, kIOUSBInterfaceNotFound
);
1861 CaseErrorStringifyHardCode( 0xE000404D, kIOUSBLowLatencyBufferNotPreviouslyAllocated
);
1862 CaseErrorStringifyHardCode( 0xE000404C, kIOUSBLowLatencyFrameListNotPreviouslyAllocated
);
1863 CaseErrorStringifyHardCode( 0xE000404B, kIOUSBHighSpeedSplitError
);
1864 CaseErrorStringifyHardCode( 0xE0004010, kIOUSBLinkErr
);
1865 CaseErrorStringifyHardCode( 0xE000400F, kIOUSBNotSent2Err
);
1866 CaseErrorStringifyHardCode( 0xE000400E, kIOUSBNotSent1Err
);
1867 CaseErrorStringifyHardCode( 0xE000400D, kIOUSBBufferUnderrunErr
);
1868 CaseErrorStringifyHardCode( 0xE000400C, kIOUSBBufferOverrunErr
);
1869 CaseErrorStringifyHardCode( 0xE000400B, kIOUSBReserved2Err
);
1870 CaseErrorStringifyHardCode( 0xE000400A, kIOUSBReserved1Err
);
1871 CaseErrorStringifyHardCode( 0xE0004007, kIOUSBWrongPIDErr
);
1872 CaseErrorStringifyHardCode( 0xE0004006, kIOUSBPIDCheckErr
);
1873 CaseErrorStringifyHardCode( 0xE0004003, kIOUSBDataToggleErr
);
1874 CaseErrorStringifyHardCode( 0xE0004002, kIOUSBBitstufErr
);
1875 CaseErrorStringifyHardCode( 0xE0004001, kIOUSBCRCErr
);
1883 #if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
1884 if( inBuffer
&& ( inBufferSize
> 0 ) )
1888 n
= FormatMessageA( FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_IGNORE_INSERTS
, NULL
, (DWORD
) inErrorCode
,
1889 MAKELANGID( LANG_NEUTRAL
, SUBLANG_DEFAULT
), buffer
, sizeof( buffer
), NULL
);
1892 // Remove any trailing CR's or LF's since some messages have them.
1894 while( ( n
> 0 ) && isspace( ( (unsigned char *) buffer
)[ n
- 1 ] ) )
1896 buffer
[ --n
] = '\0';
1905 #if ( !TARGET_API_MAC_OSX_KERNEL && !TARGET_OS_WINDOWS_CE )
1906 s
= strerror( inErrorCode
);
1910 s
= "<unknown error code>";
1916 // Copy the string to the output buffer. If no buffer is supplied or it is empty, return an empty string.
1918 if( inBuffer
&& ( inBufferSize
> 0 ) )
1921 end
= dst
+ ( inBufferSize
- 1 );
1922 while( ( ( end
- dst
) > 0 ) && ( *s
!= '\0' ) )
1938 const char * inLabel
,
1940 int inLabelMinWidth
,
1941 const char * inType
,
1943 const void * inDataStart
,
1944 const void * inData
,
1948 size_t inBufferSize
)
1950 static const char kHexChars
[] = "0123456789ABCDEF";
1951 const uint8_t * start
;
1952 const uint8_t * src
;
1958 const char * newline
;
1959 char separator
[ 8 ];
1962 DEBUG_UNUSED( inType
);
1963 DEBUG_UNUSED( inTypeSize
);
1965 // Set up the function-wide variables.
1967 if( inLabelSize
== kSizeCString
)
1969 inLabelSize
= strlen( inLabel
);
1971 start
= (const uint8_t *) inData
;
1974 end
= dst
+ inBufferSize
;
1975 offset
= (int)( (intptr_t) inData
- (intptr_t) inDataStart
);
1976 width
= ( (int) inLabelSize
> inLabelMinWidth
) ? (int) inLabelSize
: inLabelMinWidth
;
1977 newline
= ( inFlags
& kDebugFlagsNoNewLine
) ? "" : "\n";
1979 // Set up the separator string. This is used to insert spaces on subsequent "lines" when not using newlines.
1982 if( inFlags
& kDebugFlagsNoNewLine
)
1984 if( inFlags
& kDebugFlags8BitSeparator
)
1988 if( inFlags
& kDebugFlags16BitSeparator
)
1992 if( !( inFlags
& kDebugFlagsNo32BitSeparator
) )
1996 check( ( (size_t)( s
- separator
) ) < sizeof( separator
) );
2002 char prefixString
[ 32 ];
2003 char hexString
[ 64 ];
2004 char asciiString
[ 32 ];
2005 char byteCountString
[ 32 ];
2010 // If this is a label-only item (i.e. no data), print the label (accounting for prefix string spacing) and exit.
2012 if( inDataSize
== 0 )
2014 if( inLabel
&& ( inLabelSize
> 0 ) )
2017 if( !( inFlags
& kDebugFlagsNoAddress
) )
2019 width
+= 8; // "00000000"
2020 if( !( inFlags
& kDebugFlagsNoOffset
) )
2025 if( inFlags
& kDebugFlags32BitOffset
)
2027 width
+= 8; // "00000000"
2029 else if( !( inFlags
& kDebugFlagsNoOffset
) )
2031 width
+= 4; // "0000"
2036 dst
+= DebugSNPrintF( dst
, (size_t)( end
- dst
), "%*s" "%-*.*s" "%.*s" "%s",
2038 ( width
> 0 ) ? ": " : "",
2039 width
, (int) inLabelSize
, inLabel
,
2044 dst
+= DebugPrintF( inLevel
, "%*s" "%-*.*s" "%.*s" "%s",
2046 ( width
> 0 ) ? ": " : "",
2047 width
, (int) inLabelSize
, inLabel
,
2054 // Build the prefix string. It will be in one of the following formats:
2056 // 1) "00000000+0000[0000]" (address and offset)
2057 // 2) "00000000" (address only)
2058 // 3) "0000[0000]" (offset only)
2059 // 4) "" (no address or offset)
2061 // Note: If we're printing multiple "lines", but not printing newlines, a space is used to separate.
2064 if( !( inFlags
& kDebugFlagsNoAddress
) )
2066 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 28 ) & 0xF ];
2067 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 24 ) & 0xF ];
2068 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 20 ) & 0xF ];
2069 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 16 ) & 0xF ];
2070 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 12 ) & 0xF ];
2071 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 8 ) & 0xF ];
2072 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 4 ) & 0xF ];
2073 *s
++ = kHexChars
[ ( (uintptr_t) src
) & 0xF ];
2075 if( !( inFlags
& kDebugFlagsNoOffset
) )
2080 if( !( inFlags
& kDebugFlagsNoOffset
) )
2082 if( inFlags
& kDebugFlags32BitOffset
)
2084 *s
++ = kHexChars
[ ( offset
>> 28 ) & 0xF ];
2085 *s
++ = kHexChars
[ ( offset
>> 24 ) & 0xF ];
2086 *s
++ = kHexChars
[ ( offset
>> 20 ) & 0xF ];
2087 *s
++ = kHexChars
[ ( offset
>> 16 ) & 0xF ];
2089 *s
++ = kHexChars
[ ( offset
>> 12 ) & 0xF ];
2090 *s
++ = kHexChars
[ ( offset
>> 8 ) & 0xF ];
2091 *s
++ = kHexChars
[ ( offset
>> 4 ) & 0xF ];
2092 *s
++ = kHexChars
[ offset
& 0xF ];
2094 if( s
!= prefixString
)
2099 check( ( (size_t)( s
- prefixString
) ) < sizeof( prefixString
) );
2102 // Build a hex string with a optional spaces after every 1, 2, and/or 4 bytes to make it easier to read.
2103 // Optionally pads the hex string with space to fill the full 16 byte range (so it lines up).
2106 chunkSize
= ( inDataSize
< 16 ) ? inDataSize
: 16;
2107 n
= ( inFlags
& kDebugFlagsNo16ByteHexPad
) ? chunkSize
: 16;
2108 for( i
= 0; i
< n
; ++i
)
2110 if( ( inFlags
& kDebugFlags8BitSeparator
) && ( i
> 0 ) )
2114 if( ( inFlags
& kDebugFlags16BitSeparator
) && ( i
> 0 ) && ( ( i
% 2 ) == 0 ) )
2118 if( !( inFlags
& kDebugFlagsNo32BitSeparator
) && ( i
> 0 ) && ( ( i
% 4 ) == 0 ) )
2124 *s
++ = kHexChars
[ src
[ i
] >> 4 ];
2125 *s
++ = kHexChars
[ src
[ i
] & 0xF ];
2133 check( ( (size_t)( s
- hexString
) ) < sizeof( hexString
) );
2136 // Build a string with the ASCII version of the data (replaces non-printable characters with '^').
2137 // Optionally pads the string with '`' to fill the full 16 byte range (so it lines up).
2140 if( !( inFlags
& kDebugFlagsNoASCII
) )
2144 for( i
= 0; i
< n
; ++i
)
2149 if( !DebugIsPrint( c
) )
2161 check( ( (size_t)( s
- asciiString
) ) < sizeof( asciiString
) );
2165 // Build a string indicating how bytes are in the hex dump. Only printed on the first line.
2167 s
= byteCountString
;
2168 if( !( inFlags
& kDebugFlagsNoByteCount
) )
2172 s
+= DebugSNPrintF( s
, sizeof( byteCountString
), " (%d bytes)", (int) inDataSize
);
2175 check( ( (size_t)( s
- byteCountString
) ) < sizeof( byteCountString
) );
2178 // Build the entire line from all the pieces we've previously built.
2184 dst
+= DebugSNPrintF( dst
, (size_t)( end
- dst
),
2186 "%s" // Separator (only if needed)
2195 ( src
!= start
) ? separator
: "",
2197 width
, (int) inLabelSize
, inLabel
? inLabel
: "",
2198 ( width
> 0 ) ? " " : "",
2206 dst
+= DebugSNPrintF( dst
, (size_t)( end
- dst
),
2208 "%s" // Separator (only if needed)
2210 "%*s" // Label Spacing
2217 ( src
!= start
) ? separator
: "",
2220 ( width
> 0 ) ? " " : "",
2231 dst
+= DebugPrintF( inLevel
,
2233 "%s" // Separator (only if needed)
2242 ( src
!= start
) ? separator
: "",
2244 width
, (int) inLabelSize
, inLabel
,
2245 ( width
> 0 ) ? " " : "",
2253 dst
+= DebugPrintF( inLevel
,
2255 "%s" // Separator (only if needed)
2257 "%*s" // Label Spacing
2264 ( src
!= start
) ? separator
: "",
2267 ( width
> 0 ) ? " " : "",
2275 // Move to the next chunk. Exit if there is no more data.
2277 offset
+= (int) chunkSize
;
2279 inDataSize
-= chunkSize
;
2280 if( inDataSize
== 0 )
2286 // Note: The "dst - outBuffer" size calculation works even if "outBuffer" is NULL because it's all relative.
2288 return (size_t)( dst
- outBuffer
);
2292 // DebugNumVersionToString
2293 static char * DebugNumVersionToString( uint32_t inVersion
, char *inString
)
2304 majorRev
= (uint8_t)( ( inVersion
>> 24 ) & 0xFF );
2305 minor
= (uint8_t)( ( inVersion
>> 20 ) & 0x0F );
2306 bugFix
= (uint8_t)( ( inVersion
>> 16 ) & 0x0F );
2307 stage
= (uint8_t)( ( inVersion
>> 8 ) & 0xFF );
2308 revision
= (uint8_t)( inVersion
& 0xFF );
2310 // Convert the major, minor, and bugfix numbers.
2313 s
+= sprintf( s
, "%u", majorRev
);
2314 s
+= sprintf( s
, ".%u", minor
);
2317 s
+= sprintf( s
, ".%u", bugFix
);
2320 // Convert the version stage and non-release revision number.
2324 case kVersionStageDevelopment
:
2325 s
+= sprintf( s
, "d%u", revision
);
2328 case kVersionStageAlpha
:
2329 s
+= sprintf( s
, "a%u", revision
);
2332 case kVersionStageBeta
:
2333 s
+= sprintf( s
, "b%u", revision
);
2336 case kVersionStageFinal
:
2338 // A non-release revision of zero is a special case indicating the software is GM (at the golden master
2339 // stage) and therefore, the non-release revision should not be added to the string.
2343 s
+= sprintf( s
, "f%u", revision
);
2348 dlog( kDebugLevelError
, "invalid NumVersion stage (0x%02X)\n", stage
);
2356 DEBUG_EXPORT
uint32_t DebugTaskLevel( void )
2362 #if ( TARGET_OS_VXWORKS )
2365 level
|= ( ( 1 << kDebugInterruptLevelShift
) & kDebugInterruptLevelMask
);
2372 #if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
2374 // DebugWinEnableConsole
2375 #pragma warning( disable:4311 )
2377 static void DebugWinEnableConsole( void )
2379 static bool sConsoleEnabled
= false;
2385 if( sConsoleEnabled
)
2390 // Create console window.
2392 result
= AllocConsole();
2393 require_quiet( result
, exit
);
2395 // Redirect stdin to the console stdin.
2397 fileHandle
= _open_osfhandle( (long) GetStdHandle( STD_INPUT_HANDLE
), _O_TEXT
);
2399 #if ( defined( __MWERKS__ ) )
2400 file
= __handle_reopen( (unsigned long) fileHandle
, "r", stdin
);
2401 require_quiet( file
, exit
);
2403 file
= _fdopen( fileHandle
, "r" );
2404 require_quiet( file
, exit
);
2409 err
= setvbuf( stdin
, NULL
, _IONBF
, 0 );
2410 require_noerr_quiet( err
, exit
);
2412 // Redirect stdout to the console stdout.
2414 fileHandle
= _open_osfhandle( (long) GetStdHandle( STD_OUTPUT_HANDLE
), _O_TEXT
);
2416 #if ( defined( __MWERKS__ ) )
2417 file
= __handle_reopen( (unsigned long) fileHandle
, "w", stdout
);
2418 require_quiet( file
, exit
);
2420 file
= _fdopen( fileHandle
, "w" );
2421 require_quiet( file
, exit
);
2426 err
= setvbuf( stdout
, NULL
, _IONBF
, 0 );
2427 require_noerr_quiet( err
, exit
);
2429 // Redirect stderr to the console stdout.
2431 fileHandle
= _open_osfhandle( (long) GetStdHandle( STD_OUTPUT_HANDLE
), _O_TEXT
);
2433 #if ( defined( __MWERKS__ ) )
2434 file
= __handle_reopen( (unsigned long) fileHandle
, "w", stderr
);
2435 require_quiet( file
, exit
);
2437 file
= _fdopen( fileHandle
, "w" );
2438 require_quiet( file
, exit
);
2443 err
= setvbuf( stderr
, NULL
, _IONBF
, 0 );
2444 require_noerr_quiet( err
, exit
);
2446 sConsoleEnabled
= true;
2452 #pragma warning( default:4311 )
2454 #endif // TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE
2456 #if ( TARGET_OS_WIN32 )
2458 // DebugWinCharToTCharString
2460 DebugWinCharToTCharString(
2461 const char * inCharString
,
2463 TCHAR
* outTCharString
,
2464 size_t inTCharCountMax
,
2465 size_t * outTCharCount
)
2471 if( inCharCount
== kSizeCString
)
2473 inCharCount
= strlen( inCharString
);
2476 dst
= outTCharString
;
2477 if( inTCharCountMax
> 0 )
2479 inTCharCountMax
-= 1;
2480 if( inTCharCountMax
> inCharCount
)
2482 inTCharCountMax
= inCharCount
;
2485 end
= dst
+ inTCharCountMax
;
2488 *dst
++ = (TCHAR
) *src
++;
2494 *outTCharCount
= (size_t)( dst
- outTCharString
);
2496 return outTCharString
;
2502 #pragma mark == Debugging ==
2506 // DebugServicesTest
2507 DEBUG_EXPORT OSStatus
DebugServicesTest( void )
2514 0x11, 0x22, 0x33, 0x44,
2516 0x77, 0x88, 0x99, 0xAA,
2520 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
2521 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0,
2522 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71, 0x81, 0x91, 0xA1
2525 debug_initialize( kDebugOutputTypeMetaConsole
);
2529 check( 0 && "SHOULD SEE: check" );
2530 check( 1 && "SHOULD *NOT* SEE: check (valid)" );
2531 check_string( 0, "SHOULD SEE: check_string" );
2532 check_string( 1, "SHOULD *NOT* SEE: check_string (valid)" );
2533 check_noerr( -123 );
2534 check_noerr( 10038 );
2537 check_noerr_string( -6712, "SHOULD SEE: check_noerr_string" );
2538 check_noerr_string( 0, "SHOULD *NOT* SEE: check_noerr_string (valid)" );
2539 check_translated_errno( 0 >= 0 && "SHOULD *NOT* SEE", -384, -999 );
2540 check_translated_errno( -1 >= 0 && "SHOULD SEE", -384, -999 );
2541 check_translated_errno( -1 >= 0 && "SHOULD SEE", 0, -999 );
2542 check_ptr_overlap( "SHOULD *NOT* SEE" ? 10 : 0, 10, 22, 10 );
2543 check_ptr_overlap( "SHOULD SEE" ? 10 : 0, 10, 5, 10 );
2544 check_ptr_overlap( "SHOULD SEE" ? 10 : 0, 10, 12, 6 );
2545 check_ptr_overlap( "SHOULD SEE" ? 12 : 0, 6, 10, 10 );
2546 check_ptr_overlap( "SHOULD SEE" ? 12 : 0, 10, 10, 10 );
2547 check_ptr_overlap( "SHOULD *NOT* SEE" ? 22 : 0, 10, 10, 10 );
2548 check_ptr_overlap( "SHOULD *NOT* SEE" ? 10 : 0, 10, 20, 10 );
2549 check_ptr_overlap( "SHOULD *NOT* SEE" ? 20 : 0, 10, 10, 10 );
2553 require( 0 && "SHOULD SEE", require1
);
2554 { err
= kResponseErr
; goto exit
; }
2556 require( 1 && "SHOULD *NOT* SEE", require2
);
2559 { err
= kResponseErr
; goto exit
; }
2561 require_string( 0 && "SHOULD SEE", require3
, "SHOULD SEE: require_string" );
2562 { err
= kResponseErr
; goto exit
; }
2564 require_string( 1 && "SHOULD *NOT* SEE", require4
, "SHOULD *NOT* SEE: require_string (valid)" );
2567 { err
= kResponseErr
; goto exit
; }
2569 require_quiet( 0 && "SHOULD SEE", require5
);
2570 { err
= kResponseErr
; goto exit
; }
2572 require_quiet( 1 && "SHOULD *NOT* SEE", require6
);
2575 { err
= kResponseErr
; goto exit
; }
2577 require_noerr( -1, require7
);
2578 { err
= kResponseErr
; goto exit
; }
2580 require_noerr( 0, require8
);
2583 { err
= kResponseErr
; goto exit
; }
2585 require_noerr_string( -2, require9
, "SHOULD SEE: require_noerr_string");
2586 { err
= kResponseErr
; goto exit
; }
2588 require_noerr_string( 0, require10
, "SHOULD *NOT* SEE: require_noerr_string (valid)" );
2591 { err
= kResponseErr
; goto exit
; }
2593 require_noerr_action_string( -3, require11
, dlog( kDebugLevelMax
, "action 1 (expected)\n" ), "require_noerr_action_string" );
2594 { err
= kResponseErr
; goto exit
; }
2596 require_noerr_action_string( 0, require12
, dlog( kDebugLevelMax
, "action 2\n" ), "require_noerr_action_string (valid)" );
2599 { err
= kResponseErr
; goto exit
; }
2601 require_noerr_quiet( -4, require13
);
2602 { err
= kResponseErr
; goto exit
; }
2604 require_noerr_quiet( 0, require14
);
2607 { err
= kResponseErr
; goto exit
; }
2609 require_noerr_action( -5, require15
, dlog( kDebugLevelMax
, "SHOULD SEE: action 3 (expected)\n" ) );
2610 { err
= kResponseErr
; goto exit
; }
2612 require_noerr_action( 0, require16
, dlog( kDebugLevelMax
, "SHOULD *NOT* SEE: action 4\n" ) );
2615 { err
= kResponseErr
; goto exit
; }
2617 require_noerr_action_quiet( -4, require17
, dlog( kDebugLevelMax
, "SHOULD SEE: action 5 (expected)\n" ) );
2618 { err
= kResponseErr
; goto exit
; }
2620 require_noerr_action_quiet( 0, require18
, dlog( kDebugLevelMax
, "SHOULD *NOT* SEE: action 6\n" ) );
2623 { err
= kResponseErr
; goto exit
; }
2625 require_action( 0 && "SHOULD SEE", require19
, dlog( kDebugLevelMax
, "SHOULD SEE: action 7 (expected)\n" ) );
2626 { err
= kResponseErr
; goto exit
; }
2628 require_action( 1 && "SHOULD *NOT* SEE", require20
, dlog( kDebugLevelMax
, "SHOULD *NOT* SEE: action 8\n" ) );
2631 { err
= kResponseErr
; goto exit
; }
2633 require_action_quiet( 0, require21
, dlog( kDebugLevelMax
, "SHOULD SEE: action 9 (expected)\n" ) );
2634 { err
= kResponseErr
; goto exit
; }
2636 require_action_quiet( 1, require22
, dlog( kDebugLevelMax
, "SHOULD *NOT* SEE: action 10\n" ) );
2639 { err
= kResponseErr
; goto exit
; }
2641 require_action_string( 0, require23
, dlog( kDebugLevelMax
, "SHOULD SEE: action 11 (expected)\n" ), "SHOULD SEE: require_action_string" );
2642 { err
= kResponseErr
; goto exit
; }
2644 require_action_string( 1, require24
, dlog( kDebugLevelMax
, "SHOULD *NOT* SEE: action 12\n" ), "SHOULD *NOT* SEE: require_action_string" );
2647 { err
= kResponseErr
; goto exit
; }
2650 #if ( defined( __MWERKS__ ) )
2651 #if ( defined( __cplusplus ) && __option( exceptions ) )
2652 #define COMPILER_HAS_EXCEPTIONS 1
2654 #define COMPILER_HAS_EXCEPTIONS 0
2657 #if ( defined( __cplusplus ) )
2658 #define COMPILER_HAS_EXCEPTIONS 1
2660 #define COMPILER_HAS_EXCEPTIONS 0
2664 #if ( COMPILER_HAS_EXCEPTIONS )
2667 require_throw( 1 && "SHOULD *NOT* SEE" );
2668 require_throw( 0 && "SHOULD SEE" );
2674 { err
= kResponseErr
; goto exit
; }
2680 err
= translate_errno( 1 != -1, -123, -567 );
2681 require( ( err
== 0 ) && "SHOULD *NOT* SEE", exit
);
2683 err
= translate_errno( -1 != -1, -123, -567 );
2684 require( ( err
== -123 ) && "SHOULD *NOT* SEE", exit
);
2686 err
= translate_errno( -1 != -1, 0, -567 );
2687 require( ( err
== -567 ) && "SHOULD *NOT* SEE", exit
);
2691 debug_string( "debug_string" );
2695 DebugSNPrintF( s
, sizeof( s
), "%d", 1234 );
2696 require_action( strcmp( s
, "1234" ) == 0, exit
, err
= -1 );
2698 DebugSNPrintF( s
, sizeof( s
), "%X", 0x2345 );
2699 require_action( strcmp( s
, "2345" ) == 0, exit
, err
= -1 );
2701 DebugSNPrintF( s
, sizeof( s
), "%#s", "\05test" );
2702 require_action( strcmp( s
, "test" ) == 0, exit
, err
= -1 );
2704 DebugSNPrintF( s
, sizeof( s
), "%##s", "\03www\05apple\03com" );
2705 require_action( strcmp( s
, "www.apple.com." ) == 0, exit
, err
= -1 );
2707 DebugSNPrintF( s
, sizeof( s
), "%ld", (long) INT32_C( 2147483647 ) );
2708 require_action( strcmp( s
, "2147483647" ) == 0, exit
, err
= -1 );
2710 DebugSNPrintF( s
, sizeof( s
), "%lu", (unsigned long) UINT32_C( 4294967295 ) );
2711 require_action( strcmp( s
, "4294967295" ) == 0, exit
, err
= -1 );
2713 #if ( TYPE_LONGLONG_NATIVE )
2714 DebugSNPrintF( s
, sizeof( s
), "%lld", (long_long_compat
) INT64_C( 9223372036854775807 ) );
2715 require_action( strcmp( s
, "9223372036854775807" ) == 0, exit
, err
= -1 );
2717 DebugSNPrintF( s
, sizeof( s
), "%lld", (long_long_compat
) INT64_C( -9223372036854775807 ) );
2718 require_action( strcmp( s
, "-9223372036854775807" ) == 0, exit
, err
= -1 );
2720 DebugSNPrintF( s
, sizeof( s
), "%llu", (unsigned_long_long_compat
) UINT64_C( 18446744073709551615 ) );
2721 require_action( strcmp( s
, "18446744073709551615" ) == 0, exit
, err
= -1 );
2724 DebugSNPrintF( s
, sizeof( s
), "%lb", (unsigned long) binary_32( 01111011, 01111011, 01111011, 01111011 ) );
2725 require_action( strcmp( s
, "1111011011110110111101101111011" ) == 0, exit
, err
= -1 );
2727 DebugSNPrintF( s
, sizeof( s
), "%C", 0x41624364 ); // 'AbCd'
2728 require_action( strcmp( s
, "AbCd" ) == 0, exit
, err
= -1 );
2730 #if ( defined( MDNS_DEBUGMSGS ) )
2734 memset( &maddr
, 0, sizeof( maddr
) );
2735 maddr
.type
= mDNSAddrType_IPv4
;
2736 maddr
.ip
.v4
.b
[ 0 ] = 127;
2737 maddr
.ip
.v4
.b
[ 1 ] = 0;
2738 maddr
.ip
.v4
.b
[ 2 ] = 0;
2739 maddr
.ip
.v4
.b
[ 3 ] = 1;
2740 DebugSNPrintF( s
, sizeof( s
), "%#a", &maddr
);
2741 require_action( strcmp( s
, "127.0.0.1" ) == 0, exit
, err
= -1 );
2743 memset( &maddr
, 0, sizeof( maddr
) );
2744 maddr
.type
= mDNSAddrType_IPv6
;
2745 maddr
.ip
.v6
.b
[ 0 ] = 0xFE;
2746 maddr
.ip
.v6
.b
[ 1 ] = 0x80;
2747 maddr
.ip
.v6
.b
[ 15 ] = 0x01;
2748 DebugSNPrintF( s
, sizeof( s
), "%#a", &maddr
);
2749 require_action( strcmp( s
, "FE80:0000:0000:0000:0000:0000:0000:0001" ) == 0, exit
, err
= -1 );
2755 struct sockaddr_in sa4
;
2757 memset( &sa4
, 0, sizeof( sa4
) );
2758 sa4
.sin_family
= AF_INET
;
2759 p
= (uint8_t *) &sa4
.sin_port
;
2760 p
[ 0 ] = (uint8_t)( ( 80 >> 8 ) & 0xFF );
2761 p
[ 1 ] = (uint8_t)( 80 & 0xFF );
2762 p
= (uint8_t *) &sa4
.sin_addr
.s_addr
;
2763 p
[ 0 ] = (uint8_t)( ( INADDR_LOOPBACK
>> 24 ) & 0xFF );
2764 p
[ 1 ] = (uint8_t)( ( INADDR_LOOPBACK
>> 16 ) & 0xFF );
2765 p
[ 2 ] = (uint8_t)( ( INADDR_LOOPBACK
>> 8 ) & 0xFF );
2766 p
[ 3 ] = (uint8_t)( INADDR_LOOPBACK
& 0xFF );
2767 DebugSNPrintF( s
, sizeof( s
), "%##a", &sa4
);
2768 require_action( strcmp( s
, "127.0.0.1:80" ) == 0, exit
, err
= -1 );
2774 struct sockaddr_in6 sa6
;
2776 memset( &sa6
, 0, sizeof( sa6
) );
2777 sa6
.sin6_family
= AF_INET6
;
2778 p
= (uint8_t *) &sa6
.sin6_port
;
2779 p
[ 0 ] = (uint8_t)( ( 80 >> 8 ) & 0xFF );
2780 p
[ 1 ] = (uint8_t)( 80 & 0xFF );
2781 sa6
.sin6_addr
.s6_addr
[ 0 ] = 0xFE;
2782 sa6
.sin6_addr
.s6_addr
[ 1 ] = 0x80;
2783 sa6
.sin6_addr
.s6_addr
[ 15 ] = 0x01;
2784 sa6
.sin6_scope_id
= 2;
2785 DebugSNPrintF( s
, sizeof( s
), "%##a", &sa6
);
2786 require_action( strcmp( s
, "[FE80:0000:0000:0000:0000:0000:0000:0001%2]:80" ) == 0, exit
, err
= -1 );
2792 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "tes" );
2793 require_action( strcmp( s
, "tes" ) == 0, exit
, err
= kResponseErr
);
2795 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "test" );
2796 require_action( strcmp( s
, "test" ) == 0, exit
, err
= kResponseErr
);
2798 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "testing" );
2799 require_action( strcmp( s
, "test" ) == 0, exit
, err
= kResponseErr
);
2801 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "te\xC3\xA9" );
2802 require_action( strcmp( s
, "te\xC3\xA9" ) == 0, exit
, err
= kResponseErr
);
2804 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "te\xC3\xA9ing" );
2805 require_action( strcmp( s
, "te\xC3\xA9" ) == 0, exit
, err
= kResponseErr
);
2807 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "tes\xC3\xA9ing" );
2808 require_action( strcmp( s
, "tes" ) == 0, exit
, err
= kResponseErr
);
2810 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "t\xed\x9f\xbf" );
2811 require_action( strcmp( s
, "t\xed\x9f\xbf" ) == 0, exit
, err
= kResponseErr
);
2813 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "t\xed\x9f\xbfing" );
2814 require_action( strcmp( s
, "t\xed\x9f\xbf" ) == 0, exit
, err
= kResponseErr
);
2816 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "te\xed\x9f\xbf" );
2817 require_action( strcmp( s
, "te" ) == 0, exit
, err
= kResponseErr
);
2819 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "te\xed\x9f\xbfing" );
2820 require_action( strcmp( s
, "te" ) == 0, exit
, err
= kResponseErr
);
2822 DebugSNPrintF(s
, sizeof(s
), "%.*s", 7, "te\xC3\xA9\xed\x9f\xbfing" );
2823 require_action( strcmp( s
, "te\xC3\xA9\xed\x9f\xbf" ) == 0, exit
, err
= kResponseErr
);
2825 DebugSNPrintF(s
, sizeof(s
), "%.*s", 6, "te\xC3\xA9\xed\x9f\xbfing" );
2826 require_action( strcmp( s
, "te\xC3\xA9" ) == 0, exit
, err
= kResponseErr
);
2828 DebugSNPrintF(s
, sizeof(s
), "%.*s", 5, "te\xC3\xA9\xed\x9f\xbfing" );
2829 require_action( strcmp( s
, "te\xC3\xA9" ) == 0, exit
, err
= kResponseErr
);
2831 #if ( TARGET_RT_BIG_ENDIAN )
2832 DebugSNPrintF( s
, sizeof( s
), "%S", "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" );
2833 require_action( strcmp( s
, "abcd" ) == 0, exit
, err
= -1 );
2835 DebugSNPrintF( s
, sizeof( s
), "%S", "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" "\x00" );
2836 require_action( strcmp( s
, "abcd" ) == 0, exit
, err
= -1 );
2839 DebugSNPrintF( s
, sizeof( s
), "%S",
2840 "\xFE\xFF" "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" ); // Big Endian BOM
2841 require_action( strcmp( s
, "abcd" ) == 0, exit
, err
= -1 );
2843 DebugSNPrintF( s
, sizeof( s
), "%S",
2844 "\xFF\xFE" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" "\x00" ); // Little Endian BOM
2845 require_action( strcmp( s
, "abcd" ) == 0, exit
, err
= -1 );
2847 DebugSNPrintF( s
, sizeof( s
), "%#S", "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" ); // Big Endian
2848 require_action( strcmp( s
, "abcd" ) == 0, exit
, err
= -1 );
2850 DebugSNPrintF( s
, sizeof( s
), "%##S", "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" "\x00" ); // Little Endian
2851 require_action( strcmp( s
, "abcd" ) == 0, exit
, err
= -1 );
2853 DebugSNPrintF( s
, sizeof( s
), "%.*S",
2854 4, "\xFE\xFF" "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" ); // Big Endian BOM
2855 require_action( strcmp( s
, "abc" ) == 0, exit
, err
= -1 );
2857 DebugSNPrintF( s
, sizeof( s
), "%.*S",
2858 4, "\xFF\xFE" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" ); // Little Endian BOM
2859 require_action( strcmp( s
, "abc" ) == 0, exit
, err
= -1 );
2861 #if ( TARGET_RT_BIG_ENDIAN )
2862 DebugSNPrintF( s
, sizeof( s
), "%.*S", 3, "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" );
2863 require_action( strcmp( s
, "abc" ) == 0, exit
, err
= -1 );
2865 DebugSNPrintF( s
, sizeof( s
), "%.*S", 3, "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" );
2866 require_action( strcmp( s
, "abc" ) == 0, exit
, err
= -1 );
2869 DebugSNPrintF( s
, sizeof( s
), "%#.*S", 3, "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" ); // Big Endian
2870 require_action( strcmp( s
, "abc" ) == 0, exit
, err
= -1 );
2872 DebugSNPrintF( s
, sizeof( s
), "%##.*S", 3, "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" ); // Little Endian
2873 require_action( strcmp( s
, "abc" ) == 0, exit
, err
= -1 );
2877 DebugSNPrintF( s
, sizeof( s
), "%U", "\x10\xb8\xa7\x6b" "\xad\x9d" "\xd1\x11" "\x80\xb4" "\x00\xc0\x4f\xd4\x30\xc8" );
2878 require_action( strcmp( s
, "6ba7b810-9dad-11d1-80b4-00c04fd430c8" ) == 0, exit
, err
= -1 );
2880 DebugSNPrintF( s
, sizeof( s
), "%m", 0 );
2881 require_action( strcmp( s
, "no error" ) == 0, exit
, err
= -1 );
2883 DebugSNPrintF( s
, sizeof( s
), "%lm", (long) 0 );
2884 require_action( strcmp( s
, "no error" ) == 0, exit
, err
= -1 );
2886 DebugSNPrintF( s
, sizeof( s
), "\"%H\"", "\x6b\xa7\xb8\x10\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8", 16, 16 );
2887 DebugPrintF( kDebugLevelMax
, "%s\n\n", s
);
2889 DebugSNPrintF( s
, sizeof( s
), "\"%H\"",
2890 "\x6b\xa7\xb8\x10\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8"
2891 "\x6b\xa7\xb8\x10\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8",
2893 DebugPrintF( kDebugLevelMax
, "%s\n\n", s
);
2895 DebugSNPrintF( s
, sizeof( s
), "\"%H\"", "\x6b\xa7", 2, 2 );
2896 DebugPrintF( kDebugLevelMax
, "%s\n\n", s
);
2901 DebugHexDump( kDebugLevelMax
, 0, "My Label", kSizeCString
, 0, NULL
, 0, data
, data
, sizeof( data
),
2902 kDebugFlagsNone
, s
, sizeof( s
) );
2903 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
2906 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
),
2907 kDebugFlagsNoAddress
| kDebugFlagsNoOffset
, s
, sizeof( s
) );
2908 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
2911 DebugHexDump( kDebugLevelMax
, 0, "My Label", kSizeCString
, 0, NULL
, 0, data
, data
, sizeof( data
),
2912 kDebugFlagsNoAddress
| kDebugFlagsNoOffset
, s
, sizeof( s
) );
2913 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
2916 DebugHexDump( kDebugLevelMax
, 0, "My Label", kSizeCString
, 0, NULL
, 0, data
, data
, sizeof( data
),
2917 kDebugFlagsNoAddress
, s
, sizeof( s
) );
2918 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
2921 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
),
2922 kDebugFlagsNoOffset
, s
, sizeof( s
) );
2923 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
2926 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
),
2927 kDebugFlagsNoAddress
, s
, sizeof( s
) );
2928 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
2931 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
),
2932 kDebugFlagsNoOffset
, s
, sizeof( s
) );
2933 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
2936 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
),
2937 kDebugFlagsNoByteCount
, s
, sizeof( s
) );
2938 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
2941 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, "\x41\x62\x43\x64", "\x41\x62\x43\x64", 4, // 'AbCd'
2942 kDebugFlagsNoAddress
| kDebugFlagsNoOffset
| kDebugFlagsNoNewLine
|
2943 kDebugFlagsNo32BitSeparator
| kDebugFlagsNo16ByteHexPad
| kDebugFlagsNoByteCount
,
2945 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
2948 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
),
2949 kDebugFlagsNoAddress
| kDebugFlagsNoOffset
| kDebugFlagsNoASCII
| kDebugFlagsNoNewLine
|
2950 kDebugFlags16BitSeparator
| kDebugFlagsNo32BitSeparator
|
2951 kDebugFlagsNo16ByteHexPad
| kDebugFlagsNoByteCount
, s
, sizeof( s
) );
2952 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
2955 DebugHexDump( kDebugLevelMax
, 8, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
), kDebugFlagsNone
, s
, sizeof( s
) );
2956 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
2960 dlog( kDebugLevelNotice
, "dlog\n" );
2961 dlog( kDebugLevelNotice
, "dlog integer: %d\n", 123 );
2962 dlog( kDebugLevelNotice
, "dlog string: \"%s\"\n", "test string" );
2963 dlogmem( kDebugLevelNotice
, data
, sizeof( data
) );
2967 DebugPrintF( kDebugLevelMax
, "\n\nALL TESTS DONE\n\n" );
2973 DebugPrintF( kDebugLevelMax
, "\n\n### TEST FAILED ###\n\n" );