stdio.c

来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 180 行

C
180
字号
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright (c) 1995, 1996, 1997, 1998  Microsoft Corporation

Module Name:  
    stdio.c

Abstract:  
    Function implementations for DbgPrintf() and support routines.

Functions:


Notes: 

--*/
#include <stdarg.h>
#include "common.h"
#include "stdio.h"

/* This routine works just like printf() except that it prints to the	*/
/*	debug serial port, and it does not support floating point numbers.	*/
/*	Supported formating options include x, X, d, u, lx, lX, ld, lu, s	*/
/*	and c.  It also supports field widths and leading zeroes.			*/
int DbgPrintf( char *pszFormat, ... ) {

	int iNumArgs;
	int iFieldWidth, i;
	DWORD dwBase;
	BYTE fLeadZero, fLong, fLowerCase, fUnSigned;
	char *pszSubString;
	long int ilTemp;
	va_list ArgList;

	va_start( ArgList, pszFormat );

	while( *pszFormat ) {
		switch(*pszFormat) {
		case '\n':
			OEM_DbgWriteByte( '\r' );
			OEM_DbgWriteByte( '\n' );
			break;
		case '%':
			/* Set it for 'd' defaults	*/
			fUnSigned = fLeadZero = fLowerCase = fLong = 0;
			iFieldWidth = 0;
			dwBase = 10;
			iNumArgs = 0;
			pszFormat++;
			while(*pszFormat) {
				/* Check for a leading zero modifier	*/
				if (*pszFormat == '0') {
					fLeadZero = 1;
					pszFormat++;
				}
				/* Check for a 'long' modifier	*/
				else if (*pszFormat == 'l') {
					fLong = 1;
					pszFormat++;
				}
				/* Check for a field width parameter	*/
				else if (*pszFormat >= '1' && *pszFormat <= '9') {
					iFieldWidth = 0;
					while(*pszFormat && *pszFormat >= '1' && *pszFormat <= '9') {
						iFieldWidth *= 10;
						iFieldWidth += *pszFormat++ - '0';
					}
				}
				/* Otherwise, it must be a field specification termination character	*/
				else {
					/* Check for a literal '%' terminator	*/
					if (*pszFormat == '%')
						OEM_DbgWriteByte('%');
					/* Check for a character terminator	*/
					if (*pszFormat == 'c') {
						for( i = 0; i < iFieldWidth - 1; i++ )
							OEM_DbgWriteByte( ' ' );
						OEM_DbgWriteByte(va_arg( ArgList, char ));
					}
					/* Check for a string terminator	*/
					else if (*pszFormat == 's') {
						pszSubString = va_arg( ArgList, char * );
						for( i = 0; *pszSubString; i++ )
							OEM_DbgWriteByte(*pszSubString++);
						for( ; i < iFieldWidth; i++ )
							OEM_DbgWriteByte( ' ' );
					}
					/* Look for all the numeric terminators	*/
					else {
						/* Check for an unsigned integer	*/
						if (*pszFormat == 'u')
							fUnSigned = 1;
						/* Check for a lower case hex terminator	*/
						else if (*pszFormat == 'x') {
							dwBase = 16;
							fLowerCase = 1;
							fUnSigned = 1;
						}
						/* Check for an upper case hex terminator	*/
						else if (*pszFormat == 'X') {
							dwBase = 16;
							fUnSigned = 1;
						}
						/* If it's not a base ten terminator, fill in error	*/
						else if (*pszFormat != 'd') {
							OEM_DbgWriteByte( '!' );
							return 0;
						}
						ilTemp = (fLong) ? va_arg( ArgList, long int ) : va_arg( ArgList, int );
						WriteASCNum( ilTemp, dwBase, fLeadZero, fUnSigned, fLowerCase, (int)iFieldWidth );
					}
					break;
				}
			}
			iNumArgs++;
			break;
		default:
			OEM_DbgWriteByte( *pszFormat );
			break;
		}
		pszFormat++;
	}

	va_end( ArgList );

	return iNumArgs;

} /* DbgPrintf() */



/* This routine takes a numeric integer value and writes it's ASC equivalent	*/
/*	to the debug serial port.  It will do this using the given numeric base and	*/
/*	it will fit the given field, signedness of the number, leading zero and		*/
/*	lower case flags.															*/
void WriteASCNum( long int ilValue, DWORD dwBase, BYTE fLeadZero, BYTE fUnSigned, BYTE fLowerCase, int iFieldWidth ) {

	int iPlacesNeeded, iCurPlace, i, j;
	DWORD dwTemp, dwValue;

	if (!fUnSigned && ilValue < 0) {
		OEM_DbgWriteByte( '-' );
		ilValue *= -1;
		iCurPlace = 1;
	}
	else
		iCurPlace = 0;
	dwValue = (DWORD)ilValue;

	/* First determine how many digits will be required to display the value	*/
	for( iPlacesNeeded = 0, dwTemp = dwValue; dwTemp; iPlacesNeeded++ )
		dwTemp /= dwBase;
	if (!iPlacesNeeded)
		iPlacesNeeded = 1;

	/* Fill in leading zeroes or spaces as needed	*/
	/* If the value itself is zero, make sure that we print at least 1 0	*/
	for( iCurPlace += iPlacesNeeded; iCurPlace < iFieldWidth; iCurPlace++ )
		if (fLeadZero)
			OEM_DbgWriteByte( '0' );
		else
			OEM_DbgWriteByte( ' ' );

	/* Now write out the digits */
	for( i = 0; i < iPlacesNeeded; i++ ) {
		dwTemp = dwValue;
		for( j = 0; j < iPlacesNeeded - i - 1; j++ )
			dwTemp /= dwBase;
		dwTemp %= dwBase;
		if (fLowerCase)
			OEM_DbgWriteByte( (dwTemp > 9) ? ('a' + dwTemp - 10) : ('0' + dwTemp) );
		else
			OEM_DbgWriteByte( (dwTemp > 9) ? ('A' + dwTemp - 10) : ('0' + dwTemp) );
	}

} /* WriteASCNum */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?