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

📄 vsprintf.c

📁 Intel PXA270的bootloader程序,在linux环境下运行的.
💻 C
字号:
#include <types.h>#include <ctype.h>#include <stdarg.h>#include <string.h>extern int vsprintf(char *buf, const char *fmt, va_list args);#define do_div(n, base)												\			({														\				int	__res;											\				__res = ((unsigned long)(n)) % (unsigned) (base);	\				(n) = ((unsigned long)(n)) / (unsigned)(base);		\				__res;												\			})static int skip_atoi(const char **s){	int i=0;	while (isdigit(**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 LARGE	64		// use 'ABCDEF' instead of 'abcdef'.static char *number(char * str, long long num, int base, int size, int precision, int type){	char c,sign,tmp[66];	const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";	int i;	if (type & LARGE) digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";	if (type & LEFT) type &= ~ZEROPAD;	if (base < 2 || base > 36) return 0;	c = (type & ZEROPAD) ? '0' : ' ';	sign = 0;	if (type & SIGN){		if (num < 0){			sign = '-';			num = -num;			size--;		} else if (type & PLUS){			sign = '+';			size--;		} else if (type & SPACE){			sign = ' ';			size--;		}	}	if (type & SPECIAL) {		if (base == 16)			size -= 2;		else if (base == 8)			size--;	}	i = 0;	if (num == 0) tmp[i++]='0';	else {		while (num != 0) tmp[i++] = digits[do_div(num,base)];	}		if (i > precision) precision = i;	size -= precision;	if (!(type&(ZEROPAD+LEFT)))		while(size-->0) *str++ = ' ';	if (sign) *str++ = sign;	if (type & SPECIAL) {		if (base==8)			*str++ = '0';		else if (base==16) {			*str++ = '0';			*str++ = digits[33];		}	}	if (!(type & LEFT))		while (size-- > 0)			*str++ = c;	while (i < precision--)		*str++ = '0';	while (i-- > 0)		*str++ = tmp[i];	while (size-- > 0)		*str++ = ' ';	return str;}/** * vsprintf - Format a string and place it in a buffer * @buf: The buffer to place the result into * @fmt: The format string to use * @args: Arguments for the format string * * Call this function if you are already dealing with a va_list. * You probably want sprintf instead. */extern int vsprintf(char *buf, const char *fmt, va_list args){	int len;	unsigned long long num;	int i, base;	char *str;	const char *s;	int flags;			// flags to number().	int field_width;	// width of output field.	int precision;		// min. # of digits for integers; max number of chars for from string.	int qualifier;		// 'h', 'l', or 'L' for integer fields.						// 'z' support added 23/7/1999 S.H.						// 'z' changed to 'Z' --davidm 1/25/99.	for (str=buf ; *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 (isdigit(*fmt))			field_width = skip_atoi(&fmt);		else if (*fmt == '*'){			++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 (isdigit(*fmt))				precision = skip_atoi(&fmt);			else if (*fmt == '*'){				++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' || *fmt =='Z'){			qualifier = *fmt;			++fmt;		}		/* default base */		base = 10;		switch (*fmt){			case 'c':				if (!(flags & LEFT))					while (--field_width > 0)						*str++ = ' ';				*str++ = (unsigned char) va_arg(args, int);				while (--field_width > 0)					*str++ = ' ';				continue;				case 's':				s = va_arg(args, char *);				if (!s)					s = "<NULL>";					len = strnlen(s, precision);					if (!(flags & LEFT))					while (len < field_width--)						*str++ = ' ';				for (i = 0; i < len; ++i)					*str++ = *s++;				while (len < field_width--)					*str++ = ' ';				continue;			case 'p':				if (field_width == -1){					field_width = 2*sizeof(void *);					flags |= ZEROPAD;				}				str = number(str, (unsigned long) va_arg(args, void *), 16, field_width, precision, flags);				continue;			case 'n':				if (qualifier == 'l'){					long * ip = va_arg(args, long *);					*ip = (str - buf);				} else if (qualifier == 'Z'){					uint * ip = va_arg(args, uint *);					*ip = (str - buf);				} else {					int * ip = va_arg(args, int *);					*ip = (str - buf);				}				continue;			case '%':				*str++ = '%';				continue;			case 'o':		// integer number formats - set up the flags and "break".				base = 8;				break;			case 'X':				flags |= LARGE;			case 'x':				base = 16;				break;			case 'd':			case 'i':				flags |= SIGN;			case 'u':				break;			default:				*str++ = '%';				if (*fmt)	*str++ = *fmt;				else		--fmt;				continue;		}		if (qualifier == 'L')			num = va_arg(args, long long);		else if (qualifier == 'l'){			num = va_arg(args, unsigned long);			if (flags & SIGN)				num = (signed long) num;		} else if (qualifier == 'Z'){			num = va_arg(args, uint);		} else if (qualifier == 'h'){			num = (unsigned short) va_arg(args, int);			if (flags & SIGN)				num = (signed short) num;		} else {			num = va_arg(args, unsigned int);			if (flags & SIGN)				num = (signed int) num;		}		str = number(str, num, base, field_width, precision, flags);	}	*str = '\0';	return str-buf;}/** * sprintf - Format a string and place it in a buffer * @buf: The buffer to place the result into * @fmt: The format string to use * @...: Arguments for the format string */int sprintf(char *buf, const char *fmt, ...){	va_list args;	int i;	va_start(args, fmt);	i=vsprintf(buf,fmt,args);	va_end(args);	return i;}

⌨️ 快捷键说明

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