⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ut7_vsprintf.c

📁 小型操作系统,以VC为开发环境,需要boachs调试
💻 C
字号:
/***************************************************************************
**     File name   : ut7_vsprintf.c
**     Author      : x.cheng
**     Create date :
**
**	   Comment:
**        vsprintf() defined in this file...
**
**     Revisions:
**     $Log: ut7_vsprintf.c,v $
**     Revision 1.1.1.1  2005/07/27 06:53:15  x.cheng
**     add into repositories
**
**
***************************************************************************/
#include "const.h"
#include "stdarg.h"
#include "string.h"

#define is_digit(c)	((c) >= '0' && (c) <= '9')

/***********************************************************
 *将字符数字串转换成整数,注意,结果指针前移
 ***********************************************************/
static int siSkip_atoi(const char **s)
{
	int i=0;

	while (is_digit(* *s))
		i = i*10 + *((*s)++)-'0';

	return i;
}

/*定义转换类型的各种符号常数*/
#define ZEROPAD	1	/*pad with zero*/
#define	SIGN	2	/*unsigned/signed long */
#define	PLUS	4	/*show plus */
#define	SPACE	8	/*space if plus */
#define	LEFT	16	/*left justified */
#define	SPECIAL	32	/*0x */
#define	SMALL	64	/*use "abcd" instead of "ABCD" */

/*除操作,n被除数,base除数,结果n为商,返回值为余数*/
#define do_div(n, base)	({\
	int __res;	\
	__asm__ ("div %4":"=a"(n),"=d"(__res):"0"(n),"1"(0),"r"(base));	\
	__res; })


/************************************************************
*************************************************************
**      Function Name:			sszSkip_itoa
**      Author:                 x.cheng
**
**      Comment:
**			将整数转换为指定进制的字符串
**
**      List of parameters:
**			iSize	 转换字符的长度
**			iType	见前定义
**			iPrecision
**
**      Return value:   
**          转换好的字符串    
**
**      Revisions:
**
*************************************************************
*************************************************************/
static char * sszSkip_itoa(char *szBuffer, int iNum, int iRadix, int iSize, 
						   int iPrecision, int iType)
{
	char ch, sign, tmp[36];
	const char *digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	int i;

	if (iType&SMALL)	digits = "0123456789abcdefghijklmnopqrstuvwxyz";
	if (iType&LEFT)	iType &=~ZEROPAD;
	if ( (iRadix < 2) || (iRadix > 36) )	return 0;

	ch = iType&ZEROPAD ? '0':' ';
	if ( (iType&SIGN) && iNum<0 ){
		sign = '-', iNum = -iNum;
	}
	else {
		sign = (iType&PLUS) ? '+': ( (iType&SPACE)?' ':0);
	}
	/*如果带符号,则长度减一*/
	if (sign) iSize--;
	if (iType&SPECIAL) {
			if (iRadix == 16) iSize -= 2;
			else if (iRadix == 8) iSize --;
	}

	i=0;
	if (iNum == 0)
		tmp[i++] = '0';
	else {
		while (iNum !=0) {
			tmp[i++] = digits[do_div(iNum, iRadix)];
		}
	}
	
	if ( i > iPrecision )	iPrecision = i;
	iSize -= iPrecision;

	/*padding*/
	if (!(iType&(ZEROPAD + LEFT))) while ( iSize -- >0 ) *szBuffer++ = ' ';

	if (sign) *szBuffer ++ = sign;

	if (iType&SPECIAL) {
		if ( iRadix==8 )
			*szBuffer ++ = '0';
		else if ( iRadix==16 ) {
			*szBuffer ++ = '0', *szBuffer ++ = digits[33]; /*'X' or 'x' */
		}
	}

	if ( !(iType&LEFT) ) while (iSize-- >0) *szBuffer ++ = ch;

	while(i<iPrecision--) *szBuffer ++ = '0';
	while(i-- > 0) *szBuffer++ = tmp[i];
	/*如果宽度仍大于0,则表示有左靠齐标志,填空格*/
	while(iSize-- > 0) *szBuffer ++ = ' ';

	return szBuffer;
}

