📄 ut7_vsprintf.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 + -