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.
17 Change History (most recent first):
19 $Log: DebugServices.c,v $
20 Revision 1.6 2006/08/14 23:24:56 cheshire
21 Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
23 Revision 1.5 2004/09/17 01:08:57 cheshire
24 Renamed mDNSClientAPI.h to mDNSEmbeddedAPI.h
25 The name "mDNSClientAPI.h" is misleading to new developers looking at this code. The interfaces
26 declared in that file are ONLY appropriate to single-address-space embedded applications.
27 For clients on general-purpose computers, the interfaces defined in dns_sd.h should be used.
29 Revision 1.4 2004/04/15 08:59:08 bradley
30 Removed deprecated debug and log levels and replaced them with modern equivalents.
32 Revision 1.3 2004/04/08 09:29:55 bradley
33 Manually do host->network byte order conversion to avoid needing libraries for htons/htonl. Changed
34 hex dumps to better separate hex and ASCII. Added support for %.8a syntax in DebugSNPrintF for Fibre
35 Channel addresses (00:11:22:33:44:55:66:77). Fixed a few places where HeaderDoc was incorrect.
37 Revision 1.2 2004/03/07 05:59:34 bradley
38 Sync'd with internal version: Added expect macros, error codes, and CoreServices exclusion.
40 Revision 1.1 2004/01/30 02:27:30 bradley
41 Debugging support for various platforms.
46 - Use StackWalk on Windows to optionally print stack frames.
50 #pragma mark == Includes ==
53 //===========================================================================================================================
55 //===========================================================================================================================
63 #include "CommonServices.h"
65 #include "DebugServices.h"
69 #if( TARGET_OS_VXWORKS )
73 #if( TARGET_OS_WIN32 )
76 #if( !TARGET_OS_WINDOWS_CE )
82 #if( DEBUG_IDEBUG_ENABLED && TARGET_API_MAC_OSX_KERNEL )
83 #include <IOKit/IOLib.h>
86 // If MDNS_DEBUGMSGS is defined (even if defined 0), it is aware of mDNS and it is probably safe to include mDNSEmbeddedAPI.h.
88 #if( defined( MDNS_DEBUGMSGS ) )
89 #include "mDNSEmbeddedAPI.h"
93 #pragma mark == Macros ==
96 //===========================================================================================================================
98 //===========================================================================================================================
100 #define DebugIsPrint( C ) ( ( ( C ) >= 0x20 ) && ( ( C ) <= 0x7E ) )
103 #pragma mark == Prototypes ==
106 //===========================================================================================================================
108 //===========================================================================================================================
110 static OSStatus
DebugPrint( DebugLevel inLevel
, char *inData
, size_t inSize
);
114 #if( DEBUG_FPRINTF_ENABLED )
115 static OSStatus
DebugFPrintFInit( DebugOutputTypeFlags inFlags
, const char *inFilename
);
116 static void DebugFPrintFPrint( char *inData
, size_t inSize
);
119 // iDebug (Mac OS X user and kernel)
121 #if( DEBUG_IDEBUG_ENABLED )
122 static OSStatus
DebugiDebugInit( void );
123 static void DebugiDebugPrint( char *inData
, size_t inSize
);
126 // kprintf (Mac OS X Kernel)
128 #if( DEBUG_KPRINTF_ENABLED )
129 static void DebugKPrintFPrint( char *inData
, size_t inSize
);
132 // Mac OS X IOLog (Mac OS X Kernel)
134 #if( DEBUG_MAC_OS_X_IOLOG_ENABLED )
135 static void DebugMacOSXIOLogPrint( char *inData
, size_t inSize
);
141 static OSStatus
DebugMacOSXLogInit( void );
142 static void DebugMacOSXLogPrint( char *inData
, size_t inSize
);
147 #if( TARGET_OS_WIN32 )
148 static void DebugWindowsDebuggerPrint( char *inData
, size_t inSize
);
153 #if( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
154 static OSStatus
DebugWindowsEventLogInit( const char *inName
, HMODULE inModule
);
155 static void DebugWindowsEventLogPrint( DebugLevel inLevel
, char *inData
, size_t inSize
);
160 #if( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
162 DebugAssertOutputHandler(
163 OSType inComponentSignature
,
165 const char * inAssertionString
,
166 const char * inExceptionString
,
167 const char * inErrorString
,
168 const char * inFileName
,
171 ConstStr255Param inOutputMsg
);
176 static char * DebugNumVersionToString( uint32_t inVersion
, char *inString
);
178 #if( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
179 static void DebugWinEnableConsole( void );
182 #if( TARGET_OS_WIN32 )
184 DebugWinCharToTCharString(
185 const char * inCharString
,
187 TCHAR
* outTCharString
,
188 size_t inTCharCountMax
,
189 size_t * outTCharCount
);
193 #pragma mark == Globals ==
196 //===========================================================================================================================
198 //===========================================================================================================================
200 #if( TARGET_OS_VXWORKS )
201 // TCP States for inetstatShow.
203 extern char ** pTcpstates
; // defined in tcpLib.c
205 const char * kDebugTCPStates
[] =
210 "(3) TCPS_SYN_RECEIVED",
211 "(4) TCPS_ESTABLISHED",
212 "(5) TCPS_CLOSE_WAIT",
213 "(6) TCPS_FIN_WAIT_1",
216 "(9) TCPS_FIN_WAIT_2",
217 "(10) TCPS_TIME_WAIT",
223 static bool gDebugInitialized
= false;
224 static DebugOutputType gDebugOutputType
= kDebugOutputTypeNone
;
225 static DebugLevel gDebugPrintLevelMin
= kDebugLevelInfo
;
226 static DebugLevel gDebugPrintLevelMax
= kDebugLevelMax
;
227 static DebugLevel gDebugBreakLevel
= kDebugLevelAssert
;
228 #if( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
229 static DebugAssertOutputHandlerUPP gDebugAssertOutputHandlerUPP
= NULL
;
234 static DebugOutputFunctionPtr gDebugCustomOutputFunction
= NULL
;
235 static void * gDebugCustomOutputContext
= NULL
;
239 #if( DEBUG_FPRINTF_ENABLED )
240 static FILE * gDebugFPrintFFile
= NULL
;
246 typedef int ( *DebugMacOSXLogFunctionPtr
)( const char *inFormat
, ... );
248 static DebugMacOSXLogFunctionPtr gDebugMacOSXLogFunction
= NULL
;
254 #if( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
255 static HANDLE gDebugWindowsEventLogEventSource
= NULL
;
260 #pragma mark == General ==
263 //===========================================================================================================================
265 //===========================================================================================================================
267 DEBUG_EXPORT OSStatus
DebugInitialize( DebugOutputType inType
, ... )
270 DebugOutputType type
;
273 va_start( args
, inType
);
275 #if( TARGET_OS_VXWORKS )
276 // Set up the TCP state strings if they are not already set up by VxWorks (normally not set up for some reason).
280 pTcpstates
= (char **) kDebugTCPStates
;
284 // Set up DebugLib stuff (if building with Debugging.h).
286 #if( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
287 if( !gDebugAssertOutputHandlerUPP
)
289 gDebugAssertOutputHandlerUPP
= NewDebugAssertOutputHandlerUPP( DebugAssertOutputHandler
);
290 check( gDebugAssertOutputHandlerUPP
);
291 if( gDebugAssertOutputHandlerUPP
)
293 InstallDebugAssertOutputHandler( gDebugAssertOutputHandlerUPP
);
298 // Pre-process meta-output kind to pick an appropriate output kind for the platform.
301 if( type
== kDebugOutputTypeMetaConsole
)
304 type
= kDebugOutputTypeMacOSXLog
;
305 #elif( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
306 #if( DEBUG_FPRINTF_ENABLED )
307 type
= kDebugOutputTypeFPrintF
;
309 type
= kDebugOutputTypeWindowsDebugger
;
311 #elif( TARGET_API_MAC_OSX_KERNEL )
312 #if( DEBUG_MAC_OS_X_IOLOG_ENABLED )
313 type
= kDebugOutputTypeMacOSXIOLog
;
314 #elif( DEBUG_IDEBUG_ENABLED )
315 type
= kDebugOutputTypeiDebug
;
316 #elif( DEBUG_KPRINTF_ENABLED )
317 type
= kDebugOutputTypeKPrintF
;
319 #elif( TARGET_OS_VXWORKS )
320 #if( DEBUG_FPRINTF_ENABLED )
321 type
= kDebugOutputTypeFPrintF
;
323 #error target is VxWorks, but fprintf output is disabled
326 #if( DEBUG_FPRINTF_ENABLED )
327 type
= kDebugOutputTypeFPrintF
;
332 // Process output kind.
334 gDebugOutputType
= type
;
337 case kDebugOutputTypeNone
:
341 case kDebugOutputTypeCustom
:
342 gDebugCustomOutputFunction
= va_arg( args
, DebugOutputFunctionPtr
);
343 gDebugCustomOutputContext
= va_arg( args
, void * );
347 #if( DEBUG_FPRINTF_ENABLED )
348 case kDebugOutputTypeFPrintF
:
349 if( inType
== kDebugOutputTypeMetaConsole
)
351 err
= DebugFPrintFInit( kDebugOutputTypeFlagsStdErr
, NULL
);
355 DebugOutputTypeFlags flags
;
356 const char * filename
;
358 flags
= (DebugOutputTypeFlags
) va_arg( args
, unsigned int );
359 if( ( flags
& kDebugOutputTypeFlagsTypeMask
) == kDebugOutputTypeFlagsFile
)
361 filename
= va_arg( args
, const char * );
367 err
= DebugFPrintFInit( flags
, filename
);
372 #if( DEBUG_IDEBUG_ENABLED )
373 case kDebugOutputTypeiDebug
:
374 err
= DebugiDebugInit();
378 #if( DEBUG_KPRINTF_ENABLED )
379 case kDebugOutputTypeKPrintF
:
384 #if( DEBUG_MAC_OS_X_IOLOG_ENABLED )
385 case kDebugOutputTypeMacOSXIOLog
:
391 case kDebugOutputTypeMacOSXLog
:
392 err
= DebugMacOSXLogInit();
396 #if( TARGET_OS_WIN32 )
397 case kDebugOutputTypeWindowsDebugger
:
402 #if( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
403 case kDebugOutputTypeWindowsEventLog
:
408 name
= va_arg( args
, const char * );
409 module = va_arg( args
, HMODULE
);
410 err
= DebugWindowsEventLogInit( name
, module );
419 gDebugInitialized
= true;
426 //===========================================================================================================================
428 //===========================================================================================================================
430 DEBUG_EXPORT
void DebugFinalize( void )
432 #if( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
433 check( gDebugAssertOutputHandlerUPP
);
434 if( gDebugAssertOutputHandlerUPP
)
436 InstallDebugAssertOutputHandler( NULL
);
437 DisposeDebugAssertOutputHandlerUPP( gDebugAssertOutputHandlerUPP
);
438 gDebugAssertOutputHandlerUPP
= NULL
;
443 //===========================================================================================================================
445 //===========================================================================================================================
447 DEBUG_EXPORT OSStatus
DebugGetProperty( DebugPropertyTag inTag
, ... )
453 va_start( args
, inTag
);
456 case kDebugPropertyTagPrintLevelMin
:
457 level
= va_arg( args
, DebugLevel
* );
458 *level
= gDebugPrintLevelMin
;
462 case kDebugPropertyTagPrintLevelMax
:
463 level
= va_arg( args
, DebugLevel
* );
464 *level
= gDebugPrintLevelMax
;
468 case kDebugPropertyTagBreakLevel
:
469 level
= va_arg( args
, DebugLevel
* );
470 *level
= gDebugBreakLevel
;
475 err
= kUnsupportedErr
;
482 //===========================================================================================================================
484 //===========================================================================================================================
486 DEBUG_EXPORT OSStatus
DebugSetProperty( DebugPropertyTag inTag
, ... )
492 va_start( args
, inTag
);
495 case kDebugPropertyTagPrintLevelMin
:
496 level
= va_arg( args
, DebugLevel
);
497 gDebugPrintLevelMin
= level
;
501 case kDebugPropertyTagPrintLevelMax
:
502 level
= va_arg( args
, DebugLevel
);
503 gDebugPrintLevelMax
= level
;
507 case kDebugPropertyTagBreakLevel
:
508 level
= va_arg( args
, DebugLevel
);
509 gDebugBreakLevel
= level
;
514 err
= kUnsupportedErr
;
523 #pragma mark == Output ==
526 //===========================================================================================================================
528 //===========================================================================================================================
530 DEBUG_EXPORT
size_t DebugPrintF( DebugLevel inLevel
, const char *inFormat
, ... )
535 // Skip if the level is not in the enabled range..
537 if( ( inLevel
< gDebugPrintLevelMin
) || ( inLevel
> gDebugPrintLevelMax
) )
543 va_start( args
, inFormat
);
544 n
= DebugPrintFVAList( inLevel
, inFormat
, args
);
551 //===========================================================================================================================
553 //===========================================================================================================================
555 DEBUG_EXPORT
size_t DebugPrintFVAList( DebugLevel inLevel
, const char *inFormat
, va_list inArgs
)
560 // Skip if the level is not in the enabled range..
562 if( ( inLevel
< gDebugPrintLevelMin
) || ( inLevel
> gDebugPrintLevelMax
) )
568 n
= DebugSNPrintFVAList( buffer
, sizeof( buffer
), inFormat
, inArgs
);
569 DebugPrint( inLevel
, buffer
, (size_t) n
);
575 //===========================================================================================================================
577 //===========================================================================================================================
579 static OSStatus
DebugPrint( DebugLevel inLevel
, char *inData
, size_t inSize
)
583 // Skip if the level is not in the enabled range..
585 if( ( inLevel
< gDebugPrintLevelMin
) || ( inLevel
> gDebugPrintLevelMax
) )
591 // Printing is not safe at interrupt time so check for this and warn with an interrupt safe mechanism (if available).
593 if( DebugTaskLevel() & kDebugInterruptLevelMask
)
595 #if( TARGET_OS_VXWORKS )
596 logMsg( "\ncannot print at interrupt time\n\n", 1, 2, 3, 4, 5, 6 );
599 err
= kExecutionStateErr
;
603 // Initialize the debugging library if it hasn't already been initialized (allows for zero-config usage).
605 if( !gDebugInitialized
)
607 debug_initialize( kDebugOutputTypeMetaConsole
);
610 // Print based on the current output type.
612 switch( gDebugOutputType
)
614 case kDebugOutputTypeNone
:
617 case kDebugOutputTypeCustom
:
618 if( gDebugCustomOutputFunction
)
620 gDebugCustomOutputFunction( inData
, inSize
, gDebugCustomOutputContext
);
624 #if( DEBUG_FPRINTF_ENABLED )
625 case kDebugOutputTypeFPrintF
:
626 DebugFPrintFPrint( inData
, inSize
);
630 #if( DEBUG_IDEBUG_ENABLED )
631 case kDebugOutputTypeiDebug
:
632 DebugiDebugPrint( inData
, inSize
);
636 #if( DEBUG_KPRINTF_ENABLED )
637 case kDebugOutputTypeKPrintF
:
638 DebugKPrintFPrint( inData
, inSize
);
642 #if( DEBUG_MAC_OS_X_IOLOG_ENABLED )
643 case kDebugOutputTypeMacOSXIOLog
:
644 DebugMacOSXIOLogPrint( inData
, inSize
);
649 case kDebugOutputTypeMacOSXLog
:
650 DebugMacOSXLogPrint( inData
, inSize
);
654 #if( TARGET_OS_WIN32 )
655 case kDebugOutputTypeWindowsDebugger
:
656 DebugWindowsDebuggerPrint( inData
, inSize
);
660 #if( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
661 case kDebugOutputTypeWindowsEventLog
:
662 DebugWindowsEventLogPrint( inLevel
, inData
, inSize
);
675 //===========================================================================================================================
678 // Warning: This routine relies on several of the strings being string constants that will exist forever because the
679 // underlying logMsg API that does the printing is asynchronous so it cannot use temporary/stack-based
680 // pointer variables (e.g. local strings). The debug macros that invoke this function only use constant
681 // constant strings, but if this function is invoked directly from other places, it must use constant strings.
682 //===========================================================================================================================
686 int_least32_t inErrorCode
,
687 const char * inAssertString
,
688 const char * inMessage
,
689 const char * inFilename
,
690 int_least32_t inLineNumber
,
691 const char * inFunction
)
693 // Skip if the level is not in the enabled range..
695 if( ( kDebugLevelAssert
< gDebugPrintLevelMin
) || ( kDebugLevelAssert
> gDebugPrintLevelMax
) )
700 if( inErrorCode
!= 0 )
705 "[ASSERT] error: %ld (%m)\n"
706 "[ASSERT] where: \"%s\", line %ld, \"%s\"\n"
708 inErrorCode
, inErrorCode
,
709 inFilename
? inFilename
: "",
711 inFunction
? inFunction
: "" );
718 "[ASSERT] assert: \"%s\" %s\n"
719 "[ASSERT] where: \"%s\", line %ld, \"%s\"\n"
721 inAssertString
? inAssertString
: "",
722 inMessage
? inMessage
: "",
723 inFilename
? inFilename
: "",
725 inFunction
? inFunction
: "" );
728 // Break into the debugger if enabled.
730 #if( TARGET_OS_WIN32 )
731 if( gDebugBreakLevel
<= kDebugLevelAssert
)
733 if( IsDebuggerPresent() )
745 #if( DEBUG_FPRINTF_ENABLED )
746 //===========================================================================================================================
748 //===========================================================================================================================
750 static OSStatus
DebugFPrintFInit( DebugOutputTypeFlags inFlags
, const char *inFilename
)
753 DebugOutputTypeFlags typeFlags
;
755 typeFlags
= inFlags
& kDebugOutputTypeFlagsTypeMask
;
756 if( typeFlags
== kDebugOutputTypeFlagsStdOut
)
758 #if( TARGET_OS_WIN32 )
759 DebugWinEnableConsole();
762 gDebugFPrintFFile
= stdout
;
764 else if( typeFlags
== kDebugOutputTypeFlagsStdErr
)
766 #if( TARGET_OS_WIN32 )
767 DebugWinEnableConsole();
770 gDebugFPrintFFile
= stdout
;
772 else if( typeFlags
== kDebugOutputTypeFlagsFile
)
774 require_action_quiet( inFilename
&& ( *inFilename
!= '\0' ), exit
, err
= kOpenErr
);
776 gDebugFPrintFFile
= fopen( inFilename
, "a" );
777 require_action_quiet( gDebugFPrintFFile
, exit
, err
= kOpenErr
);
790 //===========================================================================================================================
792 //===========================================================================================================================
794 static void DebugFPrintFPrint( char *inData
, size_t inSize
)
799 // Convert \r to \n. fprintf will interpret \n and convert to whatever is appropriate for the platform.
812 // Write the data and flush.
814 if( gDebugFPrintFFile
)
816 fprintf( gDebugFPrintFFile
, "%.*s", (int) inSize
, inData
);
817 fflush( gDebugFPrintFFile
);
820 #endif // DEBUG_FPRINTF_ENABLED
822 #if( DEBUG_IDEBUG_ENABLED )
823 //===========================================================================================================================
825 //===========================================================================================================================
827 static OSStatus
DebugiDebugInit( void )
831 #if( TARGET_API_MAC_OSX_KERNEL )
833 extern uint32_t * _giDebugReserved1
;
835 // Emulate the iDebugSetOutputType macro in iDebugServices.h.
836 // Note: This is not thread safe, but neither is iDebugServices.h nor iDebugKext.
838 if( !_giDebugReserved1
)
840 _giDebugReserved1
= (uint32_t *) IOMalloc( sizeof( uint32_t ) );
841 require_action_quiet( _giDebugReserved1
, exit
, err
= kNoMemoryErr
);
843 *_giDebugReserved1
= 0x00010000U
;
848 __private_extern__
void iDebugSetOutputTypeInternal( uint32_t inType
);
850 iDebugSetOutputTypeInternal( 0x00010000U
);
858 //===========================================================================================================================
860 //===========================================================================================================================
862 static void DebugiDebugPrint( char *inData
, size_t inSize
)
864 #if( TARGET_API_MAC_OSX_KERNEL )
866 // Locally declared here so we do not need to include iDebugKext.h.
867 // Note: IOKit uses a global namespace for all code and only a partial link occurs at build time. When the
868 // KEXT is loaded, the runtime linker will link in this extern'd symbol (assuming iDebug is present).
869 // _giDebugLogInternal is actually part of IOKit proper so this should link even if iDebug is not present.
871 typedef void ( *iDebugLogFunctionPtr
)( uint32_t inLevel
, uint32_t inTag
, const char *inFormat
, ... );
873 extern iDebugLogFunctionPtr _giDebugLogInternal
;
875 if( _giDebugLogInternal
)
877 _giDebugLogInternal( 0, 0, "%.*s", (int) inSize
, inData
);
882 __private_extern__
void iDebugLogInternal( uint32_t inLevel
, uint32_t inTag
, const char *inFormat
, ... );
884 iDebugLogInternal( 0, 0, "%.*s", (int) inSize
, inData
);
890 #if( DEBUG_KPRINTF_ENABLED )
891 //===========================================================================================================================
893 //===========================================================================================================================
895 static void DebugKPrintFPrint( char *inData
, size_t inSize
)
897 extern void kprintf( const char *inFormat
, ... );
899 kprintf( "%.*s", (int) inSize
, inData
);
903 #if( DEBUG_MAC_OS_X_IOLOG_ENABLED )
904 //===========================================================================================================================
905 // DebugMacOSXIOLogPrint
906 //===========================================================================================================================
908 static void DebugMacOSXIOLogPrint( char *inData
, size_t inSize
)
910 extern void IOLog( const char *inFormat
, ... );
912 IOLog( "%.*s", (int) inSize
, inData
);
917 //===========================================================================================================================
918 // DebugMacOSXLogInit
919 //===========================================================================================================================
921 static OSStatus
DebugMacOSXLogInit( void )
927 CFStringRef functionName
;
932 // Create a bundle reference for System.framework.
934 path
= CFSTR( "/System/Library/Frameworks/System.framework" );
935 url
= CFURLCreateWithFileSystemPath( NULL
, path
, kCFURLPOSIXPathStyle
, true );
936 require_action_quiet( url
, exit
, err
= memFullErr
);
938 bundle
= CFBundleCreate( NULL
, url
);
940 require_action_quiet( bundle
, exit
, err
= memFullErr
);
942 // Get a ptr to the system's "printf" function from System.framework.
944 functionName
= CFSTR( "printf" );
945 functionPtr
= CFBundleGetFunctionPointerForName( bundle
, functionName
);
946 require_action_quiet( functionPtr
, exit
, err
= memFullErr
);
948 // Success! Note: The bundle cannot be released because it would invalidate the function ptr.
950 gDebugMacOSXLogFunction
= (DebugMacOSXLogFunctionPtr
) functionPtr
;
962 //===========================================================================================================================
963 // DebugMacOSXLogPrint
964 //===========================================================================================================================
966 static void DebugMacOSXLogPrint( char *inData
, size_t inSize
)
968 if( gDebugMacOSXLogFunction
)
970 gDebugMacOSXLogFunction( "%.*s", (int) inSize
, inData
);
975 #if( TARGET_OS_WIN32 )
976 //===========================================================================================================================
977 // DebugWindowsDebuggerPrint
978 //===========================================================================================================================
980 void DebugWindowsDebuggerPrint( char *inData
, size_t inSize
)
988 // Copy locally and null terminate the string. This also converts from char to TCHAR in case we are
989 // building with UNICODE enabled since the input is always char. Also convert \r to \n in the process.
992 if( inSize
>= sizeof_array( buffer
) )
994 inSize
= sizeof_array( buffer
) - 1;
1009 // Print out the string to the debugger.
1011 OutputDebugString( buffer
);
1015 #if( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
1016 //===========================================================================================================================
1017 // DebugWindowsEventLogInit
1018 //===========================================================================================================================
1020 static OSStatus
DebugWindowsEventLogInit( const char *inName
, HMODULE inModule
)
1026 TCHAR path
[ MAX_PATH
];
1028 DWORD typesSupported
;
1033 // Use a default name if needed then convert the name to TCHARs so it works on ANSI or Unicode builds.
1035 if( !inName
|| ( *inName
== '\0' ) )
1037 inName
= "DefaultApp";
1039 DebugWinCharToTCharString( inName
, kSizeCString
, name
, sizeof( name
), NULL
);
1041 // Build the path string using the fixed registry path and app name.
1043 src
= "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\";
1044 DebugWinCharToTCharString( src
, kSizeCString
, path
, sizeof_array( path
), &size
);
1045 DebugWinCharToTCharString( inName
, kSizeCString
, path
+ size
, sizeof_array( path
) - size
, NULL
);
1047 // Add/Open the source name as a sub-key under the Application key in the EventLog registry key.
1049 err
= RegCreateKeyEx( HKEY_LOCAL_MACHINE
, path
, 0, NULL
, REG_OPTION_NON_VOLATILE
, KEY_ALL_ACCESS
, NULL
, &key
, NULL
);
1050 require_noerr_quiet( err
, exit
);
1052 // Set the path in the EventMessageFile subkey. Add 1 to the TCHAR count to include the null terminator.
1054 n
= GetModuleFileName( inModule
, path
, sizeof_array( path
) );
1055 err
= translate_errno( n
> 0, (OSStatus
) GetLastError(), kParamErr
);
1056 require_noerr_quiet( err
, exit
);
1058 n
*= sizeof( TCHAR
);
1060 err
= RegSetValueEx( key
, TEXT( "EventMessageFile" ), 0, REG_EXPAND_SZ
, (const LPBYTE
) path
, n
);
1061 require_noerr_quiet( err
, exit
);
1063 // Set the supported event types in the TypesSupported subkey.
1065 typesSupported
= EVENTLOG_SUCCESS
| EVENTLOG_ERROR_TYPE
| EVENTLOG_WARNING_TYPE
| EVENTLOG_INFORMATION_TYPE
|
1066 EVENTLOG_AUDIT_SUCCESS
| EVENTLOG_AUDIT_FAILURE
;
1067 err
= RegSetValueEx( key
, TEXT( "TypesSupported" ), 0, REG_DWORD
, (const LPBYTE
) &typesSupported
, sizeof( DWORD
) );
1068 require_noerr_quiet( err
, exit
);
1070 // Set up the event source.
1072 gDebugWindowsEventLogEventSource
= RegisterEventSource( NULL
, name
);
1073 err
= translate_errno( gDebugWindowsEventLogEventSource
, (OSStatus
) GetLastError(), kParamErr
);
1074 require_noerr_quiet( err
, exit
);
1084 //===========================================================================================================================
1085 // DebugWindowsEventLogPrint
1086 //===========================================================================================================================
1088 static void DebugWindowsEventLogPrint( DebugLevel inLevel
, char *inData
, size_t inSize
)
1091 TCHAR buffer
[ 512 ];
1096 const TCHAR
* array
[ 1 ];
1098 // Map the debug level to a Windows EventLog type.
1100 if( inLevel
<= kDebugLevelNotice
)
1102 type
= EVENTLOG_INFORMATION_TYPE
;
1104 else if( inLevel
<= kDebugLevelWarning
)
1106 type
= EVENTLOG_WARNING_TYPE
;
1110 type
= EVENTLOG_ERROR_TYPE
;
1113 // Copy locally and null terminate the string. This also converts from char to TCHAR in case we are
1114 // building with UNICODE enabled since the input is always char. Also convert \r to \n in the process.
1117 if( inSize
>= sizeof_array( buffer
) )
1119 inSize
= sizeof_array( buffer
) - 1;
1134 // Add the the string to the event log.
1136 array
[ 0 ] = buffer
;
1137 if( gDebugWindowsEventLogEventSource
)
1139 ReportEvent( gDebugWindowsEventLogEventSource
, type
, 0, 0x20000001L
, NULL
, 1, 0, array
, NULL
);
1142 #endif // TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE
1144 #if( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
1145 //===========================================================================================================================
1146 // DebugAssertOutputHandler
1147 //===========================================================================================================================
1150 DebugAssertOutputHandler(
1151 OSType inComponentSignature
,
1153 const char * inAssertString
,
1154 const char * inExceptionString
,
1155 const char * inErrorString
,
1156 const char * inFileName
,
1159 ConstStr255Param inOutputMsg
)
1161 DEBUG_UNUSED( inComponentSignature
);
1162 DEBUG_UNUSED( inOptions
);
1163 DEBUG_UNUSED( inExceptionString
);
1164 DEBUG_UNUSED( inValue
);
1165 DEBUG_UNUSED( inOutputMsg
);
1167 DebugPrintAssert( 0, inAssertString
, inErrorString
, inFileName
, (int_least32_t) inLineNumber
, "" );
1173 #pragma mark == Utilities ==
1176 //===========================================================================================================================
1179 // Stolen from mDNS.c's mDNS_snprintf/mDNS_vsnprintf with the following changes:
1181 // Changed names to avoid name collisions with the mDNS versions.
1182 // Changed types to standard C types since mDNSEmbeddedAPI.h may not be available.
1183 // Conditionalized mDNS stuff so it can be used with or with mDNSEmbeddedAPI.h.
1184 // Added 64-bit support for %d (%lld), %i (%lli), %u (%llu), %o (%llo), %x (%llx), and %b (%llb).
1185 // Added %@ - Cocoa/CoreFoundation object. Param is the object. Strings are used directly. Others use CFCopyDescription.
1186 // Added %.8a - FIbre Channel address. Arg=ptr to address.
1187 // Added %##a - IPv4 (if AF_INET defined) or IPv6 (if AF_INET6 defined) sockaddr. Arg=ptr to sockaddr.
1188 // Added %b - Binary representation of integer (e.g. 01101011). Modifiers and arg=the same as %d, %x, etc.
1189 // Added %C - Mac-style FourCharCode (e.g. 'APPL'). Arg=32-bit value to print as a Mac-style FourCharCode.
1190 // Added %H - Hex Dump (e.g. "\x6b\xa7" -> "6B A7"). 1st arg=ptr, 2nd arg=size, 3rd arg=max size.
1191 // Added %#H - Hex Dump & ASCII (e.g. "\x41\x62" -> "6B A7 'Ab'"). 1st arg=ptr, 2nd arg=size, 3rd arg=max size.
1192 // Added %m - Error Message (e.g. 0 -> "kNoErr"). Modifiers and error code args are the same as %d, %x, etc.
1193 // Added %S - UTF-16 string. Host order if no BOM. Precision is UTF-16 char count. BOM counts in any precision. Arg=ptr.
1194 // Added %#S - Big Endian UTF-16 string (unless BOM overrides). Otherwise the same as %S.
1195 // Added %##S - Little Endian UTF-16 string (unless BOM overrides). Otherwise the same as %S.
1196 // Added %U - Universally Unique Identifier (UUID) (e.g. 6ba7b810-9dad-11d1-80b4-00c04fd430c8). Arg=ptr to 16-byte UUID.
1197 //===========================================================================================================================
1199 DEBUG_EXPORT
size_t DebugSNPrintF(char *sbuffer
, size_t buflen
, const char *fmt
, ...)
1205 length
= DebugSNPrintFVAList(sbuffer
, buflen
, fmt
, ptr
);
1211 //===========================================================================================================================
1212 // DebugSNPrintFVAList - va_list version of DebugSNPrintF. See DebugSNPrintF for more info.
1213 //===========================================================================================================================
1215 DEBUG_EXPORT
size_t DebugSNPrintFVAList(char *sbuffer
, size_t buflen
, const char *fmt
, va_list arg
)
1217 static const struct DebugSNPrintF_format
1219 unsigned leftJustify
: 1;
1220 unsigned forceSign
: 1;
1221 unsigned zeroPad
: 1;
1222 unsigned havePrecision
: 1;
1226 char sign
; // +, - or space
1227 unsigned int fieldWidth
;
1228 unsigned int precision
;
1229 } DebugSNPrintF_format_default
= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1231 size_t nwritten
= 0;
1233 if (buflen
== 0) return(0);
1234 buflen
--; // Pre-reserve one space in the buffer for the terminating nul
1235 if (buflen
== 0) goto exit
;
1237 for (c
= *fmt
; c
!= 0; c
= *++fmt
)
1241 *sbuffer
++ = (char)c
;
1242 if (++nwritten
>= buflen
) goto exit
;
1247 // The mDNS Vsprintf Argument Conversion Buffer is used as a temporary holding area for
1248 // generating decimal numbers, hexdecimal numbers, IP addresses, domain name strings, etc.
1249 // The size needs to be enough for a 256-byte domain name plus some error text.
1250 #define mDNS_VACB_Size 300
1251 char mDNS_VACB
[mDNS_VACB_Size
];
1252 #define mDNS_VACB_Lim (&mDNS_VACB[mDNS_VACB_Size])
1253 #define mDNS_VACB_Remain(s) ((size_t)(mDNS_VACB_Lim - s))
1254 char *s
= mDNS_VACB_Lim
;
1255 const char *digits
= "0123456789ABCDEF";
1256 struct DebugSNPrintF_format F
= DebugSNPrintF_format_default
;
1258 for(;;) // decode flags
1261 if (c
== '-') F
.leftJustify
= 1;
1262 else if (c
== '+') F
.forceSign
= 1;
1263 else if (c
== ' ') F
.sign
= ' ';
1264 else if (c
== '#') F
.altForm
++;
1265 else if (c
== '0') F
.zeroPad
= 1;
1269 if (c
== '*') // decode field width
1271 int f
= va_arg(arg
, int);
1272 if (f
< 0) { f
= -f
; F
.leftJustify
= 1; }
1273 F
.fieldWidth
= (unsigned int)f
;
1278 for (; c
>= '0' && c
<= '9'; c
= *++fmt
)
1279 F
.fieldWidth
= (10 * F
.fieldWidth
) + (c
- '0');
1282 if (c
== '.') // decode precision
1284 if ((c
= *++fmt
) == '*')
1285 { F
.precision
= va_arg(arg
, unsigned int); c
= *++fmt
; }
1286 else for (; c
>= '0' && c
<= '9'; c
= *++fmt
)
1287 F
.precision
= (10 * F
.precision
) + (c
- '0');
1288 F
.havePrecision
= 1;
1291 if (F
.leftJustify
) F
.zeroPad
= 0;
1294 switch (c
) // perform appropriate conversion
1296 #if TYPE_LONGLONG_NATIVE
1297 unsigned_long_long_compat n
;
1298 unsigned_long_long_compat base
;
1303 case 'h' : F
.hSize
= 1; c
= *++fmt
; goto conv
;
1304 case 'l' : // fall through
1305 case 'L' : F
.lSize
++; c
= *++fmt
; goto conv
;
1307 case 'i' : base
= 10;
1309 case 'u' : base
= 10;
1311 case 'o' : base
= 8;
1313 case 'b' : base
= 2;
1315 case 'p' : n
= va_arg(arg
, uintptr_t);
1316 F
.havePrecision
= 1;
1317 F
.precision
= (sizeof(uintptr_t) == 4) ? 8 : 16;
1322 case 'x' : digits
= "0123456789abcdef";
1323 case 'X' : base
= 16;
1326 #if TYPE_LONGLONG_NATIVE
1327 if (F
.lSize
== 1) n
= (unsigned_long_long_compat
)va_arg(arg
, long);
1328 else if (F
.lSize
== 2) n
= (unsigned_long_long_compat
)va_arg(arg
, long_long_compat
);
1329 else n
= (unsigned_long_long_compat
)va_arg(arg
, int);
1331 if (F
.lSize
== 1) n
= (unsigned long)va_arg(arg
, long);
1332 else if (F
.lSize
== 2) goto exit
;
1333 else n
= (unsigned long)va_arg(arg
, int);
1335 if (F
.hSize
) n
= (short) n
;
1336 #if TYPE_LONGLONG_NATIVE
1337 if ((long_long_compat
) n
< 0) { n
= (unsigned_long_long_compat
)-(long_long_compat
)n
; F
.sign
= '-'; }
1339 if ((long) n
< 0) { n
= (unsigned long)-(long)n
; F
.sign
= '-'; }
1341 else if (F
.forceSign
) F
.sign
= '+';
1344 notSigned
: if (F
.lSize
== 1) n
= va_arg(arg
, unsigned long);
1345 else if (F
.lSize
== 2)
1347 #if TYPE_LONGLONG_NATIVE
1348 n
= va_arg(arg
, unsigned_long_long_compat
);
1353 else n
= va_arg(arg
, unsigned int);
1354 if (F
.hSize
) n
= (unsigned short) n
;
1358 number
: if (!F
.havePrecision
)
1362 F
.precision
= F
.fieldWidth
;
1363 if (F
.altForm
) F
.precision
-= 2;
1364 if (F
.sign
) --F
.precision
;
1366 if (F
.precision
< 1) F
.precision
= 1;
1368 if (F
.precision
> mDNS_VACB_Size
- 1)
1369 F
.precision
= mDNS_VACB_Size
- 1;
1370 for (i
= 0; n
; n
/= base
, i
++) *--s
= (char)(digits
[n
% base
]);
1371 for (; i
< F
.precision
; i
++) *--s
= '0';
1372 if (F
.altForm
) { *--s
= (char)c
; *--s
= '0'; i
+= 2; }
1373 if (F
.sign
) { *--s
= F
.sign
; i
++; }
1377 unsigned char *a
= va_arg(arg
, unsigned char *);
1380 if (!a
) { static char emsg
[] = "<<NULL>>"; s
= emsg
; i
= sizeof(emsg
)-1; }
1383 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1386 #if(defined(MDNS_DEBUGMSGS))
1387 mDNSAddr
*ip
= (mDNSAddr
*)a
;
1390 case mDNSAddrType_IPv4
: F
.precision
= 4; a
= (unsigned char *)&ip
->ip
.v4
; break;
1391 case mDNSAddrType_IPv6
: F
.precision
= 16; a
= (unsigned char *)&ip
->ip
.v6
; break;
1392 default: F
.precision
= 0; break;
1395 F
.precision
= 0; // mDNSEmbeddedAPI.h not included so no mDNSAddr support
1398 else if (F
.altForm
== 2)
1401 const struct sockaddr
*sa
;
1402 unsigned char *port
;
1403 sa
= (const struct sockaddr
*)a
;
1404 switch (sa
->sa_family
)
1406 case AF_INET
: F
.precision
= 4; a
= (unsigned char*)&((const struct sockaddr_in
*)a
)->sin_addr
;
1407 port
= (unsigned char*)&((const struct sockaddr_in
*)sa
)->sin_port
;
1408 DebugSNPrintF(post
, sizeof(post
), ":%d", (port
[0] << 8) | port
[1]); break;
1410 case AF_INET6
: F
.precision
= 16; a
= (unsigned char*)&((const struct sockaddr_in6
*)a
)->sin6_addr
;
1411 pre
[0] = '['; pre
[1] = '\0';
1412 port
= (unsigned char*)&((const struct sockaddr_in6
*)sa
)->sin6_port
;
1413 DebugSNPrintF(post
, sizeof(post
), "%%%d]:%d",
1414 (int)((const struct sockaddr_in6
*)sa
)->sin6_scope_id
,
1415 (port
[0] << 8) | port
[1]); break;
1417 default: F
.precision
= 0; break;
1420 F
.precision
= 0; // socket interfaces not included so no sockaddr support
1423 switch (F
.precision
)
1425 case 4: i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "%d.%d.%d.%d%s",
1426 a
[0], a
[1], a
[2], a
[3], post
); break;
1427 case 6: i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "%02X:%02X:%02X:%02X:%02X:%02X",
1428 a
[0], a
[1], a
[2], a
[3], a
[4], a
[5]); break;
1429 case 8: i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
1430 a
[0], a
[1], a
[2], a
[3], a
[4], a
[5], a
[6], a
[7]); break;
1431 case 16: i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
),
1432 "%s%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X%s",
1433 pre
, a
[0], a
[1], a
[2], a
[3], a
[4], a
[5], a
[6], a
[7], a
[8],
1434 a
[9], a
[10], a
[11], a
[12], a
[13], a
[14], a
[15], post
); break;
1435 default: i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "%s", "<< ERROR: Must specify address size "
1436 "(i.e. %.4a=IPv4, %.6a=Ethernet, %.8a=Fibre Channel %.16a=IPv6) >>"); break;
1443 unsigned char *a
= va_arg(arg
, unsigned char *);
1444 if (!a
) { static char emsg
[] = "<<NULL>>"; s
= emsg
; i
= sizeof(emsg
)-1; }
1447 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1448 i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
1449 *((uint32_t*) &a
[0]), *((uint16_t*) &a
[4]), *((uint16_t*) &a
[6]),
1450 a
[8], a
[9], a
[10], a
[11], a
[12], a
[13], a
[14], a
[15]); break;
1455 case 'c' : *--s
= (char)va_arg(arg
, int); i
= 1; break;
1457 case 'C' : if (F
.lSize
) n
= va_arg(arg
, unsigned long);
1458 else n
= va_arg(arg
, unsigned int);
1459 if (F
.hSize
) n
= (unsigned short) n
;
1460 c
= (int)( n
& 0xFF); *--s
= (char)(DebugIsPrint(c
) ? c
: '^');
1461 c
= (int)((n
>> 8) & 0xFF); *--s
= (char)(DebugIsPrint(c
) ? c
: '^');
1462 c
= (int)((n
>> 16) & 0xFF); *--s
= (char)(DebugIsPrint(c
) ? c
: '^');
1463 c
= (int)((n
>> 24) & 0xFF); *--s
= (char)(DebugIsPrint(c
) ? c
: '^');
1467 case 's' : s
= va_arg(arg
, char *);
1468 if (!s
) { static char emsg
[] = "<<NULL>>"; s
= emsg
; i
= sizeof(emsg
)-1; }
1469 else switch (F
.altForm
)
1472 if (F
.havePrecision
) // C string
1474 while((i
< F
.precision
) && s
[i
]) i
++;
1475 // Make sure we don't truncate in the middle of a UTF-8 character.
1476 // If the last character is part of a multi-byte UTF-8 character, back up to the start of it.
1478 while((i
> 0) && ((c
= s
[i
-1]) & 0x80)) { j
++; i
--; if((c
& 0xC0) != 0x80) break; }
1479 // If the actual count of UTF-8 characters matches the encoded UTF-8 count, add it back.
1480 if((j
> 1) && (j
<= 6))
1482 int test
= (0xFF << (8-j
)) & 0xFF;
1483 int mask
= test
| (1 << ((8-j
)-1));
1484 if((c
& mask
) == test
) i
+= j
;
1490 case 1: i
= (unsigned char) *s
++; break; // Pascal string
1491 case 2: { // DNS label-sequence name
1492 unsigned char *a
= (unsigned char *)s
;
1493 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1494 if (*a
== 0) *s
++ = '.'; // Special case for root DNS name
1497 if (*a
> 63) { s
+= DebugSNPrintF(s
, mDNS_VACB_Remain(s
), "<<INVALID LABEL LENGTH %u>>", *a
); break; }
1498 if (s
+ *a
>= &mDNS_VACB
[254]) { s
+= DebugSNPrintF(s
, mDNS_VACB_Remain(s
), "<<NAME TOO LONG>>"); break; }
1499 s
+= DebugSNPrintF(s
, mDNS_VACB_Remain(s
), "%#s.", a
);
1502 i
= (size_t)(s
- mDNS_VACB
);
1503 s
= mDNS_VACB
; // Reset s back to the start of the buffer
1507 if (F
.havePrecision
&& i
> F
.precision
) // Make sure we don't truncate in the middle of a UTF-8 character
1508 { i
= F
.precision
; while (i
>0 && (s
[i
] & 0xC0) == 0x80) i
--; }
1511 case 'S': { // UTF-16 string
1512 unsigned char *a
= va_arg(arg
, unsigned char *);
1513 uint16_t *u
= (uint16_t*)a
;
1514 if (!u
) { static char emsg
[] = "<<NULL>>"; s
= emsg
; i
= sizeof(emsg
)-1; }
1515 if ((!F
.havePrecision
|| F
.precision
))
1517 if ((a
[0] == 0xFE) && (a
[1] == 0xFF)) { F
.altForm
= 1; u
+= 1; a
+= 2; F
.precision
--; } // Big Endian
1518 else if ((a
[0] == 0xFF) && (a
[1] == 0xFE)) { F
.altForm
= 2; u
+= 1; a
+= 2; F
.precision
--; } // Little Endian
1520 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1523 case 0: while ((!F
.havePrecision
|| (i
< F
.precision
)) && u
[i
] && mDNS_VACB_Remain(s
)) // Host Endian
1524 { c
= u
[i
]; *s
++ = (char)(DebugIsPrint(c
) ? c
: '^'); i
++; }
1526 case 1: while ((!F
.havePrecision
|| (i
< F
.precision
)) && u
[i
] && mDNS_VACB_Remain(s
)) // Big Endian
1527 { c
= ((a
[0] << 8) | a
[1]) & 0xFF; *s
++ = (char)(DebugIsPrint(c
) ? c
: '^'); i
++; a
+= 2; }
1529 case 2: while ((!F
.havePrecision
|| (i
< F
.precision
)) && u
[i
] && mDNS_VACB_Remain(s
)) // Little Endian
1530 { c
= ((a
[1] << 8) | a
[0]) & 0xFF; *s
++ = (char)(DebugIsPrint(c
) ? c
: '^'); i
++; a
+= 2; }
1534 s
= mDNS_VACB
; // Reset s back to the start of the buffer
1538 case '@': { // Cocoa/CoreFoundation object
1541 cfObj
= (CFTypeRef
) va_arg(arg
, void *);
1542 cfStr
= (CFGetTypeID(cfObj
) == CFStringGetTypeID()) ? (CFStringRef
)CFRetain(cfObj
) : CFCopyDescription(cfObj
);
1543 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1548 range
= CFRangeMake(0, CFStringGetLength(cfStr
));
1550 CFStringGetBytes(cfStr
, range
, kCFStringEncodingUTF8
, '^', false, (UInt8
*)mDNS_VACB
, (CFIndex
)sizeof(mDNS_VACB
), &m
);
1556 i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "%s", "ERROR: <invalid CF object>" );
1559 if (F
.havePrecision
&& i
> F
.precision
) // Make sure we don't truncate in the middle of a UTF-8 character
1560 { i
= F
.precision
; while (i
>0 && (s
[i
] & 0xC0) == 0x80) i
--; }
1564 case 'm' : { // Error Message
1566 if (F
.lSize
) err
= va_arg(arg
, long);
1567 else err
= va_arg(arg
, int);
1568 if (F
.hSize
) err
= (short)err
;
1569 DebugGetErrorString(err
, mDNS_VACB
, sizeof(mDNS_VACB
));
1570 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1571 for(i
=0;s
[i
];i
++) {}
1575 case 'H' : { // Hex Dump
1576 void *a
= va_arg(arg
, void *);
1577 size_t size
= (size_t)va_arg(arg
, int);
1578 size_t max
= (size_t)va_arg(arg
, int);
1580 kDebugFlagsNoAddress
| kDebugFlagsNoOffset
| kDebugFlagsNoNewLine
|
1581 kDebugFlags8BitSeparator
| kDebugFlagsNo32BitSeparator
|
1582 kDebugFlagsNo16ByteHexPad
| kDebugFlagsNoByteCount
;
1583 if (F
.altForm
== 0) flags
|= kDebugFlagsNoASCII
;
1584 size
= (max
< size
) ? max
: size
;
1585 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1586 i
= DebugHexDump(kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, a
, a
, size
, flags
, mDNS_VACB
, sizeof(mDNS_VACB
));
1590 case 'v' : { // Version
1592 version
= va_arg(arg
, unsigned int);
1593 DebugNumVersionToString(version
, mDNS_VACB
);
1594 s
= mDNS_VACB
; // Adjust s to point to the start of the buffer, not the end
1595 for(i
=0;s
[i
];i
++) {}
1599 case 'n' : s
= va_arg(arg
, char *);
1600 if (F
.hSize
) * (short *) s
= (short)nwritten
;
1601 else if (F
.lSize
) * (long *) s
= (long)nwritten
;
1602 else * (int *) s
= (int)nwritten
;
1605 default: s
= mDNS_VACB
;
1606 i
= DebugSNPrintF(mDNS_VACB
, sizeof(mDNS_VACB
), "<<UNKNOWN FORMAT CONVERSION CODE %%%c>>", c
);
1608 case '%' : *sbuffer
++ = (char)c
;
1609 if (++nwritten
>= buflen
) goto exit
;
1613 if (i
< F
.fieldWidth
&& !F
.leftJustify
) // Pad on the left
1616 if (++nwritten
>= buflen
) goto exit
;
1617 } while (i
< --F
.fieldWidth
);
1619 if (i
> buflen
- nwritten
) // Make sure we don't truncate in the middle of a UTF-8 character
1620 { i
= buflen
- nwritten
; while (i
>0 && (s
[i
] & 0xC0) == 0x80) i
--; }
1621 for (j
=0; j
<i
; j
++) *sbuffer
++ = *s
++; // Write the converted result
1623 if (nwritten
>= buflen
) goto exit
;
1625 for (; i
< F
.fieldWidth
; i
++) // Pad on the right
1628 if (++nwritten
>= buflen
) goto exit
;
1637 //===========================================================================================================================
1638 // DebugGetErrorString
1639 //===========================================================================================================================
1641 DEBUG_EXPORT
const char * DebugGetErrorString( int_least32_t inErrorCode
, char *inBuffer
, size_t inBufferSize
)
1646 #if( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
1650 switch( inErrorCode
)
1652 #define CaseErrorString( X, STR ) case X: s = STR; break
1653 #define CaseErrorStringify( X ) case X: s = # X; break
1654 #define CaseErrorStringifyHardCode( VALUE, X ) case VALUE: s = # X; break
1658 CaseErrorString( 0, "no error" );
1659 CaseErrorString( 1, "in-progress/waiting" );
1660 CaseErrorString( -1, "catch-all unknown error" );
1664 CaseErrorStringifyHardCode( -2, kACPBadRequestErr
);
1665 CaseErrorStringifyHardCode( -3, kACPNoMemoryErr
);
1666 CaseErrorStringifyHardCode( -4, kACPBadParamErr
);
1667 CaseErrorStringifyHardCode( -5, kACPNotFoundErr
);
1668 CaseErrorStringifyHardCode( -6, kACPBadChecksumErr
);
1669 CaseErrorStringifyHardCode( -7, kACPCommandNotHandledErr
);
1670 CaseErrorStringifyHardCode( -8, kACPNetworkErr
);
1671 CaseErrorStringifyHardCode( -9, kACPDuplicateCommandHandlerErr
);
1672 CaseErrorStringifyHardCode( -10, kACPUnknownPropertyErr
);
1673 CaseErrorStringifyHardCode( -11, kACPImmutablePropertyErr
);
1674 CaseErrorStringifyHardCode( -12, kACPBadPropertyValueErr
);
1675 CaseErrorStringifyHardCode( -13, kACPNoResourcesErr
);
1676 CaseErrorStringifyHardCode( -14, kACPBadOptionErr
);
1677 CaseErrorStringifyHardCode( -15, kACPBadSizeErr
);
1678 CaseErrorStringifyHardCode( -16, kACPBadPasswordErr
);
1679 CaseErrorStringifyHardCode( -17, kACPNotInitializedErr
);
1680 CaseErrorStringifyHardCode( -18, kACPNonReadablePropertyErr
);
1681 CaseErrorStringifyHardCode( -19, kACPBadVersionErr
);
1682 CaseErrorStringifyHardCode( -20, kACPBadSignatureErr
);
1683 CaseErrorStringifyHardCode( -21, kACPBadIndexErr
);
1684 CaseErrorStringifyHardCode( -22, kACPUnsupportedErr
);
1685 CaseErrorStringifyHardCode( -23, kACPInUseErr
);
1686 CaseErrorStringifyHardCode( -24, kACPParamCountErr
);
1687 CaseErrorStringifyHardCode( -25, kACPIDErr
);
1688 CaseErrorStringifyHardCode( -26, kACPFormatErr
);
1689 CaseErrorStringifyHardCode( -27, kACPUnknownUserErr
);
1690 CaseErrorStringifyHardCode( -28, kACPAccessDeniedErr
);
1691 CaseErrorStringifyHardCode( -29, kACPIncorrectFWErr
);
1693 // Common Services Errors
1695 CaseErrorStringify( kUnknownErr
);
1696 CaseErrorStringify( kOptionErr
);
1697 CaseErrorStringify( kSelectorErr
);
1698 CaseErrorStringify( kExecutionStateErr
);
1699 CaseErrorStringify( kPathErr
);
1700 CaseErrorStringify( kParamErr
);
1701 CaseErrorStringify( kParamCountErr
);
1702 CaseErrorStringify( kCommandErr
);
1703 CaseErrorStringify( kIDErr
);
1704 CaseErrorStringify( kStateErr
);
1705 CaseErrorStringify( kRangeErr
);
1706 CaseErrorStringify( kRequestErr
);
1707 CaseErrorStringify( kResponseErr
);
1708 CaseErrorStringify( kChecksumErr
);
1709 CaseErrorStringify( kNotHandledErr
);
1710 CaseErrorStringify( kVersionErr
);
1711 CaseErrorStringify( kSignatureErr
);
1712 CaseErrorStringify( kFormatErr
);
1713 CaseErrorStringify( kNotInitializedErr
);
1714 CaseErrorStringify( kAlreadyInitializedErr
);
1715 CaseErrorStringify( kNotInUseErr
);
1716 CaseErrorStringify( kInUseErr
);
1717 CaseErrorStringify( kTimeoutErr
);
1718 CaseErrorStringify( kCanceledErr
);
1719 CaseErrorStringify( kAlreadyCanceledErr
);
1720 CaseErrorStringify( kCannotCancelErr
);
1721 CaseErrorStringify( kDeletedErr
);
1722 CaseErrorStringify( kNotFoundErr
);
1723 CaseErrorStringify( kNoMemoryErr
);
1724 CaseErrorStringify( kNoResourcesErr
);
1725 CaseErrorStringify( kDuplicateErr
);
1726 CaseErrorStringify( kImmutableErr
);
1727 CaseErrorStringify( kUnsupportedDataErr
);
1728 CaseErrorStringify( kIntegrityErr
);
1729 CaseErrorStringify( kIncompatibleErr
);
1730 CaseErrorStringify( kUnsupportedErr
);
1731 CaseErrorStringify( kUnexpectedErr
);
1732 CaseErrorStringify( kValueErr
);
1733 CaseErrorStringify( kNotReadableErr
);
1734 CaseErrorStringify( kNotWritableErr
);
1735 CaseErrorStringify( kBadReferenceErr
);
1736 CaseErrorStringify( kFlagErr
);
1737 CaseErrorStringify( kMalformedErr
);
1738 CaseErrorStringify( kSizeErr
);
1739 CaseErrorStringify( kNameErr
);
1740 CaseErrorStringify( kNotReadyErr
);
1741 CaseErrorStringify( kReadErr
);
1742 CaseErrorStringify( kWriteErr
);
1743 CaseErrorStringify( kMismatchErr
);
1744 CaseErrorStringify( kDateErr
);
1745 CaseErrorStringify( kUnderrunErr
);
1746 CaseErrorStringify( kOverrunErr
);
1747 CaseErrorStringify( kEndingErr
);
1748 CaseErrorStringify( kConnectionErr
);
1749 CaseErrorStringify( kAuthenticationErr
);
1750 CaseErrorStringify( kOpenErr
);
1751 CaseErrorStringify( kTypeErr
);
1752 CaseErrorStringify( kSkipErr
);
1753 CaseErrorStringify( kNoAckErr
);
1754 CaseErrorStringify( kCollisionErr
);
1755 CaseErrorStringify( kBackoffErr
);
1756 CaseErrorStringify( kNoAddressAckErr
);
1757 CaseErrorStringify( kBusyErr
);
1758 CaseErrorStringify( kNoSpaceErr
);
1760 // mDNS/DNS-SD Errors
1762 CaseErrorStringifyHardCode( -65537, mStatus_UnknownErr
);
1763 CaseErrorStringifyHardCode( -65538, mStatus_NoSuchNameErr
);
1764 CaseErrorStringifyHardCode( -65539, mStatus_NoMemoryErr
);
1765 CaseErrorStringifyHardCode( -65540, mStatus_BadParamErr
);
1766 CaseErrorStringifyHardCode( -65541, mStatus_BadReferenceErr
);
1767 CaseErrorStringifyHardCode( -65542, mStatus_BadStateErr
);
1768 CaseErrorStringifyHardCode( -65543, mStatus_BadFlagsErr
);
1769 CaseErrorStringifyHardCode( -65544, mStatus_UnsupportedErr
);
1770 CaseErrorStringifyHardCode( -65545, mStatus_NotInitializedErr
);
1771 CaseErrorStringifyHardCode( -65546, mStatus_NoCache
);
1772 CaseErrorStringifyHardCode( -65547, mStatus_AlreadyRegistered
);
1773 CaseErrorStringifyHardCode( -65548, mStatus_NameConflict
);
1774 CaseErrorStringifyHardCode( -65549, mStatus_Invalid
);
1775 CaseErrorStringifyHardCode( -65550, mStatus_GrowCache
);
1776 CaseErrorStringifyHardCode( -65551, mStatus_BadInterfaceErr
);
1777 CaseErrorStringifyHardCode( -65552, mStatus_Incompatible
);
1778 CaseErrorStringifyHardCode( -65791, mStatus_ConfigChanged
);
1779 CaseErrorStringifyHardCode( -65792, mStatus_MemFree
);
1783 CaseErrorStringifyHardCode( -400000, kRSPUnknownErr
);
1784 CaseErrorStringifyHardCode( -400050, kRSPParamErr
);
1785 CaseErrorStringifyHardCode( -400108, kRSPNoMemoryErr
);
1786 CaseErrorStringifyHardCode( -405246, kRSPRangeErr
);
1787 CaseErrorStringifyHardCode( -409057, kRSPSizeErr
);
1788 CaseErrorStringifyHardCode( -400200, kRSPHardwareErr
);
1789 CaseErrorStringifyHardCode( -401712, kRSPTimeoutErr
);
1790 CaseErrorStringifyHardCode( -402053, kRSPUnsupportedErr
);
1791 CaseErrorStringifyHardCode( -402419, kRSPIDErr
);
1792 CaseErrorStringifyHardCode( -403165, kRSPFlagErr
);
1793 CaseErrorString( -200000, "kRSPControllerStatusBase - 0x50" );
1794 CaseErrorString( -200080, "kRSPCommandSucceededErr - 0x50" );
1795 CaseErrorString( -200001, "kRSPCommandFailedErr - 0x01" );
1796 CaseErrorString( -200051, "kRSPChecksumErr - 0x33" );
1797 CaseErrorString( -200132, "kRSPCommandTimeoutErr - 0x84" );
1798 CaseErrorString( -200034, "kRSPPasswordRequiredErr - 0x22 OBSOLETE" );
1799 CaseErrorString( -200128, "kRSPCanceledErr - 0x02 Async" );
1803 CaseErrorStringifyHardCode( -100043, kXMLNotFoundErr
);
1804 CaseErrorStringifyHardCode( -100050, kXMLParamErr
);
1805 CaseErrorStringifyHardCode( -100108, kXMLNoMemoryErr
);
1806 CaseErrorStringifyHardCode( -100206, kXMLFormatErr
);
1807 CaseErrorStringifyHardCode( -100586, kXMLNoRootElementErr
);
1808 CaseErrorStringifyHardCode( -101703, kXMLWrongDataTypeErr
);
1809 CaseErrorStringifyHardCode( -101726, kXMLKeyErr
);
1810 CaseErrorStringifyHardCode( -102053, kXMLUnsupportedErr
);
1811 CaseErrorStringifyHardCode( -102063, kXMLMissingElementErr
);
1812 CaseErrorStringifyHardCode( -103026, kXMLParseErr
);
1813 CaseErrorStringifyHardCode( -103159, kXMLBadDataErr
);
1814 CaseErrorStringifyHardCode( -103170, kXMLBadNameErr
);
1815 CaseErrorStringifyHardCode( -105246, kXMLRangeErr
);
1816 CaseErrorStringifyHardCode( -105251, kXMLUnknownElementErr
);
1817 CaseErrorStringifyHardCode( -108739, kXMLMalformedInputErr
);
1818 CaseErrorStringifyHardCode( -109057, kXMLBadSizeErr
);
1819 CaseErrorStringifyHardCode( -101730, kXMLMissingChildElementErr
);
1820 CaseErrorStringifyHardCode( -102107, kXMLMissingParentElementErr
);
1821 CaseErrorStringifyHardCode( -130587, kXMLNonRootElementErr
);
1822 CaseErrorStringifyHardCode( -102015, kXMLDateErr
);
1828 CaseErrorStringifyHardCode( 0x00002000, MACH_MSG_IPC_SPACE
);
1829 CaseErrorStringifyHardCode( 0x00001000, MACH_MSG_VM_SPACE
);
1830 CaseErrorStringifyHardCode( 0x00000800, MACH_MSG_IPC_KERNEL
);
1831 CaseErrorStringifyHardCode( 0x00000400, MACH_MSG_VM_KERNEL
);
1832 CaseErrorStringifyHardCode( 0x10000001, MACH_SEND_IN_PROGRESS
);
1833 CaseErrorStringifyHardCode( 0x10000002, MACH_SEND_INVALID_DATA
);
1834 CaseErrorStringifyHardCode( 0x10000003, MACH_SEND_INVALID_DEST
);
1835 CaseErrorStringifyHardCode( 0x10000004, MACH_SEND_TIMED_OUT
);
1836 CaseErrorStringifyHardCode( 0x10000007, MACH_SEND_INTERRUPTED
);
1837 CaseErrorStringifyHardCode( 0x10000008, MACH_SEND_MSG_TOO_SMALL
);
1838 CaseErrorStringifyHardCode( 0x10000009, MACH_SEND_INVALID_REPLY
);
1839 CaseErrorStringifyHardCode( 0x1000000A, MACH_SEND_INVALID_RIGHT
);
1840 CaseErrorStringifyHardCode( 0x1000000B, MACH_SEND_INVALID_NOTIFY
);
1841 CaseErrorStringifyHardCode( 0x1000000C, MACH_SEND_INVALID_MEMORY
);
1842 CaseErrorStringifyHardCode( 0x1000000D, MACH_SEND_NO_BUFFER
);
1843 CaseErrorStringifyHardCode( 0x1000000E, MACH_SEND_TOO_LARGE
);
1844 CaseErrorStringifyHardCode( 0x1000000F, MACH_SEND_INVALID_TYPE
);
1845 CaseErrorStringifyHardCode( 0x10000010, MACH_SEND_INVALID_HEADER
);
1846 CaseErrorStringifyHardCode( 0x10000011, MACH_SEND_INVALID_TRAILER
);
1847 CaseErrorStringifyHardCode( 0x10000015, MACH_SEND_INVALID_RT_OOL_SIZE
);
1848 CaseErrorStringifyHardCode( 0x10004001, MACH_RCV_IN_PROGRESS
);
1849 CaseErrorStringifyHardCode( 0x10004002, MACH_RCV_INVALID_NAME
);
1850 CaseErrorStringifyHardCode( 0x10004003, MACH_RCV_TIMED_OUT
);
1851 CaseErrorStringifyHardCode( 0x10004004, MACH_RCV_TOO_LARGE
);
1852 CaseErrorStringifyHardCode( 0x10004005, MACH_RCV_INTERRUPTED
);
1853 CaseErrorStringifyHardCode( 0x10004006, MACH_RCV_PORT_CHANGED
);
1854 CaseErrorStringifyHardCode( 0x10004007, MACH_RCV_INVALID_NOTIFY
);
1855 CaseErrorStringifyHardCode( 0x10004008, MACH_RCV_INVALID_DATA
);
1856 CaseErrorStringifyHardCode( 0x10004009, MACH_RCV_PORT_DIED
);
1857 CaseErrorStringifyHardCode( 0x1000400A, MACH_RCV_IN_SET
);
1858 CaseErrorStringifyHardCode( 0x1000400B, MACH_RCV_HEADER_ERROR
);
1859 CaseErrorStringifyHardCode( 0x1000400C, MACH_RCV_BODY_ERROR
);
1860 CaseErrorStringifyHardCode( 0x1000400D, MACH_RCV_INVALID_TYPE
);
1861 CaseErrorStringifyHardCode( 0x1000400E, MACH_RCV_SCATTER_SMALL
);
1862 CaseErrorStringifyHardCode( 0x1000400F, MACH_RCV_INVALID_TRAILER
);
1863 CaseErrorStringifyHardCode( 0x10004011, MACH_RCV_IN_PROGRESS_TIMED
);
1865 // Mach OSReturn Errors
1867 CaseErrorStringifyHardCode( 0xDC000001, kOSReturnError
);
1868 CaseErrorStringifyHardCode( 0xDC004001, kOSMetaClassInternal
);
1869 CaseErrorStringifyHardCode( 0xDC004002, kOSMetaClassHasInstances
);
1870 CaseErrorStringifyHardCode( 0xDC004003, kOSMetaClassNoInit
);
1871 CaseErrorStringifyHardCode( 0xDC004004, kOSMetaClassNoTempData
);
1872 CaseErrorStringifyHardCode( 0xDC004005, kOSMetaClassNoDicts
);
1873 CaseErrorStringifyHardCode( 0xDC004006, kOSMetaClassNoKModSet
);
1874 CaseErrorStringifyHardCode( 0xDC004007, kOSMetaClassNoInsKModSet
);
1875 CaseErrorStringifyHardCode( 0xDC004008, kOSMetaClassNoSuper
);
1876 CaseErrorStringifyHardCode( 0xDC004009, kOSMetaClassInstNoSuper
);
1877 CaseErrorStringifyHardCode( 0xDC00400A, kOSMetaClassDuplicateClass
);
1881 CaseErrorStringifyHardCode( 0xE00002BC, kIOReturnError
);
1882 CaseErrorStringifyHardCode( 0xE00002BD, kIOReturnNoMemory
);
1883 CaseErrorStringifyHardCode( 0xE00002BE, kIOReturnNoResources
);
1884 CaseErrorStringifyHardCode( 0xE00002BF, kIOReturnIPCError
);
1885 CaseErrorStringifyHardCode( 0xE00002C0, kIOReturnNoDevice
);
1886 CaseErrorStringifyHardCode( 0xE00002C1, kIOReturnNotPrivileged
);
1887 CaseErrorStringifyHardCode( 0xE00002C2, kIOReturnBadArgument
);
1888 CaseErrorStringifyHardCode( 0xE00002C3, kIOReturnLockedRead
);
1889 CaseErrorStringifyHardCode( 0xE00002C4, kIOReturnLockedWrite
);
1890 CaseErrorStringifyHardCode( 0xE00002C5, kIOReturnExclusiveAccess
);
1891 CaseErrorStringifyHardCode( 0xE00002C6, kIOReturnBadMessageID
);
1892 CaseErrorStringifyHardCode( 0xE00002C7, kIOReturnUnsupported
);
1893 CaseErrorStringifyHardCode( 0xE00002C8, kIOReturnVMError
);
1894 CaseErrorStringifyHardCode( 0xE00002C9, kIOReturnInternalError
);
1895 CaseErrorStringifyHardCode( 0xE00002CA, kIOReturnIOError
);
1896 CaseErrorStringifyHardCode( 0xE00002CC, kIOReturnCannotLock
);
1897 CaseErrorStringifyHardCode( 0xE00002CD, kIOReturnNotOpen
);
1898 CaseErrorStringifyHardCode( 0xE00002CE, kIOReturnNotReadable
);
1899 CaseErrorStringifyHardCode( 0xE00002CF, kIOReturnNotWritable
);
1900 CaseErrorStringifyHardCode( 0xE00002D0, kIOReturnNotAligned
);
1901 CaseErrorStringifyHardCode( 0xE00002D1, kIOReturnBadMedia
);
1902 CaseErrorStringifyHardCode( 0xE00002D2, kIOReturnStillOpen
);
1903 CaseErrorStringifyHardCode( 0xE00002D3, kIOReturnRLDError
);
1904 CaseErrorStringifyHardCode( 0xE00002D4, kIOReturnDMAError
);
1905 CaseErrorStringifyHardCode( 0xE00002D5, kIOReturnBusy
);
1906 CaseErrorStringifyHardCode( 0xE00002D6, kIOReturnTimeout
);
1907 CaseErrorStringifyHardCode( 0xE00002D7, kIOReturnOffline
);
1908 CaseErrorStringifyHardCode( 0xE00002D8, kIOReturnNotReady
);
1909 CaseErrorStringifyHardCode( 0xE00002D9, kIOReturnNotAttached
);
1910 CaseErrorStringifyHardCode( 0xE00002DA, kIOReturnNoChannels
);
1911 CaseErrorStringifyHardCode( 0xE00002DB, kIOReturnNoSpace
);
1912 CaseErrorStringifyHardCode( 0xE00002DD, kIOReturnPortExists
);
1913 CaseErrorStringifyHardCode( 0xE00002DE, kIOReturnCannotWire
);
1914 CaseErrorStringifyHardCode( 0xE00002DF, kIOReturnNoInterrupt
);
1915 CaseErrorStringifyHardCode( 0xE00002E0, kIOReturnNoFrames
);
1916 CaseErrorStringifyHardCode( 0xE00002E1, kIOReturnMessageTooLarge
);
1917 CaseErrorStringifyHardCode( 0xE00002E2, kIOReturnNotPermitted
);
1918 CaseErrorStringifyHardCode( 0xE00002E3, kIOReturnNoPower
);
1919 CaseErrorStringifyHardCode( 0xE00002E4, kIOReturnNoMedia
);
1920 CaseErrorStringifyHardCode( 0xE00002E5, kIOReturnUnformattedMedia
);
1921 CaseErrorStringifyHardCode( 0xE00002E6, kIOReturnUnsupportedMode
);
1922 CaseErrorStringifyHardCode( 0xE00002E7, kIOReturnUnderrun
);
1923 CaseErrorStringifyHardCode( 0xE00002E8, kIOReturnOverrun
);
1924 CaseErrorStringifyHardCode( 0xE00002E9, kIOReturnDeviceError
);
1925 CaseErrorStringifyHardCode( 0xE00002EA, kIOReturnNoCompletion
);
1926 CaseErrorStringifyHardCode( 0xE00002EB, kIOReturnAborted
);
1927 CaseErrorStringifyHardCode( 0xE00002EC, kIOReturnNoBandwidth
);
1928 CaseErrorStringifyHardCode( 0xE00002ED, kIOReturnNotResponding
);
1929 CaseErrorStringifyHardCode( 0xE00002EE, kIOReturnIsoTooOld
);
1930 CaseErrorStringifyHardCode( 0xE00002EF, kIOReturnIsoTooNew
);
1931 CaseErrorStringifyHardCode( 0xE00002F0, kIOReturnNotFound
);
1932 CaseErrorStringifyHardCode( 0xE0000001, kIOReturnInvalid
);
1934 // IOKit FireWire Errors
1936 CaseErrorStringifyHardCode( 0xE0008010, kIOFireWireResponseBase
);
1937 CaseErrorStringifyHardCode( 0xE0008020, kIOFireWireBusReset
);
1938 CaseErrorStringifyHardCode( 0xE0008001, kIOConfigNoEntry
);
1939 CaseErrorStringifyHardCode( 0xE0008002, kIOFireWirePending
);
1940 CaseErrorStringifyHardCode( 0xE0008003, kIOFireWireLastDCLToken
);
1941 CaseErrorStringifyHardCode( 0xE0008004, kIOFireWireConfigROMInvalid
);
1942 CaseErrorStringifyHardCode( 0xE0008005, kIOFireWireAlreadyRegistered
);
1943 CaseErrorStringifyHardCode( 0xE0008006, kIOFireWireMultipleTalkers
);
1944 CaseErrorStringifyHardCode( 0xE0008007, kIOFireWireChannelActive
);
1945 CaseErrorStringifyHardCode( 0xE0008008, kIOFireWireNoListenerOrTalker
);
1946 CaseErrorStringifyHardCode( 0xE0008009, kIOFireWireNoChannels
);
1947 CaseErrorStringifyHardCode( 0xE000800A, kIOFireWireChannelNotAvailable
);
1948 CaseErrorStringifyHardCode( 0xE000800B, kIOFireWireSeparateBus
);
1949 CaseErrorStringifyHardCode( 0xE000800C, kIOFireWireBadSelfIDs
);
1950 CaseErrorStringifyHardCode( 0xE000800D, kIOFireWireLowCableVoltage
);
1951 CaseErrorStringifyHardCode( 0xE000800E, kIOFireWireInsufficientPower
);
1952 CaseErrorStringifyHardCode( 0xE000800F, kIOFireWireOutOfTLabels
);
1953 CaseErrorStringifyHardCode( 0xE0008101, kIOFireWireBogusDCLProgram
);
1954 CaseErrorStringifyHardCode( 0xE0008102, kIOFireWireTalkingAndListening
);
1955 CaseErrorStringifyHardCode( 0xE0008103, kIOFireWireHardwareSlept
);
1956 CaseErrorStringifyHardCode( 0xE00087D0, kIOFWMessageServiceIsRequestingClose
);
1957 CaseErrorStringifyHardCode( 0xE00087D1, kIOFWMessagePowerStateChanged
);
1958 CaseErrorStringifyHardCode( 0xE00087D2, kIOFWMessageTopologyChanged
);
1962 CaseErrorStringifyHardCode( 0xE0004061, kIOUSBUnknownPipeErr
);
1963 CaseErrorStringifyHardCode( 0xE0004060, kIOUSBTooManyPipesErr
);
1964 CaseErrorStringifyHardCode( 0xE000405F, kIOUSBNoAsyncPortErr
);
1965 CaseErrorStringifyHardCode( 0xE000405E, kIOUSBNotEnoughPipesErr
);
1966 CaseErrorStringifyHardCode( 0xE000405D, kIOUSBNotEnoughPowerErr
);
1967 CaseErrorStringifyHardCode( 0xE0004057, kIOUSBEndpointNotFound
);
1968 CaseErrorStringifyHardCode( 0xE0004056, kIOUSBConfigNotFound
);
1969 CaseErrorStringifyHardCode( 0xE0004051, kIOUSBTransactionTimeout
);
1970 CaseErrorStringifyHardCode( 0xE0004050, kIOUSBTransactionReturned
);
1971 CaseErrorStringifyHardCode( 0xE000404F, kIOUSBPipeStalled
);
1972 CaseErrorStringifyHardCode( 0xE000404E, kIOUSBInterfaceNotFound
);
1973 CaseErrorStringifyHardCode( 0xE000404D, kIOUSBLowLatencyBufferNotPreviouslyAllocated
);
1974 CaseErrorStringifyHardCode( 0xE000404C, kIOUSBLowLatencyFrameListNotPreviouslyAllocated
);
1975 CaseErrorStringifyHardCode( 0xE000404B, kIOUSBHighSpeedSplitError
);
1976 CaseErrorStringifyHardCode( 0xE0004010, kIOUSBLinkErr
);
1977 CaseErrorStringifyHardCode( 0xE000400F, kIOUSBNotSent2Err
);
1978 CaseErrorStringifyHardCode( 0xE000400E, kIOUSBNotSent1Err
);
1979 CaseErrorStringifyHardCode( 0xE000400D, kIOUSBBufferUnderrunErr
);
1980 CaseErrorStringifyHardCode( 0xE000400C, kIOUSBBufferOverrunErr
);
1981 CaseErrorStringifyHardCode( 0xE000400B, kIOUSBReserved2Err
);
1982 CaseErrorStringifyHardCode( 0xE000400A, kIOUSBReserved1Err
);
1983 CaseErrorStringifyHardCode( 0xE0004007, kIOUSBWrongPIDErr
);
1984 CaseErrorStringifyHardCode( 0xE0004006, kIOUSBPIDCheckErr
);
1985 CaseErrorStringifyHardCode( 0xE0004003, kIOUSBDataToggleErr
);
1986 CaseErrorStringifyHardCode( 0xE0004002, kIOUSBBitstufErr
);
1987 CaseErrorStringifyHardCode( 0xE0004001, kIOUSBCRCErr
);
1995 #if( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
1996 if( inBuffer
&& ( inBufferSize
> 0 ) )
2000 n
= FormatMessageA( FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_IGNORE_INSERTS
, NULL
, (DWORD
) inErrorCode
,
2001 MAKELANGID( LANG_NEUTRAL
, SUBLANG_DEFAULT
), buffer
, sizeof( buffer
), NULL
);
2004 // Remove any trailing CR's or LF's since some messages have them.
2006 while( ( n
> 0 ) && isspace( ( (unsigned char *) buffer
)[ n
- 1 ] ) )
2008 buffer
[ --n
] = '\0';
2017 #if( !TARGET_API_MAC_OSX_KERNEL && !TARGET_OS_WINDOWS_CE )
2018 s
= strerror( inErrorCode
);
2022 s
= "<unknown error code>";
2028 // Copy the string to the output buffer. If no buffer is supplied or it is empty, return an empty string.
2030 if( inBuffer
&& ( inBufferSize
> 0 ) )
2033 end
= dst
+ ( inBufferSize
- 1 );
2034 while( ( ( end
- dst
) > 0 ) && ( *s
!= '\0' ) )
2044 //===========================================================================================================================
2046 //===========================================================================================================================
2052 const char * inLabel
,
2054 int inLabelMinWidth
,
2055 const char * inType
,
2057 const void * inDataStart
,
2058 const void * inData
,
2062 size_t inBufferSize
)
2064 static const char kHexChars
[] = "0123456789ABCDEF";
2065 const uint8_t * start
;
2066 const uint8_t * src
;
2072 const char * newline
;
2073 char separator
[ 8 ];
2076 DEBUG_UNUSED( inType
);
2077 DEBUG_UNUSED( inTypeSize
);
2079 // Set up the function-wide variables.
2081 if( inLabelSize
== kSizeCString
)
2083 inLabelSize
= strlen( inLabel
);
2085 start
= (const uint8_t *) inData
;
2088 end
= dst
+ inBufferSize
;
2089 offset
= (int)( (intptr_t) inData
- (intptr_t) inDataStart
);
2090 width
= ( (int) inLabelSize
> inLabelMinWidth
) ? (int) inLabelSize
: inLabelMinWidth
;
2091 newline
= ( inFlags
& kDebugFlagsNoNewLine
) ? "" : "\n";
2093 // Set up the separator string. This is used to insert spaces on subsequent "lines" when not using newlines.
2096 if( inFlags
& kDebugFlagsNoNewLine
)
2098 if( inFlags
& kDebugFlags8BitSeparator
)
2102 if( inFlags
& kDebugFlags16BitSeparator
)
2106 if( !( inFlags
& kDebugFlagsNo32BitSeparator
) )
2110 check( ( (size_t)( s
- separator
) ) < sizeof( separator
) );
2116 char prefixString
[ 32 ];
2117 char hexString
[ 64 ];
2118 char asciiString
[ 32 ];
2119 char byteCountString
[ 32 ];
2124 // If this is a label-only item (i.e. no data), print the label (accounting for prefix string spacing) and exit.
2126 if( inDataSize
== 0 )
2128 if( inLabel
&& ( inLabelSize
> 0 ) )
2131 if( !( inFlags
& kDebugFlagsNoAddress
) )
2133 width
+= 8; // "00000000"
2134 if( !( inFlags
& kDebugFlagsNoOffset
) )
2139 if( inFlags
& kDebugFlags32BitOffset
)
2141 width
+= 8; // "00000000"
2143 else if( !( inFlags
& kDebugFlagsNoOffset
) )
2145 width
+= 4; // "0000"
2150 dst
+= DebugSNPrintF( dst
, (size_t)( end
- dst
), "%*s" "%-*.*s" "%.*s" "%s",
2152 ( width
> 0 ) ? ": " : "",
2153 width
, (int) inLabelSize
, inLabel
,
2158 dst
+= DebugPrintF( inLevel
, "%*s" "%-*.*s" "%.*s" "%s",
2160 ( width
> 0 ) ? ": " : "",
2161 width
, (int) inLabelSize
, inLabel
,
2168 // Build the prefix string. It will be in one of the following formats:
2170 // 1) "00000000+0000[0000]" (address and offset)
2171 // 2) "00000000" (address only)
2172 // 3) "0000[0000]" (offset only)
2173 // 4) "" (no address or offset)
2175 // Note: If we're printing multiple "lines", but not printing newlines, a space is used to separate.
2178 if( !( inFlags
& kDebugFlagsNoAddress
) )
2180 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 28 ) & 0xF ];
2181 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 24 ) & 0xF ];
2182 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 20 ) & 0xF ];
2183 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 16 ) & 0xF ];
2184 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 12 ) & 0xF ];
2185 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 8 ) & 0xF ];
2186 *s
++ = kHexChars
[ ( ( (uintptr_t) src
) >> 4 ) & 0xF ];
2187 *s
++ = kHexChars
[ ( (uintptr_t) src
) & 0xF ];
2189 if( !( inFlags
& kDebugFlagsNoOffset
) )
2194 if( !( inFlags
& kDebugFlagsNoOffset
) )
2196 if( inFlags
& kDebugFlags32BitOffset
)
2198 *s
++ = kHexChars
[ ( offset
>> 28 ) & 0xF ];
2199 *s
++ = kHexChars
[ ( offset
>> 24 ) & 0xF ];
2200 *s
++ = kHexChars
[ ( offset
>> 20 ) & 0xF ];
2201 *s
++ = kHexChars
[ ( offset
>> 16 ) & 0xF ];
2203 *s
++ = kHexChars
[ ( offset
>> 12 ) & 0xF ];
2204 *s
++ = kHexChars
[ ( offset
>> 8 ) & 0xF ];
2205 *s
++ = kHexChars
[ ( offset
>> 4 ) & 0xF ];
2206 *s
++ = kHexChars
[ offset
& 0xF ];
2208 if( s
!= prefixString
)
2213 check( ( (size_t)( s
- prefixString
) ) < sizeof( prefixString
) );
2216 // Build a hex string with a optional spaces after every 1, 2, and/or 4 bytes to make it easier to read.
2217 // Optionally pads the hex string with space to fill the full 16 byte range (so it lines up).
2220 chunkSize
= ( inDataSize
< 16 ) ? inDataSize
: 16;
2221 n
= ( inFlags
& kDebugFlagsNo16ByteHexPad
) ? chunkSize
: 16;
2222 for( i
= 0; i
< n
; ++i
)
2224 if( ( inFlags
& kDebugFlags8BitSeparator
) && ( i
> 0 ) )
2228 if( ( inFlags
& kDebugFlags16BitSeparator
) && ( i
> 0 ) && ( ( i
% 2 ) == 0 ) )
2232 if( !( inFlags
& kDebugFlagsNo32BitSeparator
) && ( i
> 0 ) && ( ( i
% 4 ) == 0 ) )
2238 *s
++ = kHexChars
[ src
[ i
] >> 4 ];
2239 *s
++ = kHexChars
[ src
[ i
] & 0xF ];
2247 check( ( (size_t)( s
- hexString
) ) < sizeof( hexString
) );
2250 // Build a string with the ASCII version of the data (replaces non-printable characters with '^').
2251 // Optionally pads the string with '`' to fill the full 16 byte range (so it lines up).
2254 if( !( inFlags
& kDebugFlagsNoASCII
) )
2258 for( i
= 0; i
< n
; ++i
)
2263 if( !DebugIsPrint( c
) )
2275 check( ( (size_t)( s
- asciiString
) ) < sizeof( asciiString
) );
2279 // Build a string indicating how bytes are in the hex dump. Only printed on the first line.
2281 s
= byteCountString
;
2282 if( !( inFlags
& kDebugFlagsNoByteCount
) )
2286 s
+= DebugSNPrintF( s
, sizeof( byteCountString
), " (%d bytes)", (int) inDataSize
);
2289 check( ( (size_t)( s
- byteCountString
) ) < sizeof( byteCountString
) );
2292 // Build the entire line from all the pieces we've previously built.
2298 dst
+= DebugSNPrintF( dst
, (size_t)( end
- dst
),
2300 "%s" // Separator (only if needed)
2309 ( src
!= start
) ? separator
: "",
2311 width
, (int) inLabelSize
, inLabel
? inLabel
: "",
2312 ( width
> 0 ) ? " " : "",
2320 dst
+= DebugSNPrintF( dst
, (size_t)( end
- dst
),
2322 "%s" // Separator (only if needed)
2324 "%*s" // Label Spacing
2331 ( src
!= start
) ? separator
: "",
2334 ( width
> 0 ) ? " " : "",
2345 dst
+= DebugPrintF( inLevel
,
2347 "%s" // Separator (only if needed)
2356 ( src
!= start
) ? separator
: "",
2358 width
, (int) inLabelSize
, inLabel
,
2359 ( width
> 0 ) ? " " : "",
2367 dst
+= DebugPrintF( inLevel
,
2369 "%s" // Separator (only if needed)
2371 "%*s" // Label Spacing
2378 ( src
!= start
) ? separator
: "",
2381 ( width
> 0 ) ? " " : "",
2389 // Move to the next chunk. Exit if there is no more data.
2391 offset
+= (int) chunkSize
;
2393 inDataSize
-= chunkSize
;
2394 if( inDataSize
== 0 )
2400 // Note: The "dst - outBuffer" size calculation works even if "outBuffer" is NULL because it's all relative.
2402 return( (size_t)( dst
- outBuffer
) );
2405 //===========================================================================================================================
2406 // DebugNumVersionToString
2407 //===========================================================================================================================
2409 static char * DebugNumVersionToString( uint32_t inVersion
, char *inString
)
2420 majorRev
= (uint8_t)( ( inVersion
>> 24 ) & 0xFF );
2421 minor
= (uint8_t)( ( inVersion
>> 20 ) & 0x0F );
2422 bugFix
= (uint8_t)( ( inVersion
>> 16 ) & 0x0F );
2423 stage
= (uint8_t)( ( inVersion
>> 8 ) & 0xFF );
2424 revision
= (uint8_t)( inVersion
& 0xFF );
2426 // Convert the major, minor, and bugfix numbers.
2429 s
+= sprintf( s
, "%u", majorRev
);
2430 s
+= sprintf( s
, ".%u", minor
);
2433 s
+= sprintf( s
, ".%u", bugFix
);
2436 // Convert the version stage and non-release revision number.
2440 case kVersionStageDevelopment
:
2441 s
+= sprintf( s
, "d%u", revision
);
2444 case kVersionStageAlpha
:
2445 s
+= sprintf( s
, "a%u", revision
);
2448 case kVersionStageBeta
:
2449 s
+= sprintf( s
, "b%u", revision
);
2452 case kVersionStageFinal
:
2454 // A non-release revision of zero is a special case indicating the software is GM (at the golden master
2455 // stage) and therefore, the non-release revision should not be added to the string.
2459 s
+= sprintf( s
, "f%u", revision
);
2464 dlog( kDebugLevelError
, "invalid NumVersion stage (0x%02X)\n", stage
);
2470 //===========================================================================================================================
2472 //===========================================================================================================================
2474 DEBUG_EXPORT
uint32_t DebugTaskLevel( void )
2480 #if( TARGET_OS_VXWORKS )
2483 level
|= ( ( 1 << kDebugInterruptLevelShift
) & kDebugInterruptLevelMask
);
2490 #if( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
2491 //===========================================================================================================================
2492 // DebugWinEnableConsole
2493 //===========================================================================================================================
2495 #pragma warning( disable:4311 )
2497 static void DebugWinEnableConsole( void )
2499 static bool sConsoleEnabled
= false;
2505 if( sConsoleEnabled
)
2510 // Create console window.
2512 result
= AllocConsole();
2513 require_quiet( result
, exit
);
2515 // Redirect stdin to the console stdin.
2517 fileHandle
= _open_osfhandle( (long) GetStdHandle( STD_INPUT_HANDLE
), _O_TEXT
);
2519 #if( defined( __MWERKS__ ) )
2520 file
= __handle_reopen( (unsigned long) fileHandle
, "r", stdin
);
2521 require_quiet( file
, exit
);
2523 file
= _fdopen( fileHandle
, "r" );
2524 require_quiet( file
, exit
);
2529 err
= setvbuf( stdin
, NULL
, _IONBF
, 0 );
2530 require_noerr_quiet( err
, exit
);
2532 // Redirect stdout to the console stdout.
2534 fileHandle
= _open_osfhandle( (long) GetStdHandle( STD_OUTPUT_HANDLE
), _O_TEXT
);
2536 #if( defined( __MWERKS__ ) )
2537 file
= __handle_reopen( (unsigned long) fileHandle
, "w", stdout
);
2538 require_quiet( file
, exit
);
2540 file
= _fdopen( fileHandle
, "w" );
2541 require_quiet( file
, exit
);
2546 err
= setvbuf( stdout
, NULL
, _IONBF
, 0 );
2547 require_noerr_quiet( err
, exit
);
2549 // Redirect stderr to the console stdout.
2551 fileHandle
= _open_osfhandle( (long) GetStdHandle( STD_OUTPUT_HANDLE
), _O_TEXT
);
2553 #if( defined( __MWERKS__ ) )
2554 file
= __handle_reopen( (unsigned long) fileHandle
, "w", stderr
);
2555 require_quiet( file
, exit
);
2557 file
= _fdopen( fileHandle
, "w" );
2558 require_quiet( file
, exit
);
2563 err
= setvbuf( stderr
, NULL
, _IONBF
, 0 );
2564 require_noerr_quiet( err
, exit
);
2566 sConsoleEnabled
= true;
2572 #pragma warning( default:4311 )
2574 #endif // TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE
2576 #if( TARGET_OS_WIN32 )
2577 //===========================================================================================================================
2578 // DebugWinCharToTCharString
2579 //===========================================================================================================================
2582 DebugWinCharToTCharString(
2583 const char * inCharString
,
2585 TCHAR
* outTCharString
,
2586 size_t inTCharCountMax
,
2587 size_t * outTCharCount
)
2593 if( inCharCount
== kSizeCString
)
2595 inCharCount
= strlen( inCharString
);
2598 dst
= outTCharString
;
2599 if( inTCharCountMax
> 0 )
2601 inTCharCountMax
-= 1;
2602 if( inTCharCountMax
> inCharCount
)
2604 inTCharCountMax
= inCharCount
;
2607 end
= dst
+ inTCharCountMax
;
2610 *dst
++ = (TCHAR
) *src
++;
2616 *outTCharCount
= (size_t)( dst
- outTCharString
);
2618 return( outTCharString
);
2624 #pragma mark == Debugging ==
2627 //===========================================================================================================================
2628 // DebugServicesTest
2629 //===========================================================================================================================
2631 DEBUG_EXPORT OSStatus
DebugServicesTest( void )
2638 0x11, 0x22, 0x33, 0x44,
2640 0x77, 0x88, 0x99, 0xAA,
2644 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
2645 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0,
2646 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71, 0x81, 0x91, 0xA1
2649 debug_initialize( kDebugOutputTypeMetaConsole
);
2653 check( 0 && "SHOULD SEE: check" );
2654 check( 1 && "SHOULD *NOT* SEE: check (valid)" );
2655 check_string( 0, "SHOULD SEE: check_string" );
2656 check_string( 1, "SHOULD *NOT* SEE: check_string (valid)" );
2657 check_noerr( -123 );
2658 check_noerr( 10038 );
2661 check_noerr_string( -6712, "SHOULD SEE: check_noerr_string" );
2662 check_noerr_string( 0, "SHOULD *NOT* SEE: check_noerr_string (valid)" );
2663 check_translated_errno( 0 >= 0 && "SHOULD *NOT* SEE", -384, -999 );
2664 check_translated_errno( -1 >= 0 && "SHOULD SEE", -384, -999 );
2665 check_translated_errno( -1 >= 0 && "SHOULD SEE", 0, -999 );
2666 check_ptr_overlap( "SHOULD *NOT* SEE" ? 10 : 0, 10, 22, 10 );
2667 check_ptr_overlap( "SHOULD SEE" ? 10 : 0, 10, 5, 10 );
2668 check_ptr_overlap( "SHOULD SEE" ? 10 : 0, 10, 12, 6 );
2669 check_ptr_overlap( "SHOULD SEE" ? 12 : 0, 6, 10, 10 );
2670 check_ptr_overlap( "SHOULD SEE" ? 12 : 0, 10, 10, 10 );
2671 check_ptr_overlap( "SHOULD *NOT* SEE" ? 22 : 0, 10, 10, 10 );
2672 check_ptr_overlap( "SHOULD *NOT* SEE" ? 10 : 0, 10, 20, 10 );
2673 check_ptr_overlap( "SHOULD *NOT* SEE" ? 20 : 0, 10, 10, 10 );
2677 require( 0 && "SHOULD SEE", require1
);
2678 { err
= kResponseErr
; goto exit
; }
2680 require( 1 && "SHOULD *NOT* SEE", require2
);
2683 { err
= kResponseErr
; goto exit
; }
2685 require_string( 0 && "SHOULD SEE", require3
, "SHOULD SEE: require_string" );
2686 { err
= kResponseErr
; goto exit
; }
2688 require_string( 1 && "SHOULD *NOT* SEE", require4
, "SHOULD *NOT* SEE: require_string (valid)" );
2691 { err
= kResponseErr
; goto exit
; }
2693 require_quiet( 0 && "SHOULD SEE", require5
);
2694 { err
= kResponseErr
; goto exit
; }
2696 require_quiet( 1 && "SHOULD *NOT* SEE", require6
);
2699 { err
= kResponseErr
; goto exit
; }
2701 require_noerr( -1, require7
);
2702 { err
= kResponseErr
; goto exit
; }
2704 require_noerr( 0, require8
);
2707 { err
= kResponseErr
; goto exit
; }
2709 require_noerr_string( -2, require9
, "SHOULD SEE: require_noerr_string");
2710 { err
= kResponseErr
; goto exit
; }
2712 require_noerr_string( 0, require10
, "SHOULD *NOT* SEE: require_noerr_string (valid)" );
2715 { err
= kResponseErr
; goto exit
; }
2717 require_noerr_action_string( -3, require11
, dlog( kDebugLevelMax
, "action 1 (expected)\n" ), "require_noerr_action_string" );
2718 { err
= kResponseErr
; goto exit
; }
2720 require_noerr_action_string( 0, require12
, dlog( kDebugLevelMax
, "action 2\n" ), "require_noerr_action_string (valid)" );
2723 { err
= kResponseErr
; goto exit
; }
2725 require_noerr_quiet( -4, require13
);
2726 { err
= kResponseErr
; goto exit
; }
2728 require_noerr_quiet( 0, require14
);
2731 { err
= kResponseErr
; goto exit
; }
2733 require_noerr_action( -5, require15
, dlog( kDebugLevelMax
, "SHOULD SEE: action 3 (expected)\n" ) );
2734 { err
= kResponseErr
; goto exit
; }
2736 require_noerr_action( 0, require16
, dlog( kDebugLevelMax
, "SHOULD *NOT* SEE: action 4\n" ) );
2739 { err
= kResponseErr
; goto exit
; }
2741 require_noerr_action_quiet( -4, require17
, dlog( kDebugLevelMax
, "SHOULD SEE: action 5 (expected)\n" ) );
2742 { err
= kResponseErr
; goto exit
; }
2744 require_noerr_action_quiet( 0, require18
, dlog( kDebugLevelMax
, "SHOULD *NOT* SEE: action 6\n" ) );
2747 { err
= kResponseErr
; goto exit
; }
2749 require_action( 0 && "SHOULD SEE", require19
, dlog( kDebugLevelMax
, "SHOULD SEE: action 7 (expected)\n" ) );
2750 { err
= kResponseErr
; goto exit
; }
2752 require_action( 1 && "SHOULD *NOT* SEE", require20
, dlog( kDebugLevelMax
, "SHOULD *NOT* SEE: action 8\n" ) );
2755 { err
= kResponseErr
; goto exit
; }
2757 require_action_quiet( 0, require21
, dlog( kDebugLevelMax
, "SHOULD SEE: action 9 (expected)\n" ) );
2758 { err
= kResponseErr
; goto exit
; }
2760 require_action_quiet( 1, require22
, dlog( kDebugLevelMax
, "SHOULD *NOT* SEE: action 10\n" ) );
2763 { err
= kResponseErr
; goto exit
; }
2765 require_action_string( 0, require23
, dlog( kDebugLevelMax
, "SHOULD SEE: action 11 (expected)\n" ), "SHOULD SEE: require_action_string" );
2766 { err
= kResponseErr
; goto exit
; }
2768 require_action_string( 1, require24
, dlog( kDebugLevelMax
, "SHOULD *NOT* SEE: action 12\n" ), "SHOULD *NOT* SEE: require_action_string" );
2771 { err
= kResponseErr
; goto exit
; }
2774 #if( defined( __MWERKS__ ) )
2775 #if( defined( __cplusplus ) && __option( exceptions ) )
2776 #define COMPILER_HAS_EXCEPTIONS 1
2778 #define COMPILER_HAS_EXCEPTIONS 0
2781 #if( defined( __cplusplus ) )
2782 #define COMPILER_HAS_EXCEPTIONS 1
2784 #define COMPILER_HAS_EXCEPTIONS 0
2788 #if( COMPILER_HAS_EXCEPTIONS )
2791 require_throw( 1 && "SHOULD *NOT* SEE" );
2792 require_throw( 0 && "SHOULD SEE" );
2798 { err
= kResponseErr
; goto exit
; }
2804 err
= translate_errno( 1 != -1, -123, -567 );
2805 require( ( err
== 0 ) && "SHOULD *NOT* SEE", exit
);
2807 err
= translate_errno( -1 != -1, -123, -567 );
2808 require( ( err
== -123 ) && "SHOULD *NOT* SEE", exit
);
2810 err
= translate_errno( -1 != -1, 0, -567 );
2811 require( ( err
== -567 ) && "SHOULD *NOT* SEE", exit
);
2815 debug_string( "debug_string" );
2819 DebugSNPrintF( s
, sizeof( s
), "%d", 1234 );
2820 require_action( strcmp( s
, "1234" ) == 0, exit
, err
= -1 );
2822 DebugSNPrintF( s
, sizeof( s
), "%X", 0x2345 );
2823 require_action( strcmp( s
, "2345" ) == 0, exit
, err
= -1 );
2825 DebugSNPrintF( s
, sizeof( s
), "%#s", "\05test" );
2826 require_action( strcmp( s
, "test" ) == 0, exit
, err
= -1 );
2828 DebugSNPrintF( s
, sizeof( s
), "%##s", "\03www\05apple\03com" );
2829 require_action( strcmp( s
, "www.apple.com." ) == 0, exit
, err
= -1 );
2831 DebugSNPrintF( s
, sizeof( s
), "%ld", (long) INT32_C( 2147483647 ) );
2832 require_action( strcmp( s
, "2147483647" ) == 0, exit
, err
= -1 );
2834 DebugSNPrintF( s
, sizeof( s
), "%lu", (unsigned long) UINT32_C( 4294967295 ) );
2835 require_action( strcmp( s
, "4294967295" ) == 0, exit
, err
= -1 );
2837 #if( TYPE_LONGLONG_NATIVE )
2838 DebugSNPrintF( s
, sizeof( s
), "%lld", (long_long_compat
) INT64_C( 9223372036854775807 ) );
2839 require_action( strcmp( s
, "9223372036854775807" ) == 0, exit
, err
= -1 );
2841 DebugSNPrintF( s
, sizeof( s
), "%lld", (long_long_compat
) INT64_C( -9223372036854775807 ) );
2842 require_action( strcmp( s
, "-9223372036854775807" ) == 0, exit
, err
= -1 );
2844 DebugSNPrintF( s
, sizeof( s
), "%llu", (unsigned_long_long_compat
) UINT64_C( 18446744073709551615 ) );
2845 require_action( strcmp( s
, "18446744073709551615" ) == 0, exit
, err
= -1 );
2848 DebugSNPrintF( s
, sizeof( s
), "%lb", (unsigned long) binary_32( 01111011, 01111011, 01111011, 01111011 ) );
2849 require_action( strcmp( s
, "1111011011110110111101101111011" ) == 0, exit
, err
= -1 );
2851 DebugSNPrintF( s
, sizeof( s
), "%C", 0x41624364 ); // 'AbCd'
2852 require_action( strcmp( s
, "AbCd" ) == 0, exit
, err
= -1 );
2854 #if( defined( MDNS_DEBUGMSGS ) )
2858 memset( &maddr
, 0, sizeof( maddr
) );
2859 maddr
.type
= mDNSAddrType_IPv4
;
2860 maddr
.ip
.v4
.b
[ 0 ] = 127;
2861 maddr
.ip
.v4
.b
[ 1 ] = 0;
2862 maddr
.ip
.v4
.b
[ 2 ] = 0;
2863 maddr
.ip
.v4
.b
[ 3 ] = 1;
2864 DebugSNPrintF( s
, sizeof( s
), "%#a", &maddr
);
2865 require_action( strcmp( s
, "127.0.0.1" ) == 0, exit
, err
= -1 );
2867 memset( &maddr
, 0, sizeof( maddr
) );
2868 maddr
.type
= mDNSAddrType_IPv6
;
2869 maddr
.ip
.v6
.b
[ 0 ] = 0xFE;
2870 maddr
.ip
.v6
.b
[ 1 ] = 0x80;
2871 maddr
.ip
.v6
.b
[ 15 ] = 0x01;
2872 DebugSNPrintF( s
, sizeof( s
), "%#a", &maddr
);
2873 require_action( strcmp( s
, "FE80:0000:0000:0000:0000:0000:0000:0001" ) == 0, exit
, err
= -1 );
2879 struct sockaddr_in sa4
;
2881 memset( &sa4
, 0, sizeof( sa4
) );
2882 sa4
.sin_family
= AF_INET
;
2883 p
= (uint8_t *) &sa4
.sin_port
;
2884 p
[ 0 ] = (uint8_t)( ( 80 >> 8 ) & 0xFF );
2885 p
[ 1 ] = (uint8_t)( 80 & 0xFF );
2886 p
= (uint8_t *) &sa4
.sin_addr
.s_addr
;
2887 p
[ 0 ] = (uint8_t)( ( INADDR_LOOPBACK
>> 24 ) & 0xFF );
2888 p
[ 1 ] = (uint8_t)( ( INADDR_LOOPBACK
>> 16 ) & 0xFF );
2889 p
[ 2 ] = (uint8_t)( ( INADDR_LOOPBACK
>> 8 ) & 0xFF );
2890 p
[ 3 ] = (uint8_t)( INADDR_LOOPBACK
& 0xFF );
2891 DebugSNPrintF( s
, sizeof( s
), "%##a", &sa4
);
2892 require_action( strcmp( s
, "127.0.0.1:80" ) == 0, exit
, err
= -1 );
2898 struct sockaddr_in6 sa6
;
2900 memset( &sa6
, 0, sizeof( sa6
) );
2901 sa6
.sin6_family
= AF_INET6
;
2902 p
= (uint8_t *) &sa6
.sin6_port
;
2903 p
[ 0 ] = (uint8_t)( ( 80 >> 8 ) & 0xFF );
2904 p
[ 1 ] = (uint8_t)( 80 & 0xFF );
2905 sa6
.sin6_addr
.s6_addr
[ 0 ] = 0xFE;
2906 sa6
.sin6_addr
.s6_addr
[ 1 ] = 0x80;
2907 sa6
.sin6_addr
.s6_addr
[ 15 ] = 0x01;
2908 sa6
.sin6_scope_id
= 2;
2909 DebugSNPrintF( s
, sizeof( s
), "%##a", &sa6
);
2910 require_action( strcmp( s
, "[FE80:0000:0000:0000:0000:0000:0000:0001%2]:80" ) == 0, exit
, err
= -1 );
2916 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "tes" );
2917 require_action( strcmp( s
, "tes" ) == 0, exit
, err
= kResponseErr
);
2919 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "test" );
2920 require_action( strcmp( s
, "test" ) == 0, exit
, err
= kResponseErr
);
2922 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "testing" );
2923 require_action( strcmp( s
, "test" ) == 0, exit
, err
= kResponseErr
);
2925 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "te\xC3\xA9" );
2926 require_action( strcmp( s
, "te\xC3\xA9" ) == 0, exit
, err
= kResponseErr
);
2928 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "te\xC3\xA9ing" );
2929 require_action( strcmp( s
, "te\xC3\xA9" ) == 0, exit
, err
= kResponseErr
);
2931 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "tes\xC3\xA9ing" );
2932 require_action( strcmp( s
, "tes" ) == 0, exit
, err
= kResponseErr
);
2934 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "t\xed\x9f\xbf" );
2935 require_action( strcmp( s
, "t\xed\x9f\xbf" ) == 0, exit
, err
= kResponseErr
);
2937 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "t\xed\x9f\xbfing" );
2938 require_action( strcmp( s
, "t\xed\x9f\xbf" ) == 0, exit
, err
= kResponseErr
);
2940 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "te\xed\x9f\xbf" );
2941 require_action( strcmp( s
, "te" ) == 0, exit
, err
= kResponseErr
);
2943 DebugSNPrintF(s
, sizeof(s
), "%.*s", 4, "te\xed\x9f\xbfing" );
2944 require_action( strcmp( s
, "te" ) == 0, exit
, err
= kResponseErr
);
2946 DebugSNPrintF(s
, sizeof(s
), "%.*s", 7, "te\xC3\xA9\xed\x9f\xbfing" );
2947 require_action( strcmp( s
, "te\xC3\xA9\xed\x9f\xbf" ) == 0, exit
, err
= kResponseErr
);
2949 DebugSNPrintF(s
, sizeof(s
), "%.*s", 6, "te\xC3\xA9\xed\x9f\xbfing" );
2950 require_action( strcmp( s
, "te\xC3\xA9" ) == 0, exit
, err
= kResponseErr
);
2952 DebugSNPrintF(s
, sizeof(s
), "%.*s", 5, "te\xC3\xA9\xed\x9f\xbfing" );
2953 require_action( strcmp( s
, "te\xC3\xA9" ) == 0, exit
, err
= kResponseErr
);
2955 #if( TARGET_RT_BIG_ENDIAN )
2956 DebugSNPrintF( s
, sizeof( s
), "%S", "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" );
2957 require_action( strcmp( s
, "abcd" ) == 0, exit
, err
= -1 );
2959 DebugSNPrintF( s
, sizeof( s
), "%S", "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" "\x00" );
2960 require_action( strcmp( s
, "abcd" ) == 0, exit
, err
= -1 );
2963 DebugSNPrintF( s
, sizeof( s
), "%S",
2964 "\xFE\xFF" "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" ); // Big Endian BOM
2965 require_action( strcmp( s
, "abcd" ) == 0, exit
, err
= -1 );
2967 DebugSNPrintF( s
, sizeof( s
), "%S",
2968 "\xFF\xFE" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" "\x00" ); // Little Endian BOM
2969 require_action( strcmp( s
, "abcd" ) == 0, exit
, err
= -1 );
2971 DebugSNPrintF( s
, sizeof( s
), "%#S", "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" ); // Big Endian
2972 require_action( strcmp( s
, "abcd" ) == 0, exit
, err
= -1 );
2974 DebugSNPrintF( s
, sizeof( s
), "%##S", "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" "\x00" ); // Little Endian
2975 require_action( strcmp( s
, "abcd" ) == 0, exit
, err
= -1 );
2977 DebugSNPrintF( s
, sizeof( s
), "%.*S",
2978 4, "\xFE\xFF" "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" ); // Big Endian BOM
2979 require_action( strcmp( s
, "abc" ) == 0, exit
, err
= -1 );
2981 DebugSNPrintF( s
, sizeof( s
), "%.*S",
2982 4, "\xFF\xFE" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" ); // Little Endian BOM
2983 require_action( strcmp( s
, "abc" ) == 0, exit
, err
= -1 );
2985 #if( TARGET_RT_BIG_ENDIAN )
2986 DebugSNPrintF( s
, sizeof( s
), "%.*S", 3, "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" );
2987 require_action( strcmp( s
, "abc" ) == 0, exit
, err
= -1 );
2989 DebugSNPrintF( s
, sizeof( s
), "%.*S", 3, "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" );
2990 require_action( strcmp( s
, "abc" ) == 0, exit
, err
= -1 );
2993 DebugSNPrintF( s
, sizeof( s
), "%#.*S", 3, "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" ); // Big Endian
2994 require_action( strcmp( s
, "abc" ) == 0, exit
, err
= -1 );
2996 DebugSNPrintF( s
, sizeof( s
), "%##.*S", 3, "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" ); // Little Endian
2997 require_action( strcmp( s
, "abc" ) == 0, exit
, err
= -1 );
3001 DebugSNPrintF( s
, sizeof( s
), "%U", "\x10\xb8\xa7\x6b" "\xad\x9d" "\xd1\x11" "\x80\xb4" "\x00\xc0\x4f\xd4\x30\xc8" );
3002 require_action( strcmp( s
, "6ba7b810-9dad-11d1-80b4-00c04fd430c8" ) == 0, exit
, err
= -1 );
3004 DebugSNPrintF( s
, sizeof( s
), "%m", 0 );
3005 require_action( strcmp( s
, "no error" ) == 0, exit
, err
= -1 );
3007 DebugSNPrintF( s
, sizeof( s
), "%lm", (long) 0 );
3008 require_action( strcmp( s
, "no error" ) == 0, exit
, err
= -1 );
3010 DebugSNPrintF( s
, sizeof( s
), "\"%H\"", "\x6b\xa7\xb8\x10\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8", 16, 16 );
3011 DebugPrintF( kDebugLevelMax
, "%s\n\n", s
);
3013 DebugSNPrintF( s
, sizeof( s
), "\"%H\"",
3014 "\x6b\xa7\xb8\x10\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8"
3015 "\x6b\xa7\xb8\x10\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8",
3017 DebugPrintF( kDebugLevelMax
, "%s\n\n", s
);
3019 DebugSNPrintF( s
, sizeof( s
), "\"%H\"", "\x6b\xa7", 2, 2 );
3020 DebugPrintF( kDebugLevelMax
, "%s\n\n", s
);
3025 DebugHexDump( kDebugLevelMax
, 0, "My Label", kSizeCString
, 0, NULL
, 0, data
, data
, sizeof( data
),
3026 kDebugFlagsNone
, s
, sizeof( s
) );
3027 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3030 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
),
3031 kDebugFlagsNoAddress
| kDebugFlagsNoOffset
, s
, sizeof( s
) );
3032 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3035 DebugHexDump( kDebugLevelMax
, 0, "My Label", kSizeCString
, 0, NULL
, 0, data
, data
, sizeof( data
),
3036 kDebugFlagsNoAddress
| kDebugFlagsNoOffset
, s
, sizeof( s
) );
3037 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3040 DebugHexDump( kDebugLevelMax
, 0, "My Label", kSizeCString
, 0, NULL
, 0, data
, data
, sizeof( data
),
3041 kDebugFlagsNoAddress
, s
, sizeof( s
) );
3042 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3045 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
),
3046 kDebugFlagsNoOffset
, s
, sizeof( s
) );
3047 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3050 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
),
3051 kDebugFlagsNoAddress
, s
, sizeof( s
) );
3052 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3055 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
),
3056 kDebugFlagsNoOffset
, s
, sizeof( s
) );
3057 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3060 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
),
3061 kDebugFlagsNoByteCount
, s
, sizeof( s
) );
3062 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3065 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, "\x41\x62\x43\x64", "\x41\x62\x43\x64", 4, // 'AbCd'
3066 kDebugFlagsNoAddress
| kDebugFlagsNoOffset
| kDebugFlagsNoNewLine
|
3067 kDebugFlagsNo32BitSeparator
| kDebugFlagsNo16ByteHexPad
| kDebugFlagsNoByteCount
,
3069 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3072 DebugHexDump( kDebugLevelMax
, 0, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
),
3073 kDebugFlagsNoAddress
| kDebugFlagsNoOffset
| kDebugFlagsNoASCII
| kDebugFlagsNoNewLine
|
3074 kDebugFlags16BitSeparator
| kDebugFlagsNo32BitSeparator
|
3075 kDebugFlagsNo16ByteHexPad
| kDebugFlagsNoByteCount
, s
, sizeof( s
) );
3076 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3079 DebugHexDump( kDebugLevelMax
, 8, NULL
, 0, 0, NULL
, 0, data
, data
, sizeof( data
), kDebugFlagsNone
, s
, sizeof( s
) );
3080 DebugPrintF( kDebugLevelMax
, "%s\n", s
);
3084 dlog( kDebugLevelNotice
, "dlog\n" );
3085 dlog( kDebugLevelNotice
, "dlog integer: %d\n", 123 );
3086 dlog( kDebugLevelNotice
, "dlog string: \"%s\"\n", "test string" );
3087 dlogmem( kDebugLevelNotice
, data
, sizeof( data
) );
3091 DebugPrintF( kDebugLevelMax
, "\n\nALL TESTS DONE\n\n" );
3097 DebugPrintF( kDebugLevelMax
, "\n\n### TEST FAILED ###\n\n" );