[patch] synch src/lib/stdio/vfprintf.c with FreeBSD rev 1.34
Chris Pressey
cpressey at catseye.mine.nu
Thu Jan 13 22:32:45 PST 2005
Hi,
The attached patch synchs DFly's vfprintf.c with FreeBSD's 1.34.
Basically this provides support for some C99 format length specifiers
(z, t, j, hh) and locale-sensitive "thousands" (grouping) seperators.
It's not been tested yet (buildworld+buildkernel currently in progress.)
Patching was done by hand, due to our style difference from FreeBSD,
plus I wanted to follow the logic of each of the changes. They seem
sound, except for the assumption that quad_t == long long, so (on
Joerg's advice) I added a compile-time assertion on that assumption.
Your feedback/review/testing is of course appreciated :)
Thanks,
-Chris
Index: stdio/vfprintf.c
===================================================================
RCS file: /home/dcvs/src/lib/libc/stdio/vfprintf.c,v
retrieving revision 1.5
diff -u -r1.5 vfprintf.c
--- stdio/vfprintf.c 7 Jun 2004 20:35:41 -0000 1.5
+++ stdio/vfprintf.c 14 Jan 2005 05:42:46 -0000
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)vfprintf.c 8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libc/stdio/vfprintf.c,v 1.22.2.5 2002/10/12 10:46:37 schweikh Exp $
+ * $FreeBSD: src/lib/libc/stdio/vfprintf.c,v 1.34 2001/12/13 19:45:41 phantom Exp $
* $DragonFly: src/lib/libc/stdio/vfprintf.c,v 1.5 2004/06/07 20:35:41 hmp Exp $
*/
@@ -46,7 +46,11 @@
#include <sys/types.h>
+#include <ctype.h>
#include <limits.h>
+#include <locale.h>
+#include <stddef.h>
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -60,12 +64,61 @@
/* Define FLOATING_POINT to get floating point. */
#define FLOATING_POINT
-static int __sprint (FILE *, struct __suio *);
-static int __sbprintf (FILE *, const char *, va_list);
-static char * __ultoa (u_long, char *, int, int, char *);
-static char * __uqtoa (u_quad_t, char *, int, int, char *);
-static void __find_arguments (const char *, va_list, void ***);
-static void __grow_type_table (int, unsigned char **, int *);
+/* Borrowed from sys/systm.h, which is _KERNEL-only: */
+#define CTASSERT(x) _CTASSERT(x, __LINE__)
+#define _CTASSERT(x, y) __CTASSERT(x, y)
+#define __CTASSERT(x, y) typedef char __assert ## y[(x) ? 1 : -1]
+
+/* This code assumes that a quad_t can fit in a long long: */
+CTASSERT(sizeof(quad_t) == sizeof(long long));
+
+union arg {
+ int intarg;
+ unsigned int uintarg;
+ long longarg;
+ unsigned long ulongarg;
+ long long longlongarg;
+ unsigned long long ulonglongarg;
+ ptrdiff_t ptrdiffarg;
+ size_t sizearg;
+ intmax_t intmaxarg;
+ uintmax_t uintmaxarg;
+ void *pvoidarg;
+ char *pchararg;
+ signed char *pschararg;
+ short *pshortarg;
+ int *pintarg;
+ long *plongarg;
+ long long *plonglongarg;
+ ptrdiff_t *pptrdiffarg;
+ size_t *psizearg;
+ intmax_t *pintmaxarg;
+#ifdef FLOATING_POINT
+ double doublearg;
+ long double longdoublearg;
+#endif
+};
+
+/*
+ * Type ids for argument type table.
+ */
+enum typeid {
+ T_UNUSED, TP_SHORT, T_INT, T_U_INT, TP_INT,
+ T_LONG, T_U_LONG, TP_LONG, T_LLONG, T_U_LLONG, TP_LLONG,
+ T_PTRDIFFT, TP_PTRDIFFT, T_SIZET, TP_SIZET,
+ T_INTMAXT, T_UINTMAXT, TP_INTMAXT, TP_VOID, TP_CHAR, TP_SCHAR,
+ T_DOUBLE, T_LONG_DOUBLE
+};
+
+static int __sprint(FILE *, struct __suio *);
+static int __sbprintf(FILE *, const char *, va_list) __printflike(2, 0);
+static char * __ujtoa(uintmax_t, char *, int, int, char *, int,
+ char, const char *);
+static char * __ultoa(u_long, char *, int, int, char *, int,
+ char, const char *);
+static char * __uqtoa(u_quad_t, char *, int, int, char *);
+static void __find_arguments(const char *, va_list, union arg **);
+static void __grow_type_table(int, enum typeid **, int *);
/*
* Flush out all the vectors defined by the given uio,
@@ -132,10 +185,12 @@
* use the given digits.
*/
static char *
-__ultoa(u_long val, char *endp, int base, int octzero, char *xdigs)
+__ultoa(u_long val, char *endp, int base, int octzero, char *xdigs,
+ int needgrp, char thousep, const char *grp)
{
char *cp = endp;
long sval;
+ int ndig;
/*
* Handle the three cases separately, in the hope of getting
@@ -147,6 +202,7 @@
*--cp = to_char(val);
return (cp);
}
+ ndig = 0;
/*
* On many machines, unsigned arithmetic is harder than
* signed arithmetic, so we do at most one unsigned mod and
@@ -155,11 +211,29 @@
*/
if (val > LONG_MAX) {
*--cp = to_char(val % 10);
+ ndig++;
sval = val / 10;
} else
sval = val;
do {
*--cp = to_char(sval % 10);
+ ndig++;
+ /*
+ * If (*grp == CHAR_MAX) then no more grouping
+ * should be performed.
+ */
+ if (needgrp && ndig == *grp && *grp != CHAR_MAX &&
+ sval > 9) {
+ *--cp = thousep;
+ ndig = 0;
+ /*
+ * If (*(grp+1) == '\0') then we have to
+ * use *grp character (last grouping rule)
+ * for all next cases
+ */
+ if (*(grp + 1) != '\0')
+ grp++;
+ }
sval /= 10;
} while (sval != 0);
break;
@@ -186,32 +260,54 @@
return (cp);
}
-/* Identical to __ultoa, but for quads. */
+/* Identical to __ultoa, but for intmax_t. */
static char *
-__uqtoa(u_quad_t val, char *endp, int base, int octzero, char *xdigs)
+__ujtoa(u_quad_t val, char *endp, int base, int octzero, char *xdigs,
+ int needgrp, char thousep, const char *grp)
{
char *cp = endp;
- quad_t sval;
+ intmax_t sval;
+ int ndig;
/* quick test for small values; __ultoa is typically much faster */
/* (perhaps instead we should run until small, then call __ultoa?) */
if (val <= ULONG_MAX)
- return (__ultoa((u_long)val, endp, base, octzero, xdigs));
+ return (__ultoa((u_long)val, endp, base, octzero, xdigs,
+ needgrp, thousep, grp));
switch (base) {
case 10:
if (val < 10) {
*--cp = to_char(val % 10);
return (cp);
}
- if (val > QUAD_MAX) {
+ ndig = 0;
+ if (val > INTMAX_MAX) {
*--cp = to_char(val % 10);
+ ndig++;
sval = val / 10;
} else
sval = val;
- do {
- *--cp = to_char(sval % 10);
- sval /= 10;
- } while (sval != 0);
+ do {
+ *--cp = to_char(sval % 10);
+ ndig++;
+ /*
+ * If (*grp == CHAR_MAX) then no more grouping
+ * should be performed.
+ */
+ if (needgrp && *grp != CHAR_MAX && ndig == *grp &&
+ sval > 9) {
+ *--cp = thousep;
+ ndig = 0;
+ /*
+ * If (*(grp+1) == '\0') then we have to
+ * use *grp character (last grouping rule)
+ * for all next cases
+ */
+ if (*(grp + 1) != '\0')
+ grp++;
+ }
+ sval /= 10;
+ } while (sval != 0);
break;
case 8:
@@ -237,11 +333,10 @@
}
#ifdef FLOATING_POINT
-#include <locale.h>
#include <math.h>
#include "floatio.h"
-#define BUF (MAXEXP+MAXFRACT+1) /* + decimal point */
+#define BUF ((MAXEXP * 2) + MAXFRACT + 1) /* + decimal point */
#define DEFPREC 6
static char *cvt (double, int, int, char *, int *, int, int *, char **);
@@ -249,7 +344,7 @@
#else /* no FLOATING_POINT */
-#define BUF 68
+#define BUF 136
#endif /* FLOATING_POINT */
@@ -263,10 +358,16 @@
#define LADJUST 0x004 /* left adjustment */
#define LONGDBL 0x008 /* long double */
#define LONGINT 0x010 /* long integer */
-#define QUADINT 0x020 /* quad integer */
+#define LLONGINT 0x020 /* long long integer */
#define SHORTINT 0x040 /* short integer */
#define ZEROPAD 0x080 /* zero (as opposed to blank) pad */
-#define FPT 0x100 /* Floating point number */
+#define FPT 0x100 /* Floating point number */
+#define GROUPING 0x200 /* use grouping ("'" flag) */
+ /* C99 additional size modifiers: */
+#define SIZET 0x400 /* size_t */
+#define PTRDIFFT 0x800 /* ptrdiff_t */
+#define INTMAXT 0x1000 /* intmax_t */
+#define CHARINT 0x2000 /* print char using int format */
int
vfprintf(FILE *fp, const char *fmt0, va_list ap)
{
@@ -280,8 +381,10 @@
int width; /* width from format (%8d), or 0 */
int prec; /* precision from format (%.3d), or -1 */
char sign; /* sign prefix (' ', '+', '-', or \0) */
-#ifdef FLOATING_POINT
- char *decimal_point = localeconv()->decimal_point;
+ char thousands_sep; /* locale specific thousands separator */
+ const char *grouping; /* locale specific numeric grouping rules */
+ #ifdef FLOATING_POINT
+ char *decimal_point; /* locale specific decimal point */
char softsign; /* temporary negative sign for floats */
double _double; /* double precision arguments %[eEfgG] */
int expt; /* integer value of exponent */
@@ -291,7 +394,7 @@
char *dtoaresult; /* buffer allocated by dtoa */
#endif
u_long ulval; /* integer arguments %[diouxX] */
- u_quad_t uqval; /* %q integers */
+ uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */
int base; /* base for [diouxX] conversion */
int dprec; /* a copy of prec if [diouxX], 0 otherwise */
int realsz; /* field size expanded by dprec, sign, etc */
@@ -301,10 +404,10 @@
#define NIOV 8
struct __suio uio; /* output information: summary */
struct __siov iov[NIOV];/* ... and individual io vectors */
- char buf[BUF]; /* space for %c, %[diouxX], %[eEfgG] */
- char ox[2]; /* space for 0x hex-prefix */
- void **argtable; /* args, built due to positional arg */
- void *statargtable [STATIC_ARG_TBL_SIZE];
+ char buf[BUF]; /* space for %c, %[diouxX], %[eEfFgG] */
+ char ox[2]; /* space for 0x hex-prefix */
+ union arg *argtable; /* args, built due to positional arg */
+ union arg statargtable[STATIC_ARG_TBL_SIZE];
int nextarg; /* 1-based argument index */
va_list orgap; /* original argument pointer */
@@ -355,7 +458,7 @@
* argument (and arguments must be gotten sequentially).
*/
#define GETARG(type) \
- ((argtable != NULL) ? *((type*)(argtable[nextarg++])) : \
+ ((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : \
(nextarg++, va_arg(ap, type)))
/*
@@ -365,11 +468,24 @@
#define SARG() \
(flags&LONGINT ? GETARG(long) : \
flags&SHORTINT ? (long)(short)GETARG(int) : \
+ flags&CHARINT ? (long)(signed char)GETARG(int) : \
(long)GETARG(int))
#define UARG() \
(flags&LONGINT ? GETARG(u_long) : \
flags&SHORTINT ? (u_long)(u_short)GETARG(int) : \
+ flags&CHARINT ? (u_long)(u_char)GETARG(int) : \
(u_long)GETARG(u_int))
+#define INTMAX_SIZE (INTMAXT|SIZET|PTRDIFFT|LLONGINT)
+#define SJARG() \
+ (flags&INTMAXT ? GETARG(intmax_t) : \
+ flags&SIZET ? (intmax_t)GETARG(size_t) : \
+ flags&PTRDIFFT ? (intmax_t)GETARG(ptrdiff_t) : \
+ (intmax_t)GETARG(long long))
+#define UJARG() \
+ (flags&INTMAXT ? GETARG(uintmax_t) : \
+ flags&SIZET ? (uintmax_t)GETARG(size_t) : \
+ flags&PTRDIFFT ? (uintmax_t)GETARG(ptrdiff_t) : \
+ (uintmax_t)GETARG(unsigned long long))
/*
* Get * arguments, including the form *nn$. Preserve the nextarg
@@ -395,10 +511,13 @@
} else { \
val = GETARG (int); \
}
-
+
+ thousands_sep = '\0';
+ grouping = NULL;
#ifdef FLOATING_POINT
dtoaresult = NULL;
+ decimal_point = localeconv()->decimal_point;
#endif
FLOCKFILE(fp);
/* sorry, fprintf(read_only_file, "") returns EOF, not 0 */
@@ -479,6 +598,11 @@
case '+':
sign = '+';
goto rflag;
+ case '\'':
+ flags |= GROUPING;
+ thousands_sep = *(localeconv()->thousands_sep);
+ grouping = localeconv()->grouping;
+ goto rflag;
case '.':
if ((ch = *fmt++) == '*') {
GETASTER (n);
@@ -524,16 +648,30 @@
goto rflag;
#endif
case 'h':
- flags |= SHORTINT;
+ if (flags & SHORTINT) {
+ flags &= ~SHORTINT;
+ flags |= CHARINT;
+ } else
+ flags |= SHORTINT;
+ goto rflag;
+ case 'j':
+ flags |= INTMAXT;
goto rflag;
case 'l':
- if (flags & LONGINT)
- flags |= QUADINT;
- else
+ if (flags & LONGINT) {
+ flags &= ~LONGINT;
+ flags |= LLONGINT;
+ } else
flags |= LONGINT;
goto rflag;
case 'q':
- flags |= QUADINT;
+ flags |= LLONGINT;
+ goto rflag;
+ case 't':
+ flags |= PTRDIFFT;
+ goto rflag;
+ case 'z':
+ flags |= SIZET;
goto rflag;
case 'c':
*(cp = buf) = GETARG(int);
@@ -545,10 +683,10 @@
/*FALLTHROUGH*/
case 'd':
case 'i':
- if (flags & QUADINT) {
- uqval = GETARG(quad_t);
- if ((quad_t)uqval < 0) {
- uqval = -uqval;
+ if (flags & INTMAX_SIZE) {
+ ujval = SJARG();
+ if ((intmax_t)ujval < 0) {
+ ujval = -ujval;
sign = '-';
}
} else {
@@ -561,9 +699,22 @@
base = 10;
goto number;
#ifdef FLOATING_POINT
+#ifdef HEXFLOAT
+ case 'a':
+ case 'A':
+#endif
case 'e':
case 'E':
+ /*
+ * Grouping apply to %i, %d, %u, %f, %F, %g, %G
+ * conversion specifiers only. For other conversions
+ * behavior is undefined.
+ * -- POSIX
+ */
+ flags &= ~GROUPING;
+ /*FALLTHROUGH*/
case 'f':
+ case 'F':
goto fp_begin;
case 'g':
case 'G':
@@ -580,12 +731,18 @@
if (isinf(_double)) {
if (_double < 0)
sign = '-';
- cp = "Inf";
+ if (isupper(ch))
+ cp = "INF";
+ else
+ cp = "inf";
size = 3;
break;
}
if (isnan(_double)) {
- cp = "NaN";
+ if (isupper(ch))
+ cp = "NAN";
+ else
+ cp = "nan";
size = 3;
break;
}
@@ -602,13 +759,13 @@
else
ch = 'g';
}
- if (ch <= 'e') { /* 'e' or 'E' fmt */
+ if (ch == 'e' || ch == 'E') {
--expt;
expsize = exponent(expstr, expt, ch);
size = expsize + ndig;
if (ndig > 1 || flags & ALT)
++size;
- } else if (ch == 'f') { /* f fmt */
+ } else if (ch == 'f' || ch == 'F') {
if (expt > 0) {
size = expt;
if (prec || flags & ALT)
@@ -628,12 +785,25 @@
break;
#endif /* FLOATING_POINT */
case 'n':
- if (flags & QUADINT)
- *GETARG(quad_t *) = ret;
+ /*
+ * Assignment-like behavior is specified if the
+ * value overflows or is otherwise unrepresentable.
+ * C99 says to use `signed char' for %hhn conversions.
+ */
+ if (flags & LLONGINT)
+ *GETARG(long long *) = ret;
+ else if (flags & SIZET)
+ *GETARG(ssize_t *) = (ssize_t)ret;
+ else if (flags & PTRDIFFT)
+ *GETARG(ptrdiff_t *) = ret;
+ else if (flags & INTMAXT)
+ *GETARG(intmax_t *) = ret;
else if (flags & LONGINT)
*GETARG(long *) = ret;
else if (flags & SHORTINT)
*GETARG(short *) = ret;
+ else if (flags & CHARINT)
+ *GETARG(signed char *) = ret;
else
*GETARG(int *) = ret;
continue; /* no output */
@@ -641,8 +811,8 @@
flags |= LONGINT;
/*FALLTHROUGH*/
case 'o':
- if (flags & QUADINT)
- uqval = GETARG(u_quad_t);
+ if (flags & INTMAX_SIZE)
+ ujval = UJARG();
else
ulval = UARG();
base = 8;
@@ -655,10 +825,10 @@
* defined manner.''
* -- ANSI X3J11
*/
- ulval = (u_long)GETARG(void *);
+ ujval = (uintmax_t)(uintptr_t)GETARG(void *);
base = 16;
xdigs = "0123456789abcdef";
- flags = (flags & ~QUADINT) | HEXPREFIX;
+ flags = flags | INTMAXT | HEXPREFIX;
ch = 'x';
goto nosign;
case 's':
@@ -686,8 +856,8 @@
flags |= LONGINT;
/*FALLTHROUGH*/
case 'u':
- if (flags & QUADINT)
- uqval = GETARG(u_quad_t);
+ if (flags & INTMAX_SIZE)
+ ujval = UJARG();
else
ulval = UARG();
base = 10;
@@ -697,16 +867,18 @@
goto hex;
case 'x':
xdigs = "0123456789abcdef";
-hex: if (flags & QUADINT)
- uqval = GETARG(u_quad_t);
+hex:
+ if (flags & INTMAX_SIZE)
+ ujval = UJARG();
else
ulval = UARG();
base = 16;
/* leading 0x/X only if non-zero */
if (flags & ALT &&
- (flags & QUADINT ? uqval != 0 : ulval != 0))
+ (flags & INTMAX_SIZE ? ujval != 0 : ulval != 0))
flags |= HEXPREFIX;
+ flags &= ~GROUPING;
/* unsigned conversions */
nosign: sign = '\0';
/*
@@ -723,15 +895,19 @@
* -- ANSI X3J11
*/
cp = buf + BUF;
- if (flags & QUADINT) {
- if (uqval != 0 || prec != 0)
- cp = __uqtoa(uqval, cp, base,
- flags & ALT, xdigs);
- } else {
- if (ulval != 0 || prec != 0)
- cp = __ultoa(ulval, cp, base,
- flags & ALT, xdigs);
- }
+ if (flags & INTMAX_SIZE) {
+ if (ujval != 0 || prec != 0)
+ cp = __ujtoa(ujval, cp, base,
+ flags & ALT, xdigs,
+ flags & GROUPING, thousands_sep,
+ grouping);
+ } else {
+ if (ulval != 0 || prec != 0)
+ cp = __ultoa(ulval, cp, base,
+ flags & ALT, xdigs,
+ flags & GROUPING, thousands_sep,
+ grouping);
+ }
size = buf + BUF - cp;
break;
default: /* "%?" prints ?, unless ? is NUL */
@@ -864,34 +1040,13 @@
}
/*
- * Type ids for argument type table.
- */
-#define T_UNUSED 0
-#define T_SHORT 1
-#define T_U_SHORT 2
-#define TP_SHORT 3
-#define T_INT 4
-#define T_U_INT 5
-#define TP_INT 6
-#define T_LONG 7
-#define T_U_LONG 8
-#define TP_LONG 9
-#define T_QUAD 10
-#define T_U_QUAD 11
-#define TP_QUAD 12
-#define T_DOUBLE 13
-#define T_LONG_DOUBLE 14
-#define TP_CHAR 15
-#define TP_VOID 16
-
-/*
* Find all arguments when a positional parameter is encountered. Returns a
* table, indexed by argument number, of pointers to each arguments. The
* initial argument table should be an array of STATIC_ARG_TBL_SIZE entries.
* It will be replaces with a malloc-ed one if it overflows.
*/
static void
-__find_arguments (const char *fmt0, va_list ap, void ***argtable)
+__find_arguments (const char *fmt0, va_list ap, union arg **argtable)
{
char *fmt; /* format string */
int ch; /* character from fmt */
@@ -899,8 +1054,8 @@
char *cp; /* handy char pointer (short term usage) */
int flags; /* flags as above */
int width; /* width from format (%8d), or 0 */
- unsigned char *typetable; /* table of types */
- unsigned char stattypetable [STATIC_ARG_TBL_SIZE];
+ enum typeid *typetable; /* table of types */
+ enum typeid stattypetable[STATIC_ARG_TBL_SIZE];
int tablesize; /* current size of type table */
int tablemax; /* largest used index in table */
int nextarg; /* 1-based argument index */
@@ -915,12 +1070,18 @@
typetable[nextarg++] = type)
#define ADDSARG() \
- ((flags&LONGINT) ? ADDTYPE(T_LONG) : \
- ((flags&SHORTINT) ? ADDTYPE(T_SHORT) : ADDTYPE(T_INT)))
+ ((flags&INTMAXT) ? ADDTYPE(T_INTMAXT) : \
+ ((flags&SIZET) ? ADDTYPE(T_SIZET) : \
+ ((flags&PTRDIFFT) ? ADDTYPE(T_PTRDIFFT) : \
+ ((flags&LLONGINT) ? ADDTYPE(T_LLONG) : \
+ ((flags&LONGINT) ? ADDTYPE(T_LONG) : ADDTYPE(T_INT))))))
#define ADDUARG() \
- ((flags&LONGINT) ? ADDTYPE(T_U_LONG) : \
- ((flags&SHORTINT) ? ADDTYPE(T_U_SHORT) : ADDTYPE(T_U_INT)))
+ ((flags&INTMAXT) ? ADDTYPE(T_UINTMAXT) : \
+ ((flags&SIZET) ? ADDTYPE(T_SIZET) : \
+ ((flags&PTRDIFFT) ? ADDTYPE(T_PTRDIFFT) : \
+ ((flags&LLONGINT) ? ADDTYPE(T_U_LLONG) : \
+ ((flags&LONGINT) ? ADDTYPE(T_U_LONG) : ADDTYPE(T_U_INT))))))
/*
* Add * arguments to the type array.
@@ -971,6 +1132,7 @@
goto rflag;
case '-':
case '+':
+ case '\'':
goto rflag;
case '.':
if ((ch = *fmt++) == '*') {
@@ -1001,18 +1163,32 @@
flags |= LONGDBL;
goto rflag;
#endif
- case 'h':
- flags |= SHORTINT;
+ case 'h':
+ if (flags & SHORTINT) {
+ flags &= ~SHORTINT;
+ flags |= CHARINT;
+ } else
+ flags |= SHORTINT;
goto rflag;
- case 'l':
- if (flags & LONGINT)
- flags |= QUADINT;
- else
- flags |= LONGINT;
+ case 'j':
+ flags |= INTMAXT;
goto rflag;
- case 'q':
- flags |= QUADINT;
+ case 'l':
+ if (flags & LONGINT) {
+ flags &= ~LONGINT;
+ flags |= LLONGINT;
+ } else
+ flags |= LONGINT;
+ goto rflag;
+ case 'q':
+ flags |= LLONGINT;
goto rflag;
+ case 't':
+ flags |= PTRDIFFT;
+ goto rflag;
+ case 'z':
+ flags |= SIZET;
+ goto rflag;
case 'c':
ADDTYPE(T_INT);
break;
@@ -1020,14 +1196,14 @@
flags |= LONGINT;
/*FALLTHROUGH*/
case 'd':
- case 'i':
- if (flags & QUADINT) {
- ADDTYPE(T_QUAD);
- } else {
- ADDSARG();
- }
- break;
+ case 'i':
+ ADDSARG();
+ break;
#ifdef FLOATING_POINT
+#ifdef HEXFLOAT
+ case 'a':
+ case 'A':
+#endif
case 'e':
case 'E':
case 'f':
@@ -1040,12 +1216,20 @@
break;
#endif /* FLOATING_POINT */
case 'n':
- if (flags & QUADINT)
- ADDTYPE(TP_QUAD);
+ if (flags & INTMAXT)
+ ADDTYPE(TP_INTMAXT);
+ else if (flags & PTRDIFFT)
+ ADDTYPE(TP_PTRDIFFT);
+ else if (flags & SIZET)
+ ADDTYPE(TP_SIZET);
+ else if (flags & LLONGINT)
+ ADDTYPE(TP_LLONG);
else if (flags & LONGINT)
ADDTYPE(TP_LONG);
else if (flags & SHORTINT)
ADDTYPE(TP_SHORT);
+ else if (flags & CHARINT)
+ ADDTYPE(TP_SCHAR);
else
ADDTYPE(TP_INT);
continue; /* no output */
@@ -1053,10 +1237,7 @@
flags |= LONGINT;
/*FALLTHROUGH*/
case 'o':
- if (flags & QUADINT)
- ADDTYPE(T_U_QUAD);
- else
- ADDUARG();
+ ADDUARG();
break;
case 'p':
ADDTYPE(TP_VOID);
@@ -1067,19 +1248,11 @@
case 'U':
flags |= LONGINT;
/*FALLTHROUGH*/
- case 'u':
- if (flags & QUADINT)
- ADDTYPE(T_U_QUAD);
- else
- ADDUARG();
- break;
- case 'X':
- case 'x':
- if (flags & QUADINT)
- ADDTYPE(T_U_QUAD);
- else
- ADDUARG();
- break;
+ case 'u':
+ case 'X':
+ case 'x':
+ ADDUARG();
+ break;
default: /* "%?" prints ?, unless ? is NUL */
if (ch == '\0')
goto done;
@@ -1091,63 +1264,77 @@
* Build the argument table.
*/
if (tablemax >= STATIC_ARG_TBL_SIZE) {
- *argtable = (void **)
- malloc (sizeof (void *) * (tablemax + 1));
+ *argtable = (union arg *)
+ malloc(sizeof(union arg) * (tablemax + 1));
}
-
- (*argtable) [0] = NULL;
+ (*argtable)[0].intarg = 0;
for (n = 1; n <= tablemax; n++) {
switch (typetable [n]) {
- case T_UNUSED:
- (*argtable) [n] = (void *) &va_arg (ap, int);
- break;
- case T_SHORT:
- (*argtable) [n] = (void *) &va_arg (ap, int);
- break;
- case T_U_SHORT:
- (*argtable) [n] = (void *) &va_arg (ap, int);
+ case T_UNUSED: /* "whoops" */
+ case T_INT:
+ (*argtable)[n].intarg = va_arg(ap, int);
break;
+ case TP_SCHAR:
+ (*argtable) [n].pschararg = va_arg (ap, signed char *);
case TP_SHORT:
- (*argtable) [n] = (void *) &va_arg (ap, short *);
- break;
- case T_INT:
- (*argtable) [n] = (void *) &va_arg (ap, int);
+ (*argtable)[n].pshortarg = va_arg(ap, short *);
break;
case T_U_INT:
- (*argtable) [n] = (void *) &va_arg (ap, unsigned int);
+ (*argtable)[n].uintarg = va_arg(ap, unsigned int);
break;
case TP_INT:
- (*argtable) [n] = (void *) &va_arg (ap, int *);
+ (*argtable)[n].pintarg = va_arg(ap, int *);
break;
case T_LONG:
- (*argtable) [n] = (void *) &va_arg (ap, long);
+ (*argtable)[n].longarg = va_arg(ap, long);
break;
case T_U_LONG:
- (*argtable) [n] = (void *) &va_arg (ap, unsigned long);
+ (*argtable)[n].ulongarg = va_arg(ap, unsigned long);
break;
case TP_LONG:
- (*argtable) [n] = (void *) &va_arg (ap, long *);
+ (*argtable)[n].plongarg = va_arg(ap, long *);
+ break;
+ case T_LLONG:
+ (*argtable)[n].longlongarg = va_arg(ap, long long);
+ break;
+ case T_U_LLONG:
+ (*argtable)[n].ulonglongarg = va_arg(ap, unsigned long long);
+ break;
+ case TP_LLONG:
+ (*argtable)[n].plonglongarg = va_arg(ap, long long *);
+ break;
+ case T_PTRDIFFT:
+ (*argtable)[n].ptrdiffarg = va_arg(ap, ptrdiff_t);
+ break;
+ case TP_PTRDIFFT:
+ (*argtable)[n].pptrdiffarg = va_arg(ap, ptrdiff_t *);
+ break;
+ case T_SIZET:
+ (*argtable)[n].sizearg = va_arg(ap, size_t);
break;
- case T_QUAD:
- (*argtable) [n] = (void *) &va_arg (ap, quad_t);
+ case TP_SIZET:
+ (*argtable)[n].psizearg = va_arg(ap, ssize_t *);
break;
- case T_U_QUAD:
- (*argtable) [n] = (void *) &va_arg (ap, u_quad_t);
+ case T_INTMAXT:
+ (*argtable)[n].intmaxarg = va_arg(ap, intmax_t);
+ break;
+ case T_UINTMAXT:
+ (*argtable)[n].uintmaxarg = va_arg(ap, uintmax_t);
break;
- case TP_QUAD:
- (*argtable) [n] = (void *) &va_arg (ap, quad_t *);
+ case TP_INTMAXT:
+ (*argtable)[n].pintmaxarg = va_arg (ap, intmax_t *);
break;
case T_DOUBLE:
- (*argtable) [n] = (void *) &va_arg (ap, double);
+ (*argtable)[n].doublearg = va_arg(ap, double);
break;
case T_LONG_DOUBLE:
- (*argtable) [n] = (void *) &va_arg (ap, long double);
+ (*argtable)[n].longdoublearg = va_arg(ap, long double);
break;
case TP_CHAR:
- (*argtable) [n] = (void *) &va_arg (ap, char *);
+ (*argtable)[n].pchararg = va_arg(ap, char *);
break;
case TP_VOID:
- (*argtable) [n] = (void *) &va_arg (ap, void *);
+ (*argtable)[n].pvoidarg = va_arg(ap, void *);
break;
}
}
@@ -1160,11 +1347,11 @@
* Increase the size of the type table.
*/
static void
-__grow_type_table (int nextarg, unsigned char **typetable, int *tablesize)
+__grow_type_table(int nextarg, enum typeid **typetable, int *tablesize)
{
- unsigned char *const oldtable = *typetable;
+ enum typeid * const oldtable = *typetable;
const int oldsize = *tablesize;
- unsigned char *newtable;
+ enum typeid *newtable;
int newsize = oldsize * 2;
if (newsize < nextarg + 1)
More information about the Submit
mailing list