📄 vfprintf.c
字号:
*va_arg(ap, long *) = ret; else if (flags & SHORTINT) *va_arg(ap, short *) = ret; else *va_arg(ap, int *) = ret; continue; /* no output */ case 'O': flags |= LONGINT; /*FALLTHROUGH*/ case 'o':#ifdef __ALTIVEC__ if (!(flags & VECTOR) && vec_sep != ' ') { fmt = format_anchor; continue; }#endif /* __ALTIVEC__ */ _uquad = UARG(); base = OCT; goto nosign; case 'p': /* * ``The argument shall be a pointer to void. The * value of the pointer is converted to a sequence * of printable characters, in an implementation- * defined manner.'' * -- ANSI X3J11 */ /* NOSTRICT */#ifdef __ALTIVEC__ if (flags & VECTOR) _uquad = UARG(); else if (vec_sep != ' ') { fmt = format_anchor; continue; } else#endif /* __ALTIVEC__ */ _uquad = (u_long)(unsigned _POINTER_INT)va_arg(ap, void *); base = HEX; xdigs = "0123456789abcdef"; flags |= HEXPREFIX; ch = 'x'; goto nosign; case 's':#ifdef __ALTIVEC__ if (flags & VECTOR) { fmt = format_anchor; continue; }#endif /* __ALTIVEC__ */ 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 = 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':#ifdef __ALTIVEC__ if (!(flags & VECTOR) && vec_sep != ' ') { fmt = format_anchor; continue; }#endif /* __ALTIVEC__ */ _uquad = UARG(); base = DEC; goto nosign; case 'X': xdigs = "0123456789ABCDEF"; goto hex; case 'x': xdigs = "0123456789abcdef";#ifdef __ALTIVEC__ if (!(flags & VECTOR) && vec_sep != ' ') { fmt = format_anchor; continue; }#endif /* __ALTIVEC__ */hex: _uquad = UARG(); base = HEX; /* leading 0x/X only if non-zero */ if (flags & ALT && _uquad != 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 (_uquad != 0 || prec != 0) { /* * 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(_uquad & 7); _uquad >>= 3; } while (_uquad); /* handle octal leading 0 */ if (flags & ALT && *cp != '0') *--cp = '0'; break; case DEC: /* many numbers are 1 digit */ while (_uquad >= 10) { *--cp = to_char(_uquad % 10); _uquad /= 10; } *--cp = to_char(_uquad); break; case HEX: do { *--cp = xdigs[_uquad & 15]; _uquad >>= 4; } while (_uquad); break; default: cp = "bug in vfprintf: bad base"; size = strlen(cp); goto skipsize; } } /* * ...result is to be converted to an 'alternate form'. * For o conversion, it increases the precision to force * the first digit of the result to be a zero." * -- ANSI X3J11 * * To demonstrate this case, compile and run: * printf ("%#.0o",0); */ else if (base == OCT && (flags & ALT)) *--cp = '0'; size = buf + BUF - cp; skipsize: break; default: /* "%?" prints ?, unless ? is NUL */ flags &= ~VECTOR; 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. * size excludes decimal prec; realsz includes it. */ realsz = dprec > size ? dprec : size; if (sign) realsz++; else if (flags & HEXPREFIX) realsz+= 2; /* right-adjusting blank padding */ if ((flags & (LADJUST|ZEROPAD)) == 0) PAD(width - realsz, blanks); /* 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(width - realsz, zeroes); /* leading zeroes from decimal precision */ PAD(dprec - size, zeroes); /* the string or number proper */#ifdef FLOATING_POINT if ((flags & FPT) == 0) {#ifdef __SPE__ if (flags & FIXEDPOINT) { if (_uquad == 0 && !sign) { /* kludge for __dtoa irregularity */ PRINT("0", 1); if (expt < ndig || (flags & ALT) != 0) { PRINT(decimal_point, 1); PAD(ndig - 1, zeroes); } } else if (expt <= 0) { PRINT("0", 1); if(expt || ndig) { PRINT(decimal_point, 1); PAD(-expt, zeroes); PRINT(cp, ndig); } } else if (expt >= ndig) { PRINT(cp, ndig); PAD(expt - ndig, zeroes); if (flags & ALT) PRINT(".", 1); } else { PRINT(cp, expt); cp += expt; PRINT(".", 1); PRINT(cp, ndig-expt); } } else#endif /* __SPE__ */ PRINT(cp, size); } else { /* glue together f_p fragments */ if (ch >= 'f') { /* 'f' or 'g' */ if (_fpvalue == 0) { /* kludge for __dtoa irregularity */ PRINT("0", 1); if (expt < ndig || (flags & ALT) != 0) { PRINT(decimal_point, 1); PAD(ndig - 1, zeroes); } } else if (expt <= 0) { PRINT("0", 1); if(expt || ndig) { PRINT(decimal_point, 1); PAD(-expt, zeroes); PRINT(cp, ndig); } } else if (expt >= ndig) { PRINT(cp, ndig); PAD(expt - ndig, zeroes); if (flags & ALT) PRINT(".", 1); } else { PRINT(cp, expt); cp += expt; PRINT(".", 1); PRINT(cp, ndig-expt); } } else { /* 'e' or 'E' */ if (ndig > 1 || flags & ALT) { ox[0] = *cp++; ox[1] = '.'; PRINT(ox, 2); if (_fpvalue) { PRINT(cp, ndig-1); } else /* 0.[0..] */ /* __dtoa irregularity */ PAD(ndig - 1, zeroes); } else /* XeYYY */ PRINT(cp, 1); PRINT(expstr, expsize); } }#else PRINT(cp, size);#endif /* left-adjusting padding (always blank) */ if (flags & LADJUST) PAD(width - realsz, blanks); /* finally, adjust ret */ ret += width > realsz ? width : realsz;#ifdef __ALTIVEC__ if ((flags & VECTOR) && vec_print_count-- > 1) { /* add vector separator */ if (ch != 'c' || vec_sep != ' ') { PRINT(&vec_sep, 1); ret += 1; } FLUSH(); sign = old_sign; ch = old_ch; goto reswitch; }#endif /* __ALTIVEC__ */ FLUSH(); /* copy out the I/O vectors */ }done: FLUSH();error: return (__sferror(fp) ? EOF : ret); /* NOTREACHED */}#ifdef FLOATING_POINT#ifdef _NO_LONGDBLextern char *_dtoa_r _PARAMS((struct _reent *, double, int, int, int *, int *, char **));#elseextern char *_ldtoa_r _PARAMS((struct _reent *, _LONG_DOUBLE, int, int, int *, int *, char **));#undef word0#define word0(x) ldword0(x)#endifstatic char *cvt(data, value, ndigits, flags, sign, decpt, ch, length) struct _reent *data;#ifdef _NO_LONGDBL double value;#else _LONG_DOUBLE value;#endif int ndigits, flags, *decpt, ch, *length; char *sign;{ int mode, dsgn; char *digits, *bp, *rve;#ifdef _NO_LONGDBL union double_union tmp;#else struct ldieee *ldptr;#endif if (ch == 'f') { mode = 3; /* ndigits after the decimal point */ } else { /* To obtain ndigits after the decimal point for the 'e' * and 'E' formats, round to ndigits + 1 significant * figures. */ if (ch == 'e' || ch == 'E') { ndigits++; } mode = 2; /* ndigits significant digits */ }#ifdef _NO_LONGDBL tmp.d = value; if (word0(tmp) & Sign_bit) { /* this will check for < 0 and -0.0 */ value = -value; *sign = '-'; } else *sign = '\000'; digits = _dtoa_r(data, value, mode, ndigits, decpt, &dsgn, &rve);#else /* !_NO_LONGDBL */ ldptr = (struct ldieee *)&value; if (ldptr->sign) { /* this will check for < 0 and -0.0 */ value = -value; *sign = '-'; } else *sign = '\000'; digits = _ldtoa_r(data, value, mode, ndigits, decpt, &dsgn, &rve);#endif /* !_NO_LONGDBL */ if ((ch != 'g' && ch != 'G') || flags & ALT) { /* Print trailing zeros */ bp = digits + ndigits; if (ch == 'f') { if (*digits == '0' && value) *decpt = -ndigits + 1; bp += *decpt; } if (value == 0) /* kludge for __dtoa irregularity */ rve = bp; while (rve < bp) *rve++ = '0'; } *length = rve - digits; return (digits);}static intexponent(p0, exp, fmtch) char *p0; int exp, fmtch;{ register char *p, *t; char expbuf[40]; p = p0; *p++ = fmtch; if (exp < 0) { exp = -exp; *p++ = '-'; } else *p++ = '+'; t = expbuf + 40; if (exp > 9) { do { *--t = to_char(exp % 10); } while ((exp /= 10) > 9); *--t = to_char(exp); for (; t < expbuf + 40; *p++ = *t++); } else { *p++ = '0'; *p++ = to_char(exp); } return (p - p0);}#endif /* FLOATING_POINT */#ifdef __SPE__extern char *_ufix64toa_r _PARAMS((struct _reent *, unsigned long long, int, int, int *, int *, char **));static char *cvt_ufix64 (data, value, ndigits, decpt, length) struct _reent *data; unsigned long long value; int ndigits, *decpt, *length;{ int dsgn; char *digits, *bp, *rve; /* treat the same as %f format and use mode=3 */ digits = _ufix64toa_r (data, value, 3, ndigits, decpt, &dsgn, &rve); /* print trailing zeroes */ bp = digits + ndigits; if (*digits == '0' && value) *decpt = -ndigits + 1; bp += *decpt; if (value == 0) /* kludge for __dtoa irregularity */ rve = bp; while (rve < bp) *rve++ = '0'; *length = rve - digits; return (digits);}#endif /* __SPE__ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -