From 904322a50255c8384a7757555c856db2cfa9bcd7 Mon Sep 17 00:00:00 2001 From: David Schultz Date: Sun, 18 Jan 2004 08:28:32 +0000 Subject: [PATCH] Fix some bugs affecting the %a and %A format specifiers. Since these are not fully implemented and ifdef'd out, the bugs have never manifested themselves. Specifically: - Fix a memory leak in the case where %a follows another floating-point format. - Make the %a/%A code behave like %e/%E with respect to precision. - It is no longer valid to assume that '-' and '0x' are mutually exclusive. - Address other minor issues. --- lib/libc/stdio/vfprintf.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/lib/libc/stdio/vfprintf.c b/lib/libc/stdio/vfprintf.c index 19ce151f0f6a..8d048a35faf7 100644 --- a/lib/libc/stdio/vfprintf.c +++ b/lib/libc/stdio/vfprintf.c @@ -840,12 +840,16 @@ reswitch: switch (ch) { xdigs = xdigs_upper; expchar = 'P'; } + if (prec >= 0) + prec++; + if (dtoaresult != NULL) + freedtoa(dtoaresult); /* * XXX We don't actually have a conversion * XXX routine for this yet. */ if (flags & LONGDBL) { - fparg.ldbl = (double)GETARG(long double); + fparg.ldbl = GETARG(long double); dtoaresult = cp = __hldtoa(fparg.ldbl, xdigs, prec, &expt, &signflag, &dtoaend); @@ -855,8 +859,12 @@ reswitch: switch (ch) { __hdtoa(fparg.dbl, xdigs, prec, &expt, &signflag, &dtoaend); } - goto fp_begin; -#endif + if (prec < 0) + prec = dtoaend - cp; + if (expt == INT_MAX) + ox[1] = '\0'; + goto fp_common; +#endif /* HEXFLOAT */ case 'e': case 'E': expchar = ch; @@ -892,6 +900,7 @@ reswitch: switch (ch) { if (expt == 9999) expt = INT_MAX; } +fp_common: if (signflag) sign = '-'; if (expt == INT_MAX) { /* inf or nan */ @@ -1132,7 +1141,7 @@ number: if ((dprec = prec) >= 0) realsz = dprec > size ? dprec : size; if (sign) realsz++; - else if (ox[1]) + if (ox[1]) realsz += 2; prsize = width > realsz ? width : realsz; @@ -1146,9 +1155,10 @@ number: if ((dprec = prec) >= 0) PAD(width - realsz, blanks); /* prefix */ - if (sign) { + if (sign) PRINT(&sign, 1); - } else if (ox[1]) { /* ox[1] is either x, X, or \0 */ + + if (ox[1]) { /* ox[1] is either x, X, or \0 */ ox[0] = '0'; PRINT(ox, 2); }