/************************************************************
*************************************************************
**      Function Name:			iVSPrintf
**      Author:                 x.cheng
**
**      Comment:
**			送格式化输出道字符串中
**
**      List of parameters:
**			szBuffer 存放结果字符串
**
**      Return value:   
**          return code, or information
**
**      Revisions:
**
*************************************************************
*************************************************************/ 
int iVSPrintf(char *szBuffer, const char *fmt, va_list args)
{
	int len;
	int i;
	char *str;
	char *s;
	int *ip;
	int flags;		/* flags to sszSkip_itoa() */
	int field_width;	/* width of output field */
	int precision;		/* min. # of digits for integers; max sszSkip_itoa of chars for from string */
	int qualifier;		/* 'h', 'l', or 'L' for integer fields */

	for (str = szBuffer ; *fmt; fmt++) {
		if (*fmt != '%') {
			*str++ = *fmt;
			continue;
		}

		/* process flags */
		flags = 0;
repeat:
		++fmt;		/* this also skips first '%' */
		switch (*fmt) {
		case '-':
			flags |= LEFT;
			goto repeat;
		case '+':
			flags |= PLUS;
			goto repeat;
		case ' ':
			flags |= SPACE;
			goto repeat;
		case '#':
			flags |= SPECIAL;
			goto repeat;
		case '0':
			flags |= ZEROPAD;
			goto repeat;
		}

		/* get field width */
		field_width = -1;
		if (is_digit(*fmt))
			field_width = siSkip_atoi(&fmt);
		else if (*fmt == '*') {
			/* it's the next argument */
			field_width = va_arg(args, int);
			if (field_width < 0) {
				field_width = -field_width;
				flags |= LEFT;
			}
		}

		/* get the precision */
		precision = -1;
		if (*fmt == '.') {
			++fmt;
			if (is_digit(*fmt))
				precision = siSkip_atoi(&fmt);
			else if (*fmt == '*') {
				/* it's the next argument */
				precision = va_arg(args, int);
			}
			if (precision < 0)
				precision = 0;
		}

		/* get the conversion qualifier */
		qualifier = -1;
		if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') {
			qualifier = *fmt;
			++fmt;
		}

		switch (*fmt) {
		case 'c':
			if (!(flags & LEFT))
				while (--field_width > 0)
					*str++ = ' ';
			*str++ = (unsigned char) va_arg(args, int);
			while (--field_width > 0)
				*str++ = ' ';
			break;

		case 's':
			s = va_arg(args, char *);
			/********************************************
			 *stranger? why we need the following line?
			 ********************************************/
			//vPutString("\n");		//don't need it ...2005.05.20

			len = strlen(s);
			if (precision < 0)
				precision = len;
			else if (len > precision)
				len = precision;

			if (!(flags & LEFT))
				while (len < field_width--)
					*str++ = ' ';
			for (i = 0; i < len; ++i)
				*str++ = *s++;
			while (len < field_width--)
				*str++ = ' ';

			break;

		case 'o':
			str = sszSkip_itoa(str, va_arg(args, unsigned long), 8, field_width, precision, flags);
			break;

		case 'p':
			if (field_width == -1) {
				field_width = 8;
				flags |= ZEROPAD;
			}
			str = sszSkip_itoa(str, (unsigned long) va_arg(args, void *), 16, field_width, precision, flags);
			break;

		case 'x':
			flags |= SMALL|SPECIAL;
		case 'X':
			str = sszSkip_itoa(str, va_arg(args, unsigned long), 16, field_width, precision, flags);
			break;

		case 'd':
		case 'i':
			flags |= SIGN;
		case 'u':
			str = sszSkip_itoa(str, va_arg(args, unsigned long), 10, field_width, precision, flags);
			break;

		case 'n':
			ip = va_arg(args, int *);
			*ip = (str - szBuffer);
			break;

		default:
			if (*fmt != '%')
				*str++ = '%';
			if (*fmt)
				*str++ = *fmt;
			else
				--fmt;
			break;
		}
	}
	*str = '\0';

	return str-szBuffer;

}

⌨️ 快捷键说明

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