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_VXWORKS )
46 #if ( TARGET_OS_WIN32 )
49 #if ( !TARGET_OS_WINDOWS_CE )
55 #if ( DEBUG_IDEBUG_ENABLED && TARGET_API_MAC_OSX_KERNEL )
56 #include <IOKit/IOLib.h>
59 // If MDNS_DEBUGMSGS is defined (even if defined 0), it is aware of mDNS and it is probably safe to include mDNSEmbeddedAPI.h.
61 #if ( defined( MDNS_DEBUGMSGS ) )
62 #include "mDNSEmbeddedAPI.h"
66 #pragma mark == Macros ==
69 //===========================================================================================================================
71 //===========================================================================================================================
73 #define DebugIsPrint( C ) ( ( ( C ) >= 0x20 ) && ( ( C ) <= 0x7E ) )
76 #pragma mark == Prototypes ==
79 //===========================================================================================================================
81 //===========================================================================================================================
83 static OSStatus
DebugPrint( DebugLevel inLevel
, char *inData
, size_t inSize
);
87 #if ( DEBUG_FPRINTF_ENABLED )
88 static OSStatus
DebugFPrintFInit( DebugOutputTypeFlags inFlags
, const char *inFilename
);
89 static void DebugFPrintFPrint( char *inData
, size_t inSize
);
92 // iDebug (Mac OS X user and kernel)
94 #if ( DEBUG_IDEBUG_ENABLED )
95 static OSStatus
DebugiDebugInit( void );
96 static void DebugiDebugPrint( char *inData
, size_t inSize
);
99 // kprintf (Mac OS X Kernel)
101 #if ( DEBUG_KPRINTF_ENABLED )
102 static void DebugKPrintFPrint( char *inData
, size_t inSize
);
105 // Mac OS X IOLog (Mac OS X Kernel)
107 #if ( DEBUG_MAC_OS_X_IOLOG_ENABLED )
108 static void DebugMacOSXIOLogPrint( char *inData
, size_t inSize
);
113 #if ( TARGET_OS_MAC )
114 static OSStatus
DebugMacOSXLogInit( void );
115 static void DebugMacOSXLogPrint( char *inData
, size_t inSize
);
120 #if ( TARGET_OS_WIN32 )
121 static void DebugWindowsDebuggerPrint( char *inData
, size_t inSize
);
126 #if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
127 static OSStatus
DebugWindowsEventLogInit( const char *inName
, HMODULE inModule
);
128 static void DebugWindowsEventLogPrint( DebugLevel inLevel
, char *inData
, size_t inSize
);
133 #if ( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
135 DebugAssertOutputHandler(
136 OSType inComponentSignature
,
138 const char * inAssertionString
,
139 const char * inExceptionString
,
140 const char * inErrorString
,
141 const char * inFileName
,
144 ConstStr255Param inOutputMsg
);
149 static char * DebugNumVersionToString( uint32_t inVersion
, char *inString
);
151 #if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
152 static void DebugWinEnableConsole( void );
155 #if ( TARGET_OS_WIN32 )
157 DebugWinCharToTCharString(
158 const char * inCharString
,
160 TCHAR
* outTCharString
,
161 size_t inTCharCountMax
,
162 size_t * outTCharCount
);
166 #pragma mark == Globals ==
169 //===========================================================================================================================
171 //===========================================================================================================================
173 #if ( TARGET_OS_VXWORKS )
174 // TCP States for inetstatShow.
176 extern char ** pTcpstates
; // defined in tcpLib.c
178 const char * kDebugTCPStates
[] =
183 "(3) TCPS_SYN_RECEIVED",
184 "(4) TCPS_ESTABLISHED",
185 "(5) TCPS_CLOSE_WAIT",
186 "(6) TCPS_FIN_WAIT_1",
189 "(9) TCPS_FIN_WAIT_2",
190 "(10) TCPS_TIME_WAIT",
196 static bool gDebugInitialized
= false;
197 static DebugOutputType gDebugOutputType
= kDebugOutputTypeNone
;
198 static DebugLevel gDebugPrintLevelMin
= kDebugLevelInfo
;
199 static DebugLevel gDebugPrintLevelMax
= kDebugLevelMax
;
200 static DebugLevel gDebugBreakLevel
= kDebugLevelAssert
;
201 #if ( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
202 static DebugAssertOutputHandlerUPP gDebugAssertOutputHandlerUPP
= NULL
;
207 static DebugOutputFunctionPtr gDebugCustomOutputFunction
= NULL
;
208 static void * gDebugCustomOutputContext
= NULL
;
212 #if ( DEBUG_FPRINTF_ENABLED )
213 static FILE * gDebugFPrintFFile
= NULL
;
218 #if ( TARGET_OS_MAC )
219 typedef int ( *DebugMacOSXLogFunctionPtr
)( const char *inFormat
, ... );
221 static DebugMacOSXLogFunctionPtr gDebugMacOSXLogFunction
= NULL
;
227 #if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
228 static HANDLE gDebugWindowsEventLogEventSource
= NULL
;
233 #pragma mark == General ==
236 //===========================================================================================================================
238 //===========================================================================================================================
240 DEBUG_EXPORT OSStatus
DebugInitialize( DebugOutputType inType
, ... )
243 DebugOutputType type
;
246 va_start( args
, inType
);
248 #if ( TARGET_OS_VXWORKS )
249 // Set up the TCP state strings if they are not already set up by VxWorks (normally not set up for some reason).
253 pTcpstates
= (char **) kDebugTCPStates
;
257 // Set up DebugLib stuff (if building with Debugging.h).
259 #if ( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
260 if( !gDebugAssertOutputHandlerUPP
)
262 gDebugAssertOutputHandlerUPP
= NewDebugAssertOutputHandlerUPP( DebugAssertOutputHandler
);
263 check( gDebugAssertOutputHandlerUPP
);
264 if( gDebugAssertOutputHandlerUPP
)
266 InstallDebugAssertOutputHandler( gDebugAssertOutputHandlerUPP
);
271 // Pre-process meta-output kind to pick an appropriate output kind for the platform.
274 if( type
== kDebugOutputTypeMetaConsole
)
276 #if ( TARGET_OS_MAC )
277 type
= kDebugOutputTypeMacOSXLog
;
278 #elif ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
279 #if ( DEBUG_FPRINTF_ENABLED )
280 type
= kDebugOutputTypeFPrintF
;
282 type
= kDebugOutputTypeWindowsDebugger
;
284 #elif ( TARGET_API_MAC_OSX_KERNEL )
285 #if ( DEBUG_MAC_OS_X_IOLOG_ENABLED )
286 type
= kDebugOutputTypeMacOSXIOLog
;
287 #elif ( DEBUG_IDEBUG_ENABLED )
288 type
= kDebugOutputTypeiDebug
;
289 #elif ( DEBUG_KPRINTF_ENABLED )
290 type
= kDebugOutputTypeKPrintF
;
292 #elif ( TARGET_OS_VXWORKS )
293 #if ( DEBUG_FPRINTF_ENABLED )
294 type
= kDebugOutputTypeFPrintF
;
296 #error target is VxWorks, but fprintf output is disabled
299 #if ( DEBUG_FPRINTF_ENABLED )
300 type
= kDebugOutputTypeFPrintF
;
305 // Process output kind.
307 gDebugOutputType
= type
;
310 case kDebugOutputTypeNone
:
314 case kDebugOutputTypeCustom
:
315 gDebugCustomOutputFunction
= va_arg( args
, DebugOutputFunctionPtr
);
316 gDebugCustomOutputContext
= va_arg( args
, void * );
320 #if ( DEBUG_FPRINTF_ENABLED )
321 case kDebugOutputTypeFPrintF
:
322 if( inType
== kDebugOutputTypeMetaConsole
)
324 err
= DebugFPrintFInit( kDebugOutputTypeFlagsStdErr
, NULL
);
328 DebugOutputTypeFlags flags
;
329 const char * filename
;
331 flags
= (DebugOutputTypeFlags
) va_arg( args
, unsigned int );
332 if( ( flags
& kDebugOutputTypeFlagsTypeMask
) == kDebugOutputTypeFlagsFile
)
334 filename
= va_arg( args
, const char * );
340 err
= DebugFPrintFInit( flags
, filename
);
345 #if ( DEBUG_IDEBUG_ENABLED )
346 case kDebugOutputTypeiDebug
:
347 err
= DebugiDebugInit();
351 #if ( DEBUG_KPRINTF_ENABLED )
352 case kDebugOutputTypeKPrintF
:
357 #if ( DEBUG_MAC_OS_X_IOLOG_ENABLED )
358 case kDebugOutputTypeMacOSXIOLog
:
363 #if ( TARGET_OS_MAC )
364 case kDebugOutputTypeMacOSXLog
:
365 err
= DebugMacOSXLogInit();
369 #if ( TARGET_OS_WIN32 )
370 case kDebugOutputTypeWindowsDebugger
:
375 #if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
376 case kDebugOutputTypeWindowsEventLog
:
381 name
= va_arg( args
, const char * );
382 module = va_arg( args
, HMODULE
);
383 err
= DebugWindowsEventLogInit( name
, module );
392 gDebugInitialized
= true;
399 //===========================================================================================================================
401 //===========================================================================================================================
403 DEBUG_EXPORT
void DebugFinalize( void )
405 #if ( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
406 check( gDebugAssertOutputHandlerUPP
);
407 if( gDebugAssertOutputHandlerUPP
)
409 InstallDebugAssertOutputHandler( NULL
);
410 DisposeDebugAssertOutputHandlerUPP( gDebugAssertOutputHandlerUPP
);
411 gDebugAssertOutputHandlerUPP
= NULL
;
416 //===========================================================================================================================
418 //===========================================================================================================================
420 DEBUG_EXPORT OSStatus
DebugGetProperty( DebugPropertyTag inTag
, ... )
426 va_start( args
, inTag
);
429 case kDebugPropertyTagPrintLevelMin
:
430 level
= va_arg( args
, DebugLevel
* );
431 *level
= gDebugPrintLevelMin
;
435 case kDebugPropertyTagPrintLevelMax
:
436 level
= va_arg( args
, DebugLevel
* );
437 *level
= gDebugPrintLevelMax
;
441 case kDebugPropertyTagBreakLevel
:
442 level
= va_arg( args
, DebugLevel
* );
443 *level
= gDebugBreakLevel
;
448 err
= kUnsupportedErr
;
455 //===========================================================================================================================
457 //===========================================================================================================================
459 DEBUG_EXPORT OSStatus
DebugSetProperty( DebugPropertyTag inTag
, ... )
465 va_start( args
, inTag
);
468 case kDebugPropertyTagPrintLevelMin
:
469 level
= va_arg( args
, DebugLevel
);
470 gDebugPrintLevelMin
= level
;
474 case kDebugPropertyTagPrintLevelMax
:
475 level
= va_arg( args
, DebugLevel
);
476 gDebugPrintLevelMax
= level
;
480 case kDebugPropertyTagBreakLevel
:
481 level
= va_arg( args
, DebugLevel
);
482 gDebugBreakLevel
= level
;
487 err
= kUnsupportedErr
;
496 #pragma mark == Output ==
499 //===========================================================================================================================
501 //===========================================================================================================================
503 DEBUG_EXPORT
size_t DebugPrintF( DebugLevel inLevel
, const char *inFormat
, ... )
508 // Skip if the level is not in the enabled range..
510 if( ( inLevel
< gDebugPrintLevelMin
) || ( inLevel
> gDebugPrintLevelMax
) )
516 va_start( args
, inFormat
);
517 n
= DebugPrintFVAList( inLevel
, inFormat
, args
);
524 //===========================================================================================================================
526 //===========================================================================================================================
528 DEBUG_EXPORT
size_t DebugPrintFVAList( DebugLevel inLevel
, const char *inFormat
, va_list inArgs
)
533 // Skip if the level is not in the enabled range..
535 if( ( inLevel
< gDebugPrintLevelMin
) || ( inLevel
> gDebugPrintLevelMax
) )
541 n
= DebugSNPrintFVAList( buffer
, sizeof( buffer
), inFormat
, inArgs
);
542 DebugPrint( inLevel
, buffer
, (size_t) n
);
548 //===========================================================================================================================
550 //===========================================================================================================================
552 static OSStatus
DebugPrint( DebugLevel inLevel
, char *inData
, size_t inSize
)
556 // Skip if the level is not in the enabled range..
558 if( ( inLevel
< gDebugPrintLevelMin
) || ( inLevel
> gDebugPrintLevelMax
) )
564 // Printing is not safe at interrupt time so check for this and warn with an interrupt safe mechanism (if available).
566 if( DebugTaskLevel() & kDebugInterruptLevelMask
)
568 #if ( TARGET_OS_VXWORKS )
569 logMsg( "\ncannot print at interrupt time\n\n", 1, 2, 3, 4, 5, 6 );
572 err
= kExecutionStateErr
;
576 // Initialize the debugging library if it hasn't already been initialized (allows for zero-config usage).
578 if( !gDebugInitialized
)
580 debug_initialize( kDebugOutputTypeMetaConsole
);
583 // Print based on the current output type.
585 switch( gDebugOutputType
)
587 case kDebugOutputTypeNone
:
590 case kDebugOutputTypeCustom
:
591 if( gDebugCustomOutputFunction
)
593 gDebugCustomOutputFunction( inData
, inSize
, gDebugCustomOutputContext
);
597 #if ( DEBUG_FPRINTF_ENABLED )
598 case kDebugOutputTypeFPrintF
:
599 DebugFPrintFPrint( inData
, inSize
);
603 #if ( DEBUG_IDEBUG_ENABLED )
604 case kDebugOutputTypeiDebug
:
605 DebugiDebugPrint( inData
, inSize
);
609 #if ( DEBUG_KPRINTF_ENABLED )
610 case kDebugOutputTypeKPrintF
:
611 DebugKPrintFPrint( inData
, inSize
);
615 #if ( DEBUG_MAC_OS_X_IOLOG_ENABLED )
616 case kDebugOutputTypeMacOSXIOLog
:
617 DebugMacOSXIOLogPrint( inData
, inSize
);
621 #if ( TARGET_OS_MAC )
622 case kDebugOutputTypeMacOSXLog
:
623 DebugMacOSXLogPrint( inData
, inSize
);
627 #if ( TARGET_OS_WIN32 )
628 case kDebugOutputTypeWindowsDebugger
:
629 DebugWindowsDebuggerPrint( inData
, inSize
);
633 #if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
634 case kDebugOutputTypeWindowsEventLog
:
635 DebugWindowsEventLogPrint( inLevel
, inData
, inSize
);
648 //===========================================================================================================================
651 // Warning: This routine relies on several of the strings being string constants that will exist forever because the
652 // underlying logMsg API that does the printing is asynchronous so it cannot use temporary/stack-based
653 // pointer variables (e.g. local strings). The debug macros that invoke this function only use constant
654 // constant strings, but if this function is invoked directly from other places, it must use constant strings.
655 //===========================================================================================================================
659 int_least32_t inErrorCode
,
660 const char * inAssertString
,
661 const char * inMessage
,
662 const char * inFilename
,
663 int_least32_t inLineNumber
,
664 const char * inFunction
)
666 // Skip if the level is not in the enabled range..
668 if( ( kDebugLevelAssert
< gDebugPrintLevelMin
) || ( kDebugLevelAssert
> gDebugPrintLevelMax
) )
673 if( inErrorCode
!= 0 )
678 "[ASSERT] error: %ld (%m)\n"
679 "[ASSERT] where: \"%s\", line %ld, \"%s\"\n"
681 inErrorCode
, inErrorCode
,
682 inFilename
? inFilename
: "",
684 inFunction
? inFunction
: "" );
691 "[ASSERT] assert: \"%s\" %s\n"
692 "[ASSERT] where: \"%s\", line %ld, \"%s\"\n"
694 inAssertString
? inAssertString
: "",
695 inMessage
? inMessage
: "",
696 inFilename
? inFilename
: "",
698 inFunction
? inFunction
: "" );
701 // Break into the debugger if enabled.
703 #if ( TARGET_OS_WIN32 )
704 if( gDebugBreakLevel
<= kDebugLevelAssert
)
706 if( IsDebuggerPresent() )
718 #if ( DEBUG_FPRINTF_ENABLED )
719 //===========================================================================================================================
721 //===========================================================================================================================
723 static OSStatus
DebugFPrintFInit( DebugOutputTypeFlags inFlags
, const char *inFilename
)
726 DebugOutputTypeFlags typeFlags
;
728 typeFlags
= inFlags
& kDebugOutputTypeFlagsTypeMask
;
729 if( typeFlags
== kDebugOutputTypeFlagsStdOut
)
731 #if ( TARGET_OS_WIN32 )
732 DebugWinEnableConsole();
735 gDebugFPrintFFile
= stdout
;
737 else if( typeFlags
== kDebugOutputTypeFlagsStdErr
)
739 #if ( TARGET_OS_WIN32 )
740 DebugWinEnableConsole();
743 gDebugFPrintFFile
= stdout
;
745 else if( typeFlags
== kDebugOutputTypeFlagsFile
)
747 require_action_quiet( inFilename
&& ( *inFilename
!= '\0' ), exit
, err
= kOpenErr
);
749 gDebugFPrintFFile
= fopen( inFilename
, "a" );
750 require_action_quiet( gDebugFPrintFFile
, exit
, err
= kOpenErr
);
763 //===========================================================================================================================
765 //===========================================================================================================================
767 static void DebugFPrintFPrint( char *inData
, size_t inSize
)
772 // Convert \r to \n. fprintf will interpret \n and convert to whatever is appropriate for the platform.
785 // Write the data and flush.
787 if( gDebugFPrintFFile
)
789 fprintf( gDebugFPrintFFile
, "%.*s", (int) inSize
, inData
);
790 fflush( gDebugFPrintFFile
);
793 #endif // DEBUG_FPRINTF_ENABLED
795 #if ( DEBUG_IDEBUG_ENABLED )
796 //===========================================================================================================================
798 //===========================================================================================================================
800 static OSStatus
DebugiDebugInit( void )
804 #if ( TARGET_API_MAC_OSX_KERNEL )
806 extern uint32_t * _giDebugReserved1
;
808 // Emulate the iDebugSetOutputType macro in iDebugServices.h.
809 // Note: This is not thread safe, but neither is iDebugServices.h nor iDebugKext.
811 if( !_giDebugReserved1
)
813 _giDebugReserved1
= (uint32_t *) IOMalloc( sizeof( uint32_t ) );
814 require_action_quiet( _giDebugReserved1
, exit
, err
= kNoMemoryErr
);
816 *_giDebugReserved1
= 0x00010000U
;
821 __private_extern__
void iDebugSetOutputTypeInternal( uint32_t inType
);
823 iDebugSetOutputTypeInternal( 0x00010000U
);
831 //===========================================================================================================================
833 //===========================================================================================================================
835 static void DebugiDebugPrint( char *inData
, size_t inSize
)
837 #if ( TARGET_API_MAC_OSX_KERNEL )
839 // Locally declared here so we do not need to include iDebugKext.h.
840 // Note: IOKit uses a global namespace for all code and only a partial link occurs at build time. When the
841 // KEXT is loaded, the runtime linker will link in this extern'd symbol (assuming iDebug is present).
842 // _giDebugLogInternal is actually part of IOKit proper so this should link even if iDebug is not present.
844 typedef void ( *iDebugLogFunctionPtr
)( uint32_t inLevel
, uint32_t inTag
, const char *inFormat
, ... );
846 extern iDebugLogFunctionPtr _giDebugLogInternal
;
848 if( _giDebugLogInternal
)
850 _giDebugLogInternal( 0, 0, "%.*s", (int) inSize
, inData
);
855 __private_extern__
void iDebugLogInternal( uint32_t inLevel
, uint32_t inTag
, const char *inFormat
, ... );
857 iDebugLogInternal( 0, 0, "%.*s", (int) inSize
, inData
);
863 #if ( DEBUG_KPRINTF_ENABLED )
864 //===========================================================================================================================
866 //===========================================================================================================================
868 static void DebugKPrintFPrint( char *inData
, size_t inSize
)
870 extern void kprintf( const char *inFormat
, ... );
872 kprintf( "%.*s", (int) inSize
, inData
);
876 #if ( DEBUG_MAC_OS_X_IOLOG_ENABLED )
877 //===========================================================================================================================
878 // DebugMacOSXIOLogPrint
879 //===========================================================================================================================
881 static void DebugMacOSXIOLogPrint( char *inData
, size_t inSize
)
883 extern void IOLog( const char *inFormat
, ... );
885 IOLog( "%.*s", (int) inSize
, inData
);
889 #if ( TARGET_OS_MAC )
890 //===========================================================================================================================
891 // DebugMacOSXLogInit
892 //===========================================================================================================================
894 static OSStatus
DebugMacOSXLogInit( void )
900 CFStringRef functionName
;
905 // Create a bundle reference for System.framework.
907 path
= CFSTR( "/System/Library/Frameworks/System.framework" );
908 url
= CFURLCreateWithFileSystemPath( NULL
, path
, kCFURLPOSIXPathStyle
, true );
909 require_action_quiet( url
, exit
, err
= memFullErr
);
911 bundle
= CFBundleCreate( NULL
, url
);
913 require_action_quiet( bundle
, exit
, err
= memFullErr
);
915 // Get a ptr to the system's "printf" function from System.framework.
917 functionName
= CFSTR( "printf" );
918 functionPtr
= CFBundleGetFunctionPointerForName( bundle
, functionName
);
919 require_action_quiet( functionPtr
, exit
, err
= memFullErr
);
921 // Success! Note: The bundle cannot be released because it would invalidate the function ptr.
923 gDebugMacOSXLogFunction
= (DebugMacOSXLogFunctionPtr
) functionPtr
;
935 //===========================================================================================================================
936 // DebugMacOSXLogPrint
937 //===========================================================================================================================
939 static void DebugMacOSXLogPrint( char *inData
, size_t inSize
)
941 if( gDebugMacOSXLogFunction
)
943 gDebugMacOSXLogFunction( "%.*s", (int) inSize
, inData
);
948 #if ( TARGET_OS_WIN32 )
949 //===========================================================================================================================
950 // DebugWindowsDebuggerPrint
951 //===========================================================================================================================
953 void DebugWindowsDebuggerPrint( char *inData
, size_t inSize
)
961 // Copy locally and null terminate the string. This also converts from char to TCHAR in case we are
962 // building with UNICODE enabled since the input is always char. Also convert \r to \n in the process.
965 if( inSize
>= sizeof_array( buffer
) )
967 inSize
= sizeof_array( buffer
) - 1;
982 // Print out the string to the debugger.
984 OutputDebugString( buffer
);
988 #if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
989 //===========================================================================================================================
990 // DebugWindowsEventLogInit
991 //===========================================================================================================================
993 static OSStatus
DebugWindowsEventLogInit( const char *inName
, HMODULE inModule
)
999 TCHAR path
[ MAX_PATH
];
1001 DWORD typesSupported
;
1006 // Use a default name if needed then convert the name to TCHARs so it works on ANSI or Unicode builds.
1008 if( !inName
|| ( *inName
== '\0' ) )
1010 inName
= "DefaultApp";
1012 DebugWinCharToTCharString( inName
, kSizeCString
, name
, sizeof( name
), NULL
);
1014 // Build the path string using the fixed registry path and app name.
1016 src
= "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\";
1017 DebugWinCharToTCharString( src
, kSizeCString
, path
, sizeof_array( path
), &size
);
1018 DebugWinCharToTCharString( inName
, kSizeCString
, path
+ size
, sizeof_array( path
) - size
, NULL
);
1020 // Add/Open the source name as a sub-key under the Application key in the EventLog registry key.
1022 err
= RegCreateKeyEx( HKEY_LOCAL_MACHINE
, path
, 0, NULL
, REG_OPTION_NON_VOLATILE
, KEY_ALL_ACCESS
, NULL
, &key
, NULL
);
1023 require_noerr_quiet( err
, exit
);
1025 // Set the path in the EventMessageFile subkey. Add 1 to the TCHAR count to include the null terminator.
1027 n
= GetModuleFileName( inModule
, path
, sizeof_array( path
) );
1028 err
= translate_errno( n
> 0, (OSStatus
) GetLastError(), kParamErr
);
1029 require_noerr_quiet( err
, exit
);
1031 n
*= sizeof( TCHAR
);
1033 err
= RegSetValueEx( key
, TEXT( "EventMessageFile" ), 0, REG_EXPAND_SZ
, (const LPBYTE
) path
, n
);
1034 require_noerr_quiet( err
, exit
);
1036 // Set the supported event types in the TypesSupported subkey.
1038 typesSupported
= EVENTLOG_SUCCESS
| EVENTLOG_ERROR_TYPE
| EVENTLOG_WARNING_TYPE
| EVENTLOG_INFORMATION_TYPE
|
1039 EVENTLOG_AUDIT_SUCCESS
| EVENTLOG_AUDIT_FAILURE
;
1040 err
= RegSetValueEx( key
, TEXT( "TypesSupported" ), 0, REG_DWORD
, (const LPBYTE
) &typesSupported
, sizeof( DWORD
) );
1041 require_noerr_quiet( err
, exit
);
1043 // Set up the event source.
1045 gDebugWindowsEventLogEventSource
= RegisterEventSource( NULL
, name
);
1046 err
= translate_errno( gDebugWindowsEventLogEventSource
, (OSStatus
) GetLastError(), kParamErr
);
1047 require_noerr_quiet( err
, exit
);
1057 //===========================================================================================================================
1058 // DebugWindowsEventLogPrint
1059 //===========================================================================================================================
1061 static void DebugWindowsEventLogPrint( DebugLevel inLevel
, char *inData
, size_t inSize
)
1064 TCHAR buffer
[ 512 ];
1069 const TCHAR
* array
[ 1 ];
1071 // Map the debug level to a Windows EventLog type.
1073 if( inLevel
<= kDebugLevelNotice
)
1075 type
= EVENTLOG_INFORMATION_TYPE
;
1077 else if( inLevel
<= kDebugLevelWarning
)
1079 type
= EVENTLOG_WARNING_TYPE
;
1083 type
= EVENTLOG_ERROR_TYPE
;
1086 // Copy locally and null terminate the string. This also converts from char to TCHAR in case we are
1087 // building with UNICODE enabled since the input is always char. Also convert \r to \n in the process.
1090 if( inSize
>= sizeof_array( buffer
) )
1092 inSize
= sizeof_array( buffer
) - 1;
1107 // Add the the string to the event log.
1109 array
[ 0 ] = buffer
;
1110 if( gDebugWindowsEventLogEventSource
)
1112 ReportEvent( gDebugWindowsEventLogEventSource
, type
, 0, 0x20000001L
, NULL
, 1, 0, array
, NULL
);
1115 #endif // TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE
1117 #if ( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
1118 //===========================================================================================================================
1119 // DebugAssertOutputHandler
1120 //===========================================================================================================================
1123 DebugAssertOutputHandler(
1124 OSType inComponentSignature
,
1126 const char * inAssertString
,
1127 const char * inExceptionString
,
1128 const char * inErrorString
,
1129 const char * inFileName
,
1132 ConstStr255Param inOutputMsg
)
1134 DEBUG_UNUSED( inComponentSignature
);
1135 DEBUG_UNUSED( inOptions
);
1136 DEBUG_UNUSED( inExceptionString
);
1137 DEBUG_UNUSED( inValue
);
1138 DEBUG_UNUSED( inOutputMsg
);
1140 DebugPrintAssert( 0, inAssertString
, inErrorString
, inFileName
, (int_least32_t) inLineNumber
, "" );
1146 #pragma mark == Utilities ==
1149 //===========================================================================================================================
1152 // Stolen from mDNS.c's mDNS_snprintf/mDNS_vsnprintf with the following changes:
1154 // Changed names to avoid name collisions with the mDNS versions.
1155 // Changed types to standard C types since mDNSEmbeddedAPI.h may not be available.
1156 // Conditionalized mDNS stuff so it can be used with or with mDNSEmbeddedAPI.h.
1157 // Added 64-bit support for %d (%lld), %i (%lli), %u (%llu), %o (%llo), %x (%llx), and %b (%llb).
1158 // Added %@ - Cocoa/CoreFoundation object. Param is the object. Strings are used directly. Others use CFCopyDescription.
1159 // Added %.8a - FIbre Channel address. Arg=ptr to address.
1160 // Added %##a - IPv4 (if AF_INET defined) or IPv6 (if AF_INET6 defined) sockaddr. Arg=ptr to sockaddr.
1161 // Added %b - Binary representation of integer (e.g. 01101011). Modifiers and arg=the same as %d, %x, etc.
1162 // Added %C - Mac-style FourCharCode (e.g. 'APPL'). Arg=32-bit value to print as a Mac-style FourCharCode.
1163 // Added %H - Hex Dump (e.g. "\x6b\xa7" -> "6B A7"). 1st arg=ptr, 2nd arg=size, 3rd arg=max size.
1164 // Added %#H - Hex Dump & ASCII (e.g. "\x41\x62" -> "6B A7 'Ab'"). 1st arg=ptr, 2nd arg=size, 3rd arg=max size.
1165 // Added %m - Error Message (e.g. 0 -> "kNoErr"). Modifiers and error code args are the same as %d, %x, etc.
1166 // Added %S - UTF-16 string. Host order if no BOM. Precision is UTF-16 char count. BOM counts in any precision. Arg=ptr.
1167 // Added %#S - Big Endian UTF-16 string (unless BOM overrides). Otherwise the same as %S.
1168 // Added %##S - Little Endian UTF-16 string (unless BOM overrides). Otherwise the same as %S.
1169 // Added %U - Universally Unique Identifier (UUID) (e.g. 6ba7b810-9dad-11d1-80b4-00c04fd430c8). Arg=ptr to 16-byte UUID.
1170 //===========================================================================================================================
1172 DEBUG_EXPORT
size_t DebugSNPrintF(char *sbuffer
, size_t buflen
, const char *fmt
, ...)
1178 length
= DebugSNPrintFVAList(sbuffer
, buflen
, fmt
, ptr
);
1184 //===========================================================================================================================
1185 // DebugSNPrintFVAList - va_list version of DebugSNPrintF. See DebugSNPrintF for more info.
1186 //===========================================================================================================================
1188 DEBUG_EXPORT
size_t DebugSNPrintFVAList(char *sbuffer
, size_t buflen
, const char *fmt
, va_list arg
)
1190 static const struct DebugSNPrintF_format
1192 unsigned leftJustify
: 1;
1193 unsigned forceSign
: 1;
1194 unsigned zeroPad
: 1;
1195 unsigned havePrecision
: 1;
1199 char sign
; // +, - or space
1200 unsigned int fieldWidth
;
1201 unsigned int precision
;
1202 } DebugSNPrintF_format_default
= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1204 size_t nwritten
= 0;
1206 if (buflen
== 0) return(0);
1207 buflen
--; // Pre-reserve one space in the buffer for the terminating nul
1208 if (buflen
== 0) goto exit
;
1210 for (c
= *fmt
; c
!= 0; c
= *++fmt
)
1214 *sbuffer
++ = (char)c
;
1215 if (++nwritten
>= buflen
) goto exit
;
1220 // The mDNS Vsprintf Argument Conversion Buffer is used as a temporary holding area for
1221 // generating decimal numbers, hexdecimal numbers, IP addresses, domain name strings, etc.
1222 // The size needs to be enough for a 256-byte domain name plus some error text.
1223 #define mDNS_VACB_Size 300
1224 char mDNS_VACB
[mDNS_VACB_Size
];
1225 #define mDNS_VACB_Lim (&mDNS_VACB[mDNS_VACB_Size])
1226 #define mDNS_VACB_Remain(s) ((size_t)(mDNS_VACB_Lim - s))
1227 char *s
= mDNS_VACB_Lim
;
1228 const char *digits
= "0123456789ABCDEF";
1229 struct DebugSNPrintF_format F
= DebugSNPrintF_format_default
;
1231 for(;;) // decode flags
1234 if (c
== '-') F
.leftJustify
= 1;
1235 else if (c
== '+') F
.forceSign
= 1;
1236 else if (c
== ' ') F
.sign
= ' ';
1237 else if (c
== '#') F
.altForm
++;
1238 else if (c
== '0') F
.zeroPad
= 1;
1242 if (c
== '*') // decode field width
1244 int f
= va_arg(arg
, int);
1245 if (f
< 0) { f
= -f
; F
.leftJustify
= 1; }
1246 F
.fieldWidth
= (unsigned int)f
;
1251 for (; c
>= '0' && c
<= '9'; c
= *++fmt
)
1252 F
.fieldWidth
= (10 * F
.fieldWidth
) + (c
- '0');
1255 if (c
== '.') // decode precision
1257 if ((c
= *++fmt
) == '*')
1258 { F
.precision
= va_arg(arg
, unsigned int); c
= *++fmt
; }
1259 else for (; c
>= '0' && c
<= '9'; c
= *++fmt
)
1260 F
.precision
= (10 * F
.precision
) + (c
- '0');
1261 F
.havePrecision
= 1;
1264 if (F
.leftJustify
) F
.zeroPad
= 0;
1267 switch (c
) // perform appropriate conversion
1269 #if TYPE_LONGLONG_NATIVE
1270 unsigned_long_long_compat n
;
1271 unsigned_long_long_compat base
;
1276 case 'h': F
.hSize
= 1; c
= *++fmt
; goto conv
;
1277 case 'l': // fall through
1278 case 'L': F
.lSize
++; c
= *++fmt
; goto conv
;
1280 case 'i': base
= 10;
1282 case 'u': base
= 10;
1288 case 'p': n
= va_arg(arg
, uintptr_t);
1289 F
.havePrecision
= 1;
1290 F
.precision
= (sizeof(uintptr_t) == 4) ? 8 : 16;
1295 case 'x': digits
= "0123456789abcdef";
1296 case 'X': base
= 16;
1299 #if TYPE_LONGLONG_NATIVE
1300 if (F
.lSize
== 1) n
= (unsigned_long_long_compat
)va_arg(arg
, long);
1301 else if (F
.lSize
== 2) n
= (unsigned_long_long_compat
)va_arg(arg
, long_long_compat
);
1302 else n
= (unsigned_long_long_compat
)va_arg(arg
, int);
1304 if (F
.lSize
== 1) n
= (unsigned long)va_arg(arg
, long);
1305 else if (F
.lSize
== 2) goto exit
;
1306 else n
= (unsigned long)va_arg(arg
, int);
1308 if (F
.hSize
) n
= (short) n
;
1309 #if TYPE_LONGLONG_NATIVE
1310 if ((long_long_compat
) n
< 0) { n
= (unsigned_long_long_compat
)-(long_long_compat
)n
; F
.sign
= '-'; }
1312 if ((long) n
< 0) { n
= (unsigned long)-(long)n
; F
.sign
= '-'; }
1314 else if (F
.forceSign
) F
.sign
= '+';
1317 notSigned
: if (F
.lSize
== 1) n
= va_arg(arg
, unsigned long);
1318 else if (F
.lSize
== 2)
1320 #if TYPE_LONGLONG_NATIVE
1321 n
= va_arg(arg
, unsigned_long_long_compat
);
1326 else n
= va_arg(arg
, unsigned int);
1327 if (F
.hSize
) n
= (unsigned short) n
;
1331 number
: if (!F
.havePrecision
)
1335 F
.precision
= F
.fieldWidth
;
1336 if (F
.altForm
) F
.precision
-= 2;
1337 if (F
.sign
) --F
.precision
;
1339 if (F
.precision
< 1) F
.precision
= 1;
1341 if (F
.precision
> mDNS_VACB_Size
- 1)
1342 F
.precision
= mDNS_VACB_Size
- 1;
1343 for (i
= 0; n
; n
/= base
, i
++) *--s
= (char)(digits
[n
% base
]);
1344 for (; i
< F
.precision
; i
++) *--s
= '0';
1345 if (F
.altForm
) { *--s
= (char)c
; *--s
= '0'; i
+= 2; }
1346 if (F
.sign
) { *--s
= F
.sign
; i
++; }
1350 unsigned char *a
= va_arg(arg
, unsigned char *);
1353 if (!a
) { static char emsg
[] = "<<NULL>>"; s
= emsg
; i
= sizeof(emsg
)-1; }
1356 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1359 #if (defined(MDNS_DEBUGMSGS))
1360 mDNSAddr
*ip
= (mDNSAddr
*)a
;
1363 case mDNSAddrType_IPv4
: F
.precision
= 4; a
= (unsigned char *)&ip
->ip
.v4
; break;
1364 case mDNSAddrType_IPv6
: F
.precision
= 16; a
= (unsigned char *)&ip
->ip
.v6
; break;
1365 default: F
.precision
= 0; break;
1368 F
.precision
= 0; // mDNSEmbeddedAPI.h not included so no mDNSAddr support
1371 else if (F
.altForm
== 2)
1374 const struct sockaddr
*sa
;
1375 unsigned char *port
;
1376 sa
= (const struct sockaddr
*)a
;
1377 switch (sa
->sa_family
)
1379 case AF_INET
: F
.precision
= 4; a
= (unsigned char*)&((const struct sockaddr_in
*)a
)->sin_addr
;
1380 port
= (unsigned char*)&((const struct sockaddr_in
*)sa
)->sin_port
;
1381 DebugSNPrintF(post
, sizeof(post
), ":%d", (port
[0] << 8) | port
[1]); break;
1383 case AF_INET6
: F
.precision
= 16; a
= (unsigned char*)&((const struct sockaddr_in6
*)a
)->sin6_addr
;
1384 pre
[0] = '['; pre
[1] = '\0';
1385 port
= (unsigned char*)&((const struct sockaddr_in6
*)sa
)->sin6_port
;
1386 DebugSNPrintF(post
, sizeof(post
), "%%%d]:%d",
1387 (int)((const struct sockaddr_in6
*)sa
)->sin6_scope_id
,
1388 (port
[0] << 8) | port
[1]); break;
1390 default: F
.precision
= 0; break;
1393 F
.precision
= 0; // socket interfaces not included so no sockaddr support
1396 switch (F
.precision
)
1398 case 4: i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "%d.%d.%d.%d%s",
1399 a
[0], a
[1], a
[2], a
[3], post
); break;
1400 case 6: i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "%02X:%02X:%02X:%02X:%02X:%02X",
1401 a
[0], a
[1], a
[2], a
[3], a
[4], a
[5]); break;
1402 case 8: i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
1403 a
[0], a
[1], a
[2], a
[3], a
[4], a
[5], a
[6], a
[7]); break;
1404 case 16: i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
),
1405 "%s%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X%s",
1406 pre
, a
[0], a
[1], a
[2], a
[3], a
[4], a
[5], a
[6], a
[7], a
[8],
1407 a
[9], a
[10], a
[11], a
[12], a
[13], a
[14], a
[15], post
); break;
1408 default: i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "%s", "<< ERROR: Must specify address size "
1409 "(i.e. %.4a=IPv4, %.6a=Ethernet, %.8a=Fibre Channel %.16a=IPv6) >>"); break;
1416 unsigned char *a
= va_arg(arg
, unsigned char *);
1417 if (!a
) { static char emsg
[] = "<<NULL>>"; s
= emsg
; i
= sizeof(emsg
)-1; }
1420 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1421 i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
1422 *((uint32_t*) &a
[0]), *((uint16_t*) &a
[4]), *((uint16_t*) &a
[6]),
1423 a
[8], a
[9], a
[10], a
[11], a
[12], a
[13], a
[14], a
[15]); break;
1428 case 'c': *--s
= (char)va_arg(arg
, int); i
= 1; break;
1430 case 'C': if (F
.lSize
) n
= va_arg(arg
, unsigned long);
1431 else n
= va_arg(arg
, unsigned int);
1432 if (F
.hSize
) n
= (unsigned short) n
;
1433 c
= (int)( n
& 0xFF); *--s
= (char)(DebugIsPrint(c
) ? c
: '^');
1434 c
= (int)((n
>> 8) & 0xFF); *--s
= (char)(DebugIsPrint(c
) ? c
: '^');
1435 c
= (int)((n
>> 16) & 0xFF); *--s
= (char)(DebugIsPrint(c
) ? c
: '^');
1436 c
= (int)((n
>> 24) & 0xFF); *--s
= (char)(DebugIsPrint(c
) ? c
: '^');
1440 case 's': s
= va_arg(arg
, char *);
1441 if (!s
) { static char emsg
[] = "<<NULL>>"; s
= emsg
; i
= sizeof(emsg
)-1; }
1442 else switch (F
.altForm
)
1445 if (F
.havePrecision
) // C string
1447 while((i
< F
.precision
) && s
[i
]) i
++;
1448 // Make sure we don't truncate in the middle of a UTF-8 character.
1449 // If the last character is part of a multi-byte UTF-8 character, back up to the start of it.
1451 while((i
> 0) && ((c
= s
[i
-1]) & 0x80)) { j
++; i
--; if((c
& 0xC0) != 0x80) break;}
1452 // If the actual count of UTF-8 characters matches the encoded UTF-8 count, add it back.
1453 if((j
> 1) && (j
<= 6))
1455 int test
= (0xFF << (8-j
)) & 0xFF;
1456 int mask
= test
| (1 << ((8-j
)-1));
1457 if((c
& mask
) == test
) i
+= j
;
1463 case 1: i
= (unsigned char) *s
++; break; // Pascal string
1464 case 2: { // DNS label-sequence name
1465 unsigned char *a
= (unsigned char *)s
;
1466 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1467 if (*a
== 0) *s
++ = '.'; // Special case for root DNS name
1470 if (*a
> 63) { s
+= DebugSNPrintF(s
, mDNS_VACB_Remain(s
), "<<INVALID LABEL LENGTH %u>>", *a
); break; }
1471 if (s
+ *a
>= &mDNS_VACB
[254]) { s
+= DebugSNPrintF(s
, mDNS_VACB_Remain(s
), "<<NAME TOO LONG>>"); break; }
1472 s
+= DebugSNPrintF(s
, mDNS_VACB_Remain(s
), "%#s.", a
);
1475 i
= (size_t)(s
- mDNS_VACB
);
1476 s
= mDNS_VACB
; // Reset s back to the start of the buffer
1480 if (F
.havePrecision
&& i
> F
.precision
) // Make sure we don't truncate in the middle of a UTF-8 character
1481 { i
= F
.precision
; while (i
>0 && (s
[i
] & 0xC0) == 0x80) i
--;}
1484 case 'S': { // UTF-16 string
1485 unsigned char *a
= va_arg(arg
, unsigned char *);
1486 uint16_t *u
= (uint16_t*)a
;
1487 if (!u
) { static char emsg
[] = "<<NULL>>"; s
= emsg
; i
= sizeof(emsg
)-1; }
1488 if ((!F
.havePrecision
|| F
.precision
))
1490 if ((a
[0] == 0xFE) && (a
[1] == 0xFF)) { F
.altForm
= 1; u
+= 1; a
+= 2; F
.precision
--; } // Big Endian
1491 else if ((a
[0] == 0xFF) && (a
[1] == 0xFE)) { F
.altForm
= 2; u
+= 1; a
+= 2; F
.precision
--; } // Little Endian
1493 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1496 case 0: while ((!F
.havePrecision
|| (i
< F
.precision
)) && u
[i
] && mDNS_VACB_Remain(s
)) // Host Endian
1497 { c
= u
[i
]; *s
++ = (char)(DebugIsPrint(c
) ? c
: '^'); i
++; }
1499 case 1: while ((!F
.havePrecision
|| (i
< F
.precision
)) && u
[i
] && mDNS_VACB_Remain(s
)) // Big Endian
1500 { c
= ((a
[0] << 8) | a
[1]) & 0xFF; *s
++ = (char)(DebugIsPrint(c
) ? c
: '^'); i
++; a
+= 2; }
1502 case 2: while ((!F
.havePrecision
|| (i
< F
.precision
)) && u
[i
] && mDNS_VACB_Remain(s
)) // Little Endian
1503 { c
= ((a
[1] << 8) | a
[0]) & 0xFF; *s
++ = (char)(DebugIsPrint(c
) ? c
: '^'); i
++; a
+= 2; }
1507 s
= mDNS_VACB
; // Reset s back to the start of the buffer
1511 case '@': { // Cocoa/CoreFoundation object
1514 cfObj
= (CFTypeRef
) va_arg(arg
, void *);
1515 cfStr
= (CFGetTypeID(cfObj
) == CFStringGetTypeID()) ? (CFStringRef
)CFRetain(cfObj
) : CFCopyDescription(cfObj
);
1516 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1521 range
= CFRangeMake(0, CFStringGetLength(cfStr
));
1523 CFStringGetBytes(cfStr
, range
, kCFStringEncodingUTF8
, '^', false, (UInt8
*)mDNS_VACB
, (CFIndex
)sizeof(mDNS_VACB
), &m
);
1529 i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "%s", "ERROR: <invalid CF object>" );
1532 if (F
.havePrecision
&& i
> F
.precision
) // Make sure we don't truncate in the middle of a UTF-8 character
1533 { i
= F
.precision
; while (i
>0 && (s
[i
] & 0xC0) == 0x80) i
--;}
1537 case 'm': { // Error Message
1539 if (F
.lSize
) err
= va_arg(arg
, long);
1540 else err
= va_arg(arg
, int);
1541 if (F
.hSize
) err
= (short)err
;
1542 DebugGetErrorString(err
, mDNS_VACB
, sizeof(mDNS_VACB
));
1543 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1544 for(i
=0; s
[i
]; i
++) {}
1548 case 'H': { // Hex Dump
1549 void *a
= va_arg(arg
, void *);
1550 size_t size
= (size_t)va_arg(arg
, int);
1551 size_t max
= (size_t)va_arg(arg
, int);
1553 kDebugFlagsNoAddress
| kDebugFlagsNoOffset
| kDebugFlagsNoNewLine
|
1554 kDebugFlags8BitSeparator
| kDebugFlagsNo32BitSeparator
|
1555 kDebugFlagsNo16ByteHexPad
| kDebugFlagsNoByteCount
;
1556 if (F
.altForm
== 0) flags
|= kDebugFlagsNoASCII
;
1557 size
= (max
< size
) ? max
: size
;
1558 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1559 i
= DebugHexDump(kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, a
, a
, size
, flags
, mDNS_VACB
, sizeof(mDNS_VACB
));
1563 case 'v': { // Version
1565 version
= va_arg(arg
, unsigned int);
1566 DebugNumVersionToString(version
, mDNS_VACB
);
1567 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1568 for(i
=0; s
[i
]; i
++) {}
1572 case 'n': s
= va_arg(arg
, char *);
1573 if (F
.hSize
) *(short *) s
= (short)nwritten
;
1574 else if (F
.lSize
) *(long *) s
= (long)nwritten
;
1575 else *(int *) s
= (int)nwritten
;
1578 default: s
= mDNS_VACB
;
1579 i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "<<UNKNOWN FORMAT CONVERSION CODE %%%c>>", c
);
1581 case '%': *sbuffer
++ = (char)c
;
1582 if (++nwritten
>= buflen
) goto exit
;
1586 if (i
< F
.fieldWidth
&& !F
.leftJustify
) // Pad on the left
1589 if (++nwritten
>= buflen
) goto exit
;
1590 } while (i
< --F
.fieldWidth
);
1592 if (i
> buflen
- nwritten
) // Make sure we don't truncate in the middle of a UTF-8 character
1593 { i
= buflen
- nwritten
; while (i
>0 && (s
[i
] & 0xC0) == 0x80) i
--;}
1594 for (j
=0; j
<i
; j
++) *sbuffer
++ = *s
++; // Write the converted result
1596 if (nwritten
>= buflen
) goto exit
;
1598 for (; i
< F
.fieldWidth
; i
++) // Pad on the right
1601 if (++nwritten
>= buflen
) goto exit
;
1610 //===========================================================================================================================
1611 // DebugGetErrorString
1612 //===========================================================================================================================
1614 DEBUG_EXPORT
const char * DebugGetErrorString( int_least32_t inErrorCode
, char *inBuffer
, size_t inBufferSize
)
1619 #if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
1623 switch( inErrorCode
)
1625 #define CaseErrorString( X, STR ) case X: s = STR; break
1626 #define CaseErrorStringify( X ) case X: s = # X; break
1627 #define CaseErrorStringifyHardCode( VALUE, X ) case VALUE: s = # X; break
1631 CaseErrorString( 0, "no error" );
1632 CaseErrorString( 1, "in-progress/waiting" );
1633 CaseErrorString( -1, "catch-all unknown error" );
1637 CaseErrorStringifyHardCode( -2, kACPBadRequestErr
);
1638 CaseErrorStringifyHardCode( -3, kACPNoMemoryErr
);
1639 CaseErrorStringifyHardCode( -4, kACPBadParamErr
);
1640 CaseErrorStringifyHardCode( -5, kACPNotFoundErr
);
1641 CaseErrorStringifyHardCode( -6, kACPBadChecksumErr
);
1642 CaseErrorStringifyHardCode( -7, kACPCommandNotHandledErr
);
1643 CaseErrorStringifyHardCode( -8, kACPNetworkErr
);
1644 CaseErrorStringifyHardCode( -9, kACPDuplicateCommandHandlerErr
);
1645 CaseErrorStringifyHardCode( -10, kACPUnknownPropertyErr
);
1646 CaseErrorStringifyHardCode( -11, kACPImmutablePropertyErr
);
1647 CaseErrorStringifyHardCode( -12, kACPBadPropertyValueErr
);
1648 CaseErrorStringifyHardCode( -13, kACPNoResourcesErr
);
1649 CaseErrorStringifyHardCode( -14, kACPBadOptionErr
);
1650 CaseErrorStringifyHardCode( -15, kACPBadSizeErr
);
1651 CaseErrorStringifyHardCode( -16, kACPBadPasswordErr
);
1652 CaseErrorStringifyHardCode( -17, kACPNotInitializedErr
);
1653 CaseErrorStringifyHardCode( -18, kACPNonReadablePropertyErr
);
1654 CaseErrorStringifyHardCode( -19, kACPBadVersionErr
);
1655 CaseErrorStringifyHardCode( -20, kACPBadSignatureErr
);
1656 CaseErrorStringifyHardCode( -21, kACPBadIndexErr
);
1657 CaseErrorStringifyHardCode( -22, kACPUnsupportedErr
);
1658 CaseErrorStringifyHardCode( -23, kACPInUseErr
);
1659 CaseErrorStringifyHardCode( -24, kACPParamCountErr
);
1660 CaseErrorStringifyHardCode( -25, kACPIDErr
);
1661 CaseErrorStringifyHardCode( -26, kACPFormatErr
);
1662 CaseErrorStringifyHardCode( -27, kACPUnknownUserErr
);
1663 CaseErrorStringifyHardCode( -28, kACPAccessDeniedErr
);
1664 CaseErrorStringifyHardCode( -29, kACPIncorrectFWErr
);
1666 // Common Services Errors
1668 CaseErrorStringify( kUnknownErr
);
1669 CaseErrorStringify( kOptionErr
);
1670 CaseErrorStringify( kSelectorErr
);
1671 CaseErrorStringify( kExecutionStateErr
);
1672 CaseErrorStringify( kPathErr
);
1673 CaseErrorStringify( kParamErr
);
1674 CaseErrorStringify( kParamCountErr
);
1675 CaseErrorStringify( kCommandErr
);
1676 CaseErrorStringify( kIDErr
);
1677 CaseErrorStringify( kStateErr
);
1678 CaseErrorStringify( kRangeErr
);
1679 CaseErrorStringify( kRequestErr
);
1680 CaseErrorStringify( kResponseErr
);
1681 CaseErrorStringify( kChecksumErr
);
1682 CaseErrorStringify( kNotHandledErr
);
1683 CaseErrorStringify( kVersionErr
);
1684 CaseErrorStringify( kSignatureErr
);
1685 CaseErrorStringify( kFormatErr
);
1686 CaseErrorStringify( kNotInitializedErr
);
1687 CaseErrorStringify( kAlreadyInitializedErr
);
1688 CaseErrorStringify( kNotInUseErr
);
1689 CaseErrorStringify( kInUseErr
);
1690 CaseErrorStringify( kTimeoutErr
);
1691 CaseErrorStringify( kCanceledErr
);
1692 CaseErrorStringify( kAlreadyCanceledErr
);
1693 CaseErrorStringify( kCannotCancelErr
);
1694 CaseErrorStringify( kDeletedErr
);
1695 CaseErrorStringify( kNotFoundErr
);
1696 CaseErrorStringify( kNoMemoryErr
);
1697 CaseErrorStringify( kNoResourcesErr
);
1698 CaseErrorStringify( kDuplicateErr
);
1699 CaseErrorStringify( kImmutableErr
);
1700 CaseErrorStringify( kUnsupportedDataErr
);
1701 CaseErrorStringify( kIntegrityErr
);
1702 CaseErrorStringify( kIncompatibleErr
);
1703 CaseErrorStringify( kUnsupportedErr
);
1704 CaseErrorStringify( kUnexpectedErr
);
1705 CaseErrorStringify( kValueErr
);
1706 CaseErrorStringify( kNotReadableErr
);
1707 CaseErrorStringify( kNotWritableErr
);
1708 CaseErrorStringify( kBadReferenceErr
);
1709 CaseErrorStringify( kFlagErr
);
1710 CaseErrorStringify( kMalformedErr
);
1711 CaseErrorStringify( kSizeErr
);
1712 CaseErrorStringify( kNameErr
);
1713 CaseErrorStringify( kNotReadyErr
);
1714 CaseErrorStringify( kReadErr
);
1715 CaseErrorStringify( kWriteErr
);
1716 CaseErrorStringify( kMismatchErr
);
1717 CaseErrorStringify( kDateErr
);
1718 CaseErrorStringify( kUnderrunErr
);
1719 CaseErrorStringify( kOverrunErr
);
1720 CaseErrorStringify( kEndingErr
);
1721 CaseErrorStringify( kConnectionErr
);
1722 CaseErrorStringify( kAuthenticationErr
);
1723 CaseErrorStringify( kOpenErr
);
1724 CaseErrorStringify( kTypeErr
);
1725 CaseErrorStringify( kSkipErr
);
1726 CaseErrorStringify( kNoAckErr
);
1727 CaseErrorStringify( kCollisionErr
);
1728 CaseErrorStringify( kBackoffErr
);
1729 CaseErrorStringify( kNoAddressAckErr
);
1730 CaseErrorStringify( kBusyErr
);
1731 CaseErrorStringify( kNoSpaceErr
);
1733 // mDNS/DNS-SD Errors
1735 CaseErrorStringifyHardCode( -65537, mStatus_UnknownErr
);
1736 CaseErrorStringifyHardCode( -65538, mStatus_NoSuchNameErr
);
1737 CaseErrorStringifyHardCode( -65539, mStatus_NoMemoryErr
);
1738 CaseErrorStringifyHardCode( -65540, mStatus_BadParamErr
);
1739 CaseErrorStringifyHardCode( -65541, mStatus_BadReferenceErr
);
1740 CaseErrorStringifyHardCode( -65542, mStatus_BadStateErr
);
1741 CaseErrorStringifyHardCode( -65543, mStatus_BadFlagsErr
);
1742 CaseErrorStringifyHardCode( -65544, mStatus_UnsupportedErr
);
1743 CaseErrorStringifyHardCode( -65545, mStatus_NotInitializedErr
);
1744 CaseErrorStringifyHardCode( -65546, mStatus_NoCache
);
1745 CaseErrorStringifyHardCode( -65547, mStatus_AlreadyRegistered
);
1746 CaseErrorStringifyHardCode( -65548, mStatus_NameConflict
);
1747 CaseErrorStringifyHardCode( -65549, mStatus_Invalid
);
1748 CaseErrorStringifyHardCode( -65550, mStatus_GrowCache
);
1749 CaseErrorStringifyHardCode( -65551, mStatus_Incompatible
);
1750 CaseErrorStringifyHardCode( -65552, mStatus_BadInterfaceErr
);
1751 CaseErrorStringifyHardCode( -65791, mStatus_ConfigChanged
);
1752 CaseErrorStringifyHardCode( -65792, mStatus_MemFree
);
1756 CaseErrorStringifyHardCode( -400000, kRSPUnknownErr
);
1757 CaseErrorStringifyHardCode( -400050, kRSPParamErr
);
1758 CaseErrorStringifyHardCode( -400108, kRSPNoMemoryErr
);
1759 CaseErrorStringifyHardCode( -405246, kRSPRangeErr
);
1760 CaseErrorStringifyHardCode( -409057, kRSPSizeErr
);
1761 CaseErrorStringifyHardCode( -400200, kRSPHardwareErr
);
1762 CaseErrorStringifyHardCode( -401712, kRSPTimeoutErr
);
1763 CaseErrorStringifyHardCode( -402053, kRSPUnsupportedErr
);
1764 CaseErrorStringifyHardCode( -402419, kRSPIDErr
);
1765 CaseErrorStringifyHardCode( -403165, kRSPFlagErr
);
1766 CaseErrorString( -200000, "kRSPControllerStatusBase - 0x50" );
1767 CaseErrorString( -200080, "kRSPCommandSucceededErr - 0x50" );
1768 CaseErrorString( -200001, "kRSPCommandFailedErr - 0x01" );
1769 CaseErrorString( -200051, "kRSPChecksumErr - 0x33" );
1770 CaseErrorString( -200132, "kRSPCommandTimeoutErr - 0x84" );
1771 CaseErrorString( -200034, "kRSPPasswordRequiredErr - 0x22 OBSOLETE" );
1772 CaseErrorString( -200128, "kRSPCanceledErr - 0x02 Async" );
1776 CaseErrorStringifyHardCode( -100043, kXMLNotFoundErr
);
1777 CaseErrorStringifyHardCode( -100050, kXMLParamErr
);
1778 CaseErrorStringifyHardCode( -100108, kXMLNoMemoryErr
);
1779 CaseErrorStringifyHardCode( -100206, kXMLFormatErr
);
1780 CaseErrorStringifyHardCode( -100586, kXMLNoRootElementErr
);
1781 CaseErrorStringifyHardCode( -101703, kXMLWrongDataTypeErr
);
1782 CaseErrorStringifyHardCode( -101726, kXMLKeyErr
);
1783 CaseErrorStringifyHardCode( -102053, kXMLUnsupportedErr
);
1784 CaseErrorStringifyHardCode( -102063, kXMLMissingElementErr
);
1785 CaseErrorStringifyHardCode( -103026, kXMLParseErr
);
1786 CaseErrorStringifyHardCode( -103159, kXMLBadDataErr
);
1787 CaseErrorStringifyHardCode( -103170, kXMLBadNameErr
);
1788 CaseErrorStringifyHardCode( -105246, kXMLRangeErr
);
1789 CaseErrorStringifyHardCode( -105251, kXMLUnknownElementErr
);
1790 CaseErrorStringifyHardCode( -108739, kXMLMalformedInputErr
);
1791 CaseErrorStringifyHardCode( -109057, kXMLBadSizeErr
);
1792 CaseErrorStringifyHardCode( -101730, kXMLMissingChildElementErr
);
1793 CaseErrorStringifyHardCode( -102107, kXMLMissingParentElementErr
);
1794 CaseErrorStringifyHardCode( -130587, kXMLNonRootElementErr
);
1795 CaseErrorStringifyHardCode( -102015, kXMLDateErr
);
1801 CaseErrorStringifyHardCode( 0x00002000, MACH_MSG_IPC_SPACE
);
1802 CaseErrorStringifyHardCode( 0x00001000, MACH_MSG_VM_SPACE
);
1803 CaseErrorStringifyHardCode( 0x00000800, MACH_MSG_IPC_KERNEL
);
1804 CaseErrorStringifyHardCode( 0x00000400, MACH_MSG_VM_KERNEL
);
1805 CaseErrorStringifyHardCode( 0x10000001, MACH_SEND_IN_PROGRESS
);
1806 CaseErrorStringifyHardCode( 0x10000002, MACH_SEND_INVALID_DATA
);
1807 CaseErrorStringifyHardCode( 0x10000003, MACH_SEND_INVALID_DEST
);
1808 CaseErrorStringifyHardCode( 0x10000004, MACH_SEND_TIMED_OUT
);
1809 CaseErrorStringifyHardCode( 0x10000007, MACH_SEND_INTERRUPTED
);
1810 CaseErrorStringifyHardCode( 0x10000008, MACH_SEND_MSG_TOO_SMALL
);
1811 CaseErrorStringifyHardCode( 0x10000009, MACH_SEND_INVALID_REPLY
);
1812 CaseErrorStringifyHardCode( 0x1000000A, MACH_SEND_INVALID_RIGHT
);
1813 CaseErrorStringifyHardCode( 0x1000000B, MACH_SEND_INVALID_NOTIFY
);
1814 CaseErrorStringifyHardCode( 0x1000000C, MACH_SEND_INVALID_MEMORY
);
1815 CaseErrorStringifyHardCode( 0x1000000D, MACH_SEND_NO_BUFFER
);
1816 CaseErrorStringifyHardCode( 0x1000000E, MACH_SEND_TOO_LARGE
);
1817 CaseErrorStringifyHardCode( 0x1000000F, MACH_SEND_INVALID_TYPE
);
1818 CaseErrorStringifyHardCode( 0x10000010, MACH_SEND_INVALID_HEADER
);
1819 CaseErrorStringifyHardCode( 0x10000011, MACH_SEND_INVALID_TRAILER
);
1820 CaseErrorStringifyHardCode( 0x10000015, MACH_SEND_INVALID_RT_OOL_SIZE
);
1821 CaseErrorStringifyHardCode( 0x10004001, MACH_RCV_IN_PROGRESS
);
1822 CaseErrorStringifyHardCode( 0x10004002, MACH_RCV_INVALID_NAME
);
1823 CaseErrorStringifyHardCode( 0x10004003, MACH_RCV_TIMED_OUT
);
1824 CaseErrorStringifyHardCode( 0x10004004, MACH_RCV_TOO_LARGE
);
1825 CaseErrorStringifyHardCode( 0x10004005, MACH_RCV_INTERRUPTED
);
1826 CaseErrorStringifyHardCode( 0x10004006, MACH_RCV_PORT_CHANGED
);
1827 CaseErrorStringifyHardCode( 0x10004007, MACH_RCV_INVALID_NOTIFY
);
1828 CaseErrorStringifyHardCode( 0x10004008, MACH_RCV_INVALID_DATA
);
1829 CaseErrorStringifyHardCode( 0x10004009, MACH_RCV_PORT_DIED
);
1830 CaseErrorStringifyHardCode( 0x1000400A, MACH_RCV_IN_SET
);
1831 CaseErrorStringifyHardCode( 0x1000400B, MACH_RCV_HEADER_ERROR
);
1832 CaseErrorStringifyHardCode( 0x1000400C, MACH_RCV_BODY_ERROR
);
1833 CaseErrorStringifyHardCode( 0x1000400D, MACH_RCV_INVALID_TYPE
);
1834 CaseErrorStringifyHardCode( 0x1000400E, MACH_RCV_SCATTER_SMALL
);
1835 CaseErrorStringifyHardCode( 0x1000400F, MACH_RCV_INVALID_TRAILER
);
1836 CaseErrorStringifyHardCode( 0x10004011, MACH_RCV_IN_PROGRESS_TIMED
);
1838 // Mach OSReturn Errors
1840 CaseErrorStringifyHardCode( 0xDC000001, kOSReturnError
);
1841 CaseErrorStringifyHardCode( 0xDC004001, kOSMetaClassInternal
);
1842 CaseErrorStringifyHardCode( 0xDC004002, kOSMetaClassHasInstances
);
1843 CaseErrorStringifyHardCode( 0xDC004003, kOSMetaClassNoInit
);
1844 CaseErrorStringifyHardCode( 0xDC004004, kOSMetaClassNoTempData
);
1845 CaseErrorStringifyHardCode( 0xDC004005, kOSMetaClassNoDicts
);
1846 CaseErrorStringifyHardCode( 0xDC004006, kOSMetaClassNoKModSet
);
1847 CaseErrorStringifyHardCode( 0xDC004007, kOSMetaClassNoInsKModSet
);
1848 CaseErrorStringifyHardCode( 0xDC004008, kOSMetaClassNoSuper
);
1849 CaseErrorStringifyHardCode( 0xDC004009, kOSMetaClassInstNoSuper
);
1850 CaseErrorStringifyHardCode( 0xDC00400A, kOSMetaClassDuplicateClass
);
1854 CaseErrorStringifyHardCode( 0xE00002BC, kIOReturnError
);
1855 CaseErrorStringifyHardCode( 0xE00002BD, kIOReturnNoMemory
);
1856 CaseErrorStringifyHardCode( 0xE00002BE, kIOReturnNoResources
);
1857 CaseErrorStringifyHardCode( 0xE00002BF, kIOReturnIPCError
);
1858 CaseErrorStringifyHardCode( 0xE00002C0, kIOReturnNoDevice
);
1859 CaseErrorStringifyHardCode( 0xE00002C1, kIOReturnNotPrivileged
);
1860 CaseErrorStringifyHardCode( 0xE00002C2, kIOReturnBadArgument
);
1861 CaseErrorStringifyHardCode( 0xE00002C3, kIOReturnLockedRead
);
1862 CaseErrorStringifyHardCode( 0xE00002C4, kIOReturnLockedWrite
);
1863 CaseErrorStringifyHardCode( 0xE00002C5, kIOReturnExclusiveAccess
);
1864 CaseErrorStringifyHardCode( 0xE00002C6, kIOReturnBadMessageID
);
1865 CaseErrorStringifyHardCode( 0xE00002C7, kIOReturnUnsupported
);
1866 CaseErrorStringifyHardCode( 0xE00002C8, kIOReturnVMError
);
1867 CaseErrorStringifyHardCode( 0xE00002C9, kIOReturnInternalError
);
1868 CaseErrorStringifyHardCode( 0xE00002CA, kIOReturnIOError
);
1869 CaseErrorStringifyHardCode( 0xE00002CC, kIOReturnCannotLock
);
1870 CaseErrorStringifyHardCode( 0xE00002CD, kIOReturnNotOpen
);
1871 CaseErrorStringifyHardCode( 0xE00002CE, kIOReturnNotReadable
);
1872 CaseErrorStringifyHardCode( 0xE00002CF, kIOReturnNotWritable
);
1873 CaseErrorStringifyHardCode( 0xE00002D0, kIOReturnNotAligned
);
1874 CaseErrorStringifyHardCode( 0xE00002D1, kIOReturnBadMedia
);
1875 CaseErrorStringifyHardCode( 0xE00002D2, kIOReturnStillOpen
);
1876 CaseErrorStringifyHardCode( 0xE00002D3, kIOReturnRLDError
);
1877 CaseErrorStringifyHardCode( 0xE00002D4, kIOReturnDMAError
);
1878 CaseErrorStringifyHardCode( 0xE00002D5, kIOReturnBusy
);
1879 CaseErrorStringifyHardCode( 0xE00002D6, kIOReturnTimeout
);
1880 CaseErrorStringifyHardCode( 0xE00002D7, kIOReturnOffline
);
1881 CaseErrorStringifyHardCode( 0xE00002D8, kIOReturnNotReady
);
1882 CaseErrorStringifyHardCode( 0xE00002D9, kIOReturnNotAttached
);
1883 CaseErrorStringifyHardCode( 0xE00002DA, kIOReturnNoChannels
);
1884 CaseErrorStringifyHardCode( 0xE00002DB, kIOReturnNoSpace
);
1885 CaseErrorStringifyHardCode( 0xE00002DD, kIOReturnPortExists
);
1886 CaseErrorStringifyHardCode( 0xE00002DE, kIOReturnCannotWire
);
1887 CaseErrorStringifyHardCode( 0xE00002DF, kIOReturnNoInterrupt
);
1888 CaseErrorStringifyHardCode( 0xE00002E0, kIOReturnNoFrames
);
1889 CaseErrorStringifyHardCode( 0xE00002E1, kIOReturnMessageTooLarge
);
1890 CaseErrorStringifyHardCode( 0xE00002E2, kIOReturnNotPermitted
);
1891 CaseErrorStringifyHardCode( 0xE00002E3, kIOReturnNoPower
);
1892 CaseErrorStringifyHardCode( 0xE00002E4, kIOReturnNoMedia
);
1893 CaseErrorStringifyHardCode( 0xE00002E5, kIOReturnUnformattedMedia
);
1894 CaseErrorStringifyHardCode( 0xE00002E6, kIOReturnUnsupportedMode
);
1895 CaseErrorStringifyHardCode( 0xE00002E7, kIOReturnUnderrun
);
1896 CaseErrorStringifyHardCode( 0xE00002E8, kIOReturnOverrun
);
1897 CaseErrorStringifyHardCode( 0xE00002E9, kIOReturnDeviceError
);
1898 CaseErrorStringifyHardCode( 0xE00002EA, kIOReturnNoCompletion
);
1899 CaseErrorStringifyHardCode( 0xE00002EB, kIOReturnAborted
);
1900 CaseErrorStringifyHardCode( 0xE00002EC, kIOReturnNoBandwidth
);
1901 CaseErrorStringifyHardCode( 0xE00002ED, kIOReturnNotResponding
);
1902 CaseErrorStringifyHardCode( 0xE00002EE, kIOReturnIsoTooOld
);
1903 CaseErrorStringifyHardCode( 0xE00002EF, kIOReturnIsoTooNew
);
1904 CaseErrorStringifyHardCode( 0xE00002F0, kIOReturnNotFound
);
1905 CaseErrorStringifyHardCode( 0xE0000001, kIOReturnInvalid
);
1907 // IOKit FireWire Errors
1909 CaseErrorStringifyHardCode( 0xE0008010, kIOFireWireResponseBase
);
1910 CaseErrorStringifyHardCode( 0xE0008020, kIOFireWireBusReset
);
1911 CaseErrorStringifyHardCode( 0xE0008001, kIOConfigNoEntry
);
1912 CaseErrorStringifyHardCode( 0xE0008002, kIOFireWirePending
);
1913 CaseErrorStringifyHardCode( 0xE0008003, kIOFireWireLastDCLToken
);
1914 CaseErrorStringifyHardCode( 0xE0008004, kIOFireWireConfigROMInvalid
);
1915 CaseErrorStringifyHardCode( 0xE0008005, kIOFireWireAlreadyRegistered
);
1916 CaseErrorStringifyHardCode( 0xE0008006, kIOFireWireMultipleTalkers
);
1917 CaseErrorStringifyHardCode( 0xE0008007, kIOFireWireChannelActive
);
1918 CaseErrorStringifyHardCode( 0xE0008008, kIOFireWireNoListenerOrTalker
);
1919 CaseErrorStringifyHardCode( 0xE0008009, kIOFireWireNoChannels
);
1920 CaseErrorStringifyHardCode( 0xE000800A, kIOFireWireChannelNotAvailable
);
1921 CaseErrorStringifyHardCode( 0xE000800B, kIOFireWireSeparateBus
);
1922 CaseErrorStringifyHardCode( 0xE000800C, kIOFireWireBadSelfIDs
);
1923 CaseErrorStringifyHardCode( 0xE000800D, kIOFireWireLowCableVoltage
);
1924 CaseErrorStringifyHardCode( 0xE000800E, kIOFireWireInsufficientPower
);
1925 CaseErrorStringifyHardCode( 0xE000800F, kIOFireWireOutOfTLabels
);
1926 CaseErrorStringifyHardCode( 0xE0008101, kIOFireWireBogusDCLProgram
);
1927 CaseErrorStringifyHardCode( 0xE0008102, kIOFireWireTalkingAndListening
);
1928 CaseErrorStringifyHardCode( 0xE0008103, kIOFireWireHardwareSlept
);
1929 CaseErrorStringifyHardCode( 0xE00087D0, kIOFWMessageServiceIsRequestingClose
);
1930 CaseErrorStringifyHardCode( 0xE00087D1, kIOFWMessagePowerStateChanged
);
1931 CaseErrorStringifyHardCode( 0xE00087D2, kIOFWMessageTopologyChanged
);
1935 CaseErrorStringifyHardCode( 0xE0004061, kIOUSBUnknownPipeErr
);
1936 CaseErrorStringifyHardCode( 0xE0004060, kIOUSBTooManyPipesErr
);
1937 CaseErrorStringifyHardCode( 0xE000405F, kIOUSBNoAsyncPortErr
);
1938 CaseErrorStringifyHardCode( 0xE000405E, kIOUSBNotEnoughPipesErr
);
1939 CaseErrorStringifyHardCode( 0xE000405D, kIOUSBNotEnoughPowerErr
);
1940 CaseErrorStringifyHardCode( 0xE0004057, kIOUSBEndpointNotFound
);
1941 CaseErrorStringifyHardCode( 0xE0004056, kIOUSBConfigNotFound
);
1942 CaseErrorStringifyHardCode( 0xE0004051, kIOUSBTransactionTimeout
);
1943 CaseErrorStringifyHardCode( 0xE0004050, kIOUSBTransactionReturned
);
1944 CaseErrorStringifyHardCode( 0xE000404F, kIOUSBPipeStalled
);
1945 CaseErrorStringifyHardCode( 0xE000404E, kIOUSBInterfaceNotFound
);
1946 CaseErrorStringifyHardCode( 0xE000404D, kIOUSBLowLatencyBufferNotPreviouslyAllocated
);
1947 CaseErrorStringifyHardCode( 0xE000404C, kIOUSBLowLatencyFrameListNotPreviouslyAllocated
);
1948 CaseErrorStringifyHardCode( 0xE000404B, kIOUSBHighSpeedSplitError
);
1949 CaseErrorStringifyHardCode( 0xE0004010, kIOUSBLinkErr
);
1950 CaseErrorStringifyHardCode( 0xE000400F, kIOUSBNotSent2Err
);
1951 CaseErrorStringifyHardCode( 0xE000400E, kIOUSBNotSent1Err
);
1952 CaseErrorStringifyHardCode( 0xE000400D, kIOUSBBufferUnderrunErr
);
1953 CaseErrorStringifyHardCode( 0xE000400C, kIOUSBBufferOverrunErr
);
1954 CaseErrorStringifyHardCode( 0xE000400B, kIOUSBReserved2Err
);
1955 CaseErrorStringifyHardCode( 0xE000400A, kIOUSBReserved1Err
);
1956 CaseErrorStringifyHardCode( 0xE0004007, kIOUSBWrongPIDErr
);
1957 CaseErrorStringifyHardCode( 0xE0004006, kIOUSBPIDCheckErr
);
1958 CaseErrorStringifyHardCode( 0xE0004003, kIOUSBDataToggleErr
);
1959 CaseErrorStringifyHardCode( 0xE0004002, kIOUSBBitstufErr
);
1960 CaseErrorStringifyHardCode( 0xE0004001, kIOUSBCRCErr
);
1968 #if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
1969 if( inBuffer
&& ( inBufferSize
> 0 ) )
1973 n
= FormatMessageA( FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_IGNORE_INSERTS
, NULL
, (DWORD
) inErrorCode
,
1974 MAKELANGID( LANG_NEUTRAL
, SUBLANG_DEFAULT
), buffer
, sizeof( buffer
), NULL
);
1977 // Remove any trailing CR's or LF's since some messages have them.
1979 while( ( n
> 0 ) && isspace( ( (unsigned char *) buffer
)[ n
- 1 ] ) )
1981 buffer
[ --n
] = '\0';
1990 #if ( !TARGET_API_MAC_OSX_KERNEL && !TARGET_OS_WINDOWS_CE )
1991 s
= strerror( inErrorCode
);
1995 s
= "<unknown error code>";
2001 // Copy the string to the output buffer. If no buffer is supplied or it is empty, return an empty string.
2003 if( inBuffer
&& ( inBufferSize
> 0 ) )
2006 end
= dst
+ ( inBufferSize
- 1 );
2007 while( ( ( end
- dst
) > 0 ) && ( *s
!= '\0' ) )
2017 //===========================================================================================================================
2019 //===========================================================================================================================
2025 const char * inLabel
,
2027 int inLabelMinWidth
,
2028 const char * inType
,
2030 const void * inDataStart
,
2031 const void * inData
,
2035 size_t inBufferSize
)
2037 static const char kHexChars
[] = "0123456789ABCDEF";
2038 const uint8_t * start
;
2039 const uint8_t * src
;
2045 const char * newline
;
2046 char separator
[ 8 ];
2049 DEBUG_UNUSED( inType
);
2050 DEBUG_UNUSED( inTypeSize
);
2052 // Set up the function-wide variables.
2054 if( inLabelSize
== kSizeCString
)
2056 inLabelSize
= strlen( inLabel
);
2058 start
= (const uint8_t *) inData
;
2061 end
= dst
+ inBufferSize
;
2062 offset
= (int)( (intptr_t) inData
- (intptr_t) inDataStart
);
2063 width
= ( (int) inLabelSize
> inLabelMinWidth
) ? (int) inLabelSize
: inLabelMinWidth
;
2064 newline
= ( inFlags
& kDebugFlagsNoNewLine
) ? "" : "\n";
2066 // Set up the separator string. This is used to insert spaces on subsequent "lines" when not using newlines.
2069 if( inFlags
& kDebugFlagsNoNewLine
)
2071 if( inFlags
& kDebugFlags8BitSeparator
)
2075 if( inFlags
& kDebugFlags16BitSeparator
)
2079 if( !( inFlags
& kDebugFlagsNo32BitSeparator
) )
2083 check( ( (size_t)( s
- separator
) ) < sizeof( separator
) );
2089 char prefixString
[ 32 ];
2090 char hexString
[ 64 ];
2091 char asciiString
[ 32 ];
2092 char byteCountString
[ 32 ];
2097 // If this is a label-only item (i.e. no data), print the label (accounting for prefix string spacing) and exit.
2099 if( inDataSize
== 0 )
2101 if( inLabel
&& ( inLabelSize
> 0 ) )
2104 if( !( inFlags
& kDebugFlagsNoAddress
) )
2106 width
+= 8; // "00000000"
2107 if( !( inFlags
& kDebugFlagsNoOffset
) )
2112 if( inFlags
& kDebugFlags32BitOffset
)
2114 width
+= 8; // "00000000"
2116 else if( !( inFlags
& kDebugFlagsNoOffset
) )
2118 width
+= 4; // "0000"
2123 dst
+= DebugSNPrintF( dst
, (size_t)( end
- dst
), "%*s" "%-*.*s" "%.*s" "%s",
2125 ( width
> 0 ) ? ": " : "",
2126 width
, (int) inLabelSize
, inLabel
,
2131 dst
+= DebugPrintF( inLevel
, "%*s" "%-*.*s" "%.*s" "%s",
2133 ( width
> 0 ) ? ": " : "",
2134 width
, (int) inLabelSize
, inLabel
,
2141 // Build the prefix string. It will be in one of the following formats:
2143 // 1) "00000000+0000[0000]" (address and offset)
2144 // 2) "00000000" (address only)
2145 // 3) "0000[0000]" (offset only)
2146 // 4) "" (no address or offset)
2148 // Note: If we're printing multiple "lines", but not printing newlines, a space is used to separate.
2151 if( !( inFlags
& kDebugFlagsNoAddress
) )
2153 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 28 ) & 0xF ];
2154 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 24 ) & 0xF ];
2155 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 20 ) & 0xF ];
2156 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 16 ) & 0xF ];
2157 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 12 ) & 0xF ];
2158 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 8 ) & 0xF ];
2159 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 4 ) & 0xF ];
2160 *s
++ = kHexChars
[ ( (uintptr_t) src
) & 0xF ];
2162 if( !( inFlags
& kDebugFlagsNoOffset
) )
2167 if( !( inFlags
& kDebugFlagsNoOffset
) )
2169 if( inFlags
& kDebugFlags32BitOffset
)
2171 *s
++ = kHexChars
[ ( offset
>> 28 ) & 0xF ];
2172 *s
++ = kHexChars
[ ( offset
>> 24 ) & 0xF ];
2173 *s
++ = kHexChars
[ ( offset
>> 20 ) & 0xF ];
2174 *s
++ = kHexChars
[ ( offset
>> 16 ) & 0xF ];
2176 *s
++ = kHexChars
[ ( offset
>> 12 ) & 0xF ];
2177 *s
++ = kHexChars
[ ( offset
>> 8 ) & 0xF ];
2178 *s
++ = kHexChars
[ ( offset
>> 4 ) & 0xF ];
2179 *s
++ = kHexChars
[ offset
& 0xF ];
2181 if( s
!= prefixString
)
2186 check( ( (size_t)( s
- prefixString
) ) < sizeof( prefixString
) );
2189 // Build a hex string with a optional spaces after every 1, 2, and/or 4 bytes to make it easier to read.
2190 // Optionally pads the hex string with space to fill the full 16 byte range (so it lines up).
2193 chunkSize
= ( inDataSize
< 16 ) ? inDataSize
: 16;
2194 n
= ( inFlags
& kDebugFlagsNo16ByteHexPad
) ? chunkSize
: 16;
2195 for( i
= 0; i
< n
; ++i
)
2197 if( ( inFlags
& kDebugFlags8BitSeparator
) && ( i
> 0 ) )
2201 if( ( inFlags
& kDebugFlags16BitSeparator
) && ( i
> 0 ) && ( ( i
% 2 ) == 0 ) )
2205 if( !( inFlags
& kDebugFlagsNo32BitSeparator
) && ( i
> 0 ) && ( ( i
% 4 ) == 0 ) )
2211 *s
++ = kHexChars
[ src
[ i
] >> 4 ];
2212 *s
++ = kHexChars
[ src
[ i
] & 0xF ];
2220 check( ( (size_t)( s
- hexString
) ) < sizeof( hexString
) );
2223 // Build a string with the ASCII version of the data (replaces non-printable characters with '^').
2224 // Optionally pads the string with '`' to fill the full 16 byte range (so it lines up).
2227 if( !( inFlags
& kDebugFlagsNoASCII
) )
2231 for( i
= 0; i
< n
; ++i
)
2236 if( !DebugIsPrint( c
) )
2248 check( ( (size_t)( s
- asciiString
) ) < sizeof( asciiString
) );
2252 // Build a string indicating how bytes are in the hex dump. Only printed on the first line.
2254 s
= byteCountString
;
2255 if( !( inFlags
& kDebugFlagsNoByteCount
) )
2259 s
+= DebugSNPrintF( s
, sizeof( byteCountString
), " (%d bytes)", (int) inDataSize
);
2262 check( ( (size_t)( s
- byteCountString
) ) < sizeof( byteCountString
) );
2265 // Build the entire line from all the pieces we've previously built.
2271 dst
+= DebugSNPrintF( dst
, (size_t)( end
- dst
),
2273 "%s" // Separator (only if needed)
2282 ( src
!= start
) ? separator
: "",
2284 width
, (int) inLabelSize
, inLabel
? inLabel
: "",
2285 ( width
> 0 ) ? " " : "",
2293 dst
+= DebugSNPrintF( dst
, (size_t)( end
- dst
),
2295 "%s" // Separator (only if needed)
2297 "%*s" // Label Spacing
2304 ( src
!= start
) ? separator
: "",
2307 ( width
> 0 ) ? " " : "",
2318 dst
+= DebugPrintF( inLevel
,
2320 "%s" // Separator (only if needed)
2329 ( src
!= start
) ? separator
: "",
2331 width
, (int) inLabelSize
, inLabel
,
2332 ( width
> 0 ) ? " " : "",
2340 dst
+= DebugPrintF( inLevel
,
2342 "%s" // Separator (only if needed)
2344 "%*s" // Label Spacing
2351 ( src
!= start
) ? separator
: "",
2354 ( width
> 0 ) ? " " : "",
2362 // Move to the next chunk. Exit if there is no more data.
2364 offset
+= (int) chunkSize
;
2366 inDataSize
-= chunkSize
;
2367 if( inDataSize
== 0 )
2373 // Note: The "dst - outBuffer" size calculation works even if "outBuffer" is NULL because it's all relative.
2375 return( (size_t)( dst
- outBuffer
) );
2378 //===========================================================================================================================
2379 // DebugNumVersionToString
2380 //===========================================================================================================================
2382 static char * DebugNumVersionToString( uint32_t inVersion
, char *inString
)
2393 majorRev
= (uint8_t)( ( inVersion
>> 24 ) & 0xFF );
2394 minor
= (uint8_t)( ( inVersion
>> 20 ) & 0x0F );
2395 bugFix
= (uint8_t)( ( inVersion
>> 16 ) & 0x0F );
2396 stage
= (uint8_t)( ( inVersion
>> 8 ) & 0xFF );
2397 revision
= (uint8_t)( inVersion
& 0xFF );
2399 // Convert the major, minor, and bugfix numbers.
2402 s
+= sprintf( s
, "%u", majorRev
);
2403 s
+= sprintf( s
, ".%u", minor
);
2406 s
+= sprintf( s
, ".%u", bugFix
);
2409 // Convert the version stage and non-release revision number.
2413 case kVersionStageDevelopment
:
2414 s
+= sprintf( s
, "d%u", revision
);
2417 case kVersionStageAlpha
:
2418 s
+= sprintf( s
, "a%u", revision
);
2421 case kVersionStageBeta
:
2422 s
+= sprintf( s
, "b%u", revision
);
2425 case kVersionStageFinal
:
2427 // A non-release revision of zero is a special case indicating the software is GM (at the golden master
2428 // stage) and therefore, the non-release revision should not be added to the string.
2432 s
+= sprintf( s
, "f%u", revision
);
2437 dlog( kDebugLevelError
, "invalid NumVersion stage (0x%02X)\n", stage
);
2443 //===========================================================================================================================
2445 //===========================================================================================================================
2447 DEBUG_EXPORT
uint32_t DebugTaskLevel( void )
2453 #if ( TARGET_OS_VXWORKS )
2456 level
|= ( ( 1 << kDebugInterruptLevelShift
) & kDebugInterruptLevelMask
);
2463 #if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
2464 //===========================================================================================================================
2465 // DebugWinEnableConsole
2466 //===========================================================================================================================
2468 #pragma warning( disable:4311 )
2470 static void DebugWinEnableConsole( void )
2472 static bool sConsoleEnabled
= false;
2478 if( sConsoleEnabled
)
2483 // Create console window.
2485 result
= AllocConsole();
2486 require_quiet( result
, exit
);
2488 // Redirect stdin to the console stdin.
2490 fileHandle
= _open_osfhandle( (long) GetStdHandle( STD_INPUT_HANDLE
), _O_TEXT
);
2492 #if ( defined( __MWERKS__ ) )
2493 file
= __handle_reopen( (unsigned long) fileHandle
, "r", stdin
);
2494 require_quiet( file
, exit
);
2496 file
= _fdopen( fileHandle
, "r" );
2497 require_quiet( file
, exit
);
2502 err
= setvbuf( stdin
, NULL
, _IONBF
, 0 );
2503 require_noerr_quiet( err
, exit
);
2505 // Redirect stdout to the console stdout.
2507 fileHandle
= _open_osfhandle( (long) GetStdHandle( STD_OUTPUT_HANDLE
), _O_TEXT
);
2509 #if ( defined( __MWERKS__ ) )
2510 file
= __handle_reopen( (unsigned long) fileHandle
, "w", stdout
);
2511 require_quiet( file
, exit
);
2513 file
= _fdopen( fileHandle
, "w" );
2514 require_quiet( file
, exit
);
2519 err
= setvbuf( stdout
, NULL
, _IONBF
, 0 );
2520 require_noerr_quiet( err
, exit
);
2522 // Redirect stderr to the console stdout.
2524 fileHandle
= _open_osfhandle( (long) GetStdHandle( STD_OUTPUT_HANDLE
), _O_TEXT
);
2526 #if ( defined( __MWERKS__ ) )
2527 file
= __handle_reopen( (unsigned long) fileHandle
, "w", stderr
);
2528 require_quiet( file
, exit
);
2530 file
= _fdopen( fileHandle
, "w" );
2531 require_quiet( file
, exit
);
2536 err
= setvbuf( stderr
, NULL
, _IONBF
, 0 );
2537 require_noerr_quiet( err
, exit
);
2539 sConsoleEnabled
= true;
2545 #pragma warning( default:4311 )
2547 #endif // TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE
2549 #if ( TARGET_OS_WIN32 )
2550 //===========================================================================================================================
2551 // DebugWinCharToTCharString
2552 //===========================================================================================================================
2555 DebugWinCharToTCharString(
2556 const char * inCharString
,
2558 TCHAR
* outTCharString
,
2559 size_t inTCharCountMax
,
2560 size_t * outTCharCount
)
2566 if( inCharCount
== kSizeCString
)
2568 inCharCount
= strlen( inCharString
);
2571 dst
= outTCharString
;
2572 if( inTCharCountMax
> 0 )
2574 inTCharCountMax
-= 1;
2575 if( inTCharCountMax
> inCharCount
)
2577 inTCharCountMax
= inCharCount
;
2580 end
= dst
+ inTCharCountMax
;
2583 *dst
++ = (TCHAR
) *src
++;
2589 *outTCharCount
= (size_t)( dst
- outTCharString
);
2591 return( outTCharString
);
2597 #pragma mark == Debugging ==
2600 //===========================================================================================================================
2601 // DebugServicesTest
2602 //===========================================================================================================================
2604 DEBUG_EXPORT OSStatus
DebugServicesTest( void )
2611 0x11, 0x22, 0x33, 0x44,
2613 0x77, 0x88, 0x99, 0xAA,
2617 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
2618 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0,
2619 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71, 0x81, 0x91, 0xA1
2622 debug_initialize( kDebugOutputTypeMetaConsole
);
2626 check( 0 && "SHOULD SEE: check" );
2627 check( 1 && "SHOULD *NOT* SEE: check (valid)" );
2628 check_string( 0, "SHOULD SEE: check_string" );
2629 check_string( 1, "SHOULD *NOT* SEE: check_string (valid)" );
2630 check_noerr( -123 );
2631 check_noerr( 10038 );
2634 check_noerr_string( -6712, "SHOULD SEE: check_noerr_string" );
2635 check_noerr_string( 0, "SHOULD *NOT* SEE: check_noerr_string (valid)" );
2636 check_translated_errno( 0 >= 0 && "SHOULD *NOT* SEE", -384, -999 );
2637 check_translated_errno( -1 >= 0 && "SHOULD SEE", -384, -999 );
2638 check_translated_errno( -1 >= 0 && "SHOULD SEE", 0, -999 );
2639 check_ptr_overlap( "SHOULD *NOT* SEE" ? 10 : 0, 10, 22, 10 );
2640 check_ptr_overlap( "SHOULD SEE" ? 10 : 0, 10, 5, 10 );
2641 check_ptr_overlap( "SHOULD SEE" ? 10 : 0, 10, 12, 6 );
2642 check_ptr_overlap( "SHOULD SEE" ? 12 : 0, 6, 10, 10 );
2643 check_ptr_overlap( "SHOULD SEE" ? 12 : 0, 10, 10, 10 );
2644 check_ptr_overlap( "SHOULD *NOT* SEE" ? 22 : 0, 10, 10, 10 );
2645 check_ptr_overlap( "SHOULD *NOT* SEE" ? 10 : 0, 10, 20, 10 );
2646 check_ptr_overlap( "SHOULD *NOT* SEE" ? 20 : 0, 10, 10, 10 );
2650 require( 0 && "SHOULD SEE", require1
);
2651 { err
= kResponseErr
; goto exit
; }
2653 require( 1 && "SHOULD *NOT* SEE", require2
);
2656 { err
= kResponseErr
; goto exit
; }
2658 require_string( 0 && "SHOULD SEE", require3
, "SHOULD SEE: require_string" );
2659 { err
= kResponseErr
; goto exit
; }
2661 require_string( 1 && "SHOULD *NOT* SEE", require4
, "SHOULD *NOT* SEE: require_string (valid)" );
2664 { err
= kResponseErr
; goto exit
; }
2666 require_quiet( 0 && "SHOULD SEE", require5
);
2667 { err
= kResponseErr
; goto exit
; }
2669 require_quiet( 1 && "SHOULD *NOT* SEE", require6
);
2672 { err
= kResponseErr
; goto exit
; }
2674 require_noerr( -1, require7
);
2675 { err
= kResponseErr
; goto exit
; }
2677 require_noerr( 0, require8
);
2680 { err
= kResponseErr
; goto exit
; }
2682 require_noerr_string( -2, require9
, "SHOULD SEE: require_noerr_string");
2683 { err
= kResponseErr
; goto exit
; }
2685 require_noerr_string( 0, require10
, "SHOULD *NOT* SEE: require_noerr_string (valid)" );
2688 { err
= kResponseErr
; goto exit
; }
2690 require_noerr_action_string( -3, require11
, dlog( kDebugLevelMax
, "action 1 (expected)\n" ), "require_noerr_action_string" );
2691 { err
= kResponseErr
; goto exit
; }
2693 require_noerr_action_string( 0, require12
, dlog( kDebugLevelMax
, "action 2\n" ), "require_noerr_action_string (valid)" );
2696 { err
= kResponseErr
; goto exit
; }
2698 require_noerr_quiet( -4, require13
);
2699 { err
= kResponseErr
; goto exit
; }
2701 require_noerr_quiet( 0, require14
);
2704 { err
= kResponseErr
; goto exit
; }
2706 require_noerr_action( -5, require15
, dlog( kDebugLevelMax
, "SHOULD SEE: action 3 (expected)\n" ) );
2707 { err
= kResponseErr
; goto exit
; }
2709 require_noerr_action( 0, require16
, dlog( kDebugLevelMax
, "SHOULD *NOT* SEE: action 4\n" ) );
2712 { err
= kResponseErr
; goto exit
; }
2714 require_noerr_action_quiet( -4, require17
, dlog( kDebugLevelMax
, "SHOULD SEE: action 5 (expected)\n" ) );
2715 { err
= kResponseErr
; goto exit
; }
2717 require_noerr_action_quiet( 0, require18
, dlog( kDebugLevelMax
, "SHOULD *NOT* SEE: action 6\n" ) );
2720 { err
= kResponseErr
; goto exit
; }
2722 require_action( 0 && "SHOULD SEE", require19
, dlog( kDebugLevelMax
, "SHOULD SEE: action 7 (expected)\n" ) );
2723 { err
= kResponseErr
; goto exit
; }
2725 require_action( 1 && "SHOULD *NOT* SEE", require20
, dlog( kDebugLevelMax
, "SHOULD *NOT* SEE: action 8\n" ) );
2728 { err
= kResponseErr
; goto exit
; }
2730 require_action_quiet( 0, require21
, dlog( kDebugLevelMax
, "SHOULD SEE: action 9 (expected)\n" ) );
2731 { err
= kResponseErr
; goto exit
; }
2733 require_action_quiet( 1, require22
, dlog( kDebugLevelMax
, "SHOULD *NOT* SEE: action 10\n" ) );
2736 { err
= kResponseErr
; goto exit
; }
2738 require_action_string( 0, require23
, dlog( kDebugLevelMax
, "SHOULD SEE: action 11 (expected)\n" ), "SHOULD SEE: require_action_string" );
2739 { err
= kResponseErr
; goto exit
; }
2741 require_action_string( 1, require24
, dlog( kDebugLevelMax
, "SHOULD *NOT* SEE: action 12\n" ), "SHOULD *NOT* SEE: require_action_string" );
2744 { err
= kResponseErr
; goto exit
; }
2747 #if ( defined( __MWERKS__ ) )
2748 #if ( defined( __cplusplus ) && __option( exceptions ) )
2749 #define COMPILER_HAS_EXCEPTIONS 1
2751 #define COMPILER_HAS_EXCEPTIONS 0
2754 #if ( defined( __cplusplus ) )
2755 #define COMPILER_HAS_EXCEPTIONS 1
2757 #define COMPILER_HAS_EXCEPTIONS 0
2761 #if ( COMPILER_HAS_EXCEPTIONS )
2764 require_throw( 1 && "SHOULD *NOT* SEE" );
2765 require_throw( 0 && "SHOULD SEE" );
2771 { err
= kResponseErr
; goto exit
; }
2777 err
= translate_errno( 1 != -1, -123, -567 );
2778 require( ( err
== 0 ) && "SHOULD *NOT* SEE", exit
);
2780 err
= translate_errno( -1 != -1, -123, -567 );
2781 require( ( err
== -123 ) && "SHOULD *NOT* SEE", exit
);
2783 err
= translate_errno( -1 != -1, 0, -567 );
2784 require( ( err
== -567 ) && "SHOULD *NOT* SEE", exit
);
2788 debug_string( "debug_string" );
2792 DebugSNPrintF( s
, sizeof( s
), "%d", 1234 );
2793 require_action( strcmp( s
, "1234" ) == 0, exit
, err
= -1 );
2795 DebugSNPrintF( s
, sizeof( s
), "%X", 0x2345 );
2796 require_action( strcmp( s
, "2345" ) == 0, exit
, err
= -1 );
2798 DebugSNPrintF( s
, sizeof( s
), "%#s", "\05test" );
2799 require_action( strcmp( s
, "test" ) == 0, exit
, err
= -1 );
2801 DebugSNPrintF( s
, sizeof( s
), "%##s", "\03www\05apple\03com" );
2802 require_action( strcmp( s
, "www.apple.com." ) == 0, exit
, err
= -1 );
2804 DebugSNPrintF( s
, sizeof( s
), "%ld", (long) INT32_C( 2147483647 ) );
2805 require_action( strcmp( s
, "2147483647" ) == 0, exit
, err
= -1 );
2807 DebugSNPrintF( s
, sizeof( s
), "%lu", (unsigned long) UINT32_C( 4294967295 ) );
2808 require_action( strcmp( s
, "4294967295" ) == 0, exit
, err
= -1 );
2810 #if ( TYPE_LONGLONG_NATIVE )
2811 DebugSNPrintF( s
, sizeof( s
), "%lld", (long_long_compat
) INT64_C( 9223372036854775807 ) );
2812 require_action( strcmp( s
, "9223372036854775807" ) == 0, exit
, err
= -1 );
2814 DebugSNPrintF( s
, sizeof( s
), "%lld", (long_long_compat
) INT64_C( -9223372036854775807 ) );
2815 require_action( strcmp( s
, "-9223372036854775807" ) == 0, exit
, err
= -1 );
2817 DebugSNPrintF( s
, sizeof( s
), "%llu", (unsigned_long_long_compat
) UINT64_C( 18446744073709551615 ) );
2818 require_action( strcmp( s
, "18446744073709551615" ) == 0, exit
, err
= -1 );
2821 DebugSNPrintF( s
, sizeof( s
), "%lb", (unsigned long) binary_32( 01111011, 01111011, 01111011, 01111011 ) );
2822 require_action( strcmp( s
, "1111011011110110111101101111011" ) == 0, exit
, err
= -1 );
2824 DebugSNPrintF( s
, sizeof( s
), "%C", 0x41624364 ); // 'AbCd'
2825 require_action( strcmp( s
, "AbCd" ) == 0, exit
, err
= -1 );
2827 #if ( defined( MDNS_DEBUGMSGS ) )
2831 memset( &maddr
, 0, sizeof( maddr
) );
2832 maddr
.type
= mDNSAddrType_IPv4
;
2833 maddr
.ip
.v4
.b
[ 0 ] = 127;
2834 maddr
.ip
.v4
.b
[ 1 ] = 0;
2835 maddr
.ip
.v4
.b
[ 2 ] = 0;
2836 maddr
.ip
.v4
.b
[ 3 ] = 1;
2837 DebugSNPrintF( s
, sizeof( s
), "%#a", &maddr
);
2838 require_action( strcmp( s
, "127.0.0.1" ) == 0, exit
, err
= -1 );
2840 memset( &maddr
, 0, sizeof( maddr
) );
2841 maddr
.type
= mDNSAddrType_IPv6
;
2842 maddr
.ip
.v6
.b
[ 0 ] = 0xFE;
2843 maddr
.ip
.v6
.b
[ 1 ] = 0x80;
2844 maddr
.ip
.v6
.b
[ 15 ] = 0x01;
2845 DebugSNPrintF( s
, sizeof( s
), "%#a", &maddr
);
2846 require_action( strcmp( s
, "FE80:0000:0000:0000:0000:0000:0000:0001" ) == 0, exit
, err
= -1 );
2852 struct sockaddr_in sa4
;
2854 memset( &sa4
, 0, sizeof( sa4
) );
2855 sa4
.sin_family
= AF_INET
;
2856 p
= (uint8_t *) &sa4
.sin_port
;
2857 p
[ 0 ] = (uint8_t)( ( 80 >> 8 ) & 0xFF );
2858 p
[ 1 ] = (uint8_t)( 80 & 0xFF );
2859 p
= (uint8_t *) &sa4
.sin_addr
.s_addr
;
2860 p
[ 0 ] = (uint8_t)( ( INADDR_LOOPBACK
>> 24 ) & 0xFF );
2861 p
[ 1 ] = (uint8_t)( ( INADDR_LOOPBACK
>> 16 ) & 0xFF );
2862 p
[ 2 ] = (uint8_t)( ( INADDR_LOOPBACK
>> 8 ) & 0xFF );
2863 p
[ 3 ] = (uint8_t)( INADDR_LOOPBACK
& 0xFF );
2864 DebugSNPrintF( s
, sizeof( s
), "%##a", &sa4
);
2865 require_action( strcmp( s
, "127.0.0.1:80" ) == 0, exit
, err
= -1 );
2871 struct sockaddr_in6 sa6
;
2873 memset( &sa6
, 0, sizeof( sa6
) );
2874 sa6
.sin6_family
= AF_INET6
;
2875 p
= (uint8_t *) &sa6
.sin6_port
;
2876 p
[ 0 ] = (uint8_t)( ( 80 >> 8 ) & 0xFF );
2877 p
[ 1 ] = (uint8_t)( 80 & 0xFF );
2878 sa6
.sin6_addr
.s6_addr
[ 0 ] = 0xFE;
2879 sa6
.sin6_addr
.s6_addr
[ 1 ] = 0x80;
2880 sa6
.sin6_addr
.s6_addr
[ 15 ] = 0x01;
2881 sa6
.sin6_scope_id
= 2;
2882 DebugSNPrintF( s
, sizeof( s
), "%##a", &sa6
);
2883 require_action( strcmp( s
, "[FE80:0000:0000:0000:0000:0000:0000:0001%2]:80" ) == 0, exit
, err
= -1 );
2889 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "tes" );
2890 require_action( strcmp( s
, "tes" ) == 0, exit
, err
= kResponseErr
);
2892 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "test" );
2893 require_action( strcmp( s
, "test" ) == 0, exit
, err
= kResponseErr
);
2895 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "testing" );
2896 require_action( strcmp( s
, "test" ) == 0, exit
, err
= kResponseErr
);
2898 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "te\xC3\xA9" );
2899 require_action( strcmp( s
, "te\xC3\xA9" ) == 0, exit
, err
= kResponseErr
);
2901 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "te\xC3\xA9ing" );
2902 require_action( strcmp( s
, "te\xC3\xA9" ) == 0, exit
, err
= kResponseErr
);
2904 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "tes\xC3\xA9ing" );
2905 require_action( strcmp( s
, "tes" ) == 0, exit
, err
= kResponseErr
);
2907 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "t\xed\x9f\xbf" );
2908 require_action( strcmp( s
, "t\xed\x9f\xbf" ) == 0, exit
, err
= kResponseErr
);
2910 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "t\xed\x9f\xbfing" );
2911 require_action( strcmp( s
, "t\xed\x9f\xbf" ) == 0, exit
, err
= kResponseErr
);
2913 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "te\xed\x9f\xbf" );
2914 require_action( strcmp( s
, "te" ) == 0, exit
, err
= kResponseErr
);
2916 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "te\xed\x9f\xbfing" );
2917 require_action( strcmp( s
, "te" ) == 0, exit
, err
= kResponseErr
);
2919 DebugSNPrintF(s
, sizeof(s
), "%.*s", 7, "te\xC3\xA9\xed\x9f\xbfing" );
2920 require_action( strcmp( s
, "te\xC3\xA9\xed\x9f\xbf" ) == 0, exit
, err
= kResponseErr
);
2922 DebugSNPrintF(s
, sizeof(s
), "%.*s", 6, "te\xC3\xA9\xed\x9f\xbfing" );
2923 require_action( strcmp( s
, "te\xC3\xA9" ) == 0, exit
, err
= kResponseErr
);
2925 DebugSNPrintF(s
, sizeof(s
), "%.*s", 5, "te\xC3\xA9\xed\x9f\xbfing" );
2926 require_action( strcmp( s
, "te\xC3\xA9" ) == 0, exit
, err
= kResponseErr
);
2928 #if ( TARGET_RT_BIG_ENDIAN )
2929 DebugSNPrintF( s
, sizeof( s
), "%S", "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" );
2930 require_action( strcmp( s
, "abcd" ) == 0, exit
, err
= -1 );
2932 DebugSNPrintF( s
, sizeof( s
), "%S", "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" "\x00" );
2933 require_action( strcmp( s
, "abcd" ) == 0, exit
, err
= -1 );
2936 DebugSNPrintF( s
, sizeof( s
), "%S",
2937 "\xFE\xFF" "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" ); // Big Endian BOM
2938 require_action( strcmp( s
, "abcd" ) == 0, exit
, err
= -1 );
2940 DebugSNPrintF( s
, sizeof( s
), "%S",
2941 "\xFF\xFE" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" "\x00" ); // Little Endian BOM
2942 require_action( strcmp( s
, "abcd" ) == 0, exit
, err
= -1 );
2944 DebugSNPrintF( s
, sizeof( s
), "%#S", "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" ); // Big Endian
2945 require_action( strcmp( s
, "abcd" ) == 0, exit
, err
= -1 );
2947 DebugSNPrintF( s
, sizeof( s
), "%##S", "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" "\x00" ); // Little Endian
2948 require_action( strcmp( s
, "abcd" ) == 0, exit
, err
= -1 );
2950 DebugSNPrintF( s
, sizeof( s
), "%.*S",
2951 4, "\xFE\xFF" "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" ); // Big Endian BOM
2952 require_action( strcmp( s
, "abc" ) == 0, exit
, err
= -1 );
2954 DebugSNPrintF( s
, sizeof( s
), "%.*S",
2955 4, "\xFF\xFE" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" ); // Little Endian BOM
2956 require_action( strcmp( s
, "abc" ) == 0, exit
, err
= -1 );
2958 #if ( TARGET_RT_BIG_ENDIAN )
2959 DebugSNPrintF( s
, sizeof( s
), "%.*S", 3, "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" );
2960 require_action( strcmp( s
, "abc" ) == 0, exit
, err
= -1 );
2962 DebugSNPrintF( s
, sizeof( s
), "%.*S", 3, "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" );
2963 require_action( strcmp( s
, "abc" ) == 0, exit
, err
= -1 );
2966 DebugSNPrintF( s
, sizeof( s
), "%#.*S", 3, "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" ); // Big Endian
2967 require_action( strcmp( s
, "abc" ) == 0, exit
, err
= -1 );
2969 DebugSNPrintF( s
, sizeof( s
), "%##.*S", 3, "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" ); // Little Endian
2970 require_action( strcmp( s
, "abc" ) == 0, exit
, err
= -1 );
2974 DebugSNPrintF( s
, sizeof( s
), "%U", "\x10\xb8\xa7\x6b" "\xad\x9d" "\xd1\x11" "\x80\xb4" "\x00\xc0\x4f\xd4\x30\xc8" );
2975 require_action( strcmp( s
, "6ba7b810-9dad-11d1-80b4-00c04fd430c8" ) == 0, exit
, err
= -1 );
2977 DebugSNPrintF( s
, sizeof( s
), "%m", 0 );
2978 require_action( strcmp( s
, "no error" ) == 0, exit
, err
= -1 );
2980 DebugSNPrintF( s
, sizeof( s
), "%lm", (long) 0 );
2981 require_action( strcmp( s
, "no error" ) == 0, exit
, err
= -1 );
2983 DebugSNPrintF( s
, sizeof( s
), "\"%H\"", "\x6b\xa7\xb8\x10\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8", 16, 16 );
2984 DebugPrintF( kDebugLevelMax
, "%s\n\n", s
);
2986 DebugSNPrintF( s
, sizeof( s
), "\"%H\"",
2987 "\x6b\xa7\xb8\x10\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8"
2988 "\x6b\xa7\xb8\x10\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8",
2990 DebugPrintF( kDebugLevelMax
, "%s\n\n", s
);
2992 DebugSNPrintF( s
, sizeof( s
), "\"%H\"", "\x6b\xa7", 2, 2 );
2993 DebugPrintF( kDebugLevelMax
, "%s\n\n", s
);
2998 DebugHexDump( kDebugLevelMax
, 0, "My Label", kSizeCString
, 0, NULL
, 0, data
, data
, sizeof( data
),
2999 kDebugFlagsNone
, s
, sizeof( s
) );
3000 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3003 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
),
3004 kDebugFlagsNoAddress
| kDebugFlagsNoOffset
, s
, sizeof( s
) );
3005 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3008 DebugHexDump( kDebugLevelMax
, 0, "My Label", kSizeCString
, 0, NULL
, 0, data
, data
, sizeof( data
),
3009 kDebugFlagsNoAddress
| kDebugFlagsNoOffset
, s
, sizeof( s
) );
3010 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3013 DebugHexDump( kDebugLevelMax
, 0, "My Label", kSizeCString
, 0, NULL
, 0, data
, data
, sizeof( data
),
3014 kDebugFlagsNoAddress
, s
, sizeof( s
) );
3015 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3018 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
),
3019 kDebugFlagsNoOffset
, s
, sizeof( s
) );
3020 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3023 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
),
3024 kDebugFlagsNoAddress
, s
, sizeof( s
) );
3025 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3028 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
),
3029 kDebugFlagsNoOffset
, s
, sizeof( s
) );
3030 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3033 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
),
3034 kDebugFlagsNoByteCount
, s
, sizeof( s
) );
3035 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3038 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, "\x41\x62\x43\x64", "\x41\x62\x43\x64", 4, // 'AbCd'
3039 kDebugFlagsNoAddress
| kDebugFlagsNoOffset
| kDebugFlagsNoNewLine
|
3040 kDebugFlagsNo32BitSeparator
| kDebugFlagsNo16ByteHexPad
| kDebugFlagsNoByteCount
,
3042 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3045 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
),
3046 kDebugFlagsNoAddress
| kDebugFlagsNoOffset
| kDebugFlagsNoASCII
| kDebugFlagsNoNewLine
|
3047 kDebugFlags16BitSeparator
| kDebugFlagsNo32BitSeparator
|
3048 kDebugFlagsNo16ByteHexPad
| kDebugFlagsNoByteCount
, s
, sizeof( s
) );
3049 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3052 DebugHexDump( kDebugLevelMax
, 8, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
), kDebugFlagsNone
, s
, sizeof( s
) );
3053 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3057 dlog( kDebugLevelNotice
, "dlog\n" );
3058 dlog( kDebugLevelNotice
, "dlog integer: %d\n", 123 );
3059 dlog( kDebugLevelNotice
, "dlog string: \"%s\"\n", "test string" );
3060 dlogmem( kDebugLevelNotice
, data
, sizeof( data
) );
3064 DebugPrintF( kDebugLevelMax
, "\n\nALL TESTS DONE\n\n" );
3070 DebugPrintF( kDebugLevelMax
, "\n\n### TEST FAILED ###\n\n" );