Home | History | Annotate | Download | only in mDNSShared
      1 /* -*- Mode: C; tab-width: 4 -*-
      2  *
      3  * Copyright (c) 1997-2004 Apple Computer, Inc. All rights reserved.
      4  *
      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
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     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.
     16 
     17 	To Do:
     18 
     19 	- Use StackWalk on Windows to optionally print stack frames.
     20 */
     21 
     22 #if 0
     23 #pragma mark == Includes ==
     24 #endif
     25 
     26 //===========================================================================================================================
     27 //	Includes
     28 //===========================================================================================================================
     29 
     30 #if( !KERNEL )
     31 	#include	<ctype.h>
     32 	#include	<stdio.h>
     33 	#include	<string.h>
     34 #endif
     35 
     36 #include	"CommonServices.h"
     37 
     38 #include	"DebugServices.h"
     39 
     40 #if( DEBUG )
     41 
     42 #if( TARGET_OS_VXWORKS )
     43 	#include	"intLib.h"
     44 #endif
     45 
     46 #if( TARGET_OS_WIN32 )
     47 	#include	<time.h>
     48 
     49 	#if( !TARGET_OS_WINDOWS_CE )
     50 		#include	<fcntl.h>
     51 		#include	<io.h>
     52 	#endif
     53 #endif
     54 
     55 #if( DEBUG_IDEBUG_ENABLED && TARGET_API_MAC_OSX_KERNEL )
     56 	#include	<IOKit/IOLib.h>
     57 #endif
     58 
     59 // If MDNS_DEBUGMSGS is defined (even if defined 0), it is aware of mDNS and it is probably safe to include mDNSEmbeddedAPI.h.
     60 
     61 #if( defined( MDNS_DEBUGMSGS ) )
     62 	#include	"mDNSEmbeddedAPI.h"
     63 #endif
     64 
     65 #if 0
     66 #pragma mark == Macros ==
     67 #endif
     68 
     69 //===========================================================================================================================
     70 //	Macros
     71 //===========================================================================================================================
     72 
     73 #define DebugIsPrint( C )		( ( ( C ) >= 0x20 ) && ( ( C ) <= 0x7E ) )
     74 
     75 #if 0
     76 #pragma mark == Prototypes ==
     77 #endif
     78 
     79 //===========================================================================================================================
     80 //	Prototypes
     81 //===========================================================================================================================
     82 
     83 static OSStatus	DebugPrint( DebugLevel inLevel, char *inData, size_t inSize );
     84 
     85 // fprintf
     86 
     87 #if( DEBUG_FPRINTF_ENABLED )
     88 	static OSStatus	DebugFPrintFInit( DebugOutputTypeFlags inFlags, const char *inFilename );
     89 	static void		DebugFPrintFPrint( char *inData, size_t inSize );
     90 #endif
     91 
     92 // iDebug (Mac OS X user and kernel)
     93 
     94 #if( DEBUG_IDEBUG_ENABLED )
     95 	static OSStatus	DebugiDebugInit( void );
     96 	static void		DebugiDebugPrint( char *inData, size_t inSize );
     97 #endif
     98 
     99 // kprintf (Mac OS X Kernel)
    100 
    101 #if( DEBUG_KPRINTF_ENABLED )
    102 	static void	DebugKPrintFPrint( char *inData, size_t inSize );
    103 #endif
    104 
    105 // Mac OS X IOLog (Mac OS X Kernel)
    106 
    107 #if( DEBUG_MAC_OS_X_IOLOG_ENABLED )
    108 	static void	DebugMacOSXIOLogPrint( char *inData, size_t inSize );
    109 #endif
    110 
    111 // Mac OS X Log
    112 
    113 #if( TARGET_OS_MAC )
    114 	static OSStatus	DebugMacOSXLogInit( void );
    115 	static void		DebugMacOSXLogPrint( char *inData, size_t inSize );
    116 #endif
    117 
    118 // Windows Debugger
    119 
    120 #if( TARGET_OS_WIN32 )
    121 	static void	DebugWindowsDebuggerPrint( char *inData, size_t inSize );
    122 #endif
    123 
    124 // Windows Event Log
    125 
    126 #if( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
    127 	static OSStatus	DebugWindowsEventLogInit( const char *inName, HMODULE inModule );
    128 	static void	DebugWindowsEventLogPrint( DebugLevel inLevel, char *inData, size_t inSize );
    129 #endif
    130 
    131 // DebugLib support
    132 
    133 #if( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
    134 	static pascal void
    135 		DebugAssertOutputHandler(
    136 			OSType 				inComponentSignature,
    137 			UInt32 				inOptions,
    138 			const char *		inAssertionString,
    139 			const char *		inExceptionString,
    140 			const char *		inErrorString,
    141 			const char *		inFileName,
    142 			long 				inLineNumber,
    143 			void *				inValue,
    144 			ConstStr255Param 	inOutputMsg );
    145 #endif
    146 
    147 // Utilities
    148 
    149 static char *	DebugNumVersionToString( uint32_t inVersion, char *inString );
    150 
    151 #if( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
    152 	static void	DebugWinEnableConsole( void );
    153 #endif
    154 
    155 #if( TARGET_OS_WIN32 )
    156 	static TCHAR *
    157 		DebugWinCharToTCharString(
    158 			const char *	inCharString,
    159 			size_t 			inCharCount,
    160 			TCHAR *			outTCharString,
    161 			size_t 			inTCharCountMax,
    162 			size_t *		outTCharCount );
    163 #endif
    164 
    165 #if 0
    166 #pragma mark == Globals ==
    167 #endif
    168 
    169 //===========================================================================================================================
    170 //	Private Globals
    171 //===========================================================================================================================
    172 
    173 #if( TARGET_OS_VXWORKS )
    174 	// TCP States for inetstatShow.
    175 
    176 	extern char **	pTcpstates;		// defined in tcpLib.c
    177 
    178 	const char *		kDebugTCPStates[] =
    179 	{
    180 		"(0)  TCPS_CLOSED",
    181 		"(1)  TCPS_LISTEN",
    182 		"(2)  TCPS_SYN_SENT",
    183 		"(3)  TCPS_SYN_RECEIVED",
    184 		"(4)  TCPS_ESTABLISHED",
    185 		"(5)  TCPS_CLOSE_WAIT",
    186 		"(6)  TCPS_FIN_WAIT_1",
    187 		"(7)  TCPS_CLOSING",
    188 		"(8)  TCPS_LAST_ACK",
    189 		"(9)  TCPS_FIN_WAIT_2",
    190 		"(10) TCPS_TIME_WAIT",
    191 	};
    192 #endif
    193 
    194 // General
    195 
    196 static bool									gDebugInitialized				= false;
    197 static DebugOutputType						gDebugOutputType 				= kDebugOutputTypeNone;
    198 static DebugLevel							gDebugPrintLevelMin				= kDebugLevelInfo;
    199 static DebugLevel							gDebugPrintLevelMax				= kDebugLevelMax;
    200 static DebugLevel							gDebugBreakLevel				= kDebugLevelAssert;
    201 #if( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
    202 	static DebugAssertOutputHandlerUPP		gDebugAssertOutputHandlerUPP	= NULL;
    203 #endif
    204 
    205 // Custom
    206 
    207 static DebugOutputFunctionPtr				gDebugCustomOutputFunction 		= NULL;
    208 static void *								gDebugCustomOutputContext 		= NULL;
    209 
    210 // fprintf
    211 
    212 #if( DEBUG_FPRINTF_ENABLED )
    213 	static FILE *							gDebugFPrintFFile 				= NULL;
    214 #endif
    215 
    216 // MacOSXLog
    217 
    218 #if( TARGET_OS_MAC )
    219 	typedef int	( *DebugMacOSXLogFunctionPtr )( const char *inFormat, ... );
    220 
    221 	static DebugMacOSXLogFunctionPtr		gDebugMacOSXLogFunction			= NULL;
    222 #endif
    223 
    224 // WindowsEventLog
    225 
    226 
    227 #if( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
    228 	static HANDLE							gDebugWindowsEventLogEventSource = NULL;
    229 #endif
    230 
    231 #if 0
    232 #pragma mark -
    233 #pragma mark == General ==
    234 #endif
    235 
    236 //===========================================================================================================================
    237 //	DebugInitialize
    238 //===========================================================================================================================
    239 
    240 DEBUG_EXPORT OSStatus	DebugInitialize( DebugOutputType inType, ... )
    241 {
    242 	OSStatus			err;
    243 	DebugOutputType		type;
    244 	va_list				args;
    245 
    246 	va_start( args, inType );
    247 
    248 #if( TARGET_OS_VXWORKS )
    249 	// Set up the TCP state strings if they are not already set up by VxWorks (normally not set up for some reason).
    250 
    251 	if( !pTcpstates )
    252 	{
    253 		pTcpstates = (char **) kDebugTCPStates;
    254 	}
    255 #endif
    256 
    257 	// Set up DebugLib stuff (if building with Debugging.h).
    258 
    259 #if( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
    260 	if( !gDebugAssertOutputHandlerUPP )
    261 	{
    262 		gDebugAssertOutputHandlerUPP = NewDebugAssertOutputHandlerUPP( DebugAssertOutputHandler );
    263 		check( gDebugAssertOutputHandlerUPP );
    264 		if( gDebugAssertOutputHandlerUPP )
    265 		{
    266 			InstallDebugAssertOutputHandler( gDebugAssertOutputHandlerUPP );
    267 		}
    268 	}
    269 #endif
    270 
    271 	// Pre-process meta-output kind to pick an appropriate output kind for the platform.
    272 
    273 	type = inType;
    274 	if( type == kDebugOutputTypeMetaConsole )
    275 	{
    276 		#if( TARGET_OS_MAC )
    277 			type = kDebugOutputTypeMacOSXLog;
    278 		#elif( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
    279 			#if( DEBUG_FPRINTF_ENABLED )
    280 				type = kDebugOutputTypeFPrintF;
    281 			#else
    282 				type = kDebugOutputTypeWindowsDebugger;
    283 			#endif
    284 		#elif( TARGET_API_MAC_OSX_KERNEL )
    285 			#if( DEBUG_MAC_OS_X_IOLOG_ENABLED )
    286 				type = kDebugOutputTypeMacOSXIOLog;
    287 			#elif( DEBUG_IDEBUG_ENABLED )
    288 				type = kDebugOutputTypeiDebug;
    289 			#elif( DEBUG_KPRINTF_ENABLED )
    290 				type = kDebugOutputTypeKPrintF;
    291 			#endif
    292 		#elif( TARGET_OS_VXWORKS )
    293 			#if( DEBUG_FPRINTF_ENABLED )
    294 				type = kDebugOutputTypeFPrintF;
    295 			#else
    296 				#error target is VxWorks, but fprintf output is disabled
    297 			#endif
    298 		#else
    299 			#if( DEBUG_FPRINTF_ENABLED )
    300 				type = kDebugOutputTypeFPrintF;
    301 			#endif
    302 		#endif
    303 	}
    304 
    305 	// Process output kind.
    306 
    307 	gDebugOutputType = type;
    308 	switch( type )
    309 	{
    310 		case kDebugOutputTypeNone:
    311 			err = kNoErr;
    312 			break;
    313 
    314 		case kDebugOutputTypeCustom:
    315 			gDebugCustomOutputFunction = va_arg( args, DebugOutputFunctionPtr );
    316 			gDebugCustomOutputContext  = va_arg( args, void * );
    317 			err = kNoErr;
    318 			break;
    319 
    320 #if( DEBUG_FPRINTF_ENABLED )
    321 		case kDebugOutputTypeFPrintF:
    322 			if( inType == kDebugOutputTypeMetaConsole )
    323 			{
    324 				err = DebugFPrintFInit( kDebugOutputTypeFlagsStdErr, NULL );
    325 			}
    326 			else
    327 			{
    328 				DebugOutputTypeFlags		flags;
    329 				const char *				filename;
    330 
    331 				flags = (DebugOutputTypeFlags) va_arg( args, unsigned int );
    332 				if( ( flags & kDebugOutputTypeFlagsTypeMask ) == kDebugOutputTypeFlagsFile )
    333 				{
    334 					filename = va_arg( args, const char * );
    335 				}
    336 				else
    337 				{
    338 					filename = NULL;
    339 				}
    340 				err = DebugFPrintFInit( flags, filename );
    341 			}
    342 			break;
    343 #endif
    344 
    345 #if( DEBUG_IDEBUG_ENABLED )
    346 		case kDebugOutputTypeiDebug:
    347 			err = DebugiDebugInit();
    348 			break;
    349 #endif
    350 
    351 #if( DEBUG_KPRINTF_ENABLED )
    352 		case kDebugOutputTypeKPrintF:
    353 			err = kNoErr;
    354 			break;
    355 #endif
    356 
    357 #if( DEBUG_MAC_OS_X_IOLOG_ENABLED )
    358 		case kDebugOutputTypeMacOSXIOLog:
    359 			err = kNoErr;
    360 			break;
    361 #endif
    362 
    363 #if( TARGET_OS_MAC )
    364 		case kDebugOutputTypeMacOSXLog:
    365 			err = DebugMacOSXLogInit();
    366 			break;
    367 #endif
    368 
    369 #if( TARGET_OS_WIN32 )
    370 		case kDebugOutputTypeWindowsDebugger:
    371 			err = kNoErr;
    372 			break;
    373 #endif
    374 
    375 #if( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
    376 		case kDebugOutputTypeWindowsEventLog:
    377 		{
    378 			const char *		name;
    379 			HMODULE				module;
    380 
    381 			name   = va_arg( args, const char * );
    382 			module = va_arg( args, HMODULE );
    383 			err = DebugWindowsEventLogInit( name, module );
    384 		}
    385 		break;
    386 #endif
    387 
    388 		default:
    389 			err = kParamErr;
    390 			goto exit;
    391 	}
    392 	gDebugInitialized = true;
    393 
    394 exit:
    395 	va_end( args );
    396 	return( err );
    397 }
    398 
    399 //===========================================================================================================================
    400 //	DebugFinalize
    401 //===========================================================================================================================
    402 
    403 DEBUG_EXPORT void		DebugFinalize( void )
    404 {
    405 #if( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
    406 	check( gDebugAssertOutputHandlerUPP );
    407 	if( gDebugAssertOutputHandlerUPP )
    408 	{
    409 		InstallDebugAssertOutputHandler( NULL );
    410 		DisposeDebugAssertOutputHandlerUPP( gDebugAssertOutputHandlerUPP );
    411 		gDebugAssertOutputHandlerUPP = NULL;
    412 	}
    413 #endif
    414 }
    415 
    416 //===========================================================================================================================
    417 //	DebugGetProperty
    418 //===========================================================================================================================
    419 
    420 DEBUG_EXPORT OSStatus	DebugGetProperty( DebugPropertyTag inTag, ... )
    421 {
    422 	OSStatus			err;
    423 	va_list				args;
    424 	DebugLevel *		level;
    425 
    426 	va_start( args, inTag );
    427 	switch( inTag )
    428 	{
    429 		case kDebugPropertyTagPrintLevelMin:
    430 			level  = va_arg( args, DebugLevel * );
    431 			*level = gDebugPrintLevelMin;
    432 			err = kNoErr;
    433 			break;
    434 
    435 		case kDebugPropertyTagPrintLevelMax:
    436 			level  = va_arg( args, DebugLevel * );
    437 			*level = gDebugPrintLevelMax;
    438 			err = kNoErr;
    439 			break;
    440 
    441 		case kDebugPropertyTagBreakLevel:
    442 			level  = va_arg( args, DebugLevel * );
    443 			*level = gDebugBreakLevel;
    444 			err = kNoErr;
    445 			break;
    446 
    447 		default:
    448 			err = kUnsupportedErr;
    449 			break;
    450 	}
    451 	va_end( args );
    452 	return( err );
    453 }
    454 
    455 //===========================================================================================================================
    456 //	DebugSetProperty
    457 //===========================================================================================================================
    458 
    459 DEBUG_EXPORT OSStatus	DebugSetProperty( DebugPropertyTag inTag, ... )
    460 {
    461 	OSStatus		err;
    462 	va_list			args;
    463 	DebugLevel		level;
    464 
    465 	va_start( args, inTag );
    466 	switch( inTag )
    467 	{
    468 		case kDebugPropertyTagPrintLevelMin:
    469 			level  = va_arg( args, DebugLevel );
    470 			gDebugPrintLevelMin = level;
    471 			err = kNoErr;
    472 			break;
    473 
    474 		case kDebugPropertyTagPrintLevelMax:
    475 			level  = va_arg( args, DebugLevel );
    476 			gDebugPrintLevelMax = level;
    477 			err = kNoErr;
    478 			break;
    479 
    480 		case kDebugPropertyTagBreakLevel:
    481 			level  = va_arg( args, DebugLevel );
    482 			gDebugBreakLevel = level;
    483 			err = kNoErr;
    484 			break;
    485 
    486 		default:
    487 			err = kUnsupportedErr;
    488 			break;
    489 	}
    490 	va_end( args );
    491 	return( err );
    492 }
    493 
    494 #if 0
    495 #pragma mark -
    496 #pragma mark == Output ==
    497 #endif
    498 
    499 //===========================================================================================================================
    500 //	DebugPrintF
    501 //===========================================================================================================================
    502 
    503 DEBUG_EXPORT size_t	DebugPrintF( DebugLevel inLevel, const char *inFormat, ... )
    504 {
    505 	va_list		args;
    506 	size_t		n;
    507 
    508 	// Skip if the level is not in the enabled range..
    509 
    510 	if( ( inLevel < gDebugPrintLevelMin ) || ( inLevel > gDebugPrintLevelMax ) )
    511 	{
    512 		n = 0;
    513 		goto exit;
    514 	}
    515 
    516 	va_start( args, inFormat );
    517 	n = DebugPrintFVAList( inLevel, inFormat, args );
    518 	va_end( args );
    519 
    520 exit:
    521 	return( n );
    522 }
    523 
    524 //===========================================================================================================================
    525 //	DebugPrintFVAList
    526 //===========================================================================================================================
    527 
    528 DEBUG_EXPORT size_t	DebugPrintFVAList( DebugLevel inLevel, const char *inFormat, va_list inArgs )
    529 {
    530 	size_t		n;
    531 	char		buffer[ 512 ];
    532 
    533 	// Skip if the level is not in the enabled range..
    534 
    535 	if( ( inLevel < gDebugPrintLevelMin ) || ( inLevel > gDebugPrintLevelMax ) )
    536 	{
    537 		n = 0;
    538 		goto exit;
    539 	}
    540 
    541 	n = DebugSNPrintFVAList( buffer, sizeof( buffer ), inFormat, inArgs );
    542 	DebugPrint( inLevel, buffer, (size_t) n );
    543 
    544 exit:
    545 	return( n );
    546 }
    547 
    548 //===========================================================================================================================
    549 //	DebugPrint
    550 //===========================================================================================================================
    551 
    552 static OSStatus	DebugPrint( DebugLevel inLevel, char *inData, size_t inSize )
    553 {
    554 	OSStatus		err;
    555 
    556 	// Skip if the level is not in the enabled range..
    557 
    558 	if( ( inLevel < gDebugPrintLevelMin ) || ( inLevel > gDebugPrintLevelMax ) )
    559 	{
    560 		err = kRangeErr;
    561 		goto exit;
    562 	}
    563 
    564 	// Printing is not safe at interrupt time so check for this and warn with an interrupt safe mechanism (if available).
    565 
    566 	if( DebugTaskLevel() & kDebugInterruptLevelMask )
    567 	{
    568 		#if( TARGET_OS_VXWORKS )
    569 			logMsg( "\ncannot print at interrupt time\n\n", 1, 2, 3, 4, 5, 6 );
    570 		#endif
    571 
    572 		err = kExecutionStateErr;
    573 		goto exit;
    574 	}
    575 
    576 	// Initialize the debugging library if it hasn't already been initialized (allows for zero-config usage).
    577 
    578 	if( !gDebugInitialized )
    579 	{
    580 		debug_initialize( kDebugOutputTypeMetaConsole );
    581 	}
    582 
    583 	// Print based on the current output type.
    584 
    585 	switch( gDebugOutputType )
    586 	{
    587 		case kDebugOutputTypeNone:
    588 			break;
    589 
    590 		case kDebugOutputTypeCustom:
    591 			if( gDebugCustomOutputFunction )
    592 			{
    593 				gDebugCustomOutputFunction( inData, inSize, gDebugCustomOutputContext );
    594 			}
    595 			break;
    596 
    597 #if( DEBUG_FPRINTF_ENABLED )
    598 		case kDebugOutputTypeFPrintF:
    599 			DebugFPrintFPrint( inData, inSize );
    600 			break;
    601 #endif
    602 
    603 #if( DEBUG_IDEBUG_ENABLED )
    604 		case kDebugOutputTypeiDebug:
    605 			DebugiDebugPrint( inData, inSize );
    606 			break;
    607 #endif
    608 
    609 #if( DEBUG_KPRINTF_ENABLED )
    610 		case kDebugOutputTypeKPrintF:
    611 			DebugKPrintFPrint( inData, inSize );
    612 			break;
    613 #endif
    614 
    615 #if( DEBUG_MAC_OS_X_IOLOG_ENABLED )
    616 		case kDebugOutputTypeMacOSXIOLog:
    617 			DebugMacOSXIOLogPrint( inData, inSize );
    618 			break;
    619 #endif
    620 
    621 #if( TARGET_OS_MAC )
    622 		case kDebugOutputTypeMacOSXLog:
    623 			DebugMacOSXLogPrint( inData, inSize );
    624 			break;
    625 #endif
    626 
    627 #if( TARGET_OS_WIN32 )
    628 		case kDebugOutputTypeWindowsDebugger:
    629 			DebugWindowsDebuggerPrint( inData, inSize );
    630 			break;
    631 #endif
    632 
    633 #if( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
    634 		case kDebugOutputTypeWindowsEventLog:
    635 			DebugWindowsEventLogPrint( inLevel, inData, inSize );
    636 			break;
    637 #endif
    638 
    639 		default:
    640 			break;
    641 	}
    642 	err = kNoErr;
    643 
    644 exit:
    645 	return( err );
    646 }
    647 
    648 //===========================================================================================================================
    649 //	DebugPrintAssert
    650 //
    651 //	Warning: This routine relies on several of the strings being string constants that will exist forever because the
    652 //           underlying logMsg API that does the printing is asynchronous so it cannot use temporary/stack-based
    653 //           pointer variables (e.g. local strings). The debug macros that invoke this function only use constant
    654 //           constant strings, but if this function is invoked directly from other places, it must use constant strings.
    655 //===========================================================================================================================
    656 
    657 DEBUG_EXPORT void
    658 	DebugPrintAssert(
    659 		int_least32_t	inErrorCode,
    660 		const char *	inAssertString,
    661 		const char *	inMessage,
    662 		const char *	inFilename,
    663 		int_least32_t	inLineNumber,
    664 		const char *	inFunction )
    665 {
    666 	// Skip if the level is not in the enabled range..
    667 
    668 	if( ( kDebugLevelAssert < gDebugPrintLevelMin ) || ( kDebugLevelAssert > gDebugPrintLevelMax ) )
    669 	{
    670 		return;
    671 	}
    672 
    673 	if( inErrorCode != 0 )
    674 	{
    675 		DebugPrintF(
    676 			kDebugLevelAssert,
    677 			"\n"
    678 			"[ASSERT] error:  %ld (%m)\n"
    679 			"[ASSERT] where:  \"%s\", line %ld, \"%s\"\n"
    680 			"\n",
    681 			inErrorCode, inErrorCode,
    682 			inFilename ? inFilename : "",
    683 			inLineNumber,
    684 			inFunction ? inFunction : "" );
    685 	}
    686 	else
    687 	{
    688 		DebugPrintF(
    689 			kDebugLevelAssert,
    690 			"\n"
    691 			"[ASSERT] assert: \"%s\" %s\n"
    692 			"[ASSERT] where:  \"%s\", line %ld, \"%s\"\n"
    693 			"\n",
    694 			inAssertString ? inAssertString : "",
    695 			inMessage ? inMessage : "",
    696 			inFilename ? inFilename : "",
    697 			inLineNumber,
    698 			inFunction ? inFunction : "" );
    699 	}
    700 
    701 	// Break into the debugger if enabled.
    702 
    703 	#if( TARGET_OS_WIN32 )
    704 		if( gDebugBreakLevel <= kDebugLevelAssert )
    705 		{
    706 			if( IsDebuggerPresent() )
    707 			{
    708 				DebugBreak();
    709 			}
    710 		}
    711 	#endif
    712 }
    713 
    714 #if 0
    715 #pragma mark -
    716 #endif
    717 
    718 #if( DEBUG_FPRINTF_ENABLED )
    719 //===========================================================================================================================
    720 //	DebugFPrintFInit
    721 //===========================================================================================================================
    722 
    723 static OSStatus	DebugFPrintFInit( DebugOutputTypeFlags inFlags, const char *inFilename )
    724 {
    725 	OSStatus					err;
    726 	DebugOutputTypeFlags		typeFlags;
    727 
    728 	typeFlags = inFlags & kDebugOutputTypeFlagsTypeMask;
    729 	if( typeFlags == kDebugOutputTypeFlagsStdOut )
    730 	{
    731 		#if( TARGET_OS_WIN32 )
    732 			DebugWinEnableConsole();
    733 		#endif
    734 
    735 		gDebugFPrintFFile = stdout;
    736 	}
    737 	else if( typeFlags == kDebugOutputTypeFlagsStdErr )
    738 	{
    739 		#if( TARGET_OS_WIN32 )
    740 			DebugWinEnableConsole();
    741 		#endif
    742 
    743 		gDebugFPrintFFile = stdout;
    744 	}
    745 	else if( typeFlags == kDebugOutputTypeFlagsFile )
    746 	{
    747 		require_action_quiet( inFilename && ( *inFilename != '\0' ), exit, err = kOpenErr );
    748 
    749 		gDebugFPrintFFile = fopen( inFilename, "a" );
    750 		require_action_quiet( gDebugFPrintFFile, exit, err = kOpenErr );
    751 	}
    752 	else
    753 	{
    754 		err = kParamErr;
    755 		goto exit;
    756 	}
    757 	err = kNoErr;
    758 
    759 exit:
    760 	return( err );
    761 }
    762 
    763 //===========================================================================================================================
    764 //	DebugFPrintFPrint
    765 //===========================================================================================================================
    766 
    767 static void	DebugFPrintFPrint( char *inData, size_t inSize )
    768 {
    769 	char *		p;
    770 	char *		q;
    771 
    772 	// Convert \r to \n. fprintf will interpret \n and convert to whatever is appropriate for the platform.
    773 
    774 	p = inData;
    775 	q = p + inSize;
    776 	while( p < q )
    777 	{
    778 		if( *p == '\r' )
    779 		{
    780 			*p = '\n';
    781 		}
    782 		++p;
    783 	}
    784 
    785 	// Write the data and flush.
    786 
    787 	if( gDebugFPrintFFile )
    788 	{
    789 		fprintf( gDebugFPrintFFile, "%.*s", (int) inSize, inData );
    790 		fflush( gDebugFPrintFFile );
    791 	}
    792 }
    793 #endif	// DEBUG_FPRINTF_ENABLED
    794 
    795 #if( DEBUG_IDEBUG_ENABLED )
    796 //===========================================================================================================================
    797 //	DebugiDebugInit
    798 //===========================================================================================================================
    799 
    800 static OSStatus	DebugiDebugInit( void )
    801 {
    802 	OSStatus		err;
    803 
    804 	#if( TARGET_API_MAC_OSX_KERNEL )
    805 
    806 		extern uint32_t *		_giDebugReserved1;
    807 
    808 		// Emulate the iDebugSetOutputType macro in iDebugServices.h.
    809 		// Note: This is not thread safe, but neither is iDebugServices.h nor iDebugKext.
    810 
    811 		if( !_giDebugReserved1 )
    812 		{
    813 			_giDebugReserved1 = (uint32_t *) IOMalloc( sizeof( uint32_t ) );
    814 			require_action_quiet( _giDebugReserved1, exit, err = kNoMemoryErr );
    815 		}
    816 		*_giDebugReserved1 = 0x00010000U;
    817 		err = kNoErr;
    818 exit:
    819 	#else
    820 
    821 		__private_extern__ void	iDebugSetOutputTypeInternal( uint32_t inType );
    822 
    823 		iDebugSetOutputTypeInternal( 0x00010000U );
    824 		err = kNoErr;
    825 
    826 	#endif
    827 
    828 	return( err );
    829 }
    830 
    831 //===========================================================================================================================
    832 //	DebugiDebugPrint
    833 //===========================================================================================================================
    834 
    835 static void	DebugiDebugPrint( char *inData, size_t inSize )
    836 {
    837 	#if( TARGET_API_MAC_OSX_KERNEL )
    838 
    839 		// Locally declared here so we do not need to include iDebugKext.h.
    840 		// Note: IOKit uses a global namespace for all code and only a partial link occurs at build time. When the
    841 		// KEXT is loaded, the runtime linker will link in this extern'd symbol (assuming iDebug is present).
    842 		// _giDebugLogInternal is actually part of IOKit proper so this should link even if iDebug is not present.
    843 
    844 		typedef void ( *iDebugLogFunctionPtr )( uint32_t inLevel, uint32_t inTag, const char *inFormat, ... );
    845 
    846 		extern iDebugLogFunctionPtr		_giDebugLogInternal;
    847 
    848 		if( _giDebugLogInternal )
    849 		{
    850 			_giDebugLogInternal( 0, 0, "%.*s", (int) inSize, inData );
    851 		}
    852 
    853 	#else
    854 
    855 		__private_extern__ void	iDebugLogInternal( uint32_t inLevel, uint32_t inTag, const char *inFormat, ... );
    856 
    857 		iDebugLogInternal( 0, 0, "%.*s", (int) inSize, inData );
    858 
    859 	#endif
    860 }
    861 #endif
    862 
    863 #if( DEBUG_KPRINTF_ENABLED )
    864 //===========================================================================================================================
    865 //	DebugKPrintFPrint
    866 //===========================================================================================================================
    867 
    868 static void	DebugKPrintFPrint( char *inData, size_t inSize )
    869 {
    870 	extern void	kprintf( const char *inFormat, ... );
    871 
    872 	kprintf( "%.*s", (int) inSize, inData );
    873 }
    874 #endif
    875 
    876 #if( DEBUG_MAC_OS_X_IOLOG_ENABLED )
    877 //===========================================================================================================================
    878 //	DebugMacOSXIOLogPrint
    879 //===========================================================================================================================
    880 
    881 static void	DebugMacOSXIOLogPrint( char *inData, size_t inSize )
    882 {
    883 	extern void	IOLog( const char *inFormat, ... );
    884 
    885 	IOLog( "%.*s", (int) inSize, inData );
    886 }
    887 #endif
    888 
    889 #if( TARGET_OS_MAC )
    890 //===========================================================================================================================
    891 //	DebugMacOSXLogInit
    892 //===========================================================================================================================
    893 
    894 static OSStatus	DebugMacOSXLogInit( void )
    895 {
    896 	OSStatus		err;
    897 	CFStringRef		path;
    898 	CFURLRef		url;
    899 	CFBundleRef		bundle;
    900 	CFStringRef		functionName;
    901 	void *			functionPtr;
    902 
    903 	bundle = NULL;
    904 
    905 	// Create a bundle reference for System.framework.
    906 
    907 	path = CFSTR( "/System/Library/Frameworks/System.framework" );
    908 	url = CFURLCreateWithFileSystemPath( NULL, path, kCFURLPOSIXPathStyle, true );
    909 	require_action_quiet( url, exit, err = memFullErr );
    910 
    911 	bundle = CFBundleCreate( NULL, url );
    912 	CFRelease( url );
    913 	require_action_quiet( bundle, exit, err = memFullErr );
    914 
    915 	// Get a ptr to the system's "printf" function from System.framework.
    916 
    917 	functionName = CFSTR( "printf" );
    918 	functionPtr = CFBundleGetFunctionPointerForName( bundle, functionName );
    919 	require_action_quiet( functionPtr, exit, err = memFullErr );
    920 
    921 	// Success! Note: The bundle cannot be released because it would invalidate the function ptr.
    922 
    923 	gDebugMacOSXLogFunction = (DebugMacOSXLogFunctionPtr) functionPtr;
    924 	bundle = NULL;
    925 	err = noErr;
    926 
    927 exit:
    928 	if( bundle )
    929 	{
    930 		CFRelease( bundle );
    931 	}
    932 	return( err );
    933 }
    934 
    935 //===========================================================================================================================
    936 //	DebugMacOSXLogPrint
    937 //===========================================================================================================================
    938 
    939 static void	DebugMacOSXLogPrint( char *inData, size_t inSize )
    940 {
    941 	if( gDebugMacOSXLogFunction )
    942 	{
    943 		gDebugMacOSXLogFunction( "%.*s", (int) inSize, inData );
    944 	}
    945 }
    946 #endif
    947 
    948 #if( TARGET_OS_WIN32 )
    949 //===========================================================================================================================
    950 //	DebugWindowsDebuggerPrint
    951 //===========================================================================================================================
    952 
    953 void	DebugWindowsDebuggerPrint( char *inData, size_t inSize )
    954 {
    955 	TCHAR				buffer[ 512 ];
    956 	const char *		src;
    957 	const char *		end;
    958 	TCHAR *				dst;
    959 	char				c;
    960 
    961 	// Copy locally and null terminate the string. This also converts from char to TCHAR in case we are
    962 	// building with UNICODE enabled since the input is always char. Also convert \r to \n in the process.
    963 
    964 	src = inData;
    965 	if( inSize >= sizeof_array( buffer ) )
    966 	{
    967 		inSize = sizeof_array( buffer ) - 1;
    968 	}
    969 	end = src + inSize;
    970 	dst = buffer;
    971 	while( src < end )
    972 	{
    973 		c = *src++;
    974 		if( c == '\r' )
    975 		{
    976 			c = '\n';
    977 		}
    978 		*dst++ = (TCHAR) c;
    979 	}
    980 	*dst = 0;
    981 
    982 	// Print out the string to the debugger.
    983 
    984 	OutputDebugString( buffer );
    985 }
    986 #endif
    987 
    988 #if( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
    989 //===========================================================================================================================
    990 //	DebugWindowsEventLogInit
    991 //===========================================================================================================================
    992 
    993 static OSStatus	DebugWindowsEventLogInit( const char *inName, HMODULE inModule )
    994 {
    995 	OSStatus			err;
    996 	HKEY				key;
    997 	TCHAR				name[ 128 ];
    998 	const char *		src;
    999 	TCHAR				path[ MAX_PATH ];
   1000 	size_t				size;
   1001 	DWORD				typesSupported;
   1002 	DWORD 				n;
   1003 
   1004 	key = NULL;
   1005 
   1006 	// Use a default name if needed then convert the name to TCHARs so it works on ANSI or Unicode builds.
   1007 
   1008 	if( !inName || ( *inName == '\0' ) )
   1009 	{
   1010 		inName = "DefaultApp";
   1011 	}
   1012 	DebugWinCharToTCharString( inName, kSizeCString, name, sizeof( name ), NULL );
   1013 
   1014 	// Build the path string using the fixed registry path and app name.
   1015 
   1016 	src = "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\";
   1017 	DebugWinCharToTCharString( src, kSizeCString, path, sizeof_array( path ), &size );
   1018 	DebugWinCharToTCharString( inName, kSizeCString, path + size, sizeof_array( path ) - size, NULL );
   1019 
   1020 	// Add/Open the source name as a sub-key under the Application key in the EventLog registry key.
   1021 
   1022 	err = RegCreateKeyEx( HKEY_LOCAL_MACHINE, path, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, NULL );
   1023 	require_noerr_quiet( err, exit );
   1024 
   1025 	// Set the path in the EventMessageFile subkey. Add 1 to the TCHAR count to include the null terminator.
   1026 
   1027 	n = GetModuleFileName( inModule, path, sizeof_array( path ) );
   1028 	err = translate_errno( n > 0, (OSStatus) GetLastError(), kParamErr );
   1029 	require_noerr_quiet( err, exit );
   1030 	n += 1;
   1031 	n *= sizeof( TCHAR );
   1032 
   1033 	err = RegSetValueEx( key, TEXT( "EventMessageFile" ), 0, REG_EXPAND_SZ, (const LPBYTE) path, n );
   1034 	require_noerr_quiet( err, exit );
   1035 
   1036 	// Set the supported event types in the TypesSupported subkey.
   1037 
   1038 	typesSupported = EVENTLOG_SUCCESS | EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE |
   1039 					 EVENTLOG_AUDIT_SUCCESS | EVENTLOG_AUDIT_FAILURE;
   1040 	err = RegSetValueEx( key, TEXT( "TypesSupported" ), 0, REG_DWORD, (const LPBYTE) &typesSupported, sizeof( DWORD ) );
   1041 	require_noerr_quiet( err, exit );
   1042 
   1043 	// Set up the event source.
   1044 
   1045 	gDebugWindowsEventLogEventSource = RegisterEventSource( NULL, name );
   1046 	err = translate_errno( gDebugWindowsEventLogEventSource, (OSStatus) GetLastError(), kParamErr );
   1047 	require_noerr_quiet( err, exit );
   1048 
   1049 exit:
   1050 	if( key )
   1051 	{
   1052 		RegCloseKey( key );
   1053 	}
   1054 	return( err );
   1055 }
   1056 
   1057 //===========================================================================================================================
   1058 //	DebugWindowsEventLogPrint
   1059 //===========================================================================================================================
   1060 
   1061 static void	DebugWindowsEventLogPrint( DebugLevel inLevel, char *inData, size_t inSize )
   1062 {
   1063 	WORD				type;
   1064 	TCHAR				buffer[ 512 ];
   1065 	const char *		src;
   1066 	const char *		end;
   1067 	TCHAR *				dst;
   1068 	char				c;
   1069 	const TCHAR *		array[ 1 ];
   1070 
   1071 	// Map the debug level to a Windows EventLog type.
   1072 
   1073 	if( inLevel <= kDebugLevelNotice )
   1074 	{
   1075 		type = EVENTLOG_INFORMATION_TYPE;
   1076 	}
   1077 	else if( inLevel <= kDebugLevelWarning )
   1078 	{
   1079 		type = EVENTLOG_WARNING_TYPE;
   1080 	}
   1081 	else
   1082 	{
   1083 		type = EVENTLOG_ERROR_TYPE;
   1084 	}
   1085 
   1086 	// Copy locally and null terminate the string. This also converts from char to TCHAR in case we are
   1087 	// building with UNICODE enabled since the input is always char. Also convert \r to \n in the process.
   1088 
   1089 	src = inData;
   1090 	if( inSize >= sizeof_array( buffer ) )
   1091 	{
   1092 		inSize = sizeof_array( buffer ) - 1;
   1093 	}
   1094 	end = src + inSize;
   1095 	dst = buffer;
   1096 	while( src < end )
   1097 	{
   1098 		c = *src++;
   1099 		if( c == '\r' )
   1100 		{
   1101 			c = '\n';
   1102 		}
   1103 		*dst++ = (TCHAR) c;
   1104 	}
   1105 	*dst = 0;
   1106 
   1107 	// Add the the string to the event log.
   1108 
   1109 	array[ 0 ] = buffer;
   1110 	if( gDebugWindowsEventLogEventSource )
   1111 	{
   1112 		ReportEvent( gDebugWindowsEventLogEventSource, type, 0, 0x20000001L, NULL, 1, 0, array, NULL );
   1113 	}
   1114 }
   1115 #endif	// TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE
   1116 
   1117 #if( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
   1118 //===========================================================================================================================
   1119 //	DebugAssertOutputHandler
   1120 //===========================================================================================================================
   1121 
   1122 static pascal void
   1123 	DebugAssertOutputHandler(
   1124 		OSType 				inComponentSignature,
   1125 		UInt32 				inOptions,
   1126 		const char *		inAssertString,
   1127 		const char *		inExceptionString,
   1128 		const char *		inErrorString,
   1129 		const char *		inFileName,
   1130 		long 				inLineNumber,
   1131 		void *				inValue,
   1132 		ConstStr255Param 	inOutputMsg )
   1133 {
   1134 	DEBUG_UNUSED( inComponentSignature );
   1135 	DEBUG_UNUSED( inOptions );
   1136 	DEBUG_UNUSED( inExceptionString );
   1137 	DEBUG_UNUSED( inValue );
   1138 	DEBUG_UNUSED( inOutputMsg );
   1139 
   1140 	DebugPrintAssert( 0, inAssertString, inErrorString, inFileName, (int_least32_t) inLineNumber, "" );
   1141 }
   1142 #endif
   1143 
   1144 #if 0
   1145 #pragma mark -
   1146 #pragma mark == Utilities ==
   1147 #endif
   1148 
   1149 //===========================================================================================================================
   1150 //	DebugSNPrintF
   1151 //
   1152 //	Stolen from mDNS.c's mDNS_snprintf/mDNS_vsnprintf with the following changes:
   1153 //
   1154 //	Changed names to avoid name collisions with the mDNS versions.
   1155 //	Changed types to standard C types since mDNSEmbeddedAPI.h may not be available.
   1156 //	Conditionalized mDNS stuff so it can be used with or with mDNSEmbeddedAPI.h.
   1157 //	Added 64-bit support for %d (%lld), %i (%lli), %u (%llu), %o (%llo), %x (%llx), and %b (%llb).
   1158 //	Added %@   - Cocoa/CoreFoundation object. Param is the object. Strings are used directly. Others use CFCopyDescription.
   1159 //	Added %.8a - FIbre Channel address. Arg=ptr to address.
   1160 //	Added %##a - IPv4 (if AF_INET defined) or IPv6 (if AF_INET6 defined) sockaddr. Arg=ptr to sockaddr.
   1161 //	Added %b   - Binary representation of integer (e.g. 01101011). Modifiers and arg=the same as %d, %x, etc.
   1162 //	Added %C   - Mac-style FourCharCode (e.g. 'APPL'). Arg=32-bit value to print as a Mac-style FourCharCode.
   1163 //	Added %H   - Hex Dump (e.g. "\x6b\xa7" -> "6B A7"). 1st arg=ptr, 2nd arg=size, 3rd arg=max size.
   1164 //	Added %#H  - Hex Dump & ASCII (e.g. "\x41\x62" -> "6B A7 'Ab'"). 1st arg=ptr, 2nd arg=size, 3rd arg=max size.
   1165 //	Added %m   - Error Message (e.g. 0 -> "kNoErr"). Modifiers and error code args are the same as %d, %x, etc.
   1166 //	Added %S   - UTF-16 string. Host order if no BOM. Precision is UTF-16 char count. BOM counts in any precision. Arg=ptr.
   1167 //	Added %#S  - Big Endian UTF-16 string (unless BOM overrides). Otherwise the same as %S.
   1168 //	Added %##S - Little Endian UTF-16 string (unless BOM overrides). Otherwise the same as %S.
   1169 //	Added %U   - Universally Unique Identifier (UUID) (e.g. 6ba7b810-9dad-11d1-80b4-00c04fd430c8). Arg=ptr to 16-byte UUID.
   1170 //===========================================================================================================================
   1171 
   1172 DEBUG_EXPORT size_t DebugSNPrintF(char *sbuffer, size_t buflen, const char *fmt, ...)
   1173 	{
   1174 	size_t length;
   1175 
   1176 	va_list ptr;
   1177 	va_start(ptr,fmt);
   1178 	length = DebugSNPrintFVAList(sbuffer, buflen, fmt, ptr);
   1179 	va_end(ptr);
   1180 
   1181 	return(length);
   1182 	}
   1183 
   1184 //===========================================================================================================================
   1185 //	DebugSNPrintFVAList	- va_list version of DebugSNPrintF. See DebugSNPrintF for more info.
   1186 //===========================================================================================================================
   1187 
   1188 DEBUG_EXPORT size_t DebugSNPrintFVAList(char *sbuffer, size_t buflen, const char *fmt, va_list arg)
   1189 	{
   1190 	static const struct DebugSNPrintF_format
   1191 		{
   1192 		unsigned      leftJustify : 1;
   1193 		unsigned      forceSign : 1;
   1194 		unsigned      zeroPad : 1;
   1195 		unsigned      havePrecision : 1;
   1196 		unsigned      hSize : 1;
   1197 		char          lSize;
   1198 		char          altForm;
   1199 		char          sign;		// +, - or space
   1200 		unsigned int  fieldWidth;
   1201 		unsigned int  precision;
   1202 		} DebugSNPrintF_format_default = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
   1203 
   1204 	size_t nwritten = 0;
   1205 	int c;
   1206 	if (buflen == 0) return(0);
   1207 	buflen--;		// Pre-reserve one space in the buffer for the terminating nul
   1208 	if (buflen == 0) goto exit;
   1209 
   1210 	for (c = *fmt; c != 0; c = *++fmt)
   1211 		{
   1212 		if (c != '%')
   1213 			{
   1214 			*sbuffer++ = (char)c;
   1215 			if (++nwritten >= buflen) goto exit;
   1216 			}
   1217 		else
   1218 			{
   1219 			size_t i=0, j;
   1220 			// The mDNS Vsprintf Argument Conversion Buffer is used as a temporary holding area for
   1221 			// generating decimal numbers, hexdecimal numbers, IP addresses, domain name strings, etc.
   1222 			// The size needs to be enough for a 256-byte domain name plus some error text.
   1223 			#define mDNS_VACB_Size 300
   1224 			char mDNS_VACB[mDNS_VACB_Size];
   1225 			#define mDNS_VACB_Lim (&mDNS_VACB[mDNS_VACB_Size])
   1226 			#define mDNS_VACB_Remain(s) ((size_t)(mDNS_VACB_Lim - s))
   1227 			char *s = mDNS_VACB_Lim;
   1228 			const char *digits = "0123456789ABCDEF";
   1229 			struct DebugSNPrintF_format F = DebugSNPrintF_format_default;
   1230 
   1231 			for(;;)	//  decode flags
   1232 				{
   1233 				c = *++fmt;
   1234 				if      (c == '-') F.leftJustify = 1;
   1235 				else if (c == '+') F.forceSign = 1;
   1236 				else if (c == ' ') F.sign = ' ';
   1237 				else if (c == '#') F.altForm++;
   1238 				else if (c == '0') F.zeroPad = 1;
   1239 				else break;
   1240 				}
   1241 
   1242 			if (c == '*')	//  decode field width
   1243 				{
   1244 				int f = va_arg(arg, int);
   1245 				if (f < 0) { f = -f; F.leftJustify = 1; }
   1246 				F.fieldWidth = (unsigned int)f;
   1247 				c = *++fmt;
   1248 				}
   1249 			else
   1250 				{
   1251 				for (; c >= '0' && c <= '9'; c = *++fmt)
   1252 					F.fieldWidth = (10 * F.fieldWidth) + (c - '0');
   1253 				}
   1254 
   1255 			if (c == '.')	//  decode precision
   1256 				{
   1257 				if ((c = *++fmt) == '*')
   1258 					{ F.precision = va_arg(arg, unsigned int); c = *++fmt; }
   1259 				else for (; c >= '0' && c <= '9'; c = *++fmt)
   1260 						F.precision = (10 * F.precision) + (c - '0');
   1261 				F.havePrecision = 1;
   1262 				}
   1263 
   1264 			if (F.leftJustify) F.zeroPad = 0;
   1265 
   1266 			conv:
   1267 			switch (c)	//  perform appropriate conversion
   1268 				{
   1269 				#if TYPE_LONGLONG_NATIVE
   1270 					unsigned_long_long_compat n;
   1271 					unsigned_long_long_compat base;
   1272 				#else
   1273 					unsigned long n;
   1274 					unsigned long base;
   1275 				#endif
   1276 				case 'h' :	F.hSize = 1; c = *++fmt; goto conv;
   1277 				case 'l' :	// fall through
   1278 				case 'L' :	F.lSize++; c = *++fmt; goto conv;
   1279 				case 'd' :
   1280 				case 'i' :	base = 10;
   1281 							goto canBeSigned;
   1282 				case 'u' :	base = 10;
   1283 							goto notSigned;
   1284 				case 'o' :	base = 8;
   1285 							goto notSigned;
   1286 				case 'b' :	base = 2;
   1287 							goto notSigned;
   1288 				case 'p' :	n = va_arg(arg, uintptr_t);
   1289 							F.havePrecision = 1;
   1290 							F.precision = (sizeof(uintptr_t) == 4) ? 8 : 16;
   1291 							F.sign = 0;
   1292 							base = 16;
   1293 							c = 'x';
   1294 							goto number;
   1295 				case 'x' :	digits = "0123456789abcdef";
   1296 				case 'X' :	base = 16;
   1297 							goto notSigned;
   1298 				canBeSigned:
   1299 							#if TYPE_LONGLONG_NATIVE
   1300 								if (F.lSize == 1) n = (unsigned_long_long_compat)va_arg(arg, long);
   1301 								else if (F.lSize == 2) n = (unsigned_long_long_compat)va_arg(arg, long_long_compat);
   1302 								else n = (unsigned_long_long_compat)va_arg(arg, int);
   1303 							#else
   1304 								if (F.lSize == 1) n = (unsigned long)va_arg(arg, long);
   1305 								else if (F.lSize == 2) goto exit;
   1306 								else n = (unsigned long)va_arg(arg, int);
   1307 							#endif
   1308 							if (F.hSize) n = (short) n;
   1309 							#if TYPE_LONGLONG_NATIVE
   1310 								if ((long_long_compat) n < 0) { n = (unsigned_long_long_compat)-(long_long_compat)n; F.sign = '-'; }
   1311 							#else
   1312 								if ((long) n < 0) { n = (unsigned long)-(long)n; F.sign = '-'; }
   1313 							#endif
   1314 							else if (F.forceSign) F.sign = '+';
   1315 							goto number;
   1316 
   1317 				notSigned:	if (F.lSize == 1) n = va_arg(arg, unsigned long);
   1318 							else if (F.lSize == 2)
   1319 								{
   1320 								#if TYPE_LONGLONG_NATIVE
   1321 									n = va_arg(arg, unsigned_long_long_compat);
   1322 								#else
   1323 									goto exit;
   1324 								#endif
   1325 								}
   1326 							else n = va_arg(arg, unsigned int);
   1327 							if (F.hSize) n = (unsigned short) n;
   1328 							F.sign = 0;
   1329 							goto number;
   1330 
   1331 				number:		if (!F.havePrecision)
   1332 								{
   1333 								if (F.zeroPad)
   1334 									{
   1335 									F.precision = F.fieldWidth;
   1336 									if (F.altForm) F.precision -= 2;
   1337 									if (F.sign) --F.precision;
   1338 									}
   1339 								if (F.precision < 1) F.precision = 1;
   1340 								}
   1341 							if (F.precision > mDNS_VACB_Size - 1)
   1342 								F.precision = mDNS_VACB_Size - 1;
   1343 							for (i = 0; n; n /= base, i++) *--s = (char)(digits[n % base]);
   1344 							for (; i < F.precision; i++) *--s = '0';
   1345 							if (F.altForm) { *--s = (char)c; *--s = '0'; i += 2; }
   1346 							if (F.sign) { *--s = F.sign; i++; }
   1347 							break;
   1348 
   1349 				case 'a' :	{
   1350 							unsigned char *a = va_arg(arg, unsigned char *);
   1351 							char pre[4] = "";
   1352 							char post[32] = "";
   1353 							if (!a) { static char emsg[] = "<<NULL>>"; s = emsg; i = sizeof(emsg)-1; }
   1354 							else
   1355 								{
   1356 								s = mDNS_VACB;	// Adjust s to point to the start of the buffer, not the end
   1357 								if (F.altForm == 1)
   1358 									{
   1359 									#if(defined(MDNS_DEBUGMSGS))
   1360 										mDNSAddr *ip = (mDNSAddr*)a;
   1361 										switch (ip->type)
   1362 											{
   1363 											case mDNSAddrType_IPv4: F.precision =  4; a = (unsigned char *)&ip->ip.v4; break;
   1364 											case mDNSAddrType_IPv6: F.precision = 16; a = (unsigned char *)&ip->ip.v6; break;
   1365 											default:                F.precision =  0; break;
   1366 											}
   1367 									#else
   1368 										F.precision = 0;	// mDNSEmbeddedAPI.h not included so no mDNSAddr support
   1369 									#endif
   1370 									}
   1371 								else if (F.altForm == 2)
   1372 									{
   1373 									#ifdef AF_INET
   1374 										const struct sockaddr *sa;
   1375 										unsigned char *port;
   1376 										sa = (const struct sockaddr*)a;
   1377 										switch (sa->sa_family)
   1378 											{
   1379 											case AF_INET:  F.precision =  4; a = (unsigned char*)&((const struct sockaddr_in *)a)->sin_addr;
   1380 											               port = (unsigned char*)&((const struct sockaddr_in *)sa)->sin_port;
   1381 											               DebugSNPrintF(post, sizeof(post), ":%d", (port[0] << 8) | port[1]); break;
   1382 											#ifdef AF_INET6
   1383 											case AF_INET6: F.precision = 16; a = (unsigned char*)&((const struct sockaddr_in6 *)a)->sin6_addr;
   1384 											               pre[0] = '['; pre[1] = '\0';
   1385 											               port = (unsigned char*)&((const struct sockaddr_in6 *)sa)->sin6_port;
   1386 											               DebugSNPrintF(post, sizeof(post), "%%%d]:%d",
   1387 											               		(int)((const struct sockaddr_in6 *)sa)->sin6_scope_id,
   1388 											               		(port[0] << 8) | port[1]); break;
   1389 											#endif
   1390 											default:       F.precision =  0; break;
   1391 											}
   1392 									#else
   1393 										F.precision = 0;	// socket interfaces not included so no sockaddr support
   1394 									#endif
   1395 									}
   1396 								switch (F.precision)
   1397 									{
   1398 									case  4: i = DebugSNPrintF(mDNS_VACB, sizeof(mDNS_VACB), "%d.%d.%d.%d%s",
   1399 														a[0], a[1], a[2], a[3], post); break;
   1400 									case  6: i = DebugSNPrintF(mDNS_VACB, sizeof(mDNS_VACB), "%02X:%02X:%02X:%02X:%02X:%02X",
   1401 														a[0], a[1], a[2], a[3], a[4], a[5]); break;
   1402 									case  8: i = DebugSNPrintF(mDNS_VACB, sizeof(mDNS_VACB), "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
   1403 														a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]); break;
   1404 									case 16: i = DebugSNPrintF(mDNS_VACB, sizeof(mDNS_VACB),
   1405 														"%s%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X%s",
   1406 														pre, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8],
   1407 														a[9], a[10], a[11], a[12], a[13], a[14], a[15], post); break;
   1408 									default: i = DebugSNPrintF(mDNS_VACB, sizeof(mDNS_VACB), "%s", "<< ERROR: Must specify address size "
   1409 														"(i.e. %.4a=IPv4, %.6a=Ethernet, %.8a=Fibre Channel %.16a=IPv6) >>"); break;
   1410 									}
   1411 								}
   1412 							}
   1413 							break;
   1414 
   1415 				case 'U' :	{
   1416 							unsigned char *a = va_arg(arg, unsigned char *);
   1417 							if (!a) { static char emsg[] = "<<NULL>>"; s = emsg; i = sizeof(emsg)-1; }
   1418 							else
   1419 								{
   1420 								s = mDNS_VACB;	// Adjust s to point to the start of the buffer, not the end
   1421 								i = DebugSNPrintF(mDNS_VACB, sizeof(mDNS_VACB), "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
   1422 										*((uint32_t*) &a[0]), *((uint16_t*) &a[4]), *((uint16_t*) &a[6]),
   1423 										a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); break;
   1424 								}
   1425 							}
   1426 							break;
   1427 
   1428 				case 'c' :	*--s = (char)va_arg(arg, int); i = 1; break;
   1429 
   1430 				case 'C' :	if (F.lSize) n = va_arg(arg, unsigned long);
   1431 							else n = va_arg(arg, unsigned int);
   1432 							if (F.hSize) n = (unsigned short) n;
   1433 							c = (int)( n        & 0xFF); *--s = (char)(DebugIsPrint(c) ? c : '^');
   1434 							c = (int)((n >>  8) & 0xFF); *--s = (char)(DebugIsPrint(c) ? c : '^');
   1435 							c = (int)((n >> 16) & 0xFF); *--s = (char)(DebugIsPrint(c) ? c : '^');
   1436 							c = (int)((n >> 24) & 0xFF); *--s = (char)(DebugIsPrint(c) ? c : '^');
   1437 							i = 4;
   1438 							break;
   1439 
   1440 				case 's' :	s = va_arg(arg, char *);
   1441 							if (!s) { static char emsg[] = "<<NULL>>"; s = emsg; i = sizeof(emsg)-1; }
   1442 							else switch (F.altForm)
   1443 								{
   1444 								case 0:	i=0;
   1445 										if (F.havePrecision)				// C string
   1446 											{
   1447 											while((i < F.precision) && s[i]) i++;
   1448 											// Make sure we don't truncate in the middle of a UTF-8 character.
   1449 											// If the last character is part of a multi-byte UTF-8 character, back up to the start of it.
   1450 											j=0;
   1451 											while((i > 0) && ((c = s[i-1]) & 0x80)) { j++; i--; if((c & 0xC0) != 0x80) break; }
   1452 											// If the actual count of UTF-8 characters matches the encoded UTF-8 count, add it back.
   1453 											if((j > 1) && (j <= 6))
   1454 												{
   1455 												int test = (0xFF << (8-j)) & 0xFF;
   1456 												int mask = test | (1 << ((8-j)-1));
   1457 												if((c & mask) == test) i += j;
   1458 												}
   1459 											}
   1460 										else
   1461 											while(s[i]) i++;
   1462 										break;
   1463 								case 1: i = (unsigned char) *s++; break;	// Pascal string
   1464 								case 2: {									// DNS label-sequence name
   1465 										unsigned char *a = (unsigned char *)s;
   1466 										s = mDNS_VACB;	// Adjust s to point to the start of the buffer, not the end
   1467 										if (*a == 0) *s++ = '.';	// Special case for root DNS name
   1468 										while (*a)
   1469 											{
   1470 											if (*a > 63) { s += DebugSNPrintF(s, mDNS_VACB_Remain(s), "<<INVALID LABEL LENGTH %u>>", *a); break; }
   1471 											if (s + *a >= &mDNS_VACB[254]) { s += DebugSNPrintF(s, mDNS_VACB_Remain(s), "<<NAME TOO LONG>>"); break; }
   1472 											s += DebugSNPrintF(s, mDNS_VACB_Remain(s), "%#s.", a);
   1473 											a += 1 + *a;
   1474 											}
   1475 										i = (size_t)(s - mDNS_VACB);
   1476 										s = mDNS_VACB;	// Reset s back to the start of the buffer
   1477 										break;
   1478 										}
   1479 								}
   1480 							if (F.havePrecision && i > F.precision)		// Make sure we don't truncate in the middle of a UTF-8 character
   1481 								{ i = F.precision; while (i>0 && (s[i] & 0xC0) == 0x80) i--; }
   1482 							break;
   1483 
   1484 				case 'S':	{	// UTF-16 string
   1485 							unsigned char *a = va_arg(arg, unsigned char *);
   1486 							uint16_t      *u = (uint16_t*)a;
   1487 							if (!u) { static char emsg[] = "<<NULL>>"; s = emsg; i = sizeof(emsg)-1; }
   1488 							if ((!F.havePrecision || F.precision))
   1489 								{
   1490 								if      ((a[0] == 0xFE) && (a[1] == 0xFF)) { F.altForm = 1; u += 1; a += 2; F.precision--; }	// Big Endian
   1491 								else if ((a[0] == 0xFF) && (a[1] == 0xFE)) { F.altForm = 2; u += 1; a += 2; F.precision--; }	// Little Endian
   1492 								}
   1493 							s = mDNS_VACB;	// Adjust s to point to the start of the buffer, not the end
   1494 							switch (F.altForm)
   1495 								{
   1496 								case 0:	while ((!F.havePrecision || (i < F.precision)) && u[i] && mDNS_VACB_Remain(s))	// Host Endian
   1497 											{ c = u[i]; *s++ = (char)(DebugIsPrint(c) ? c : '^'); i++; }
   1498 										break;
   1499 								case 1: while ((!F.havePrecision || (i < F.precision)) && u[i] && mDNS_VACB_Remain(s))	// Big Endian
   1500 											{ c = ((a[0] << 8) | a[1]) & 0xFF; *s++ = (char)(DebugIsPrint(c) ? c : '^'); i++; a += 2; }
   1501 										break;
   1502 								case 2: while ((!F.havePrecision || (i < F.precision)) && u[i] && mDNS_VACB_Remain(s))	// Little Endian
   1503 											{ c = ((a[1] << 8) | a[0]) & 0xFF; *s++ = (char)(DebugIsPrint(c) ? c : '^'); i++; a += 2; }
   1504 										break;
   1505 								}
   1506 							}
   1507 							s = mDNS_VACB;	// Reset s back to the start of the buffer
   1508 							break;
   1509 
   1510 			#if TARGET_OS_MAC
   1511 				case '@':	{	// Cocoa/CoreFoundation object
   1512 							CFTypeRef cfObj;
   1513 							CFStringRef cfStr;
   1514 							cfObj = (CFTypeRef) va_arg(arg, void *);
   1515 							cfStr = (CFGetTypeID(cfObj) == CFStringGetTypeID()) ? (CFStringRef)CFRetain(cfObj) : CFCopyDescription(cfObj);
   1516 							s = mDNS_VACB;	// Adjust s to point to the start of the buffer, not the end
   1517 							if (cfStr)
   1518 								{
   1519 								CFRange range;
   1520 								CFIndex m;
   1521 								range = CFRangeMake(0, CFStringGetLength(cfStr));
   1522 								m = 0;
   1523 								CFStringGetBytes(cfStr, range, kCFStringEncodingUTF8, '^', false, (UInt8*)mDNS_VACB, (CFIndex)sizeof(mDNS_VACB), &m);
   1524 								CFRelease(cfStr);
   1525 								i = (size_t) m;
   1526 								}
   1527 							else
   1528 								{
   1529 								i = DebugSNPrintF(mDNS_VACB, sizeof(mDNS_VACB), "%s", "ERROR: <invalid CF object>" );
   1530 								}
   1531 							}
   1532 							if (F.havePrecision && i > F.precision)		// Make sure we don't truncate in the middle of a UTF-8 character
   1533 								{ i = F.precision; while (i>0 && (s[i] & 0xC0) == 0x80) i--; }
   1534 							break;
   1535 			#endif
   1536 
   1537 				case 'm' :	{	// Error Message
   1538 							long err;
   1539 							if (F.lSize) err = va_arg(arg, long);
   1540 							else err = va_arg(arg, int);
   1541 							if (F.hSize) err = (short)err;
   1542 							DebugGetErrorString(err, mDNS_VACB, sizeof(mDNS_VACB));
   1543 							s = mDNS_VACB;	// Adjust s to point to the start of the buffer, not the end
   1544 							for(i=0;s[i];i++) {}
   1545 							}
   1546 							break;
   1547 
   1548 				case 'H' :	{	// Hex Dump
   1549 							void *a = va_arg(arg, void *);
   1550 							size_t size = (size_t)va_arg(arg, int);
   1551 							size_t max = (size_t)va_arg(arg, int);
   1552 							DebugFlags flags =
   1553 								kDebugFlagsNoAddress | kDebugFlagsNoOffset | kDebugFlagsNoNewLine |
   1554 								kDebugFlags8BitSeparator | kDebugFlagsNo32BitSeparator |
   1555 								kDebugFlagsNo16ByteHexPad | kDebugFlagsNoByteCount;
   1556 							if (F.altForm == 0) flags |= kDebugFlagsNoASCII;
   1557 							size = (max < size) ? max : size;
   1558 							s = mDNS_VACB;	// Adjust s to point to the start of the buffer, not the end
   1559 							i = DebugHexDump(kDebugLevelMax, 0, NULL, 0, 0, NULL, 0, a, a, size, flags, mDNS_VACB, sizeof(mDNS_VACB));
   1560 							}
   1561 							break;
   1562 
   1563 				case 'v' :	{	// Version
   1564 							uint32_t version;
   1565 							version = va_arg(arg, unsigned int);
   1566 							DebugNumVersionToString(version, mDNS_VACB);
   1567 							s = mDNS_VACB;	// Adjust s to point to the start of the buffer, not the end
   1568 							for(i=0;s[i];i++) {}
   1569 							}
   1570 							break;
   1571 
   1572 				case 'n' :	s = va_arg(arg, char *);
   1573 							if      (F.hSize) * (short *) s = (short)nwritten;
   1574 							else if (F.lSize) * (long  *) s = (long)nwritten;
   1575 							else              * (int   *) s = (int)nwritten;
   1576 							continue;
   1577 
   1578 				default:	s = mDNS_VACB;
   1579 							i = DebugSNPrintF(mDNS_VACB, sizeof(mDNS_VACB), "<<UNKNOWN FORMAT CONVERSION CODE %%%c>>", c);
   1580 
   1581 				case '%' :	*sbuffer++ = (char)c;
   1582 							if (++nwritten >= buflen) goto exit;
   1583 							break;
   1584 				}
   1585 
   1586 			if (i < F.fieldWidth && !F.leftJustify)			// Pad on the left
   1587 				do	{
   1588 					*sbuffer++ = ' ';
   1589 					if (++nwritten >= buflen) goto exit;
   1590 					} while (i < --F.fieldWidth);
   1591 
   1592 			if (i > buflen - nwritten)	// Make sure we don't truncate in the middle of a UTF-8 character
   1593 				{ i = buflen - nwritten; while (i>0 && (s[i] & 0xC0) == 0x80) i--; }
   1594 			for (j=0; j<i; j++) *sbuffer++ = *s++;			// Write the converted result
   1595 			nwritten += i;
   1596 			if (nwritten >= buflen) goto exit;
   1597 
   1598 			for (; i < F.fieldWidth; i++)					// Pad on the right
   1599 				{
   1600 				*sbuffer++ = ' ';
   1601 				if (++nwritten >= buflen) goto exit;
   1602 				}
   1603 			}
   1604 		}
   1605 	exit:
   1606 	*sbuffer++ = 0;
   1607 	return(nwritten);
   1608 	}
   1609 
   1610 //===========================================================================================================================
   1611 //	DebugGetErrorString
   1612 //===========================================================================================================================
   1613 
   1614 DEBUG_EXPORT const char *	DebugGetErrorString( int_least32_t inErrorCode, char *inBuffer, size_t inBufferSize )
   1615 {
   1616 	const char *		s;
   1617 	char *				dst;
   1618 	char *				end;
   1619 #if( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
   1620 	char				buffer[ 256 ];
   1621 #endif
   1622 
   1623 	switch( inErrorCode )
   1624 	{
   1625 		#define	CaseErrorString( X, STR )					case X: s = STR; break
   1626 		#define	CaseErrorStringify( X )						case X: s = # X; break
   1627 		#define	CaseErrorStringifyHardCode( VALUE, X )		case VALUE: s = # X; break
   1628 
   1629 		// General Errors
   1630 
   1631 		CaseErrorString( 0,  "no error" );
   1632 		CaseErrorString( 1,  "in-progress/waiting" );
   1633 		CaseErrorString( -1, "catch-all unknown error" );
   1634 
   1635 		// ACP Errors
   1636 
   1637 		CaseErrorStringifyHardCode( -2,  kACPBadRequestErr );
   1638 		CaseErrorStringifyHardCode( -3,  kACPNoMemoryErr );
   1639 		CaseErrorStringifyHardCode( -4,  kACPBadParamErr );
   1640 		CaseErrorStringifyHardCode( -5,  kACPNotFoundErr );
   1641 		CaseErrorStringifyHardCode( -6,  kACPBadChecksumErr );
   1642 		CaseErrorStringifyHardCode( -7,  kACPCommandNotHandledErr );
   1643 		CaseErrorStringifyHardCode( -8,  kACPNetworkErr );
   1644 		CaseErrorStringifyHardCode( -9,  kACPDuplicateCommandHandlerErr );
   1645 		CaseErrorStringifyHardCode( -10, kACPUnknownPropertyErr );
   1646 		CaseErrorStringifyHardCode( -11, kACPImmutablePropertyErr );
   1647 		CaseErrorStringifyHardCode( -12, kACPBadPropertyValueErr );
   1648 		CaseErrorStringifyHardCode( -13, kACPNoResourcesErr );
   1649 		CaseErrorStringifyHardCode( -14, kACPBadOptionErr );
   1650 		CaseErrorStringifyHardCode( -15, kACPBadSizeErr );
   1651 		CaseErrorStringifyHardCode( -16, kACPBadPasswordErr );
   1652 		CaseErrorStringifyHardCode( -17, kACPNotInitializedErr );
   1653 		CaseErrorStringifyHardCode( -18, kACPNonReadablePropertyErr );
   1654 		CaseErrorStringifyHardCode( -19, kACPBadVersionErr );
   1655 		CaseErrorStringifyHardCode( -20, kACPBadSignatureErr );
   1656 		CaseErrorStringifyHardCode( -21, kACPBadIndexErr );
   1657 		CaseErrorStringifyHardCode( -22, kACPUnsupportedErr );
   1658 		CaseErrorStringifyHardCode( -23, kACPInUseErr );
   1659 		CaseErrorStringifyHardCode( -24, kACPParamCountErr );
   1660 		CaseErrorStringifyHardCode( -25, kACPIDErr );
   1661 		CaseErrorStringifyHardCode( -26, kACPFormatErr );
   1662 		CaseErrorStringifyHardCode( -27, kACPUnknownUserErr );
   1663 		CaseErrorStringifyHardCode( -28, kACPAccessDeniedErr );
   1664 		CaseErrorStringifyHardCode( -29, kACPIncorrectFWErr );
   1665 
   1666 		// Common Services Errors
   1667 
   1668 		CaseErrorStringify( kUnknownErr );
   1669 		CaseErrorStringify( kOptionErr );
   1670 		CaseErrorStringify( kSelectorErr );
   1671 		CaseErrorStringify( kExecutionStateErr );
   1672 		CaseErrorStringify( kPathErr );
   1673 		CaseErrorStringify( kParamErr );
   1674 		CaseErrorStringify( kParamCountErr );
   1675 		CaseErrorStringify( kCommandErr );
   1676 		CaseErrorStringify( kIDErr );
   1677 		CaseErrorStringify( kStateErr );
   1678 		CaseErrorStringify( kRangeErr );
   1679 		CaseErrorStringify( kRequestErr );
   1680 		CaseErrorStringify( kResponseErr );
   1681 		CaseErrorStringify( kChecksumErr );
   1682 		CaseErrorStringify( kNotHandledErr );
   1683 		CaseErrorStringify( kVersionErr );
   1684 		CaseErrorStringify( kSignatureErr );
   1685 		CaseErrorStringify( kFormatErr );
   1686 		CaseErrorStringify( kNotInitializedErr );
   1687 		CaseErrorStringify( kAlreadyInitializedErr );
   1688 		CaseErrorStringify( kNotInUseErr );
   1689 		CaseErrorStringify( kInUseErr );
   1690 		CaseErrorStringify( kTimeoutErr );
   1691 		CaseErrorStringify( kCanceledErr );
   1692 		CaseErrorStringify( kAlreadyCanceledErr );
   1693 		CaseErrorStringify( kCannotCancelErr );
   1694 		CaseErrorStringify( kDeletedErr );
   1695 		CaseErrorStringify( kNotFoundErr );
   1696 		CaseErrorStringify( kNoMemoryErr );
   1697 		CaseErrorStringify( kNoResourcesErr );
   1698 		CaseErrorStringify( kDuplicateErr );
   1699 		CaseErrorStringify( kImmutableErr );
   1700 		CaseErrorStringify( kUnsupportedDataErr );
   1701 		CaseErrorStringify( kIntegrityErr );
   1702 		CaseErrorStringify( kIncompatibleErr );
   1703 		CaseErrorStringify( kUnsupportedErr );
   1704 		CaseErrorStringify( kUnexpectedErr );
   1705 		CaseErrorStringify( kValueErr );
   1706 		CaseErrorStringify( kNotReadableErr );
   1707 		CaseErrorStringify( kNotWritableErr );
   1708 		CaseErrorStringify( kBadReferenceErr );
   1709 		CaseErrorStringify( kFlagErr );
   1710 		CaseErrorStringify( kMalformedErr );
   1711 		CaseErrorStringify( kSizeErr );
   1712 		CaseErrorStringify( kNameErr );
   1713 		CaseErrorStringify( kNotReadyErr );
   1714 		CaseErrorStringify( kReadErr );
   1715 		CaseErrorStringify( kWriteErr );
   1716 		CaseErrorStringify( kMismatchErr );
   1717 		CaseErrorStringify( kDateErr );
   1718 		CaseErrorStringify( kUnderrunErr );
   1719 		CaseErrorStringify( kOverrunErr );
   1720 		CaseErrorStringify( kEndingErr );
   1721 		CaseErrorStringify( kConnectionErr );
   1722 		CaseErrorStringify( kAuthenticationErr );
   1723 		CaseErrorStringify( kOpenErr );
   1724 		CaseErrorStringify( kTypeErr );
   1725 		CaseErrorStringify( kSkipErr );
   1726 		CaseErrorStringify( kNoAckErr );
   1727 		CaseErrorStringify( kCollisionErr );
   1728 		CaseErrorStringify( kBackoffErr );
   1729 		CaseErrorStringify( kNoAddressAckErr );
   1730 		CaseErrorStringify( kBusyErr );
   1731 		CaseErrorStringify( kNoSpaceErr );
   1732 
   1733 		// mDNS/DNS-SD Errors
   1734 
   1735 		CaseErrorStringifyHardCode( -65537, mStatus_UnknownErr );
   1736 		CaseErrorStringifyHardCode( -65538, mStatus_NoSuchNameErr );
   1737 		CaseErrorStringifyHardCode( -65539, mStatus_NoMemoryErr );
   1738 		CaseErrorStringifyHardCode( -65540, mStatus_BadParamErr );
   1739 		CaseErrorStringifyHardCode( -65541, mStatus_BadReferenceErr );
   1740 		CaseErrorStringifyHardCode( -65542, mStatus_BadStateErr );
   1741 		CaseErrorStringifyHardCode( -65543, mStatus_BadFlagsErr );
   1742 		CaseErrorStringifyHardCode( -65544, mStatus_UnsupportedErr );
   1743 		CaseErrorStringifyHardCode( -65545, mStatus_NotInitializedErr );
   1744 		CaseErrorStringifyHardCode( -65546, mStatus_NoCache );
   1745 		CaseErrorStringifyHardCode( -65547, mStatus_AlreadyRegistered );
   1746 		CaseErrorStringifyHardCode( -65548, mStatus_NameConflict );
   1747 		CaseErrorStringifyHardCode( -65549, mStatus_Invalid );
   1748 		CaseErrorStringifyHardCode( -65550, mStatus_GrowCache );
   1749 		CaseErrorStringifyHardCode( -65551, mStatus_BadInterfaceErr );
   1750 		CaseErrorStringifyHardCode( -65552, mStatus_Incompatible );
   1751 		CaseErrorStringifyHardCode( -65791, mStatus_ConfigChanged );
   1752 		CaseErrorStringifyHardCode( -65792, mStatus_MemFree );
   1753 
   1754 		// RSP Errors
   1755 
   1756 		CaseErrorStringifyHardCode( -400000, kRSPUnknownErr );
   1757 		CaseErrorStringifyHardCode( -400050, kRSPParamErr );
   1758 		CaseErrorStringifyHardCode( -400108, kRSPNoMemoryErr );
   1759 		CaseErrorStringifyHardCode( -405246, kRSPRangeErr );
   1760 		CaseErrorStringifyHardCode( -409057, kRSPSizeErr );
   1761 		CaseErrorStringifyHardCode( -400200, kRSPHardwareErr );
   1762 		CaseErrorStringifyHardCode( -401712, kRSPTimeoutErr );
   1763 		CaseErrorStringifyHardCode( -402053, kRSPUnsupportedErr );
   1764 		CaseErrorStringifyHardCode( -402419, kRSPIDErr );
   1765 		CaseErrorStringifyHardCode( -403165, kRSPFlagErr );
   1766 		CaseErrorString( 			-200000, "kRSPControllerStatusBase - 0x50" );
   1767 		CaseErrorString(			-200080, "kRSPCommandSucceededErr - 0x50" );
   1768 		CaseErrorString( 			-200001, "kRSPCommandFailedErr - 0x01" );
   1769 		CaseErrorString( 			-200051, "kRSPChecksumErr - 0x33" );
   1770 		CaseErrorString( 			-200132, "kRSPCommandTimeoutErr - 0x84" );
   1771 		CaseErrorString( 			-200034, "kRSPPasswordRequiredErr - 0x22 OBSOLETE" );
   1772 		CaseErrorString( 			-200128, "kRSPCanceledErr - 0x02 Async" );
   1773 
   1774 		// XML Errors
   1775 
   1776 		CaseErrorStringifyHardCode( -100043, kXMLNotFoundErr );
   1777 		CaseErrorStringifyHardCode( -100050, kXMLParamErr );
   1778 		CaseErrorStringifyHardCode( -100108, kXMLNoMemoryErr );
   1779 		CaseErrorStringifyHardCode( -100206, kXMLFormatErr );
   1780 		CaseErrorStringifyHardCode( -100586, kXMLNoRootElementErr );
   1781 		CaseErrorStringifyHardCode( -101703, kXMLWrongDataTypeErr );
   1782 		CaseErrorStringifyHardCode( -101726, kXMLKeyErr );
   1783 		CaseErrorStringifyHardCode( -102053, kXMLUnsupportedErr );
   1784 		CaseErrorStringifyHardCode( -102063, kXMLMissingElementErr );
   1785 		CaseErrorStringifyHardCode( -103026, kXMLParseErr );
   1786 		CaseErrorStringifyHardCode( -103159, kXMLBadDataErr );
   1787 		CaseErrorStringifyHardCode( -103170, kXMLBadNameErr );
   1788 		CaseErrorStringifyHardCode( -105246, kXMLRangeErr );
   1789 		CaseErrorStringifyHardCode( -105251, kXMLUnknownElementErr );
   1790 		CaseErrorStringifyHardCode( -108739, kXMLMalformedInputErr );
   1791 		CaseErrorStringifyHardCode( -109057, kXMLBadSizeErr );
   1792 		CaseErrorStringifyHardCode( -101730, kXMLMissingChildElementErr );
   1793 		CaseErrorStringifyHardCode( -102107, kXMLMissingParentElementErr );
   1794 		CaseErrorStringifyHardCode( -130587, kXMLNonRootElementErr );
   1795 		CaseErrorStringifyHardCode( -102015, kXMLDateErr );
   1796 
   1797 	#if( __MACH__ )
   1798 
   1799 		// Mach Errors
   1800 
   1801 		CaseErrorStringifyHardCode( 0x00002000, MACH_MSG_IPC_SPACE );
   1802 		CaseErrorStringifyHardCode( 0x00001000, MACH_MSG_VM_SPACE );
   1803 		CaseErrorStringifyHardCode( 0x00000800, MACH_MSG_IPC_KERNEL );
   1804 		CaseErrorStringifyHardCode( 0x00000400, MACH_MSG_VM_KERNEL );
   1805 		CaseErrorStringifyHardCode( 0x10000001, MACH_SEND_IN_PROGRESS );
   1806 		CaseErrorStringifyHardCode( 0x10000002, MACH_SEND_INVALID_DATA );
   1807 		CaseErrorStringifyHardCode( 0x10000003, MACH_SEND_INVALID_DEST );
   1808 		CaseErrorStringifyHardCode( 0x10000004, MACH_SEND_TIMED_OUT );
   1809 		CaseErrorStringifyHardCode( 0x10000007, MACH_SEND_INTERRUPTED );
   1810 		CaseErrorStringifyHardCode( 0x10000008, MACH_SEND_MSG_TOO_SMALL );
   1811 		CaseErrorStringifyHardCode( 0x10000009, MACH_SEND_INVALID_REPLY );
   1812 		CaseErrorStringifyHardCode( 0x1000000A, MACH_SEND_INVALID_RIGHT );
   1813 		CaseErrorStringifyHardCode( 0x1000000B, MACH_SEND_INVALID_NOTIFY );
   1814 		CaseErrorStringifyHardCode( 0x1000000C, MACH_SEND_INVALID_MEMORY );
   1815 		CaseErrorStringifyHardCode( 0x1000000D, MACH_SEND_NO_BUFFER );
   1816 		CaseErrorStringifyHardCode( 0x1000000E, MACH_SEND_TOO_LARGE );
   1817 		CaseErrorStringifyHardCode( 0x1000000F, MACH_SEND_INVALID_TYPE );
   1818 		CaseErrorStringifyHardCode( 0x10000010, MACH_SEND_INVALID_HEADER );
   1819 		CaseErrorStringifyHardCode( 0x10000011, MACH_SEND_INVALID_TRAILER );
   1820 		CaseErrorStringifyHardCode( 0x10000015, MACH_SEND_INVALID_RT_OOL_SIZE );
   1821 		CaseErrorStringifyHardCode( 0x10004001, MACH_RCV_IN_PROGRESS );
   1822 		CaseErrorStringifyHardCode( 0x10004002, MACH_RCV_INVALID_NAME );
   1823 		CaseErrorStringifyHardCode( 0x10004003, MACH_RCV_TIMED_OUT );
   1824 		CaseErrorStringifyHardCode( 0x10004004, MACH_RCV_TOO_LARGE );
   1825 		CaseErrorStringifyHardCode( 0x10004005, MACH_RCV_INTERRUPTED );
   1826 		CaseErrorStringifyHardCode( 0x10004006, MACH_RCV_PORT_CHANGED );
   1827 		CaseErrorStringifyHardCode( 0x10004007, MACH_RCV_INVALID_NOTIFY );
   1828 		CaseErrorStringifyHardCode( 0x10004008, MACH_RCV_INVALID_DATA );
   1829 		CaseErrorStringifyHardCode( 0x10004009, MACH_RCV_PORT_DIED );
   1830 		CaseErrorStringifyHardCode( 0x1000400A, MACH_RCV_IN_SET );
   1831 		CaseErrorStringifyHardCode( 0x1000400B, MACH_RCV_HEADER_ERROR );
   1832 		CaseErrorStringifyHardCode( 0x1000400C, MACH_RCV_BODY_ERROR );
   1833 		CaseErrorStringifyHardCode( 0x1000400D, MACH_RCV_INVALID_TYPE );
   1834 		CaseErrorStringifyHardCode( 0x1000400E, MACH_RCV_SCATTER_SMALL );
   1835 		CaseErrorStringifyHardCode( 0x1000400F, MACH_RCV_INVALID_TRAILER );
   1836 		CaseErrorStringifyHardCode( 0x10004011, MACH_RCV_IN_PROGRESS_TIMED );
   1837 
   1838 		// Mach OSReturn Errors
   1839 
   1840 		CaseErrorStringifyHardCode( 0xDC000001, kOSReturnError );
   1841 		CaseErrorStringifyHardCode( 0xDC004001, kOSMetaClassInternal );
   1842 		CaseErrorStringifyHardCode( 0xDC004002, kOSMetaClassHasInstances );
   1843 		CaseErrorStringifyHardCode( 0xDC004003, kOSMetaClassNoInit );
   1844 		CaseErrorStringifyHardCode( 0xDC004004, kOSMetaClassNoTempData );
   1845 		CaseErrorStringifyHardCode( 0xDC004005, kOSMetaClassNoDicts );
   1846 		CaseErrorStringifyHardCode( 0xDC004006, kOSMetaClassNoKModSet );
   1847 		CaseErrorStringifyHardCode( 0xDC004007, kOSMetaClassNoInsKModSet );
   1848 		CaseErrorStringifyHardCode( 0xDC004008, kOSMetaClassNoSuper );
   1849 		CaseErrorStringifyHardCode( 0xDC004009, kOSMetaClassInstNoSuper );
   1850 		CaseErrorStringifyHardCode( 0xDC00400A, kOSMetaClassDuplicateClass );
   1851 
   1852 		// IOKit Errors
   1853 
   1854 		CaseErrorStringifyHardCode( 0xE00002BC, kIOReturnError );
   1855 		CaseErrorStringifyHardCode( 0xE00002BD, kIOReturnNoMemory );
   1856 		CaseErrorStringifyHardCode( 0xE00002BE, kIOReturnNoResources );
   1857 		CaseErrorStringifyHardCode( 0xE00002BF, kIOReturnIPCError );
   1858 		CaseErrorStringifyHardCode( 0xE00002C0, kIOReturnNoDevice );
   1859 		CaseErrorStringifyHardCode( 0xE00002C1, kIOReturnNotPrivileged );
   1860 		CaseErrorStringifyHardCode( 0xE00002C2, kIOReturnBadArgument );
   1861 		CaseErrorStringifyHardCode( 0xE00002C3, kIOReturnLockedRead );
   1862 		CaseErrorStringifyHardCode( 0xE00002C4, kIOReturnLockedWrite );
   1863 		CaseErrorStringifyHardCode( 0xE00002C5, kIOReturnExclusiveAccess );
   1864 		CaseErrorStringifyHardCode( 0xE00002C6, kIOReturnBadMessageID );
   1865 		CaseErrorStringifyHardCode( 0xE00002C7, kIOReturnUnsupported );
   1866 		CaseErrorStringifyHardCode( 0xE00002C8, kIOReturnVMError );
   1867 		CaseErrorStringifyHardCode( 0xE00002C9, kIOReturnInternalError );
   1868 		CaseErrorStringifyHardCode( 0xE00002CA, kIOReturnIOError );
   1869 		CaseErrorStringifyHardCode( 0xE00002CC, kIOReturnCannotLock );
   1870 		CaseErrorStringifyHardCode( 0xE00002CD, kIOReturnNotOpen );
   1871 		CaseErrorStringifyHardCode( 0xE00002CE, kIOReturnNotReadable );
   1872 		CaseErrorStringifyHardCode( 0xE00002CF, kIOReturnNotWritable );
   1873 		CaseErrorStringifyHardCode( 0xE00002D0, kIOReturnNotAligned );
   1874 		CaseErrorStringifyHardCode( 0xE00002D1, kIOReturnBadMedia );
   1875 		CaseErrorStringifyHardCode( 0xE00002D2, kIOReturnStillOpen );
   1876 		CaseErrorStringifyHardCode( 0xE00002D3, kIOReturnRLDError );
   1877 		CaseErrorStringifyHardCode( 0xE00002D4, kIOReturnDMAError );
   1878 		CaseErrorStringifyHardCode( 0xE00002D5, kIOReturnBusy );
   1879 		CaseErrorStringifyHardCode( 0xE00002D6, kIOReturnTimeout );
   1880 		CaseErrorStringifyHardCode( 0xE00002D7, kIOReturnOffline );
   1881 		CaseErrorStringifyHardCode( 0xE00002D8, kIOReturnNotReady );
   1882 		CaseErrorStringifyHardCode( 0xE00002D9, kIOReturnNotAttached );
   1883 		CaseErrorStringifyHardCode( 0xE00002DA, kIOReturnNoChannels );
   1884 		CaseErrorStringifyHardCode( 0xE00002DB, kIOReturnNoSpace );
   1885 		CaseErrorStringifyHardCode( 0xE00002DD, kIOReturnPortExists );
   1886 		CaseErrorStringifyHardCode( 0xE00002DE, kIOReturnCannotWire );
   1887 		CaseErrorStringifyHardCode( 0xE00002DF, kIOReturnNoInterrupt );
   1888 		CaseErrorStringifyHardCode( 0xE00002E0, kIOReturnNoFrames );
   1889 		CaseErrorStringifyHardCode( 0xE00002E1, kIOReturnMessageTooLarge );
   1890 		CaseErrorStringifyHardCode( 0xE00002E2, kIOReturnNotPermitted );
   1891 		CaseErrorStringifyHardCode( 0xE00002E3, kIOReturnNoPower );
   1892 		CaseErrorStringifyHardCode( 0xE00002E4, kIOReturnNoMedia );
   1893 		CaseErrorStringifyHardCode( 0xE00002E5, kIOReturnUnformattedMedia );
   1894 		CaseErrorStringifyHardCode( 0xE00002E6, kIOReturnUnsupportedMode );
   1895 		CaseErrorStringifyHardCode( 0xE00002E7, kIOReturnUnderrun );
   1896 		CaseErrorStringifyHardCode( 0xE00002E8, kIOReturnOverrun );
   1897 		CaseErrorStringifyHardCode( 0xE00002E9, kIOReturnDeviceError	 );
   1898 		CaseErrorStringifyHardCode( 0xE00002EA, kIOReturnNoCompletion	 );
   1899 		CaseErrorStringifyHardCode( 0xE00002EB, kIOReturnAborted	 );
   1900 		CaseErrorStringifyHardCode( 0xE00002EC, kIOReturnNoBandwidth	 );
   1901 		CaseErrorStringifyHardCode( 0xE00002ED, kIOReturnNotResponding	 );
   1902 		CaseErrorStringifyHardCode( 0xE00002EE, kIOReturnIsoTooOld	 );
   1903 		CaseErrorStringifyHardCode( 0xE00002EF, kIOReturnIsoTooNew	 );
   1904 		CaseErrorStringifyHardCode( 0xE00002F0, kIOReturnNotFound );
   1905 		CaseErrorStringifyHardCode( 0xE0000001, kIOReturnInvalid );
   1906 
   1907 		// IOKit FireWire Errors
   1908 
   1909 		CaseErrorStringifyHardCode( 0xE0008010, kIOFireWireResponseBase );
   1910 		CaseErrorStringifyHardCode( 0xE0008020, kIOFireWireBusReset );
   1911 		CaseErrorStringifyHardCode( 0xE0008001, kIOConfigNoEntry );
   1912 		CaseErrorStringifyHardCode( 0xE0008002, kIOFireWirePending );
   1913 		CaseErrorStringifyHardCode( 0xE0008003, kIOFireWireLastDCLToken );
   1914 		CaseErrorStringifyHardCode( 0xE0008004, kIOFireWireConfigROMInvalid );
   1915 		CaseErrorStringifyHardCode( 0xE0008005, kIOFireWireAlreadyRegistered );
   1916 		CaseErrorStringifyHardCode( 0xE0008006, kIOFireWireMultipleTalkers );
   1917 		CaseErrorStringifyHardCode( 0xE0008007, kIOFireWireChannelActive );
   1918 		CaseErrorStringifyHardCode( 0xE0008008, kIOFireWireNoListenerOrTalker );
   1919 		CaseErrorStringifyHardCode( 0xE0008009, kIOFireWireNoChannels );
   1920 		CaseErrorStringifyHardCode( 0xE000800A, kIOFireWireChannelNotAvailable );
   1921 		CaseErrorStringifyHardCode( 0xE000800B, kIOFireWireSeparateBus );
   1922 		CaseErrorStringifyHardCode( 0xE000800C, kIOFireWireBadSelfIDs );
   1923 		CaseErrorStringifyHardCode( 0xE000800D, kIOFireWireLowCableVoltage );
   1924 		CaseErrorStringifyHardCode( 0xE000800E, kIOFireWireInsufficientPower );
   1925 		CaseErrorStringifyHardCode( 0xE000800F, kIOFireWireOutOfTLabels );
   1926 		CaseErrorStringifyHardCode( 0xE0008101, kIOFireWireBogusDCLProgram );
   1927 		CaseErrorStringifyHardCode( 0xE0008102, kIOFireWireTalkingAndListening );
   1928 		CaseErrorStringifyHardCode( 0xE0008103, kIOFireWireHardwareSlept );
   1929 		CaseErrorStringifyHardCode( 0xE00087D0, kIOFWMessageServiceIsRequestingClose );
   1930 		CaseErrorStringifyHardCode( 0xE00087D1, kIOFWMessagePowerStateChanged );
   1931 		CaseErrorStringifyHardCode( 0xE00087D2, kIOFWMessageTopologyChanged );
   1932 
   1933 		// IOKit USB Errors
   1934 
   1935 		CaseErrorStringifyHardCode( 0xE0004061, kIOUSBUnknownPipeErr );
   1936 		CaseErrorStringifyHardCode( 0xE0004060, kIOUSBTooManyPipesErr );
   1937 		CaseErrorStringifyHardCode( 0xE000405F, kIOUSBNoAsyncPortErr );
   1938 		CaseErrorStringifyHardCode( 0xE000405E, kIOUSBNotEnoughPipesErr );
   1939 		CaseErrorStringifyHardCode( 0xE000405D, kIOUSBNotEnoughPowerErr );
   1940 		CaseErrorStringifyHardCode( 0xE0004057, kIOUSBEndpointNotFound );
   1941 		CaseErrorStringifyHardCode( 0xE0004056, kIOUSBConfigNotFound );
   1942 		CaseErrorStringifyHardCode( 0xE0004051, kIOUSBTransactionTimeout );
   1943 		CaseErrorStringifyHardCode( 0xE0004050, kIOUSBTransactionReturned );
   1944 		CaseErrorStringifyHardCode( 0xE000404F, kIOUSBPipeStalled );
   1945 		CaseErrorStringifyHardCode( 0xE000404E, kIOUSBInterfaceNotFound );
   1946 		CaseErrorStringifyHardCode( 0xE000404D, kIOUSBLowLatencyBufferNotPreviouslyAllocated );
   1947 		CaseErrorStringifyHardCode( 0xE000404C, kIOUSBLowLatencyFrameListNotPreviouslyAllocated );
   1948 		CaseErrorStringifyHardCode( 0xE000404B, kIOUSBHighSpeedSplitError );
   1949 		CaseErrorStringifyHardCode( 0xE0004010, kIOUSBLinkErr );
   1950 		CaseErrorStringifyHardCode( 0xE000400F, kIOUSBNotSent2Err );
   1951 		CaseErrorStringifyHardCode( 0xE000400E, kIOUSBNotSent1Err );
   1952 		CaseErrorStringifyHardCode( 0xE000400D, kIOUSBBufferUnderrunErr );
   1953 		CaseErrorStringifyHardCode( 0xE000400C, kIOUSBBufferOverrunErr );
   1954 		CaseErrorStringifyHardCode( 0xE000400B, kIOUSBReserved2Err );
   1955 		CaseErrorStringifyHardCode( 0xE000400A, kIOUSBReserved1Err );
   1956 		CaseErrorStringifyHardCode( 0xE0004007, kIOUSBWrongPIDErr );
   1957 		CaseErrorStringifyHardCode( 0xE0004006, kIOUSBPIDCheckErr );
   1958 		CaseErrorStringifyHardCode( 0xE0004003, kIOUSBDataToggleErr );
   1959 		CaseErrorStringifyHardCode( 0xE0004002, kIOUSBBitstufErr );
   1960 		CaseErrorStringifyHardCode( 0xE0004001, kIOUSBCRCErr );
   1961 
   1962 	#endif	// __MACH__
   1963 
   1964 		// Other Errors
   1965 
   1966 		default:
   1967 			s = NULL;
   1968 			#if( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
   1969 				if( inBuffer && ( inBufferSize > 0 ) )
   1970 				{
   1971 					DWORD		n;
   1972 
   1973 					n = FormatMessageA( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, (DWORD) inErrorCode,
   1974 						MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), buffer, sizeof( buffer ), NULL );
   1975 					if( n > 0 )
   1976 					{
   1977 						// Remove any trailing CR's or LF's since some messages have them.
   1978 
   1979 						while( ( n > 0 ) && isspace( ( (unsigned char *) buffer )[ n - 1 ] ) )
   1980 						{
   1981 							buffer[ --n ] = '\0';
   1982 						}
   1983 						s = buffer;
   1984 					}
   1985 				}
   1986 			#endif
   1987 
   1988 			if( !s )
   1989 			{
   1990 				#if( !TARGET_API_MAC_OSX_KERNEL && !TARGET_OS_WINDOWS_CE )
   1991 					s = strerror( inErrorCode );
   1992 				#endif
   1993 				if( !s )
   1994 				{
   1995 					s = "<unknown error code>";
   1996 				}
   1997 			}
   1998 			break;
   1999 	}
   2000 
   2001 	// Copy the string to the output buffer. If no buffer is supplied or it is empty, return an empty string.
   2002 
   2003 	if( inBuffer && ( inBufferSize > 0 ) )
   2004 	{
   2005 		dst = inBuffer;
   2006 		end = dst + ( inBufferSize - 1 );
   2007 		while( ( ( end - dst ) > 0 ) && ( *s != '\0' ) )
   2008 		{
   2009 			*dst++ = *s++;
   2010 		}
   2011 		*dst = '\0';
   2012 		s = inBuffer;
   2013 	}
   2014 	return( s );
   2015 }
   2016 
   2017 //===========================================================================================================================
   2018 //	DebugHexDump
   2019 //===========================================================================================================================
   2020 
   2021 DEBUG_EXPORT size_t
   2022 	DebugHexDump(
   2023 		DebugLevel		inLevel,
   2024 		int				inIndent,
   2025 		const char * 	inLabel,
   2026 		size_t 			inLabelSize,
   2027 		int				inLabelMinWidth,
   2028 		const char *	inType,
   2029 		size_t 			inTypeSize,
   2030 		const void *	inDataStart,
   2031 		const void *	inData,
   2032 		size_t 			inDataSize,
   2033 		DebugFlags	 	inFlags,
   2034 		char *			outBuffer,
   2035 		size_t			inBufferSize )
   2036 {
   2037 	static const char		kHexChars[] = "0123456789ABCDEF";
   2038 	const uint8_t *			start;
   2039 	const uint8_t *			src;
   2040 	char *					dst;
   2041 	char *					end;
   2042 	size_t					n;
   2043 	int						offset;
   2044 	int						width;
   2045 	const char *			newline;
   2046 	char					separator[ 8 ];
   2047 	char *					s;
   2048 
   2049 	DEBUG_UNUSED( inType );
   2050 	DEBUG_UNUSED( inTypeSize );
   2051 
   2052 	// Set up the function-wide variables.
   2053 
   2054 	if( inLabelSize == kSizeCString )
   2055 	{
   2056 		inLabelSize = strlen( inLabel );
   2057 	}
   2058 	start 	= (const uint8_t *) inData;
   2059 	src 	= start;
   2060 	dst		= outBuffer;
   2061 	end		= dst + inBufferSize;
   2062 	offset 	= (int)( (intptr_t) inData - (intptr_t) inDataStart );
   2063 	width	= ( (int) inLabelSize > inLabelMinWidth ) ? (int) inLabelSize : inLabelMinWidth;
   2064 	newline	= ( inFlags & kDebugFlagsNoNewLine ) ? "" : "\n";
   2065 
   2066 	// Set up the separator string. This is used to insert spaces on subsequent "lines" when not using newlines.
   2067 
   2068 	s = separator;
   2069 	if( inFlags & kDebugFlagsNoNewLine )
   2070 	{
   2071 		if( inFlags & kDebugFlags8BitSeparator )
   2072 		{
   2073 			*s++ = ' ';
   2074 		}
   2075 		if( inFlags & kDebugFlags16BitSeparator )
   2076 		{
   2077 			*s++ = ' ';
   2078 		}
   2079 		if( !( inFlags & kDebugFlagsNo32BitSeparator ) )
   2080 		{
   2081 			*s++ = ' ';
   2082 		}
   2083 		check( ( (size_t)( s - separator ) ) < sizeof( separator ) );
   2084 	}
   2085 	*s = '\0';
   2086 
   2087 	for( ;; )
   2088 	{
   2089 		char		prefixString[ 32 ];
   2090 		char		hexString[ 64 ];
   2091 		char		asciiString[ 32 ];
   2092 		char		byteCountString[ 32 ];
   2093 		int			c;
   2094 		size_t		chunkSize;
   2095 		size_t		i;
   2096 
   2097 		// If this is a label-only item (i.e. no data), print the label (accounting for prefix string spacing) and exit.
   2098 
   2099 		if( inDataSize == 0 )
   2100 		{
   2101 			if( inLabel && ( inLabelSize > 0 ) )
   2102 			{
   2103 				width = 0;
   2104 				if( !( inFlags & kDebugFlagsNoAddress ) )
   2105 				{
   2106 					width += 8;			// "00000000"
   2107 					if( !( inFlags & kDebugFlagsNoOffset ) )
   2108 					{
   2109 						width += 1;		// "+"
   2110 					}
   2111 				}
   2112 				if( inFlags & kDebugFlags32BitOffset )
   2113 				{
   2114 					width += 8;			// "00000000"
   2115 				}
   2116 				else if( !( inFlags & kDebugFlagsNoOffset ) )
   2117 				{
   2118 					width += 4;			// "0000"
   2119 				}
   2120 
   2121 				if( outBuffer )
   2122 				{
   2123 					dst += DebugSNPrintF( dst, (size_t)( end - dst ), "%*s" "%-*.*s" "%.*s" "%s",
   2124 						width, "",
   2125 						( width > 0 ) ? ": " : "",
   2126 						width, (int) inLabelSize, inLabel,
   2127 						newline );
   2128 				}
   2129 				else
   2130 				{
   2131 					dst += DebugPrintF( inLevel, "%*s" "%-*.*s" "%.*s" "%s",
   2132 						width, "",
   2133 						( width > 0 ) ? ": " : "",
   2134 						width, (int) inLabelSize, inLabel,
   2135 						newline );
   2136 				}
   2137 			}
   2138 			break;
   2139 		}
   2140 
   2141 		// Build the prefix string. It will be in one of the following formats:
   2142 		//
   2143 		// 1) "00000000+0000[0000]"	(address and offset)
   2144 		// 2) "00000000"			(address only)
   2145 		// 3) "0000[0000]"			(offset only)
   2146 		// 4) ""					(no address or offset)
   2147 		//
   2148 		// Note: If we're printing multiple "lines", but not printing newlines, a space is used to separate.
   2149 
   2150 		s = prefixString;
   2151 		if( !( inFlags & kDebugFlagsNoAddress ) )
   2152 		{
   2153 			*s++ = kHexChars[ ( ( (uintptr_t) src ) >> 28 ) & 0xF ];
   2154 			*s++ = kHexChars[ ( ( (uintptr_t) src ) >> 24 ) & 0xF ];
   2155 			*s++ = kHexChars[ ( ( (uintptr_t) src ) >> 20 ) & 0xF ];
   2156 			*s++ = kHexChars[ ( ( (uintptr_t) src ) >> 16 ) & 0xF ];
   2157 			*s++ = kHexChars[ ( ( (uintptr_t) src ) >> 12 ) & 0xF ];
   2158 			*s++ = kHexChars[ ( ( (uintptr_t) src ) >>  8 ) & 0xF ];
   2159 			*s++ = kHexChars[ ( ( (uintptr_t) src ) >>  4 ) & 0xF ];
   2160 			*s++ = kHexChars[   ( (uintptr_t) src )         & 0xF ];
   2161 
   2162 			if( !( inFlags & kDebugFlagsNoOffset ) )
   2163 			{
   2164 				*s++ = '+';
   2165 			}
   2166 		}
   2167 		if( !( inFlags & kDebugFlagsNoOffset ) )
   2168 		{
   2169 			if( inFlags & kDebugFlags32BitOffset )
   2170 			{
   2171 				*s++ = kHexChars[ ( offset >> 28 ) & 0xF ];
   2172 				*s++ = kHexChars[ ( offset >> 24 ) & 0xF ];
   2173 				*s++ = kHexChars[ ( offset >> 20 ) & 0xF ];
   2174 				*s++ = kHexChars[ ( offset >> 16 ) & 0xF ];
   2175 			}
   2176 			*s++ = kHexChars[ ( offset >> 12 ) & 0xF ];
   2177 			*s++ = kHexChars[ ( offset >>  8 ) & 0xF ];
   2178 			*s++ = kHexChars[ ( offset >>  4 ) & 0xF ];
   2179 			*s++ = kHexChars[   offset         & 0xF ];
   2180 		}
   2181 		if( s != prefixString )
   2182 		{
   2183 			*s++ = ':';
   2184 			*s++ = ' ';
   2185 		}
   2186 		check( ( (size_t)( s - prefixString ) ) < sizeof( prefixString ) );
   2187 		*s = '\0';
   2188 
   2189 		// Build a hex string with a optional spaces after every 1, 2, and/or 4 bytes to make it easier to read.
   2190 		// Optionally pads the hex string with space to fill the full 16 byte range (so it lines up).
   2191 
   2192 		s = hexString;
   2193 		chunkSize = ( inDataSize < 16 ) ? inDataSize : 16;
   2194 		n = ( inFlags & kDebugFlagsNo16ByteHexPad ) ? chunkSize : 16;
   2195 		for( i = 0; i < n; ++i )
   2196 		{
   2197 			if( ( inFlags & kDebugFlags8BitSeparator ) && ( i > 0 ) )
   2198 			{
   2199 				*s++ = ' ';
   2200 			}
   2201 			if( ( inFlags & kDebugFlags16BitSeparator ) && ( i > 0 ) && ( ( i % 2 ) == 0 ) )
   2202 			{
   2203 				*s++ = ' ';
   2204 			}
   2205 			if( !( inFlags & kDebugFlagsNo32BitSeparator ) && ( i > 0 ) && ( ( i % 4 ) == 0 ) )
   2206 			{
   2207 				*s++ = ' ';
   2208 			}
   2209 			if( i < chunkSize )
   2210 			{
   2211 				*s++ = kHexChars[ src[ i ] >> 4   ];
   2212 				*s++ = kHexChars[ src[ i ] &  0xF ];
   2213 			}
   2214 			else
   2215 			{
   2216 				*s++ = ' ';
   2217 				*s++ = ' ';
   2218 			}
   2219 		}
   2220 		check( ( (size_t)( s - hexString ) ) < sizeof( hexString ) );
   2221 		*s = '\0';
   2222 
   2223 		// Build a string with the ASCII version of the data (replaces non-printable characters with '^').
   2224 		// Optionally pads the string with '`' to fill the full 16 byte range (so it lines up).
   2225 
   2226 		s = asciiString;
   2227 		if( !( inFlags & kDebugFlagsNoASCII ) )
   2228 		{
   2229 			*s++ = ' ';
   2230 			*s++ = '|';
   2231 			for( i = 0; i < n; ++i )
   2232 			{
   2233 				if( i < chunkSize )
   2234 				{
   2235 					c = src[ i ];
   2236 					if( !DebugIsPrint( c ) )
   2237 					{
   2238 						c = '^';
   2239 					}
   2240 				}
   2241 				else
   2242 				{
   2243 					c = '`';
   2244 				}
   2245 				*s++ = (char) c;
   2246 			}
   2247 			*s++ = '|';
   2248 			check( ( (size_t)( s - asciiString ) ) < sizeof( asciiString ) );
   2249 		}
   2250 		*s = '\0';
   2251 
   2252 		// Build a string indicating how bytes are in the hex dump. Only printed on the first line.
   2253 
   2254 		s = byteCountString;
   2255 		if( !( inFlags & kDebugFlagsNoByteCount ) )
   2256 		{
   2257 			if( src == start )
   2258 			{
   2259 				s += DebugSNPrintF( s, sizeof( byteCountString ), " (%d bytes)", (int) inDataSize );
   2260 			}
   2261 		}
   2262 		check( ( (size_t)( s - byteCountString ) ) < sizeof( byteCountString ) );
   2263 		*s = '\0';
   2264 
   2265 		// Build the entire line from all the pieces we've previously built.
   2266 
   2267 		if( outBuffer )
   2268 		{
   2269 			if( src == start )
   2270 			{
   2271 				dst += DebugSNPrintF( dst, (size_t)( end - dst ),
   2272 					"%*s"		// Indention
   2273 					"%s" 		// Separator (only if needed)
   2274 					"%s" 		// Prefix
   2275 					"%-*.*s"	// Label
   2276 					"%s"		// Separator
   2277 					"%s"		// Hex
   2278 					"%s"		// ASCII
   2279 					"%s"		// Byte Count
   2280 					"%s", 		// Newline
   2281 					inIndent, "",
   2282 					( src != start ) ? separator : "",
   2283 					prefixString,
   2284 					width, (int) inLabelSize, inLabel ? inLabel : "",
   2285 					( width > 0 ) ? " " : "",
   2286 					hexString,
   2287 					asciiString,
   2288 					byteCountString,
   2289 					newline );
   2290 			}
   2291 			else
   2292 			{
   2293 				dst += DebugSNPrintF( dst, (size_t)( end - dst ),
   2294 					"%*s"		// Indention
   2295 					"%s" 		// Separator (only if needed)
   2296 					"%s" 		// Prefix
   2297 					"%*s"		// Label Spacing
   2298 					"%s"		// Separator
   2299 					"%s"		// Hex
   2300 					"%s"		// ASCII
   2301 					"%s"		// Byte Count
   2302 					"%s", 		// Newline
   2303 					inIndent, "",
   2304 					( src != start ) ? separator : "",
   2305 					prefixString,
   2306 					width, "",
   2307 					( width > 0 ) ? " " : "",
   2308 					hexString,
   2309 					asciiString,
   2310 					byteCountString,
   2311 					newline );
   2312 			}
   2313 		}
   2314 		else
   2315 		{
   2316 			if( src == start )
   2317 			{
   2318 				dst += DebugPrintF( inLevel,
   2319 					"%*s"		// Indention
   2320 					"%s" 		// Separator (only if needed)
   2321 					"%s" 		// Prefix
   2322 					"%-*.*s"	// Label
   2323 					"%s"		// Separator
   2324 					"%s"		// Hex
   2325 					"%s"		// ASCII
   2326 					"%s"		// Byte Count
   2327 					"%s", 		// Newline
   2328 					inIndent, "",
   2329 					( src != start ) ? separator : "",
   2330 					prefixString,
   2331 					width, (int) inLabelSize, inLabel,
   2332 					( width > 0 ) ? " " : "",
   2333 					hexString,
   2334 					asciiString,
   2335 					byteCountString,
   2336 					newline );
   2337 			}
   2338 			else
   2339 			{
   2340 				dst += DebugPrintF( inLevel,
   2341 					"%*s"		// Indention
   2342 					"%s" 		// Separator (only if needed)
   2343 					"%s" 		// Prefix
   2344 					"%*s"		// Label Spacing
   2345 					"%s"		// Separator
   2346 					"%s"		// Hex
   2347 					"%s"		// ASCII
   2348 					"%s"		// Byte Count
   2349 					"%s", 		// Newline
   2350 					inIndent, "",
   2351 					( src != start ) ? separator : "",
   2352 					prefixString,
   2353 					width, "",
   2354 					( width > 0 ) ? " " : "",
   2355 					hexString,
   2356 					asciiString,
   2357 					byteCountString,
   2358 					newline );
   2359 			}
   2360 		}
   2361 
   2362 		// Move to the next chunk. Exit if there is no more data.
   2363 
   2364 		offset		+= (int) chunkSize;
   2365 		src 		+= chunkSize;
   2366 		inDataSize	-= chunkSize;
   2367 		if( inDataSize == 0 )
   2368 		{
   2369 			break;
   2370 		}
   2371 	}
   2372 
   2373 	// Note: The "dst - outBuffer" size calculation works even if "outBuffer" is NULL because it's all relative.
   2374 
   2375 	return( (size_t)( dst - outBuffer ) );
   2376 }
   2377 
   2378 //===========================================================================================================================
   2379 //	DebugNumVersionToString
   2380 //===========================================================================================================================
   2381 
   2382 static char *	DebugNumVersionToString( uint32_t inVersion, char *inString )
   2383 {
   2384 	char *		s;
   2385 	uint8_t		majorRev;
   2386 	uint8_t		minor;
   2387 	uint8_t		bugFix;
   2388 	uint8_t		stage;
   2389 	uint8_t		revision;
   2390 
   2391 	check( inString );
   2392 
   2393 	majorRev 	= (uint8_t)( ( inVersion >> 24 ) & 0xFF );
   2394 	minor		= (uint8_t)( ( inVersion >> 20 ) & 0x0F );
   2395 	bugFix		= (uint8_t)( ( inVersion >> 16 ) & 0x0F );
   2396 	stage 		= (uint8_t)( ( inVersion >>  8 ) & 0xFF );
   2397 	revision 	= (uint8_t)(   inVersion         & 0xFF );
   2398 
   2399 	// Convert the major, minor, and bugfix numbers.
   2400 
   2401 	s  = inString;
   2402 	s += sprintf( s, "%u", majorRev );
   2403 	s += sprintf( s, ".%u", minor );
   2404 	if( bugFix != 0 )
   2405 	{
   2406 		s += sprintf( s, ".%u", bugFix );
   2407 	}
   2408 
   2409 	// Convert the version stage and non-release revision number.
   2410 
   2411 	switch( stage )
   2412 	{
   2413 		case kVersionStageDevelopment:
   2414 			s += sprintf( s, "d%u", revision );
   2415 			break;
   2416 
   2417 		case kVersionStageAlpha:
   2418 			s += sprintf( s, "a%u", revision );
   2419 			break;
   2420 
   2421 		case kVersionStageBeta:
   2422 			s += sprintf( s, "b%u", revision );
   2423 			break;
   2424 
   2425 		case kVersionStageFinal:
   2426 
   2427 			// A non-release revision of zero is a special case indicating the software is GM (at the golden master
   2428 			// stage) and therefore, the non-release revision should not be added to the string.
   2429 
   2430 			if( revision != 0 )
   2431 			{
   2432 				s += sprintf( s, "f%u", revision );
   2433 			}
   2434 			break;
   2435 
   2436 		default:
   2437 			dlog( kDebugLevelError, "invalid NumVersion stage (0x%02X)\n", stage );
   2438 			break;
   2439 	}
   2440 	return( inString );
   2441 }
   2442 
   2443 //===========================================================================================================================
   2444 //	DebugTaskLevel
   2445 //===========================================================================================================================
   2446 
   2447 DEBUG_EXPORT uint32_t	DebugTaskLevel( void )
   2448 {
   2449 	uint32_t		level;
   2450 
   2451 	level = 0;
   2452 
   2453 #if( TARGET_OS_VXWORKS )
   2454 	if( intContext() )
   2455 	{
   2456 		level |= ( ( 1 << kDebugInterruptLevelShift ) & kDebugInterruptLevelMask );
   2457 	}
   2458 #endif
   2459 
   2460 	return( level );
   2461 }
   2462 
   2463 #if( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
   2464 //===========================================================================================================================
   2465 //	DebugWinEnableConsole
   2466 //===========================================================================================================================
   2467 
   2468 #pragma warning( disable:4311 )
   2469 
   2470 static void	DebugWinEnableConsole( void )
   2471 {
   2472 	static bool		sConsoleEnabled = false;
   2473 	BOOL			result;
   2474 	int				fileHandle;
   2475 	FILE *			file;
   2476 	int				err;
   2477 
   2478 	if( sConsoleEnabled )
   2479 	{
   2480 		goto exit;
   2481 	}
   2482 
   2483 	// Create console window.
   2484 
   2485 	result = AllocConsole();
   2486 	require_quiet( result, exit );
   2487 
   2488 	// Redirect stdin to the console stdin.
   2489 
   2490 	fileHandle = _open_osfhandle( (long) GetStdHandle( STD_INPUT_HANDLE ), _O_TEXT );
   2491 
   2492 	#if( defined( __MWERKS__ ) )
   2493 		file = __handle_reopen( (unsigned long) fileHandle, "r", stdin );
   2494 		require_quiet( file, exit );
   2495 	#else
   2496 		file = _fdopen( fileHandle, "r" );
   2497 		require_quiet( file, exit );
   2498 
   2499 		*stdin = *file;
   2500 	#endif
   2501 
   2502 	err = setvbuf( stdin, NULL, _IONBF, 0 );
   2503 	require_noerr_quiet( err, exit );
   2504 
   2505 	// Redirect stdout to the console stdout.
   2506 
   2507 	fileHandle = _open_osfhandle( (long) GetStdHandle( STD_OUTPUT_HANDLE ), _O_TEXT );
   2508 
   2509 	#if( defined( __MWERKS__ ) )
   2510 		file = __handle_reopen( (unsigned long) fileHandle, "w", stdout );
   2511 		require_quiet( file, exit );
   2512 	#else
   2513 		file = _fdopen( fileHandle, "w" );
   2514 		require_quiet( file, exit );
   2515 
   2516 		*stdout = *file;
   2517 	#endif
   2518 
   2519 	err = setvbuf( stdout, NULL, _IONBF, 0 );
   2520 	require_noerr_quiet( err, exit );
   2521 
   2522 	// Redirect stderr to the console stdout.
   2523 
   2524 	fileHandle = _open_osfhandle( (long) GetStdHandle( STD_OUTPUT_HANDLE ), _O_TEXT );
   2525 
   2526 	#if( defined( __MWERKS__ ) )
   2527 		file = __handle_reopen( (unsigned long) fileHandle, "w", stderr );
   2528 		require_quiet( file, exit );
   2529 	#else
   2530 		file = _fdopen( fileHandle, "w" );
   2531 		require_quiet( file, exit );
   2532 
   2533 		*stderr = *file;
   2534 	#endif
   2535 
   2536 	err = setvbuf( stderr, NULL, _IONBF, 0 );
   2537 	require_noerr_quiet( err, exit );
   2538 
   2539 	sConsoleEnabled = true;
   2540 
   2541 exit:
   2542 	return;
   2543 }
   2544 
   2545 #pragma warning( default:4311 )
   2546 
   2547 #endif	// TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE
   2548 
   2549 #if( TARGET_OS_WIN32 )
   2550 //===========================================================================================================================
   2551 //	DebugWinCharToTCharString
   2552 //===========================================================================================================================
   2553 
   2554 static TCHAR *
   2555 	DebugWinCharToTCharString(
   2556 		const char *	inCharString,
   2557 		size_t 			inCharCount,
   2558 		TCHAR *			outTCharString,
   2559 		size_t 			inTCharCountMax,
   2560 		size_t *		outTCharCount )
   2561 {
   2562 	const char *		src;
   2563 	TCHAR *				dst;
   2564 	TCHAR *				end;
   2565 
   2566 	if( inCharCount == kSizeCString )
   2567 	{
   2568 		inCharCount = strlen( inCharString );
   2569 	}
   2570 	src = inCharString;
   2571 	dst = outTCharString;
   2572 	if( inTCharCountMax > 0 )
   2573 	{
   2574 		inTCharCountMax -= 1;
   2575 		if( inTCharCountMax > inCharCount )
   2576 		{
   2577 			inTCharCountMax = inCharCount;
   2578 		}
   2579 
   2580 		end = dst + inTCharCountMax;
   2581 		while( dst < end )
   2582 		{
   2583 			*dst++ = (TCHAR) *src++;
   2584 		}
   2585 		*dst = 0;
   2586 	}
   2587 	if( outTCharCount )
   2588 	{
   2589 		*outTCharCount = (size_t)( dst - outTCharString );
   2590 	}
   2591 	return( outTCharString );
   2592 }
   2593 #endif
   2594 
   2595 #if 0
   2596 #pragma mark -
   2597 #pragma mark == Debugging ==
   2598 #endif
   2599 
   2600 //===========================================================================================================================
   2601 //	DebugServicesTest
   2602 //===========================================================================================================================
   2603 
   2604 DEBUG_EXPORT OSStatus	DebugServicesTest( void )
   2605 {
   2606 	OSStatus		err;
   2607 	char			s[ 512 ];
   2608 	uint8_t *		p;
   2609 	uint8_t			data[] =
   2610 	{
   2611 		0x11, 0x22, 0x33, 0x44,
   2612 		0x55, 0x66,
   2613 		0x77, 0x88, 0x99, 0xAA,
   2614 		0xBB, 0xCC, 0xDD,
   2615 		0xEE,
   2616 		0xFF,
   2617 		0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
   2618 		0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0,
   2619 		0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71, 0x81, 0x91, 0xA1
   2620 	};
   2621 
   2622 	debug_initialize( kDebugOutputTypeMetaConsole );
   2623 
   2624 	// check's
   2625 
   2626 	check( 0 && "SHOULD SEE: check" );
   2627 	check( 1 && "SHOULD *NOT* SEE: check (valid)" );
   2628 	check_string( 0, "SHOULD SEE: check_string" );
   2629 	check_string( 1, "SHOULD *NOT* SEE: check_string (valid)" );
   2630 	check_noerr( -123 );
   2631 	check_noerr( 10038 );
   2632 	check_noerr( 22 );
   2633 	check_noerr( 0 );
   2634 	check_noerr_string( -6712, "SHOULD SEE: check_noerr_string" );
   2635 	check_noerr_string( 0, "SHOULD *NOT* SEE: check_noerr_string (valid)" );
   2636 	check_translated_errno( 0 >= 0 && "SHOULD *NOT* SEE", -384, -999 );
   2637 	check_translated_errno( -1 >= 0 && "SHOULD SEE", -384, -999 );
   2638 	check_translated_errno( -1 >= 0 && "SHOULD SEE", 0, -999 );
   2639 	check_ptr_overlap( "SHOULD *NOT* SEE" ? 10 : 0, 10, 22, 10 );
   2640 	check_ptr_overlap( "SHOULD SEE" ? 10 : 0, 10,  5, 10 );
   2641 	check_ptr_overlap( "SHOULD SEE" ? 10 : 0, 10, 12,  6 );
   2642 	check_ptr_overlap( "SHOULD SEE" ? 12 : 0,  6, 10, 10 );
   2643 	check_ptr_overlap( "SHOULD SEE" ? 12 : 0, 10, 10, 10 );
   2644 	check_ptr_overlap( "SHOULD *NOT* SEE" ? 22 : 0, 10, 10, 10 );
   2645 	check_ptr_overlap( "SHOULD *NOT* SEE" ? 10 : 0, 10, 20, 10 );
   2646 	check_ptr_overlap( "SHOULD *NOT* SEE" ? 20 : 0, 10, 10, 10 );
   2647 
   2648 	// require's
   2649 
   2650 	require( 0 && "SHOULD SEE", require1 );
   2651 	{ err = kResponseErr; goto exit; }
   2652 require1:
   2653 	require( 1 && "SHOULD *NOT* SEE", require2 );
   2654 	goto require2Good;
   2655 require2:
   2656 	{ err = kResponseErr; goto exit; }
   2657 require2Good:
   2658 	require_string( 0 && "SHOULD SEE", require3, "SHOULD SEE: require_string" );
   2659 	{ err = kResponseErr; goto exit; }
   2660 require3:
   2661 	require_string( 1 && "SHOULD *NOT* SEE", require4, "SHOULD *NOT* SEE: require_string (valid)" );
   2662 	goto require4Good;
   2663 require4:
   2664 	{ err = kResponseErr; goto exit; }
   2665 require4Good:
   2666 	require_quiet( 0 && "SHOULD SEE", require5 );
   2667 	{ err = kResponseErr; goto exit; }
   2668 require5:
   2669 	require_quiet( 1 && "SHOULD *NOT* SEE", require6 );
   2670 	goto require6Good;
   2671 require6:
   2672 	{ err = kResponseErr; goto exit; }
   2673 require6Good:
   2674 	require_noerr( -1, require7 );
   2675 	{ err = kResponseErr; goto exit; }
   2676 require7:
   2677 	require_noerr( 0, require8 );
   2678 	goto require8Good;
   2679 require8:
   2680 	{ err = kResponseErr; goto exit; }
   2681 require8Good:
   2682 	require_noerr_string( -2, require9, "SHOULD SEE: require_noerr_string");
   2683 	{ err = kResponseErr; goto exit; }
   2684 require9:
   2685 	require_noerr_string( 0, require10, "SHOULD *NOT* SEE: require_noerr_string (valid)" );
   2686 	goto require10Good;
   2687 require10:
   2688 	{ err = kResponseErr; goto exit; }
   2689 require10Good:
   2690 	require_noerr_action_string( -3, require11, dlog( kDebugLevelMax, "action 1 (expected)\n" ), "require_noerr_action_string" );
   2691 	{ err = kResponseErr; goto exit; }
   2692 require11:
   2693 	require_noerr_action_string( 0, require12, dlog( kDebugLevelMax, "action 2\n" ), "require_noerr_action_string (valid)" );
   2694 	goto require12Good;
   2695 require12:
   2696 	{ err = kResponseErr; goto exit; }
   2697 require12Good:
   2698 	require_noerr_quiet( -4, require13 );
   2699 	{ err = kResponseErr; goto exit; }
   2700 require13:
   2701 	require_noerr_quiet( 0, require14 );
   2702 	goto require14Good;
   2703 require14:
   2704 	{ err = kResponseErr; goto exit; }
   2705 require14Good:
   2706 	require_noerr_action( -5, require15, dlog( kDebugLevelMax, "SHOULD SEE: action 3 (expected)\n" ) );
   2707 	{ err = kResponseErr; goto exit; }
   2708 require15:
   2709 	require_noerr_action( 0, require16, dlog( kDebugLevelMax, "SHOULD *NOT* SEE: action 4\n" ) );
   2710 	goto require16Good;
   2711 require16:
   2712 	{ err = kResponseErr; goto exit; }
   2713 require16Good:
   2714 	require_noerr_action_quiet( -4, require17, dlog( kDebugLevelMax, "SHOULD SEE: action 5 (expected)\n" ) );
   2715 	{ err = kResponseErr; goto exit; }
   2716 require17:
   2717 	require_noerr_action_quiet( 0, require18, dlog( kDebugLevelMax, "SHOULD *NOT* SEE: action 6\n" ) );
   2718 	goto require18Good;
   2719 require18:
   2720 	{ err = kResponseErr; goto exit; }
   2721 require18Good:
   2722 	require_action( 0 && "SHOULD SEE", require19, dlog( kDebugLevelMax, "SHOULD SEE: action 7 (expected)\n" ) );
   2723 	{ err = kResponseErr; goto exit; }
   2724 require19:
   2725 	require_action( 1 && "SHOULD *NOT* SEE", require20, dlog( kDebugLevelMax, "SHOULD *NOT* SEE: action 8\n" ) );
   2726 	goto require20Good;
   2727 require20:
   2728 	{ err = kResponseErr; goto exit; }
   2729 require20Good:
   2730 	require_action_quiet( 0, require21, dlog( kDebugLevelMax, "SHOULD SEE: action 9 (expected)\n" ) );
   2731 	{ err = kResponseErr; goto exit; }
   2732 require21:
   2733 	require_action_quiet( 1, require22, dlog( kDebugLevelMax, "SHOULD *NOT* SEE: action 10\n" ) );
   2734 	goto require22Good;
   2735 require22:
   2736 	{ err = kResponseErr; goto exit; }
   2737 require22Good:
   2738 	require_action_string( 0, require23, dlog( kDebugLevelMax, "SHOULD SEE: action 11 (expected)\n" ), "SHOULD SEE: require_action_string" );
   2739 	{ err = kResponseErr; goto exit; }
   2740 require23:
   2741 	require_action_string( 1, require24, dlog( kDebugLevelMax, "SHOULD *NOT* SEE: action 12\n" ), "SHOULD *NOT* SEE: require_action_string" );
   2742 	goto require24Good;
   2743 require24:
   2744 	{ err = kResponseErr; goto exit; }
   2745 require24Good:
   2746 
   2747 #if( defined( __MWERKS__ )  )
   2748 	#if( defined( __cplusplus ) && __option( exceptions ) )
   2749 		#define COMPILER_HAS_EXCEPTIONS		1
   2750 	#else
   2751 		#define COMPILER_HAS_EXCEPTIONS		0
   2752 	#endif
   2753 #else
   2754 	#if( defined( __cplusplus ) )
   2755 		#define COMPILER_HAS_EXCEPTIONS		1
   2756 	#else
   2757 		#define COMPILER_HAS_EXCEPTIONS		0
   2758 	#endif
   2759 #endif
   2760 
   2761 #if( COMPILER_HAS_EXCEPTIONS )
   2762 	try
   2763 	{
   2764 		require_throw( 1 && "SHOULD *NOT* SEE" );
   2765 		require_throw( 0 && "SHOULD SEE" );
   2766 	}
   2767 	catch( ... )
   2768 	{
   2769 		goto require26Good;
   2770 	}
   2771 	{ err = kResponseErr; goto exit; }
   2772 require26Good:
   2773 #endif
   2774 
   2775 	// translate_errno
   2776 
   2777 	err = translate_errno( 1 != -1, -123, -567 );
   2778 	require( ( err == 0 ) && "SHOULD *NOT* SEE", exit );
   2779 
   2780 	err = translate_errno( -1 != -1, -123, -567 );
   2781 	require( ( err == -123 ) && "SHOULD *NOT* SEE", exit );
   2782 
   2783 	err = translate_errno( -1 != -1, 0, -567 );
   2784 	require( ( err == -567 ) && "SHOULD *NOT* SEE", exit );
   2785 
   2786 	// debug_string
   2787 
   2788 	debug_string( "debug_string" );
   2789 
   2790 	// DebugSNPrintF
   2791 
   2792 	DebugSNPrintF( s, sizeof( s ), "%d", 1234 );
   2793 	require_action( strcmp( s, "1234" ) == 0, exit, err = -1 );
   2794 
   2795 	DebugSNPrintF( s, sizeof( s ), "%X", 0x2345 );
   2796 	require_action( strcmp( s, "2345" ) == 0, exit, err = -1 );
   2797 
   2798 	DebugSNPrintF( s, sizeof( s ), "%#s", "\05test" );
   2799 	require_action( strcmp( s, "test" ) == 0, exit, err = -1 );
   2800 
   2801 	DebugSNPrintF( s, sizeof( s ), "%##s", "\03www\05apple\03com" );
   2802 	require_action( strcmp( s, "www.apple.com." ) == 0, exit, err = -1 );
   2803 
   2804 	DebugSNPrintF( s, sizeof( s ), "%ld", (long) INT32_C( 2147483647 ) );
   2805 	require_action( strcmp( s, "2147483647" ) == 0, exit, err = -1 );
   2806 
   2807 	DebugSNPrintF( s, sizeof( s ), "%lu", (unsigned long) UINT32_C( 4294967295 ) );
   2808 	require_action( strcmp( s, "4294967295" ) == 0, exit, err = -1 );
   2809 
   2810 	#if( TYPE_LONGLONG_NATIVE )
   2811 		DebugSNPrintF( s, sizeof( s ), "%lld", (long_long_compat) INT64_C( 9223372036854775807 ) );
   2812 		require_action( strcmp( s, "9223372036854775807" ) == 0, exit, err = -1 );
   2813 
   2814 		DebugSNPrintF( s, sizeof( s ), "%lld", (long_long_compat) INT64_C( -9223372036854775807 ) );
   2815 		require_action( strcmp( s, "-9223372036854775807" ) == 0, exit, err = -1 );
   2816 
   2817 		DebugSNPrintF( s, sizeof( s ), "%llu", (unsigned_long_long_compat) UINT64_C( 18446744073709551615 ) );
   2818 		require_action( strcmp( s, "18446744073709551615" ) == 0, exit, err = -1 );
   2819 	#endif
   2820 
   2821 	DebugSNPrintF( s, sizeof( s ), "%lb", (unsigned long) binary_32( 01111011, 01111011, 01111011, 01111011 ) );
   2822 	require_action( strcmp( s, "1111011011110110111101101111011" ) == 0, exit, err = -1 );
   2823 
   2824 	DebugSNPrintF( s, sizeof( s ), "%C", 0x41624364 );	// 'AbCd'
   2825 	require_action( strcmp( s, "AbCd" ) == 0, exit, err = -1 );
   2826 
   2827 	#if( defined( MDNS_DEBUGMSGS ) )
   2828 	{
   2829 		mDNSAddr		maddr;
   2830 
   2831 		memset( &maddr, 0, sizeof( maddr ) );
   2832 		maddr.type = mDNSAddrType_IPv4;
   2833 		maddr.ip.v4.b[ 0 ] = 127;
   2834 		maddr.ip.v4.b[ 1 ] = 0;
   2835 		maddr.ip.v4.b[ 2 ] = 0;
   2836 		maddr.ip.v4.b[ 3 ] = 1;
   2837 		DebugSNPrintF( s, sizeof( s ), "%#a", &maddr );
   2838 		require_action( strcmp( s, "127.0.0.1" ) == 0, exit, err = -1 );
   2839 
   2840 		memset( &maddr, 0, sizeof( maddr ) );
   2841 		maddr.type = mDNSAddrType_IPv6;
   2842 		maddr.ip.v6.b[  0 ]	= 0xFE;
   2843 		maddr.ip.v6.b[  1 ]	= 0x80;
   2844 		maddr.ip.v6.b[ 15 ]	= 0x01;
   2845 		DebugSNPrintF( s, sizeof( s ), "%#a", &maddr );
   2846 		require_action( strcmp( s, "FE80:0000:0000:0000:0000:0000:0000:0001" ) == 0, exit, err = -1 );
   2847 	}
   2848 	#endif
   2849 
   2850 	#if( AF_INET )
   2851 	{
   2852 		struct sockaddr_in		sa4;
   2853 
   2854 		memset( &sa4, 0, sizeof( sa4 ) );
   2855 		sa4.sin_family 		= AF_INET;
   2856 		p 					= (uint8_t *) &sa4.sin_port;
   2857 		p[ 0 ] 				= (uint8_t)( ( 80 >> 8 ) & 0xFF );
   2858 		p[ 1 ] 				= (uint8_t)(   80        & 0xFF );
   2859 		p 					= (uint8_t *) &sa4.sin_addr.s_addr;
   2860 		p[ 0 ] 				= (uint8_t)( ( INADDR_LOOPBACK >> 24 ) & 0xFF );
   2861 		p[ 1 ] 				= (uint8_t)( ( INADDR_LOOPBACK >> 16 ) & 0xFF );
   2862 		p[ 2 ] 				= (uint8_t)( ( INADDR_LOOPBACK >>  8 ) & 0xFF );
   2863 		p[ 3 ] 				= (uint8_t)(   INADDR_LOOPBACK         & 0xFF );
   2864 		DebugSNPrintF( s, sizeof( s ), "%##a", &sa4 );
   2865 		require_action( strcmp( s, "127.0.0.1:80" ) == 0, exit, err = -1 );
   2866 	}
   2867 	#endif
   2868 
   2869 	#if( AF_INET6 )
   2870 	{
   2871 		struct sockaddr_in6		sa6;
   2872 
   2873 		memset( &sa6, 0, sizeof( sa6 ) );
   2874 		sa6.sin6_family 			= AF_INET6;
   2875 		p 							= (uint8_t *) &sa6.sin6_port;
   2876 		p[ 0 ] 						= (uint8_t)( ( 80 >> 8 ) & 0xFF );
   2877 		p[ 1 ] 						= (uint8_t)(   80        & 0xFF );
   2878 		sa6.sin6_addr.s6_addr[  0 ]	= 0xFE;
   2879 		sa6.sin6_addr.s6_addr[  1 ]	= 0x80;
   2880 		sa6.sin6_addr.s6_addr[ 15 ]	= 0x01;
   2881 		sa6.sin6_scope_id			= 2;
   2882 		DebugSNPrintF( s, sizeof( s ), "%##a", &sa6 );
   2883 		require_action( strcmp( s, "[FE80:0000:0000:0000:0000:0000:0000:0001%2]:80" ) == 0, exit, err = -1 );
   2884 	}
   2885 	#endif
   2886 
   2887 	// Unicode
   2888 
   2889 	DebugSNPrintF(s, sizeof(s), "%.*s", 4, "tes" );
   2890 	require_action( strcmp( s, "tes" ) == 0, exit, err = kResponseErr );
   2891 
   2892 	DebugSNPrintF(s, sizeof(s), "%.*s", 4, "test" );
   2893 	require_action( strcmp( s, "test" ) == 0, exit, err = kResponseErr );
   2894 
   2895 	DebugSNPrintF(s, sizeof(s), "%.*s", 4, "testing" );
   2896 	require_action( strcmp( s, "test" ) == 0, exit, err = kResponseErr );
   2897 
   2898 	DebugSNPrintF(s, sizeof(s), "%.*s", 4, "te\xC3\xA9" );
   2899 	require_action( strcmp( s, "te\xC3\xA9" ) == 0, exit, err = kResponseErr );
   2900 
   2901 	DebugSNPrintF(s, sizeof(s), "%.*s", 4, "te\xC3\xA9ing" );
   2902 	require_action( strcmp( s, "te\xC3\xA9" ) == 0, exit, err = kResponseErr );
   2903 
   2904 	DebugSNPrintF(s, sizeof(s), "%.*s", 4, "tes\xC3\xA9ing" );
   2905 	require_action( strcmp( s, "tes" ) == 0, exit, err = kResponseErr );
   2906 
   2907 	DebugSNPrintF(s, sizeof(s), "%.*s", 4, "t\xed\x9f\xbf" );
   2908 	require_action( strcmp( s, "t\xed\x9f\xbf" ) == 0, exit, err = kResponseErr );
   2909 
   2910 	DebugSNPrintF(s, sizeof(s), "%.*s", 4, "t\xed\x9f\xbfing" );
   2911 	require_action( strcmp( s, "t\xed\x9f\xbf" ) == 0, exit, err = kResponseErr );
   2912 
   2913 	DebugSNPrintF(s, sizeof(s), "%.*s", 4, "te\xed\x9f\xbf" );
   2914 	require_action( strcmp( s, "te" ) == 0, exit, err = kResponseErr );
   2915 
   2916 	DebugSNPrintF(s, sizeof(s), "%.*s", 4, "te\xed\x9f\xbfing" );
   2917 	require_action( strcmp( s, "te" ) == 0, exit, err = kResponseErr );
   2918 
   2919 	DebugSNPrintF(s, sizeof(s), "%.*s", 7, "te\xC3\xA9\xed\x9f\xbfing" );
   2920 	require_action( strcmp( s, "te\xC3\xA9\xed\x9f\xbf" ) == 0, exit, err = kResponseErr );
   2921 
   2922 	DebugSNPrintF(s, sizeof(s), "%.*s", 6, "te\xC3\xA9\xed\x9f\xbfing" );
   2923 	require_action( strcmp( s, "te\xC3\xA9" ) == 0, exit, err = kResponseErr );
   2924 
   2925 	DebugSNPrintF(s, sizeof(s), "%.*s", 5, "te\xC3\xA9\xed\x9f\xbfing" );
   2926 	require_action( strcmp( s, "te\xC3\xA9" ) == 0, exit, err = kResponseErr );
   2927 
   2928 	#if( TARGET_RT_BIG_ENDIAN )
   2929 		DebugSNPrintF( s, sizeof( s ), "%S", "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" );
   2930 		require_action( strcmp( s, "abcd" ) == 0, exit, err = -1 );
   2931 	#else
   2932 		DebugSNPrintF( s, sizeof( s ), "%S", "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" "\x00" );
   2933 		require_action( strcmp( s, "abcd" ) == 0, exit, err = -1 );
   2934 	#endif
   2935 
   2936 	DebugSNPrintF( s, sizeof( s ), "%S",
   2937 		"\xFE\xFF" "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" );	// Big Endian BOM
   2938 	require_action( strcmp( s, "abcd" ) == 0, exit, err = -1 );
   2939 
   2940 	DebugSNPrintF( s, sizeof( s ), "%S",
   2941 		"\xFF\xFE" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" "\x00" );	// Little Endian BOM
   2942 	require_action( strcmp( s, "abcd" ) == 0, exit, err = -1 );
   2943 
   2944 	DebugSNPrintF( s, sizeof( s ), "%#S", "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" );	// Big Endian
   2945 	require_action( strcmp( s, "abcd" ) == 0, exit, err = -1 );
   2946 
   2947 	DebugSNPrintF( s, sizeof( s ), "%##S", "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" "\x00" );	// Little Endian
   2948 	require_action( strcmp( s, "abcd" ) == 0, exit, err = -1 );
   2949 
   2950 	DebugSNPrintF( s, sizeof( s ), "%.*S",
   2951 		4, "\xFE\xFF" "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" );	// Big Endian BOM
   2952 	require_action( strcmp( s, "abc" ) == 0, exit, err = -1 );
   2953 
   2954 	DebugSNPrintF( s, sizeof( s ), "%.*S",
   2955 		4, "\xFF\xFE" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" );	// Little Endian BOM
   2956 	require_action( strcmp( s, "abc" ) == 0, exit, err = -1 );
   2957 
   2958 	#if( TARGET_RT_BIG_ENDIAN )
   2959 		DebugSNPrintF( s, sizeof( s ), "%.*S", 3, "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" );
   2960 		require_action( strcmp( s, "abc" ) == 0, exit, err = -1 );
   2961 	#else
   2962 		DebugSNPrintF( s, sizeof( s ), "%.*S", 3, "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" );
   2963 		require_action( strcmp( s, "abc" ) == 0, exit, err = -1 );
   2964 	#endif
   2965 
   2966 	DebugSNPrintF( s, sizeof( s ), "%#.*S", 3, "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" );	// Big Endian
   2967 	require_action( strcmp( s, "abc" ) == 0, exit, err = -1 );
   2968 
   2969 	DebugSNPrintF( s, sizeof( s ), "%##.*S", 3, "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" );	// Little Endian
   2970 	require_action( strcmp( s, "abc" ) == 0, exit, err = -1 );
   2971 
   2972 	// Misc
   2973 
   2974 	DebugSNPrintF( s, sizeof( s ), "%U", "\x10\xb8\xa7\x6b" "\xad\x9d" "\xd1\x11" "\x80\xb4" "\x00\xc0\x4f\xd4\x30\xc8" );
   2975 	require_action( strcmp( s, "6ba7b810-9dad-11d1-80b4-00c04fd430c8" ) == 0, exit, err = -1 );
   2976 
   2977 	DebugSNPrintF( s, sizeof( s ), "%m", 0 );
   2978 	require_action( strcmp( s, "no error" ) == 0, exit, err = -1 );
   2979 
   2980 	DebugSNPrintF( s, sizeof( s ), "%lm", (long) 0 );
   2981 	require_action( strcmp( s, "no error" ) == 0, exit, err = -1 );
   2982 
   2983 	DebugSNPrintF( s, sizeof( s ), "\"%H\"", "\x6b\xa7\xb8\x10\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8", 16, 16 );
   2984 	DebugPrintF( kDebugLevelMax, "%s\n\n", s );
   2985 
   2986 	DebugSNPrintF( s, sizeof( s ), "\"%H\"",
   2987 		"\x6b\xa7\xb8\x10\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8"
   2988 		"\x6b\xa7\xb8\x10\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8",
   2989 		32, 32 );
   2990 	DebugPrintF( kDebugLevelMax, "%s\n\n", s );
   2991 
   2992 	DebugSNPrintF( s, sizeof( s ), "\"%H\"", "\x6b\xa7", 2, 2 );
   2993 	DebugPrintF( kDebugLevelMax, "%s\n\n", s );
   2994 
   2995 	// Hex Dumps
   2996 
   2997 	s[ 0 ] = '\0';
   2998 	DebugHexDump( kDebugLevelMax, 0, "My Label", kSizeCString, 0, NULL, 0, data, data, sizeof( data ),
   2999 		kDebugFlagsNone, s, sizeof( s ) );
   3000 	DebugPrintF( kDebugLevelMax, "%s\n", s );
   3001 
   3002 	s[ 0 ] = '\0';
   3003 	DebugHexDump( kDebugLevelMax, 0, NULL, 0, 0, NULL, 0, data, data, sizeof( data ),
   3004 		kDebugFlagsNoAddress | kDebugFlagsNoOffset, s, sizeof( s ) );
   3005 	DebugPrintF( kDebugLevelMax, "%s\n", s );
   3006 
   3007 	s[ 0 ] = '\0';
   3008 	DebugHexDump( kDebugLevelMax, 0, "My Label", kSizeCString, 0, NULL, 0, data, data, sizeof( data ),
   3009 		kDebugFlagsNoAddress | kDebugFlagsNoOffset, s, sizeof( s ) );
   3010 	DebugPrintF( kDebugLevelMax, "%s\n", s );
   3011 
   3012 	s[ 0 ] = '\0';
   3013 	DebugHexDump( kDebugLevelMax, 0, "My Label", kSizeCString, 0, NULL, 0, data, data, sizeof( data ),
   3014 		kDebugFlagsNoAddress, s, sizeof( s ) );
   3015 	DebugPrintF( kDebugLevelMax, "%s\n", s );
   3016 
   3017 	s[ 0 ] = '\0';
   3018 	DebugHexDump( kDebugLevelMax, 0, NULL, 0, 0, NULL, 0, data, data, sizeof( data ),
   3019 		kDebugFlagsNoOffset, s, sizeof( s ) );
   3020 	DebugPrintF( kDebugLevelMax, "%s\n", s );
   3021 
   3022 	s[ 0 ] = '\0';
   3023 	DebugHexDump( kDebugLevelMax, 0, NULL, 0, 0, NULL, 0, data, data, sizeof( data ),
   3024 		kDebugFlagsNoAddress, s, sizeof( s ) );
   3025 	DebugPrintF( kDebugLevelMax, "%s\n", s );
   3026 
   3027 	s[ 0 ] = '\0';
   3028 	DebugHexDump( kDebugLevelMax, 0, NULL, 0, 0, NULL, 0, data, data, sizeof( data ),
   3029 		kDebugFlagsNoOffset, s, sizeof( s ) );
   3030 	DebugPrintF( kDebugLevelMax, "%s\n", s );
   3031 
   3032 	s[ 0 ] = '\0';
   3033 	DebugHexDump( kDebugLevelMax, 0, NULL, 0, 0, NULL, 0, data, data, sizeof( data ),
   3034 		kDebugFlagsNoByteCount, s, sizeof( s ) );
   3035 	DebugPrintF( kDebugLevelMax, "%s\n", s );
   3036 
   3037 	s[ 0 ] = '\0';
   3038 	DebugHexDump( kDebugLevelMax, 0, NULL, 0, 0, NULL, 0, "\x41\x62\x43\x64", "\x41\x62\x43\x64", 4,	// 'AbCd'
   3039 		kDebugFlagsNoAddress | kDebugFlagsNoOffset | kDebugFlagsNoNewLine |
   3040 		kDebugFlagsNo32BitSeparator | kDebugFlagsNo16ByteHexPad | kDebugFlagsNoByteCount,
   3041 		s, sizeof( s ) );
   3042 	DebugPrintF( kDebugLevelMax, "%s\n", s );
   3043 
   3044 	s[ 0 ] = '\0';
   3045 	DebugHexDump( kDebugLevelMax, 0, NULL, 0, 0, NULL, 0, data, data, sizeof( data ),
   3046 		kDebugFlagsNoAddress | kDebugFlagsNoOffset | kDebugFlagsNoASCII | kDebugFlagsNoNewLine |
   3047 		kDebugFlags16BitSeparator | kDebugFlagsNo32BitSeparator |
   3048 		kDebugFlagsNo16ByteHexPad | kDebugFlagsNoByteCount, s, sizeof( s ) );
   3049 	DebugPrintF( kDebugLevelMax, "%s\n", s );
   3050 
   3051 	s[ 0 ] = '\0';
   3052 	DebugHexDump( kDebugLevelMax, 8, NULL, 0, 0, NULL, 0, data, data, sizeof( data ), kDebugFlagsNone, s, sizeof( s ) );
   3053 	DebugPrintF( kDebugLevelMax, "%s\n", s );
   3054 
   3055 	// dlog's
   3056 
   3057 	dlog( kDebugLevelNotice, "dlog\n" );
   3058 	dlog( kDebugLevelNotice, "dlog integer: %d\n", 123 );
   3059 	dlog( kDebugLevelNotice, "dlog string:  \"%s\"\n", "test string" );
   3060 	dlogmem( kDebugLevelNotice, data, sizeof( data ) );
   3061 
   3062 	// Done
   3063 
   3064 	DebugPrintF( kDebugLevelMax, "\n\nALL TESTS DONE\n\n" );
   3065 	err = kNoErr;
   3066 
   3067 exit:
   3068 	if( err )
   3069 	{
   3070 		DebugPrintF( kDebugLevelMax, "\n\n### TEST FAILED ###\n\n" );
   3071 	}
   3072 	return( err );
   3073 }
   3074 
   3075 #endif	// DEBUG
   3076