Deleted Added
full compact
42c42
< __FBSDID("FreeBSD: src/lib/libc/stdio/vfprintf.c,v 1.52 2003/03/14 04:48:09 das Exp");
---
> __FBSDID("FreeBSD: src/lib/libc/stdio/vfprintf.c,v 1.57 2003/04/07 03:17:39 ache Exp");
44c44
< __FBSDID("$FreeBSD: head/lib/libc/stdio/vfwprintf.c 113143 2003-04-05 22:08:53Z das $");
---
> __FBSDID("$FreeBSD: head/lib/libc/stdio/vfwprintf.c 113199 2003-04-07 06:36:49Z tjr $");
117,120c117,120
< static wchar_t *__ujtoa(uintmax_t, wchar_t *, int, int, wchar_t *, int, char,
< const char *);
< static wchar_t *__ultoa(u_long, wchar_t *, int, int, wchar_t *, int, char,
< const char *);
---
> static wchar_t *__ujtoa(uintmax_t, wchar_t *, int, int, const wchar_t *, int,
> char, const char *);
> static wchar_t *__ultoa(u_long, wchar_t *, int, int, const wchar_t *, int,
> char, const char *);
172c172
< __ultoa(u_long val, wchar_t *endp, int base, int octzero, wchar_t *xdigs,
---
> __ultoa(u_long val, wchar_t *endp, int base, int octzero, const wchar_t *xdigs,
249,250c249,250
< __ujtoa(uintmax_t val, wchar_t *endp, int base, int octzero, wchar_t *xdigs,
< int needgrp, char thousep, const char *grp)
---
> __ujtoa(uintmax_t val, wchar_t *endp, int base, int octzero,
> const wchar_t *xdigs, int needgrp, char thousep, const char *grp)
332a333,335
> if (mbsarg == NULL)
> return (NULL);
>
402a406,409
>
> #define dtoa __dtoa
> #define freedtoa __freedtoa
>
405a413
> #include "gdtoa.h"
409,412d416
< extern char *__dtoa(double, int, int, int *, int *, char **);
< extern void __freedtoa(char *s);
<
< static wchar_t *cvt(double, int, int, char *, int *, wchar_t, int *);
432d435
< #define HEXPREFIX 0x002 /* add 0x or 0X prefix */
455c458
< int n, n2; /* handy integer (short term usage) */
---
> int n, n2, n3; /* handy integer (short term usage) */
460c463
< int prec; /* precision from format (%.3d), or -1 */
---
> int prec; /* precision from format; <0 for N/A */
464a468,481
> /*
> * 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
> */
466,467c483,487
< 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;
468a489,490
> char expchar; /* exponent character: [eEpP\0] */
> char *dtoaend; /* pointer to end of converted digits */
470,472c492,497
< int ndig; /* actual number of digits returned by cvt */
< wchar_t expstr[7]; /* buffer for exponent string */
< wchar_t *dtoaresult; /* buffer allocated by dtoa */
---
> int lead; /* sig figs before decimal or group sep */
> int ndig; /* actual number of digits returned by dtoa */
> wchar_t expstr[MAXEXPDIG+2]; /* buffer for exponent string: e+ZZZ */
> char *dtoaresult; /* buffer allocated by dtoa */
> int nseps; /* number of group separators with ' */
> int nrepeats; /* number of repeats of the last group */
481c506
< wchar_t *xdigs; /* digits for [xX] conversion */
---
> const wchar_t *xdigs; /* digits for [xX] conversion */
500a526,528
> static const wchar_t xdigs_lower[16] = L"0123456789abcdef";
> static const wchar_t xdigs_upper[16] = L"0123456789ABCDEF";
>
506,507c534,535
< for (n2 = 0; n2 < (len); n2++) \
< __fputwc((ptr)[n2], fp); \
---
> for (n3 = 0; n3 < (len); n3++) \
> __fputwc((ptr)[n3], fp); \
517a546,553
> #define PRINTANDPAD(p, ep, len, with) do { \
> n2 = (ep) - (p); \
> if (n2 > (len)) \
> n2 = (len); \
> if (n2 > 0) \
> PRINT((p), n2); \
> PAD((len) - (n2 > 0 ? n2 : 0), (with)); \
> } while(0)
583d618
< dtoaresult = NULL;
624a660
> ox[1] = '\0';
665,666c701
< GETASTER (n);
< prec = n < 0 ? -1 : n;
---
> GETASTER (prec);
669c704
< n = 0;
---
> prec = 0;
671c706
< n = 10 * n + to_digit(ch);
---
> prec = 10 * prec + to_digit(ch);
674d708
< prec = n < 0 ? -1 : n;
767a802,830
> 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 =
> __hldtoa(fparg.ldbl, xdigs, prec,
> &expt, &signflag, &dtoaend);
> } else {
> fparg.dbl = GETARG(double);
> dtoaresult =
> __hdtoa(fparg.dbl, xdigs, prec,
> &expt, &signflag, &dtoaend);
> }
> if (convbuf != NULL)
> free(convbuf);
> cp = convbuf = __mbsconv(dtoaresult, -1);
> freedtoa(dtoaresult);
> goto fp_begin;
771,778c834,839
< /*-
< * 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;
780a842
> expchar = '\0';
783a846
> expchar = ch - ('g' - 'e');
786c849,850
< fp_begin: if (prec == -1)
---
> fp_begin:
> if (prec < 0)
788,802c852,865
< 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 (iswupper(ch))
< cp = L"INF";
< else
< cp = L"inf";
< size = 3;
< break;
---
> if (convbuf != NULL)
> free(convbuf);
> if (flags & LONGDBL) {
> fparg.ldbl = GETARG(long double);
> dtoaresult =
> __ldtoa(&fparg.ldbl, expchar ? 2 : 3, prec,
> &expt, &signflag, &dtoaend);
> } else {
> fparg.dbl = GETARG(double);
> dtoaresult =
> dtoa(fparg.dbl, expchar ? 2 : 3, prec,
> &expt, &signflag, &dtoaend);
> if (expt == 9999)
> expt = INT_MAX;
804,808c867,877
< if (isnan(_double)) {
< if (iswupper(ch))
< cp = L"NAN";
< else
< cp = L"nan";
---
> ndig = dtoaend - dtoaresult;
> cp = convbuf = __mbsconv(dtoaresult, -1);
> freedtoa(dtoaresult);
> if (signflag)
> sign = '-';
> if (expt == INT_MAX) { /* inf or nan */
> if (*cp == 'N') {
> cp = (ch >= 'a') ? L"nan" : L"NAN";
> sign = '\0';
> } else
> cp = (ch >= 'a') ? L"inf" : L"INF";
813,818d881
< if (dtoaresult != NULL) {
< free(dtoaresult);
< dtoaresult = NULL;
< }
< dtoaresult = cp = cvt(_double, prec, flags, &softsign,
< &expt, ch, &ndig);
820,823c883,892
< 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;
> }
825,829c894,897
< 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 > 1 || flags & ALT)
831c899
< } else if (ch == 'f' || ch == 'F') {
---
> } else {
838,847c906,923
< } 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;
> }
893,895c969,971
< xdigs = L"0123456789abcdef";
< flags = flags | INTMAXT | HEXPREFIX;
< ch = 'x';
---
> xdigs = xdigs_lower;
> flags = flags | INTMAXT;
> ox[1] = 'x';
950c1026
< xdigs = L"0123456789ABCDEF";
---
> xdigs = xdigs_upper;
953c1029
< xdigs = L"0123456789abcdef";
---
> xdigs = xdigs_lower;
963c1039
< flags |= HEXPREFIX;
---
> ox[1] = ch;
1027c1103
< else if (flags & HEXPREFIX)
---
> else if (ox[1])
1043c1119
< } else if (flags & HEXPREFIX) {
---
> } else if (ox[1]) { /* ox[1] is either x, X, or \0 */
1045d1120
< ox[1] = ch;
1061,1071c1136,1140
< if (ch >= 'f') { /* 'f' or 'g' */
< if (_double == 0) {
< /* kludge for __dtoa irregularity */
< PRINT(L"0", 1);
< if (expt < ndig || (flags & ALT) != 0) {
< PRINT(decimal_point, 1);
< PAD(ndig - 1, zeroes);
< }
< } else if (expt <= 0) {
< PRINT(L"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);
1073,1078c1142,1143
< PRINT(cp, ndig);
< } else if (expt >= ndig) {
< PRINT(cp, ndig);
< PAD(expt - ndig, zeroes);
< if (flags & ALT)
< PRINT(decimal_point, 1);
---
> /* already handled initial 0's */
> prec += expt;
1080,1083c1145,1168
< PRINT(cp, expt);
< cp += expt;
< PRINT(decimal_point, 1);
< PRINT(cp, ndig-expt);
---
> PRINTANDPAD(cp, convbuf + ndig, lead, zeroes);
> cp += lead;
> if (grouping) {
> while (nseps>0 || nrepeats>0) {
> if (nrepeats > 0)
> nrepeats--;
> else {
> grouping--;
> nseps--;
> }
> PRINT(&thousands_sep,
> 1);
> PRINTANDPAD(cp,
> convbuf + ndig,
> *grouping, zeroes);
> cp += *grouping;
> }
> if (cp > convbuf + ndig)
> cp = convbuf + ndig;
> }
> if (prec || flags & ALT) {
> buf[0] = *decimal_point;
> PRINT(buf, 1);
> }
1085,1094c1170,1177
< } 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);
---
> PRINTANDPAD(cp, convbuf + ndig, prec, zeroes);
> } else { /* %[eE] or sufficiently long %[gG] */
> if (prec > 1 || flags & ALT) {
> buf[0] = *cp++;
> buf[1] = *decimal_point;
> PRINT(buf, 2);
> PRINT(cp, ndig-1);
> PAD(prec - ndig, zeroes);
1112,1115d1194
< #ifdef FLOATING_POINT
< if (dtoaresult != NULL)
< free(dtoaresult);
< #endif
1484,1529d1562
< static wchar_t *
< cvt(double value, int ndigits, int flags, char *sign, int *decpt,
< wchar_t ch, int *length)
< {
< int i, mode, dsgn;
< wchar_t *digits, *bp, *result, *rve;
< char *tresult, *trve;
<
< 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 */
< }
< tresult = __dtoa(value, mode, ndigits, decpt, &dsgn, &trve);
< if ((result = malloc((trve - tresult + 1) * sizeof(*result))) == NULL)
< abort(); /* XXX handle better */
< for (i = 0; i < trve - tresult + 1; i++)
< result[i] = (wchar_t)(unsigned char)tresult[i];
< rve = result + (trve - tresult);
< __freedtoa(tresult);
< digits = result;
< *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);
< }
<
1553c1586,1593
< *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';