Another bug (maybe I'm having too much fun finding all these printf
anomalies? :). If wint_t promotes differently than int, then %1$lc was broken
(but %1$C worked). While I was at it, I tried to reduce code size a bit.
2007-04-24 Eric Blake <ebb9@byu.net>
* libc/stdio/vfprintf.c (get_arg): Support %1$lc. Simplify types
that promote to int.
Index: libc/stdio/vfprintf.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/vfprintf.c,v
retrieving revision 1.53
diff -u -r1.53 vfprintf.c
--- libc/stdio/vfprintf.c 24 Apr 2007 20:09:50 -0000 1.53
+++ libc/stdio/vfprintf.c 24 Apr 2007 20:27:22 -0000
@@ -1603,7 +1603,8 @@
ACTION action;
int pos, last_arg;
int max_pos_arg = n;
- enum types { INT, LONG_INT, SHORT_INT, CHAR_INT, QUAD_INT, CHAR, CHAR_PTR,
DOUBLE, LONG_DOUBLE, WIDE_CHAR };
+ /* Only need types that can be reached via vararg promotions. */
+ enum types { INT, LONG_INT, QUAD_INT, CHAR_PTR, DOUBLE, LONG_DOUBLE,
WIDE_CHAR };
#ifdef _MB_CAPABLE
wchar_t wc;
mbstate_t wc_state;
@@ -1662,13 +1663,7 @@
switch (ch)
{
case 'h':
- if (*fmt == 'h')
- {
- flags |= CHARINT;
- ++fmt;
- }
- else
- flags |= SHORTINT;
+ /* No flag needed, since short and char promote to int. */
break;
case 'L':
flags |= LONGDBL;
@@ -1683,10 +1678,7 @@
flags |= QUADINT;
break;
case 'z':
- if (sizeof (size_t) < sizeof (int))
- /* POSIX states size_t is 16 or more bits, as is short. */
- flags |= SHORTINT;
- else if (sizeof (size_t) == sizeof (int))
+ if (sizeof (size_t) <= sizeof (int))
/* no flag needed */;
else if (sizeof (size_t) <= sizeof (long))
flags |= LONGINT;
@@ -1698,11 +1690,7 @@
flags |= QUADINT;
break;
case 't':
- if (sizeof (ptrdiff_t) < sizeof (int))
- /* POSIX states ptrdiff_t is 16 or more bits, as
- is short. */
- flags |= SHORTINT;
- else if (sizeof (ptrdiff_t) == sizeof (int))
+ if (sizeof (ptrdiff_t) <= sizeof (int))
/* no flag needed */;
else if (sizeof (ptrdiff_t) <= sizeof (long))
flags |= LONGINT;
@@ -1739,10 +1727,6 @@
case 'u':
if (flags & LONGINT)
spec_type = LONG_INT;
- else if (flags & SHORTINT)
- spec_type = SHORT_INT;
- else if (flags & CHARINT)
- spec_type = CHAR_INT;
#ifndef _NO_LONGLONG
else if (flags & QUADINT)
spec_type = QUAD_INT;
@@ -1775,7 +1759,10 @@
spec_type = CHAR_PTR;
break;
case 'c':
- spec_type = CHAR;
+ if (flags & LONGINT)
+ spec_type = WIDE_CHAR;
+ else
+ spec_type = INT;
break;
case 'C':
spec_type = WIDE_CHAR;
@@ -1799,9 +1786,6 @@
case WIDE_CHAR:
args[numargs++].val_wint_t = va_arg (*ap, wint_t);
break;
- case CHAR:
- case CHAR_INT:
- case SHORT_INT:
case INT:
args[numargs++].val_int = va_arg (*ap, int);
break;
@@ -1886,9 +1870,6 @@
args[numargs++].val_wint_t = va_arg (*ap, wint_t);
break;
case INT:
- case CHAR_INT:
- case SHORT_INT:
- case CHAR:
default:
args[numargs++].val_int = va_arg (*ap, int);
break;