Deleted Added
full compact
41c41
< __FBSDID("$FreeBSD: head/lib/libc/stdio/vfprintf.c 113142 2003-04-05 22:03:43Z das $");
---
> __FBSDID("$FreeBSD: head/lib/libc/stdio/vfprintf.c 113146 2003-04-05 22:11:42Z das $");
114c114
< static char *__ujtoa(uintmax_t, char *, int, int, char *, int, char,
---
> static char *__ujtoa(uintmax_t, char *, int, int, const char *, int, char,
116c116
< static char *__ultoa(u_long, char *, int, int, char *, int, char,
---
> static char *__ultoa(u_long, char *, int, int, const char *, int, char,
188c188
< __ultoa(u_long val, char *endp, int base, int octzero, char *xdigs,
---
> __ultoa(u_long val, char *endp, int base, int octzero, const char *xdigs,
265c265
< __ujtoa(uintmax_t val, char *endp, int base, int octzero, char *xdigs,
---
> __ujtoa(uintmax_t val, char *endp, int base, int octzero, const char *xdigs,
409a410,414
>
> #define dtoa __dtoa
> #define freedtoa __freedtoa
>
> #include <float.h>
411a417
> #include "gdtoa.h"
415,418d420
< extern char *__dtoa(double, int, int, int *, int *, char **);
< extern void __freedtoa(char *s);
<
< static char *cvt(double, int, int, char *, int *, int, int *);
438d439
< #define HEXPREFIX 0x002 /* add 0x or 0X prefix */
467c468
< int prec; /* precision from format (%.3d), or -1 */
---
> int prec; /* precision from format; <0 for N/A */
471a473,486
> /*
> * We can decompose the printed representation of floating
> * point numbers into several parts, some of which may be empty:
> *
> * [+|-| ] [0x|0X] MMM . NNN [e|E|p|P] [+|-] ZZ
> * A B ---C--- D E F
> *
> * A: 'sign' holds this value if present; '\0' otherwise
> * B: ox[1] holds the 'x' or 'X'; '\0' if not hexadecimal
> * C: cp points to the string MMMNNN. Leading and trailing
> * zeros are not in the string and must be added.
> * D: expchar holds this character; '\0' if no exponent, e.g. %f
> * F: at least two digits for decimal, at least one digit for hex
> */
473,474c488,492
< char softsign; /* temporary negative sign for floats */
< double _double; /* double precision arguments %[eEfgG] */
---
> int signflag; /* true if float is negative */
> union { /* floating point arguments %[aAeEfFgG] */
> double dbl;
> long double ldbl;
> } fparg;
475a494,495
> char expchar; /* exponent character: [eEpP\0] */
> char *dtoaend; /* pointer to end of converted digits */
477,478c497,499
< int ndig; /* actual number of digits returned by cvt */
< char expstr[MAXEXPDIG+2]; /* buffer for exponent string */
---
> int lead; /* sig figs before decimal or group sep */
> int ndig; /* actual number of digits returned by dtoa */
> char expstr[MAXEXPDIG+2]; /* buffer for exponent string: e+ZZZ */
479a501,502
> int nseps; /* number of group separators with ' */
> int nrepeats; /* number of repeats of the last group */
488c511
< char *xdigs; /* digits for [xX] conversion */
---
> const char *xdigs; /* digits for %[xX] conversion */
493c516
< char ox[2]; /* space for 0x hex-prefix */
---
> char ox[2]; /* space for 0x; ox[1] is either x, X, or \0 */
510a534,536
> static const char xdigs_lower[16] = "0123456789abcdef";
> static const char xdigs_upper[16] = "0123456789ABCDEF";
>
649a676
> ox[1] = '\0';
803a831,855
> if (ch == 'a') {
> ox[1] = 'x';
> xdigs = xdigs_lower;
> expchar = 'p';
> } else {
> ox[1] = 'X';
> xdigs = xdigs_upper;
> expchar = 'P';
> }
> /*
> * XXX We don't actually have a conversion
> * XXX routine for this yet.
> */
> if (flags & LONGDBL) {
> fparg.ldbl = (double)GETARG(long double);
> dtoaresult = cp =
> __hldtoa(fparg.ldbl, xdigs, prec,
> &expt, &signflag, &dtoaend);
> } else {
> fparg.dbl = GETARG(double);
> dtoaresult = cp =
> __hdtoa(fparg.dbl, xdigs, prec,
> &expt, &signflag, &dtoaend);
> }
> goto fp_begin;
807,814c859,864
< /*-
< * Grouping apply to %i, %d, %u, %f, %F, %g, %G
< * conversion specifiers only. For other conversions
< * behavior is undefined.
< * -- POSIX
< */
< flags &= ~GROUPING;
< /*FALLTHROUGH*/
---
> expchar = ch;
> if (prec < 0) /* account for digit before decpt */
> prec = DEFPREC + 1;
> else
> prec++;
> goto fp_begin;
816a867
> expchar = '\0';
819a871
> expchar = ch - ('g' - 'e');
822c874,875
< fp_begin: if (prec == -1)
---
> fp_begin:
> if (prec < 0)
824,838c877,890
< if (flags & LONGDBL)
< /* XXX this loses precision. */
< _double = (double)GETARG(long double);
< else
< _double = GETARG(double);
< /* do this before tricky precision changes */
< if (isinf(_double)) {
< if (_double < 0)
< sign = '-';
< if (isupper(ch))
< cp = "INF";
< else
< cp = "inf";
< size = 3;
< break;
---
> if (dtoaresult != NULL)
> freedtoa(dtoaresult);
> if (flags & LONGDBL) {
> fparg.ldbl = GETARG(long double);
> dtoaresult = cp =
> __ldtoa(&fparg.ldbl, expchar ? 2 : 3, prec,
> &expt, &signflag, &dtoaend);
> } else {
> fparg.dbl = GETARG(double);
> dtoaresult = cp =
> dtoa(fparg.dbl, expchar ? 2 : 3, prec,
> &expt, &signflag, &dtoaend);
> if (expt == 9999)
> expt = INT_MAX;
840,844c892,899
< if (isnan(_double)) {
< if (isupper(ch))
< cp = "NAN";
< else
< cp = "nan";
---
> if (signflag)
> sign = '-';
> if (expt == INT_MAX) { /* inf or nan */
> if (*cp == 'N') {
> cp = (ch >= 'a') ? "nan" : "NAN";
> sign = '\0';
> } else
> cp = (ch >= 'a') ? "inf" : "INF";
849,854c904
< if (dtoaresult != NULL) {
< __freedtoa(dtoaresult);
< dtoaresult = NULL;
< }
< dtoaresult = cp = cvt(_double, prec, flags, &softsign,
< &expt, ch, &ndig);
---
> ndig = dtoaend - cp;
856,859c906,915
< if (expt <= -4 || expt > prec)
< ch = (ch == 'g') ? 'e' : 'E';
< else
< ch = 'g';
---
> if (expt > -4 && expt <= prec) {
> /* Make %[gG] smell like %[fF] */
> expchar = '\0';
> if (flags & ALT)
> prec -= expt;
> else
> prec = ndig - expt;
> if (prec < 0)
> prec = 0;
> }
861,865c917,920
< if (ch == 'e' || ch == 'E') {
< --expt;
< expsize = exponent(expstr, expt, ch);
< size = expsize + ndig;
< if (ndig > 1 || flags & ALT)
---
> if (expchar) {
> expsize = exponent(expstr, expt - 1, expchar);
> size = expsize + prec;
> if (prec || flags & ALT)
867c922
< } else if (ch == 'f' || ch == 'F') {
---
> } else {
874,883c929,946
< } else if (expt >= ndig) { /* fixed g fmt */
< size = expt;
< if (flags & ALT)
< ++size;
< } else
< size = ndig + (expt > 0 ?
< 1 : 2 - expt);
<
< if (softsign)
< sign = '-';
---
> if (grouping && expt > 0) {
> /* space for thousands' grouping */
> nseps = nrepeats = 0;
> lead = expt;
> while (*grouping != CHAR_MAX) {
> if (lead <= *grouping)
> break;
> lead -= *grouping;
> if (*(grouping+1)) {
> nseps++;
> grouping++;
> } else
> nrepeats++;
> }
> size += nseps + nrepeats;
> } else
> lead = (expt < ndig) ? expt : ndig;
> }
929,931c992,994
< xdigs = "0123456789abcdef";
< flags = flags | INTMAXT | HEXPREFIX;
< ch = 'x';
---
> xdigs = xdigs_lower;
> flags = flags | INTMAXT;
> ox[1] = 'x';
983c1046
< xdigs = "0123456789ABCDEF";
---
> xdigs = xdigs_upper;
986c1049
< xdigs = "0123456789abcdef";
---
> xdigs = xdigs_lower;
996c1059
< flags |= HEXPREFIX;
---
> ox[1] = ch;
1060c1123
< else if (flags & HEXPREFIX)
---
> else if (ox[1])
1076c1139
< } else if (flags & HEXPREFIX) {
---
> } else if (ox[1]) { /* ox[1] is either x, X, or \0 */
1078d1140
< ox[1] = ch;
1094,1104c1156,1160
< if (ch >= 'f') { /* 'f' or 'g' */
< if (_double == 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);
< PRINT(decimal_point, 1);
---
> if (!expchar) { /* %[fF] or sufficiently short %[gG] */
> if (expt <= 0) {
> buf[0] = '0';
> buf[1] = *decimal_point;
> PRINT(buf, 2);
1106,1111c1162,1163
< PRINT(cp, ndig);
< } else if (expt >= ndig) {
< PRINT(cp, ndig);
< PAD(expt - ndig, zeroes);
< if (flags & ALT)
< PRINT(decimal_point, 1);
---
> if (ndig > 0)
> PRINT(cp, ndig);
1113,1116c1165,1186
< PRINT(cp, expt);
< cp += expt;
< PRINT(decimal_point, 1);
< PRINT(cp, ndig-expt);
---
> PRINT(cp, lead);
> cp += lead;
> if (grouping) {
> while (nseps>0 || nrepeats>0) {
> if (nrepeats > 0)
> nrepeats--;
> else {
> grouping--;
> nseps--;
> }
> PRINT(&thousands_sep,
> 1);
> PRINT(cp, *grouping);
> cp += *grouping;
> }
> } else {
> PAD(expt - lead, zeroes);
> }
> if (prec || flags & ALT)
> PRINT(decimal_point,1);
> if (ndig > lead)
> PRINT(cp, ndig - lead);
1118,1127c1188,1195
< } else { /* 'e' or 'E' */
< if (ndig > 1 || flags & ALT) {
< ox[0] = *cp++;
< ox[1] = *decimal_point;
< PRINT(ox, 2);
< if (_double) {
< PRINT(cp, ndig-1);
< } else /* 0.[0..] */
< /* __dtoa irregularity */
< PAD(ndig - 1, zeroes);
---
> PAD(prec - ndig + expt, zeroes);
> } else { /* %[eE] or sufficiently long %[gG] */
> if (prec || flags & ALT) {
> buf[0] = *cp++;
> buf[1] = *decimal_point;
> PRINT(buf, 2);
> PRINT(cp, ndig-1);
> PAD(prec - ndig, zeroes);
1129a1198
>
1150c1219
< __freedtoa(dtoaresult);
---
> freedtoa(dtoaresult);
1520,1557d1588
< static char *
< cvt(double value, int ndigits, int flags, char *sign, int *decpt,
< int ch, int *length)
< {
< int mode, dsgn;
< char *digits, *bp, *rve;
<
< 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 */
< }
< digits = __dtoa(value, mode, ndigits, decpt, &dsgn, &rve);
< *sign = dsgn != 0;
< if ((ch != 'g' && ch != 'G') || flags & ALT) {
< /* print trailing zeros */
< bp = digits + ndigits;
< if (ch == 'f') {
< if ((*digits == '0' || *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);
< }
<
1581c1612,1619
< *p++ = '0';
---
> /*
> * Exponents for decimal floating point conversions
> * (%[eEgG]) must be at least two characters long,
> * whereas exponents for hexadecimal conversions can
> * be only one character long.
> */
> if (fmtch == 'e' || fmtch == 'E')
> *p++ = '0';