This is the mail archive of the
newlib@sourceware.org
mailing list for the newlib project.
Re: printf %F broken
- From: Eric Blake <ebb9 at byu dot net>
- To: newlib at sources dot redhat dot com
- Date: Wed, 11 Apr 2007 22:15:55 +0000 (UTC)
- Subject: Re: printf %F broken
- References: <loom.20070411T224424-636@post.gmane.org>
Eric Blake <ebb9 <at> byu.net> writes:
> OK to check this in now (even though I may be changing it later when I get
time
> to implement %a/%A)?
>
> 2007-04-11 Eric Blake <ebb9 <at> byu.net>
>
> * libc/stdio/vfprintf.c (_VFPRINTF_F): Don't confuse %F with %e.
Missed some cases in the last patch. printf("%2$F%1$n", &i, f) was also broken.
2007-04-11 Eric Blake <ebb9@byu.net>
* libc/stdio/vfprintf.c (_VFPRINTF_F, cvt): Don't confuse %F with %e.
(chclass): Recognize 'F', 'X', 'n', and not 'W'.
(get_arg): Handle %1$F, %1$n.
Index: libc/stdio/vfprintf.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/vfprintf.c,v
retrieving revision 1.48
diff -u -r1.48 vfprintf.c
--- libc/stdio/vfprintf.c 15 Mar 2007 18:40:48 -0000 1.48
+++ libc/stdio/vfprintf.c 11 Apr 2007 22:09:59 -0000
@@ -876,7 +876,7 @@
if (isinf (_fpvalue)) {
if (_fpvalue < 0)
sign = '-';
- if (ch == 'E' || ch == 'F' || ch == 'G')
+ if (ch <= 'G') /* 'E', 'F', or 'G' */
cp = "INF";
else
cp = "inf";
@@ -884,7 +884,7 @@
break;
}
if (isnan (_fpvalue)) {
- if (ch == 'E' || ch == 'F' || ch == 'G')
+ if (ch <= 'G') /* 'E', 'F', or 'G' */
cp = "NAN";
else
cp = "nan";
@@ -905,7 +905,7 @@
if (tmp == 2) {
if (_fpvalue < 0)
sign = '-';
- if (ch == 'E' || ch == 'F' || ch == 'G')
+ if (ch <= 'G') /* 'E', 'F', or 'G' */
cp = "INF";
else
cp = "inf";
@@ -913,7 +913,7 @@
break;
}
if (tmp == 1) {
- if (ch == 'E' || ch == 'F' || ch == 'G')
+ if (ch <= 'G') /* 'E', 'F', or 'G' */
cp = "NAN";
else
cp = "nan";
@@ -929,10 +929,12 @@
if (ch == 'g' || ch == 'G') {
if (expt <= -4 || expt > prec)
- ch = (ch == 'g') ? 'e' : 'E';
+ ch -= 2; /* 'e' or 'E' */
else
ch = 'g';
- }
+ }
+ else if (ch == 'F')
+ ch = 'f';
if (ch <= 'e') { /* 'e' or 'E' fmt */
--expt;
expsize = exponent (expstr, expt, ch);
@@ -1187,6 +1189,7 @@
* 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.
+ * If flags&FPT, ch must be in [eEfg].
*
* Compute actual size, so we know how much to pad.
* size excludes decimal prec; realsz includes it.
@@ -1338,7 +1341,7 @@
} ld;
#endif
- if (ch == 'f') {
+ if (ch == 'f' || ch == 'F') {
mode = 3; /* ndigits after the decimal point */
} else {
/* To obtain ndigits after the decimal point for the 'e'
@@ -1374,7 +1377,7 @@
if ((ch != 'g' && ch != 'G') || flags & ALT) { /* Print trailing zeros
*/
bp = digits + ndigits;
- if (ch == 'f') {
+ if (ch == 'f' || ch == 'F') {
if (*digits == '0' && value)
*decpt = -ndigits + 1;
bp += *decpt;
@@ -1505,12 +1508,12 @@
/* 28-2f */ OTHER, OTHER, STAR, FLAG, OTHER, FLAG, DOT,
OTHER,
/* 30-37 */ ZERO, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT,
DIGIT,
/* 38-3f */ DIGIT, DIGIT, OTHER, OTHER, OTHER, OTHER, OTHER,
OTHER,
- /* 40-47 */ OTHER, OTHER, OTHER, SPEC, SPEC, SPEC, OTHER,
SPEC,
+ /* 40-47 */ OTHER, OTHER, OTHER, SPEC, SPEC, SPEC, SPEC,
SPEC,
/* 48-4f */ OTHER, OTHER, OTHER, OTHER, MODFR, OTHER, OTHER,
SPEC,
- /* 50-57 */ OTHER, OTHER, OTHER, SPEC, OTHER, SPEC, OTHER,
SPEC,
- /* 58-5f */ OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
OTHER,
+ /* 50-57 */ OTHER, OTHER, OTHER, SPEC, OTHER, SPEC, OTHER,
OTHER,
+ /* 58-5f */ SPEC, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
OTHER,
/* 60-67 */ OTHER, OTHER, OTHER, SPEC, SPEC, SPEC, SPEC,
SPEC,
- /* 68-6f */ MODFR, SPEC, MODFR, OTHER, MODFR, OTHER, OTHER,
SPEC,
+ /* 68-6f */ MODFR, SPEC, MODFR, OTHER, MODFR, OTHER, SPEC,
SPEC,
/* 70-77 */ SPEC, MODFR, OTHER, SPEC, MODFR, SPEC, OTHER,
OTHER,
/* 78-7f */ SPEC, OTHER, MODFR, OTHER, OTHER, OTHER, OTHER,
OTHER,
/* 80-87 */ OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
OTHER,
@@ -1735,6 +1738,7 @@
spec_type = LONG_INT;
break;
case 'f':
+ case 'F':
case 'g':
case 'G':
case 'E':
@@ -1749,6 +1753,7 @@
case 's':
case 'S':
case 'p':
+ case 'n':
spec_type = CHAR_PTR;
break;
case 'c':