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

📄 iovfprintf.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 2 页
字号:
			/* NOSTRICT */			_ulong = (unsigned long)va_arg(ap, void *);			base = HEX;			flags |= HEXPREFIX;			ch = 'x';			goto nosign;		case 's':			if ((cp = va_arg(ap, char *)) == NULL)				cp = "(null)";			if (prec >= 0) {				/*				 * can't use strlen; can only look for the				 * NUL in the first `prec' characters, and				 * strlen() will go further.				 */				char *p = (char*)memchr(cp, 0, prec);				if (p != NULL) {					size = p - cp;					if (size > prec)						size = prec;				} else					size = prec;			} else				size = strlen(cp);			sign = '\0';			break;		case 'U':			flags |= LONGINT;			/*FALLTHROUGH*/		case 'u':			_ulong = UARG();			base = DEC;			goto nosign;		case 'X':		case 'x':			_ulong = UARG();			base = HEX;			/* leading 0x/X only if non-zero */			if (flags & ALT && _ulong != 0)				flags |= HEXPREFIX;			/* unsigned conversions */nosign:			sign = '\0';			/*			 * ``... diouXx conversions ... if a precision is			 * specified, the 0 flag will be ignored.''			 *	-- ANSI X3J11			 */number:			if ((dprec = prec) >= 0)				flags &= ~ZEROPAD;			/*			 * ``The result of converting a zero value with an			 * explicit precision of zero is no characters.''			 *	-- ANSI X3J11			 */			cp = buf + BUF;			if (_ulong != 0 || prec != 0) {			        char *xdigs; /* digits for [xX] conversion */				/*				 * unsigned mod is hard, and unsigned mod				 * by a constant is easier than that by				 * a variable; hence this switch.				 */				switch (base) {				case OCT:					do {						*--cp = to_char(_ulong & 7);						_ulong >>= 3;					} while (_ulong);					/* handle octal leading 0 */					if (flags & ALT && *cp != '0')						*--cp = '0';					break;				case DEC:					/* many numbers are 1 digit */					while (_ulong >= 10) {						*--cp = to_char(_ulong % 10);						_ulong /= 10;					}					*--cp = to_char(_ulong);					break;				case HEX:					if (ch == 'X')					    xdigs = "0123456789ABCDEF";					else /* ch == 'x' || ch == 'p' */					    xdigs = "0123456789abcdef";					do {						*--cp = xdigs[_ulong & 15];						_ulong >>= 4;					} while (_ulong);					break;				default:					cp = "bug in vform: bad base";					goto skipsize;				}			}			size = buf + BUF - cp;		skipsize:			break;		default:	/* "%?" prints ?, unless ? is NUL */			if (ch == '\0')				goto done;			/* pretend it was %c with argument ch */			cp = buf;			*cp = ch;			size = 1;			sign = '\0';			break;		}		/*		 * All reasonable formats wind up here.  At this point,		 * `cp' points to a string which (if not flags&LADJUST)		 * should be padded out to `width' places.  If		 * flags&ZEROPAD, it should first be prefixed by any		 * sign or other prefix; otherwise, it should be blank		 * padded before the prefix is emitted.  After any		 * left-hand padding and prefixing, emit zeroes		 * required by a decimal [diouxX] precision, then print		 * the string proper, then emit zeroes required by any		 * leftover floating precision; finally, if LADJUST,		 * pad with blanks.		 */		/*		 * compute actual size, so we know how much to pad.		 */#if defined(FLOATING_POINT) && !defined (_IO_USE_DTOA)		fieldsz = size + fpprec;#else		fieldsz = size;#endif		dpad = dprec - size;		if (dpad < 0)		    dpad = 0;		if (sign)			fieldsz++;		else if (flags & HEXPREFIX)			fieldsz += 2;		fieldsz += dpad;		/* right-adjusting blank padding */		if ((flags & (LADJUST|ZEROPAD)) == 0)			PAD_SP(width - fieldsz);		/* prefix */		if (sign) {			PRINT(&sign, 1);		} else if (flags & HEXPREFIX) {			ox[0] = '0';			ox[1] = ch;			PRINT(ox, 2);		}		/* right-adjusting zero padding */		if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)			PAD_0(width - fieldsz);		/* leading zeroes from decimal precision */		PAD_0(dpad);		/* the string or number proper */		PRINT(cp, size);#if defined(FLOATING_POINT) && !defined (_IO_USE_DTOA)		/* trailing f.p. zeroes */		PAD_0(fpprec);#endif		/* left-adjusting padding (always blank) */		if (flags & LADJUST)			PAD_SP(width - fieldsz);		/* finally, adjust ret */		ret += width > fieldsz ? width : fieldsz;	}done:	return ret;error:	return EOF;	/* NOTREACHED */}#if defined(FLOATING_POINT) && !defined(_IO_USE_DTOA)static char *exponent(register char *p, register int exp, int fmtch){	register char *t;	char expbuf[MAXEXP];	*p++ = fmtch;	if (exp < 0) {		exp = -exp;		*p++ = '-';	}	else		*p++ = '+';	t = expbuf + MAXEXP;	if (exp > 9) {		do {			*--t = to_char(exp % 10);		} while ((exp /= 10) > 9);		*--t = to_char(exp);		for (; t < expbuf + MAXEXP; *p++ = *t++);	}	else {		*p++ = '0';		*p++ = to_char(exp);	}	return (p);}static char * round(double fract, int *exp,		    register char *start, register char *end,		    char ch, int *signp){	double tmp;	if (fract)	(void)modf(fract * 10, &tmp);	else		tmp = to_digit(ch);	if (tmp > 4)		for (;; --end) {			if (*end == '.')				--end;			if (++*end <= '9')				break;			*end = '0';			if (end == start) {				if (exp) {	/* e/E; increment exponent */					*end = '1';					++*exp;				}				else {		/* f; add extra digit */				*--end = '1';				--start;				}				break;			}		}	/* ``"%.3f", (double)-0.0004'' gives you a negative 0. */	else if (*signp == '-')		for (;; --end) {			if (*end == '.')				--end;			if (*end != '0')				break;			if (end == start)				*signp = 0;		}	return (start);}int __cvt_double(double number, register int prec, int flags, int *signp,		 int fmtch, char *startp, char *endp){	register char *p, *t;	register double fract;	int dotrim = 0, expcnt, gformat = 0;	double integer, tmp;	expcnt = 0;	if (number < 0) {		number = -number;		*signp = '-';	} else		*signp = 0;	fract = modf(number, &integer);	/* get an extra slot for rounding. */	t = ++startp;	/*	 * get integer portion of number; put into the end of the buffer; the	 * .01 is added for modf(356.0 / 10, &integer) returning .59999999...	 */	for (p = endp - 1; p >= startp && integer; ++expcnt) {		tmp = modf(integer / 10, &integer);		*p-- = to_char((int)((tmp + .01) * 10));	}	switch (fmtch) {	case 'f':	case 'F':		/* reverse integer into beginning of buffer */		if (expcnt)			for (; ++p < endp; *t++ = *p);		else			*t++ = '0';		/*		 * if precision required or alternate flag set, add in a		 * decimal point.		 */		if (prec || flags&ALT)			*t++ = '.';		/* if requires more precision and some fraction left */		if (fract) {			if (prec)				do {					fract = modf(fract * 10, &tmp);					*t++ = to_char((int)tmp);				} while (--prec && fract);			if (fract)				startp = round(fract, (int *)NULL, startp,				    t - 1, (char)0, signp);		}		for (; prec--; *t++ = '0');		break;	case 'e':	case 'E':eformat:	if (expcnt) {			*t++ = *++p;			if (prec || flags&ALT)				*t++ = '.';			/* if requires more precision and some integer left */			for (; prec && ++p < endp; --prec)				*t++ = *p;			/*			 * if done precision and more of the integer component,			 * round using it; adjust fract so we don't re-round			 * later.			 */			if (!prec && ++p < endp) {				fract = 0;				startp = round((double)0, &expcnt, startp,				    t - 1, *p, signp);			}			/* adjust expcnt for digit in front of decimal */			--expcnt;		}		/* until first fractional digit, decrement exponent */		else if (fract) {			/* adjust expcnt for digit in front of decimal */			for (expcnt = -1;; --expcnt) {				fract = modf(fract * 10, &tmp);				if (tmp)					break;			}			*t++ = to_char((int)tmp);			if (prec || flags&ALT)				*t++ = '.';		}		else {			*t++ = '0';			if (prec || flags&ALT)				*t++ = '.';		}		/* if requires more precision and some fraction left */		if (fract) {			if (prec)				do {					fract = modf(fract * 10, &tmp);					*t++ = to_char((int)tmp);				} while (--prec && fract);			if (fract)				startp = round(fract, &expcnt, startp,				    t - 1, (char)0, signp);		}		/* if requires more precision */		for (; prec--; *t++ = '0');		/* unless alternate flag, trim any g/G format trailing 0's */		if (gformat && !(flags&ALT)) {			while (t > startp && *--t == '0');			if (*t == '.')				--t;			++t;		}		t = exponent(t, expcnt, fmtch);		break;	case 'g':	case 'G':		/* a precision of 0 is treated as a precision of 1. */		if (!prec)			++prec;		/*		 * ``The style used depends on the value converted; style e		 * will be used only if the exponent resulting from the		 * conversion is less than -4 or greater than the precision.''		 *	-- ANSI X3J11		 */		if (expcnt > prec || (!expcnt && fract && fract < .0001)) {			/*			 * g/G format counts "significant digits, not digits of			 * precision; for the e/E format, this just causes an			 * off-by-one problem, i.e. g/G considers the digit			 * before the decimal point significant and e/E doesn't			 * count it as precision.			 */			--prec;			fmtch -= 2;		/* G->E, g->e */			gformat = 1;			goto eformat;		}		/*		 * reverse integer into beginning of buffer,		 * note, decrement precision		 */		if (expcnt)			for (; ++p < endp; *t++ = *p, --prec);		else			*t++ = '0';		/*		 * if precision required or alternate flag set, add in a		 * decimal point.  If no digits yet, add in leading 0.		 */		if (prec || flags&ALT) {			dotrim = 1;			*t++ = '.';		}		else			dotrim = 0;		/* if requires more precision and some fraction left */		if (fract) {			if (prec) {				/* If no integer part, don't count initial				 * zeros as significant digits. */				do {					fract = modf(fract * 10, &tmp);					*t++ = to_char((int)tmp);				} while(!tmp && !expcnt);				while (--prec && fract) {					fract = modf(fract * 10, &tmp);					*t++ = to_char((int)tmp);				}			}			if (fract)				startp = round(fract, (int *)NULL, startp,				    t - 1, (char)0, signp);		}		/* alternate format, adds 0's for precision, else trim 0's */		if (flags&ALT)			for (; prec--; *t++ = '0');		else if (dotrim) {			while (t > startp && *--t == '0');			if (*t != '.')				++t;		}	}	return (t - startp);}#endif /* defined(FLOATING_POINT) && !defined(_IO_USE_DTOA) */

⌨️ 快捷键说明

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