X-Git-Url: https://git.saurik.com/apple/libc.git/blobdiff_plain/9385eb3d10ebe5eb398c52040ec3dbfba9b0cdcf..c957a83bde4df2e2d3d1ed0963656856b48ef0a0:/stdio/FreeBSD/vfprintf.c.patch diff --git a/stdio/FreeBSD/vfprintf.c.patch b/stdio/FreeBSD/vfprintf.c.patch index 5b79cb3..88df771 100644 --- a/stdio/FreeBSD/vfprintf.c.patch +++ b/stdio/FreeBSD/vfprintf.c.patch @@ -1,40 +1,41 @@ ---- vfprintf.c.orig Thu Jul 24 12:42:14 2003 -+++ vfprintf.c Sun Aug 24 16:21:44 2003 -@@ -66,9 +66,20 @@ - #include "local.h" - #include "fvwrite.h" +--- vfprintf.c.orig 2004-11-25 11:38:35.000000000 -0800 ++++ vfprintf.c 2005-11-08 22:43:11.000000000 -0800 +@@ -40,6 +40,8 @@ + #include + __FBSDID("$FreeBSD: src/lib/libc/stdio/vfprintf.c,v 1.68 2004/08/26 06:25:28 des Exp $"); -+#ifdef ALTIVEC -+#include ++#include "xlocale_private.h" + -+#define VECTORTYPE vector unsigned char -+#endif /* ALTIVEC */ -+ - /* Define FLOATING_POINT to get floating point. */ - #define FLOATING_POINT + /* + * Actual printf innards. + * +@@ -58,6 +60,7 @@ + #include + #include + #include ++#include + + #include + #include "un-namespace.h" +@@ -66,6 +69,13 @@ + #include "local.h" + #include "fvwrite.h" -+/* if no floating point, turn off HEXFLOAT as well */ -+#if defined(HEXFLOAT) && !defined(FLOATING_POINT) -+#undef HEXFLOAT -+#endif /* defined(HEXFLOAT) && !defined(FLOATING_POINT) */ ++#ifdef VECTORS ++typedef __attribute__ ((vector_size(16))) unsigned char VECTORTYPE; ++#ifdef __SSE2__ ++#define V64TYPE ++#endif /* __SSE2__ */ ++#endif /* VECTORS */ + union arg { int intarg; u_int uintarg; -@@ -88,7 +99,7 @@ - long *plongarg; - long long *plonglongarg; - ptrdiff_t *pptrdiffarg; -- size_t *psizearg; -+ ssize_t *psizearg; - intmax_t *pintmaxarg; - #ifdef FLOATING_POINT - double doublearg; -@@ -96,6 +107,16 @@ +@@ -93,6 +103,21 @@ #endif wint_t wintarg; wchar_t *pwchararg; -+#ifdef ALTIVEC ++#ifdef VECTORS + VECTORTYPE vectorarg; + unsigned char vuchararg[16]; + signed char vchararg[16]; @@ -43,91 +44,138 @@ + unsigned int vuintarg[4]; + signed int vintarg[4]; + float vfloatarg[4]; -+#endif /* ALTIVEC */ ++#ifdef V64TYPE ++ double vdoublearg[2]; ++ unsigned long long vulonglongarg[2]; ++ long long vlonglongarg[2]; ++#endif /* V64TYPE */ ++#endif /* VECTORS */ }; /* -@@ -106,7 +127,11 @@ +@@ -103,16 +128,20 @@ 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, -+#ifdef ALTIVEC ++#ifdef VECTORS + T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR, T_VECTOR -+#else /* ! ALTIVEC */ ++#else /* ! VECTORS */ T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR -+#endif /* ALTIVEC */ ++#endif /* VECTORS */ }; static int __sprint(FILE *, struct __suio *); -@@ -119,6 +144,37 @@ +-static int __sbprintf(FILE *, const char *, va_list) __printflike(2, 0); ++static int __sbprintf(FILE *, locale_t, const char *, va_list) __printflike(3, 0); + static char *__ujtoa(uintmax_t, char *, int, int, const char *, int, char, + const char *); + static char *__ultoa(u_long, char *, int, int, const char *, int, char, + const char *); +-static char *__wcsconv(wchar_t *, int); ++static char *__wcsconv(wchar_t *, int, locale_t); static void __find_arguments(const char *, va_list, union arg **); static void __grow_type_table(int, enum typeid **, int *); -+ /* -+ * Get the argument indexed by nextarg. If the argument table is -+ * built, use it to get the argument. If its not, get the next -+ * argument (and arguments must be gotten sequentially). -+ */ -+#define GETARG(type) \ -+ ((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : \ -+ (nextarg++, va_arg(ap, type))) -+ -+#ifdef ALTIVEC -+#define hasAltivec (_cpu_capabilities & kHasAltivec) -+/*----------------------------------------------------------------------- -+ * getvec() must be a real subroutine. If it is a #define, then __vfprintf() -+ * would have its calling sequence changed by Altivec so that a non-Altivec -+ * processor would crash on illegal instruction. By isolating the calling -+ * sequence in getvec(), __vprintf() is callable by a non-Altivec processor. -+ *-----------------------------------------------------------------------*/ -+static va_list -+getvec(union arg *dst, const union arg *argtable, int nextarg, va_list ap) -+{ -+ dst->vectorarg = GETARG(VECTORTYPE); -+ return ap; +@@ -141,7 +170,7 @@ + * worries about ungetc buffers and so forth. + */ + static int +-__sbprintf(FILE *fp, const char *fmt, va_list ap) ++__sbprintf(FILE *fp, locale_t loc, const char *fmt, va_list ap) + { + int ret; + FILE fake; +@@ -160,7 +189,7 @@ + fake._lbfsize = 0; /* not actually used, but Just In Case */ + + /* do the work, then copy any error status */ +- ret = __vfprintf(&fake, fmt, ap); ++ ret = __vfprintf(&fake, loc, fmt, ap); + if (ret >= 0 && __fflush(&fake)) + ret = EOF; + if (fake._flags & __SERR) +@@ -336,7 +365,7 @@ + * that the wide char. string ends in a null character. + */ + static char * +-__wcsconv(wchar_t *wcsarg, int prec) ++__wcsconv(wchar_t *wcsarg, int prec, locale_t loc) + { + static const mbstate_t initial; + mbstate_t mbs; +@@ -354,7 +383,7 @@ + p = wcsarg; + mbs = initial; + for (;;) { +- clen = wcrtomb(buf, *p++, &mbs); ++ clen = wcrtomb_l(buf, *p++, &mbs, loc); + if (clen == 0 || clen == (size_t)-1 || + nbytes + clen > prec) + break; +@@ -363,7 +392,7 @@ + } else { + p = wcsarg; + mbs = initial; +- nbytes = wcsrtombs(NULL, (const wchar_t **)&p, 0, &mbs); ++ nbytes = wcsrtombs_l(NULL, (const wchar_t **)&p, 0, &mbs, loc); + if (nbytes == (size_t)-1) + return (NULL); + } +@@ -378,7 +407,7 @@ + p = wcsarg; + mbs = initial; + while (mbp - convbuf < nbytes) { +- clen = wcrtomb(mbp, *p++, &mbs); ++ clen = wcrtomb_l(mbp, *p++, &mbs, loc); + if (clen == 0 || clen == (size_t)-1) + break; + mbp += clen; +@@ -402,7 +431,21 @@ + int ret; + + FLOCKFILE(fp); +- ret = __vfprintf(fp, fmt0, ap); ++ ret = __vfprintf(fp, __current_locale(), fmt0, ap); ++ FUNLOCKFILE(fp); ++ return (ret); +} + -+#define SETVEC(dst) \ -+{ \ -+ ap = getvec(&dst, argtable, nextarg, ap); \ -+ nextarg++; \ -+} -+#endif /* ALTIVEC */ ++int ++vfprintf_l(FILE * __restrict fp, locale_t loc, const char * __restrict fmt0, ++ va_list ap) + - /* - * Flush out all the vectors defined by the given uio, - * then reset it so that it can be reused. -@@ -424,6 +480,15 @@ - - #endif /* FLOATING_POINT */ - -+#ifdef HEXFLOAT -+extern int __hdtoa(double d, const char *xdigs, int prec, char *cp, -+ int *expt, int *signflag, char **dtoaend); -+#if !__TYPE_LONGDOUBLE_IS_DOUBLE -+extern int __hldtoa(long double d, const char *xdigs, int prec, char *cp, -+ int *expt, int *signflag, char **dtoaend); -+#endif /* !__TYPE_LONGDOUBLE_IS_DOUBLE */ -+#endif /* HEXFLOAT */ ++{ ++ int ret; + - /* - * The size of the buffer we use as scratch space for integer - * conversions, among other things. Technically, we would need the -@@ -452,6 +517,9 @@ ++ NORMALIZE_LOCALE(loc); ++ FLOCKFILE(fp); ++ ret = __vfprintf(fp, loc, fmt0, ap); + FUNLOCKFILE(fp); + return (ret); + } +@@ -451,12 +494,15 @@ #define PTRDIFFT 0x800 /* ptrdiff_t */ #define INTMAXT 0x1000 /* intmax_t */ #define CHARINT 0x2000 /* print char using int format */ -+#ifdef ALTIVEC -+#define VECTOR 0x4000 /* Altivec vector */ -+#endif /* ALTIVEC */ ++#ifdef VECTORS ++#define VECTOR 0x4000 /* Altivec or SSE vector */ ++#endif /* VECTORS */ /* * Non-MT-safe version -@@ -503,6 +571,11 @@ + */ +-int +-__vfprintf(FILE *fp, const char *fmt0, va_list ap) ++__private_extern__ int ++__vfprintf(FILE *fp, locale_t loc, const char *fmt0, va_list ap) + { + char *fmt; /* format string */ + int ch; /* character from fmt */ +@@ -502,6 +548,11 @@ int nseps; /* number of group separators with ' */ int nrepeats; /* number of repeats of the last group */ #endif -+#ifdef ALTIVEC ++#ifdef VECTORS + union arg vval; /* Vector argument. */ + char *pct; /* Pointer to '%' at beginning of specifier. */ + char vsep; /* Vector separator character. */ @@ -135,36 +183,7 @@ u_long ulval; /* integer arguments %[diouxX] */ uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */ int base; /* base for [diouxX] conversion */ -@@ -535,6 +608,12 @@ - - static const char xdigs_lower[16] = "0123456789abcdef"; - static const char xdigs_upper[16] = "0123456789ABCDEF"; -+#ifdef HEXFLOAT -+#define HEXFLOATDELTA 32 -+#define HEXFLOATSTART 32 -+ static char *hexfloat = NULL; -+ static int hexfloatlen = 0; -+#endif /* HEXFLOAT */ - - /* - * BEWARE, these `goto error' on error, and PAD uses `n'. -@@ -575,15 +654,6 @@ - } - - /* -- * Get the argument indexed by nextarg. If the argument table is -- * built, use it to get the argument. If its not, get the next -- * argument (and arguments must be gotten sequentially). -- */ --#define GETARG(type) \ -- ((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : \ -- (nextarg++, va_arg(ap, type))) -- -- /* - * To extend shorts properly, we need both signed and unsigned - * argument extraction methods. - */ -@@ -634,7 +704,6 @@ +@@ -633,22 +684,23 @@ val = GETARG (int); \ } @@ -172,266 +191,264 @@ thousands_sep = '\0'; grouping = NULL; convbuf = NULL; -@@ -676,6 +745,9 @@ + #ifndef NO_FLOATING_POINT + dtoaresult = NULL; +- decimal_point = localeconv()->decimal_point; ++ decimal_point = localeconv_l(loc)->decimal_point; + #endif + /* sorry, fprintf(read_only_file, "") returns EOF, not 0 */ +- if (prepwrite(fp) != 0) ++ if (prepwrite(fp) != 0) { ++ errno = EBADF; + return (EOF); ++ } + + /* optimise fprintf(stderr) (and other unbuffered Unix files) */ + if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) && + fp->_file >= 0) +- return (__sbprintf(fp, fmt0, ap)); ++ return (__sbprintf(fp, loc, fmt0, ap)); + + fmt = (char *)fmt0; + argtable = NULL; +@@ -675,6 +727,9 @@ } if (ch == '\0') goto done; -+#ifdef ALTIVEC ++#ifdef VECTORS + pct = fmt; -+#endif /* ALTIVEC */ ++#endif /* VECTORS */ fmt++; /* skip over '%' */ flags = 0; -@@ -684,6 +756,9 @@ +@@ -683,6 +738,9 @@ prec = -1; sign = '\0'; ox[1] = '\0'; -+#ifdef ALTIVEC ++#ifdef VECTORS + vsep = 'X'; /* Illegal value, changed to defaults later. */ -+#endif /* ALTIVEC */ ++#endif /* VECTORS */ rflag: ch = *fmt++; reswitch: switch (ch) { -@@ -699,6 +774,11 @@ +@@ -698,6 +756,11 @@ case '#': flags |= ALT; goto rflag; -+#ifdef ALTIVEC ++#ifdef VECTORS + case ',': case ';': case ':': case '_': + vsep = ch; + goto rflag; -+#endif /* ALTIVEC */ ++#endif /* VECTORS */ case '*': /*- * ``A negative field width argument is taken as a -@@ -807,6 +887,12 @@ - } - size = (int)mbseqlen; - } else { -+#ifdef ALTIVEC -+ if (flags & VECTOR) { -+ SETVEC(vval); -+ break; -+ } -+#endif /* ALTIVEC */ - *(cp = buf) = GETARG(int); - size = 1; - } -@@ -817,6 +903,12 @@ +@@ -718,8 +781,8 @@ + goto rflag; + case '\'': + flags |= GROUPING; +- thousands_sep = *(localeconv()->thousands_sep); +- grouping = localeconv()->grouping; ++ thousands_sep = *(localeconv_l(loc)->thousands_sep); ++ grouping = localeconv_l(loc)->grouping; + goto rflag; + case '.': + if ((ch = *fmt++) == '*') { +@@ -793,14 +856,18 @@ + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'c': ++#ifdef VECTORS ++ if (flags & VECTOR) ++ break; ++#endif /* VECTORS */ + if (flags & LONGINT) { + static const mbstate_t initial; + mbstate_t mbs; + size_t mbseqlen; + + mbs = initial; +- mbseqlen = wcrtomb(cp = buf, +- (wchar_t)GETARG(wint_t), &mbs); ++ mbseqlen = wcrtomb_l(cp = buf, ++ (wchar_t)GETARG(wint_t), &mbs, loc); + if (mbseqlen == (size_t)-1) { + fp->_flags |= __SERR; + goto error; +@@ -817,6 +884,10 @@ /*FALLTHROUGH*/ case 'd': case 'i': -+#ifdef ALTIVEC -+ if (flags & VECTOR) { -+ SETVEC(vval); ++#ifdef VECTORS ++ if (flags & VECTOR) + break; -+ } else -+#endif /* ALTIVEC */ ++#endif /* VECTORS */ if (flags & INTMAX_SIZE) { ujval = SJARG(); if ((intmax_t)ujval < 0) { -@@ -836,6 +928,13 @@ - #ifdef HEXFLOAT +@@ -835,6 +906,12 @@ + #ifndef NO_FLOATING_POINT case 'a': case 'A': -+#ifdef ALTIVEC ++#ifdef VECTORS + if (flags & VECTOR) { + flags |= FPT; -+ SETVEC(vval); + break; + } -+#endif /* ALTIVEC */ ++#endif /* VECTORS */ if (ch == 'a') { ox[1] = 'x'; xdigs = xdigs_lower; -@@ -845,25 +944,51 @@ - xdigs = xdigs_upper; - expchar = 'P'; - } -- /* -- * XXX We don't actually have a conversion -- * XXX routine for this yet. -- */ -+ if (!hexfloat) { -+ hexfloat = malloc(hexfloatlen = HEXFLOATSTART); -+ if (!hexfloat) -+ goto error; -+ } -+ if (prec > hexfloatlen - 1) { -+ int hlen = prec + HEXFLOATDELTA; -+ char *hf = realloc(hexfloat, hlen); -+ if (hf == NULL) -+ goto error; -+ hexfloat = hf; -+ hexfloatlen = hlen; -+ } -+ cp = hexfloat; +@@ -848,6 +925,12 @@ + prec++; + if (dtoaresult != NULL) + freedtoa(dtoaresult); ++#ifdef LDBL_COMPAT ++ fparg.dbl = GETARG(double); ++ dtoaresult = cp = ++ __hdtoa(fparg.dbl, xdigs, prec, ++ &expt, &signflag, &dtoaend); ++#else /* !LDBL_COMPAT */ if (flags & LONGDBL) { -- fparg.ldbl = (double)GETARG(long double); -- dtoaresult = cp = -- __hldtoa(fparg.ldbl, xdigs, prec, -+#if __TYPE_LONGDOUBLE_IS_DOUBLE -+ fparg.dbl = (double)GETARG(long double); -+ prec = __hdtoa(fparg.dbl, xdigs, prec, cp, - &expt, &signflag, &dtoaend); -+#else /* ! __TYPE_LONGDOUBLE_IS_DOUBLE */ -+ fparg.ldbl = GETARG(long double); -+ prec = __hldtoa(fparg.ldbl, xdigs, prec, cp, -+ &expt, &signflag, &dtoaend); -+#endif /* __TYPE_LONGDOUBLE_IS_DOUBLE */ - } else { - fparg.dbl = GETARG(double); -- dtoaresult = cp = -- __hdtoa(fparg.dbl, xdigs, prec, -+ prec = __hdtoa(fparg.dbl, xdigs, prec, cp, + fparg.ldbl = GETARG(long double); + dtoaresult = cp = +@@ -859,6 +942,7 @@ + __hdtoa(fparg.dbl, xdigs, prec, &expt, &signflag, &dtoaend); } -- goto fp_begin; -+ prec++; -+ if (expt == INT_MAX) -+ ox[1] = 0; -+ else -+ expt++; -+ goto hex_begin; - #endif ++#endif /* LDBL_COMPAT */ + if (prec < 0) + prec = dtoaend - cp; + if (expt == INT_MAX) +@@ -866,6 +950,12 @@ + goto fp_common; case 'e': case 'E': -+#ifdef ALTIVEC ++#ifdef VECTORS + if (flags & VECTOR) { + flags |= FPT; -+ SETVEC(vval); + break; + } -+#endif /* ALTIVEC */ ++#endif /* VECTORS */ expchar = ch; if (prec < 0) /* account for digit before decpt */ prec = DEFPREC + 1; -@@ -872,10 +997,24 @@ +@@ -874,10 +964,22 @@ goto fp_begin; case 'f': case 'F': -+#ifdef ALTIVEC ++#ifdef VECTORS + if (flags & VECTOR) { + flags |= FPT; -+ SETVEC(vval); + break; + } -+#endif /* ALTIVEC */ ++#endif /* VECTORS */ expchar = '\0'; goto fp_begin; case 'g': case 'G': -+#ifdef ALTIVEC ++#ifdef VECTORS + if (flags & VECTOR) { + flags |= FPT; -+ SETVEC(vval); + break; + } -+#endif /* ALTIVEC */ ++#endif /* VECTORS */ expchar = ch - ('g' - 'e'); if (prec == 0) prec = 1; -@@ -884,6 +1023,17 @@ +@@ -886,6 +988,14 @@ prec = DEFPREC; if (dtoaresult != NULL) freedtoa(dtoaresult); -+#if __TYPE_LONGDOUBLE_IS_DOUBLE -+ if (flags & LONGDBL) -+ fparg.dbl = (double)GETARG(long double); -+ else -+ fparg.dbl = GETARG(double); ++#ifdef LDBL_COMPAT ++ fparg.dbl = GETARG(double); + dtoaresult = cp = + dtoa(fparg.dbl, expchar ? 2 : 3, prec, + &expt, &signflag, &dtoaend); + if (expt == 9999) + expt = INT_MAX; -+#else /* ! __TYPE_LONGDOUBLE_IS_DOUBLE */ ++#else /* !LDBL_COMPAT */ if (flags & LONGDBL) { fparg.ldbl = GETARG(long double); dtoaresult = cp = -@@ -897,6 +1047,10 @@ +@@ -899,6 +1009,7 @@ if (expt == 9999) expt = INT_MAX; } -+#endif /* __TYPE_LONGDOUBLE_IS_DOUBLE */ -+#ifdef HEXFLOAT -+hex_begin: -+#endif /* HEXFLOAT */ ++#endif /* LDBL_COMPAT */ + fp_common: if (signflag) sign = '-'; - if (expt == INT_MAX) { /* inf or nan */ -@@ -990,6 +1144,12 @@ +@@ -993,6 +1104,10 @@ flags |= LONGINT; /*FALLTHROUGH*/ case 'o': -+#ifdef ALTIVEC -+ if (flags & VECTOR) { -+ SETVEC(vval); ++#ifdef VECTORS ++ if (flags & VECTOR) + break; -+ } else -+#endif /* ALTIVEC */ ++#endif /* VECTORS */ if (flags & INTMAX_SIZE) ujval = UJARG(); else -@@ -1004,6 +1164,12 @@ +@@ -1007,6 +1122,10 @@ * defined manner.'' * -- ANSI X3J11 */ -+#ifdef ALTIVEC -+ if (flags & VECTOR) { -+ SETVEC(vval); ++#ifdef VECTORS ++ if (flags & VECTOR) + break; -+ } -+#endif /* ALTIVEC */ ++#endif /* VECTORS */ ujval = (uintmax_t)(uintptr_t)GETARG(void *); base = 16; xdigs = xdigs_lower; -@@ -1053,6 +1219,12 @@ +@@ -1025,7 +1144,7 @@ + if ((wcp = GETARG(wchar_t *)) == NULL) + cp = "(null)"; + else { +- convbuf = __wcsconv(wcp, prec); ++ convbuf = __wcsconv(wcp, prec, loc); + if (convbuf == NULL) { + fp->_flags |= __SERR; + goto error; +@@ -1056,6 +1175,10 @@ flags |= LONGINT; /*FALLTHROUGH*/ case 'u': -+#ifdef ALTIVEC -+ if (flags & VECTOR) { -+ SETVEC(vval); ++#ifdef VECTORS ++ if (flags & VECTOR) + break; -+ } else -+#endif /* ALTIVEC */ ++#endif /* VECTORS */ if (flags & INTMAX_SIZE) ujval = UJARG(); else -@@ -1065,6 +1237,12 @@ +@@ -1068,6 +1191,10 @@ case 'x': xdigs = xdigs_lower; hex: -+#ifdef ALTIVEC -+ if (flags & VECTOR) { -+ SETVEC(vval); ++#ifdef VECTORS ++ if (flags & VECTOR) + break; -+ } else -+#endif /* ALTIVEC */ ++#endif /* VECTORS */ if (flags & INTMAX_SIZE) ujval = UJARG(); else -@@ -1109,6 +1287,14 @@ +@@ -1112,6 +1239,11 @@ if (size > BUF) /* should never happen */ abort(); break; -+#ifdef ALTIVEC ++#ifdef VECTORS + case 'v': -+ if (hasAltivec) { -+ flags |= VECTOR; -+ goto rflag; -+ } -+ /* drap through */ -+#endif /* ALTIVEC */ ++ flags |= VECTOR; ++ goto rflag; ++#endif /* VECTORS */ default: /* "%?" prints ?, unless ? is NUL */ if (ch == '\0') goto done; -@@ -1120,6 +1306,186 @@ +@@ -1123,6 +1255,290 @@ break; } -+#ifdef ALTIVEC ++#ifdef VECTORS + if (flags & VECTOR) { + /* + * Do the minimum amount of work necessary to construct @@ -441,24 +458,32 @@ + int i, j; /* Counter. */ + int vcnt; /* Number of elements in vector. */ + char *vfmt; /* Pointer to format specifier. */ -+ char vfmt_buf[32]; /* Static buffer for format spec. */ ++#define EXTRAHH 2 ++ char vfmt_buf[32 + EXTRAHH]; /* Static buffer for format spec. */ + int vwidth = 0; /* Width specified via '*'. */ + int vprec = 0; /* Precision specified via '*'. */ -+ union { /* Element. */ -+ int i; -+ float f; -+ } velm; + char *vstr; /* Used for asprintf(). */ + int vlen; /* Length returned by asprintf(). */ ++ enum { ++ V_CHAR, V_SHORT, V_INT, ++ V_PCHAR, V_PSHORT, V_PINT, ++ V_FLOAT, ++#ifdef V64TYPE ++ V_LONGLONG, V_PLONGLONG, ++ V_DOUBLE, ++#endif /* V64TYPE */ ++ } vtype; + ++ vval.vectorarg = GETARG(VECTORTYPE); + /* + * Set vfmt. If vfmt_buf may not be big enough, + * malloc() space, taking care to free it later. ++ * (EXTRAHH is for possible extra "hh") + */ -+ if (&fmt[-1] - pct < sizeof(vfmt_buf)) ++ if (&fmt[-1] - pct + EXTRAHH < sizeof(vfmt_buf)) + vfmt = vfmt_buf; + else -+ vfmt = (char *)malloc(&fmt[-1] - pct + 1); ++ vfmt = (char *)malloc(&fmt[-1] - pct + EXTRAHH + 1); + + /* Set the separator character, if not specified. */ + if (vsep == 'X') { @@ -491,11 +516,57 @@ + * finish up the format specifier. + */ + if (flags & SHORTINT) { -+ vfmt[j++] = 'h'; ++ switch (ch) { ++ case 'c': ++ vtype = V_SHORT; ++ break; ++ case 'p': ++ vtype = V_PSHORT; ++ break; ++ default: ++ vfmt[j++] = 'h'; ++ vtype = V_SHORT; ++ break; ++ } + vcnt = 8; + } else if (flags & LONGINT) { -+ vfmt[j++] = 'l'; + vcnt = 4; ++ vtype = (ch == 'p') ? V_PINT : V_INT; ++#ifdef V64TYPE ++ } else if (flags & LLONGINT) { ++ switch (ch) { ++ case 'a': ++ case 'A': ++ case 'e': ++ case 'E': ++ case 'f': ++ case 'g': ++ case 'G': ++ vcnt = 2; ++ vtype = V_DOUBLE; ++ break; ++ case 'd': ++ case 'i': ++ case 'u': ++ case 'o': ++ case 'p': ++ case 'x': ++ case 'X': ++ vfmt[j++] = 'l'; ++ vfmt[j++] = 'l'; ++ vcnt = 2; ++ vtype = (ch == 'p') ? V_PLONGLONG : V_LONGLONG; ++ break; ++ default: ++ /* ++ * The default case should never ++ * happen. ++ */ ++ case 'c': ++ vcnt = 16; ++ vtype = V_CHAR; ++ } ++#endif /* V64TYPE */ + } else { + switch (ch) { + case 'a': @@ -506,100 +577,150 @@ + case 'g': + case 'G': + vcnt = 4; ++ vtype = V_FLOAT; + break; + default: + /* + * The default case should never + * happen. + */ -+ case 'c': + case 'd': + case 'i': + case 'u': + case 'o': -+ case 'p': + case 'x': + case 'X': ++ vfmt[j++] = 'h'; ++ vfmt[j++] = 'h'; ++ /* drop through */ ++ case 'p': ++ case 'c': + vcnt = 16; ++ vtype = (ch == 'p') ? V_PCHAR : V_CHAR; + } + } + vfmt[j++] = ch; + vfmt[j++] = '\0'; + +/* Get a vector element. */ -+#define VPRINT(cnt, ind, args...) do { \ -+ if (flags & FPT) { \ -+ velm.f = vval.vfloatarg[ind]; \ -+ vlen = asprintf(&vstr, vfmt , ## args, velm.f); \ -+ } else { \ -+ switch (cnt) { \ -+ default: \ -+ /* The default case should never happen. */ \ -+ case 4: \ -+ velm.i = (unsigned)vval.vintarg[ind]; \ -+ break; \ -+ case 8: \ -+ velm.i = (unsigned short)vval.vshortarg[ind]; \ -+ break; \ -+ case 16: \ -+ velm.i = (unsigned char)vval.vchararg[ind]; \ -+ break; \ -+ } \ -+ vlen = asprintf(&vstr, vfmt , ## args, velm.i); \ ++#ifdef V64TYPE ++#define VPRINT(type, ind, args...) do { \ ++ switch (type) { \ ++ case V_CHAR: \ ++ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vuchararg[ind]); \ ++ break; \ ++ case V_PCHAR: \ ++ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vuchararg[ind]); \ ++ break; \ ++ case V_SHORT: \ ++ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vushortarg[ind]); \ ++ break; \ ++ case V_PSHORT: \ ++ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vushortarg[ind]); \ ++ break; \ ++ case V_INT: \ ++ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vuintarg[ind]); \ ++ break; \ ++ case V_PINT: \ ++ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vuintarg[ind]); \ ++ break; \ ++ case V_LONGLONG: \ ++ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vulonglongarg[ind]); \ ++ break; \ ++ case V_PLONGLONG: \ ++ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vulonglongarg[ind]); \ ++ break; \ ++ case V_FLOAT: \ ++ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vfloatarg[ind]); \ ++ break; \ ++ case V_DOUBLE: \ ++ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vdoublearg[ind]); \ ++ break; \ ++ } \ ++ ret += vlen; \ ++ PRINT(vstr, vlen); \ ++ FLUSH(); \ ++ free(vstr); \ ++} while (0) ++#else /* !V64TYPE */ ++#define VPRINT(type, ind, args...) do { \ ++ switch (type) { \ ++ case V_CHAR: \ ++ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vuchararg[ind]); \ ++ break; \ ++ case V_PCHAR: \ ++ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vuchararg[ind]); \ ++ break; \ ++ case V_SHORT: \ ++ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vushortarg[ind]); \ ++ break; \ ++ case V_PSHORT: \ ++ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vushortarg[ind]); \ ++ break; \ ++ case V_INT: \ ++ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vuintarg[ind]); \ ++ break; \ ++ case V_PINT: \ ++ vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vuintarg[ind]); \ ++ break; \ ++ case V_FLOAT: \ ++ vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vfloatarg[ind]); \ ++ break; \ + } \ + ret += vlen; \ + PRINT(vstr, vlen); \ + FLUSH(); \ + free(vstr); \ +} while (0) ++#endif /* V64TYPE */ + + /* Actually print. */ + if (vwidth == 0) { + if (vprec == 0) { + /* First element. */ -+ VPRINT(vcnt, 0); ++ VPRINT(vtype, 0); + for (i = 1; i < vcnt; i++) { + /* Separator. */ -+ if (vsep) ++ if(vsep) + PRINT(&vsep, 1); + + /* Element. */ -+ VPRINT(vcnt, i); ++ VPRINT(vtype, i); + } + } else { + /* First element. */ -+ VPRINT(vcnt, 0, prec); ++ VPRINT(vtype, 0, prec); + for (i = 1; i < vcnt; i++) { + /* Separator. */ -+ if (vsep) ++ if(vsep) + PRINT(&vsep, 1); + + /* Element. */ -+ VPRINT(vcnt, i, prec); ++ VPRINT(vtype, i, prec); + } + } + } else { + if (vprec == 0) { + /* First element. */ -+ VPRINT(vcnt, 0, width); ++ VPRINT(vtype, 0, width); + for (i = 1; i < vcnt; i++) { + /* Separator. */ -+ if (vsep) ++ if(vsep) + PRINT(&vsep, 1); + + /* Element. */ -+ VPRINT(vcnt, i, width); ++ VPRINT(vtype, i, width); + } + } else { + /* First element. */ -+ VPRINT(vcnt, 0, width, prec); ++ VPRINT(vtype, 0, width, prec); + for (i = 1; i < vcnt; i++) { + /* Separator. */ -+ if (vsep) ++ if(vsep) + PRINT(&vsep, 1); + + /* Element. */ -+ VPRINT(vcnt, i, width, prec); ++ VPRINT(vtype, i, width, prec); + } + } + } @@ -610,109 +731,96 @@ + + continue; + } -+#endif /* ALTIVEC */ ++#endif /* VECTORS */ /* * All reasonable formats wind up here. At this point, `cp' * points to a string which (if not flags&LADJUST) should be -@@ -1137,7 +1503,7 @@ - realsz = dprec > size ? dprec : size; - if (sign) - realsz++; -- else if (ox[1]) -+ if (ox[1]) - realsz += 2; - - prsize = width > realsz ? width : realsz; -@@ -1151,9 +1517,9 @@ - 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); - } -@@ -1400,6 +1766,11 @@ +@@ -1406,6 +1822,11 @@ if (flags & LONGINT) ADDTYPE(T_WINT); else -+#ifdef ALTIVEC ++#ifdef VECTORS + if (flags & VECTOR) + ADDTYPE(T_VECTOR); + else -+#endif /* ALTIVEC */ ++#endif /* VECTORS */ ADDTYPE(T_INT); break; case 'D': -@@ -1407,6 +1778,11 @@ +@@ -1413,6 +1834,11 @@ /*FALLTHROUGH*/ case 'd': case 'i': -+#ifdef ALTIVEC ++#ifdef VECTORS + if (flags & VECTOR) + ADDTYPE(T_VECTOR); + else +#endif ADDSARG(); break; - #ifdef FLOATING_POINT -@@ -1419,6 +1795,11 @@ + #ifndef NO_FLOATING_POINT +@@ -1423,6 +1849,11 @@ case 'f': case 'g': case 'G': -+#ifdef ALTIVEC ++#ifdef VECTORS + if (flags & VECTOR) + ADDTYPE(T_VECTOR); + else -+#endif /* ALTIVEC */ ++#endif /* VECTORS */ if (flags & LONGDBL) ADDTYPE(T_LONG_DOUBLE); else -@@ -1447,9 +1828,19 @@ +@@ -1451,9 +1882,19 @@ flags |= LONGINT; /*FALLTHROUGH*/ case 'o': -+#ifdef ALTIVEC ++#ifdef VECTORS + if (flags & VECTOR) + ADDTYPE(T_VECTOR); + else -+#endif /* ALTIVEC */ ++#endif /* VECTORS */ ADDUARG(); break; case 'p': -+#ifdef ALTIVEC ++#ifdef VECTORS + if (flags & VECTOR) + ADDTYPE(T_VECTOR); + else -+#endif /* ALTIVEC */ ++#endif /* VECTORS */ ADDTYPE(TP_VOID); break; case 'S': -@@ -1467,6 +1858,11 @@ +@@ -1471,6 +1912,11 @@ case 'u': case 'X': case 'x': -+#ifdef ALTIVEC ++#ifdef VECTORS + if (flags & VECTOR) + ADDTYPE(T_VECTOR); + else -+#endif /* ALTIVEC */ ++#endif /* VECTORS */ ADDUARG(); break; default: /* "%?" prints ?, unless ? is NUL */ -@@ -1552,6 +1948,12 @@ +@@ -1537,7 +1983,7 @@ + (*argtable) [n].sizearg = va_arg (ap, size_t); + break; + case TP_SIZET: +- (*argtable) [n].psizearg = va_arg (ap, ssize_t *); ++ (*argtable) [n].psizearg = va_arg (ap, size_t *); + break; + case T_INTMAXT: + (*argtable) [n].intmaxarg = va_arg (ap, intmax_t); +@@ -1556,6 +2002,11 @@ (*argtable) [n].longdoublearg = va_arg (ap, long double); break; #endif -+#ifdef ALTIVEC ++#ifdef VECTORS + case T_VECTOR: -+ if (hasAltivec) -+ ap = getvec( &((*argtable) [n]), NULL, 0, ap ); ++ (*argtable) [n].vectorarg = va_arg (ap, VECTORTYPE); + break; -+#endif /* ALTIVEC */ ++#endif /* VECTORS */ case TP_CHAR: (*argtable) [n].pchararg = va_arg (ap, char *); break;