X-Git-Url: https://git.saurik.com/apple/libc.git/blobdiff_plain/9385eb3d10ebe5eb398c52040ec3dbfba9b0cdcf..c957a83bde4df2e2d3d1ed0963656856b48ef0a0:/stdio/FreeBSD/vfwprintf.c.patch?ds=inline diff --git a/stdio/FreeBSD/vfwprintf.c.patch b/stdio/FreeBSD/vfwprintf.c.patch index e6e2aa8..a645ab8 100644 --- a/stdio/FreeBSD/vfwprintf.c.patch +++ b/stdio/FreeBSD/vfwprintf.c.patch @@ -1,40 +1,40 @@ ---- vfwprintf.c.orig Thu Jul 24 12:42:14 2003 -+++ vfwprintf.c Sun Aug 24 16:22:23 2003 -@@ -70,9 +70,20 @@ - #include "local.h" - #include "fvwrite.h" +--- vfwprintf.c.orig 2004-11-25 11:38:36.000000000 -0800 ++++ vfwprintf.c 2005-11-08 22:46:07.000000000 -0800 +@@ -42,6 +42,8 @@ + #include + __FBSDID("$FreeBSD: src/lib/libc/stdio/vfwprintf.c,v 1.23 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 wprintf innards. + * +@@ -63,12 +65,20 @@ + #include + #include + #include ++#include + #include "un-namespace.h" -+/* if no floating point, turn off HEXFLOAT as well */ -+#if defined(HEXFLOAT) && !defined(FLOATING_POINT) -+#undef HEXFLOAT -+#endif /* defined(HEXFLOAT) && !defined(FLOATING_POINT) */ + #include "libc_private.h" + #include "local.h" + #include "fvwrite.h" + ++#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; -@@ -92,7 +103,7 @@ - long *plongarg; - long long *plonglongarg; - ptrdiff_t *pptrdiffarg; -- size_t *psizearg; -+ ssize_t *psizearg; - intmax_t *pintmaxarg; - #ifdef FLOATING_POINT - double doublearg; -@@ -100,6 +111,16 @@ +@@ -96,6 +106,21 @@ #endif wint_t wintarg; wchar_t *pwchararg; -+#ifdef ALTIVEC ++#ifdef VECTORS + VECTORTYPE vectorarg; + unsigned char vuchararg[16]; + signed char vchararg[16]; @@ -43,91 +43,159 @@ + 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 */ }; /* -@@ -110,7 +131,11 @@ +@@ -106,16 +131,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 __sbprintf(FILE *, const wchar_t *, va_list); -@@ -122,6 +147,37 @@ +-static int __sbprintf(FILE *, const wchar_t *, va_list); +-static wint_t __xfputwc(wchar_t, FILE *); ++static int __sbprintf(FILE *, locale_t, const wchar_t *, va_list); ++static wint_t __xfputwc(wchar_t, FILE *, locale_t); + static wchar_t *__ujtoa(uintmax_t, wchar_t *, int, int, const char *, int, + char, const char *); + static wchar_t *__ultoa(u_long, wchar_t *, int, int, const char *, int, + char, const char *); +-static wchar_t *__mbsconv(char *, int); ++static wchar_t *__mbsconv(char *, int, locale_t); static void __find_arguments(const wchar_t *, 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; +@@ -125,7 +154,7 @@ + * worries about ungetc buffers and so forth. + */ + static int +-__sbprintf(FILE *fp, const wchar_t *fmt, va_list ap) ++__sbprintf(FILE *fp, locale_t loc, const wchar_t *fmt, va_list ap) + { + int ret; + FILE fake; +@@ -144,7 +173,7 @@ + fake._lbfsize = 0; /* not actually used, but Just In Case */ + + /* do the work, then copy any error status */ +- ret = __vfwprintf(&fake, fmt, ap); ++ ret = __vfwprintf(&fake, loc, fmt, ap); + if (ret >= 0 && __fflush(&fake)) + ret = WEOF; + if (fake._flags & __SERR) +@@ -157,7 +186,7 @@ + * File must already be locked. + */ + static wint_t +-__xfputwc(wchar_t wc, FILE *fp) ++__xfputwc(wchar_t wc, FILE *fp, locale_t loc) + { + static const mbstate_t initial; + mbstate_t mbs; +@@ -167,10 +196,10 @@ + size_t len; + + if ((fp->_flags & __SSTR) == 0) +- return (__fputwc(wc, fp)); ++ return (__fputwc(wc, fp, loc)); + + mbs = initial; +- if ((len = wcrtomb(buf, wc, &mbs)) == (size_t)-1) { ++ if ((len = wcrtomb_l(buf, wc, &mbs, loc)) == (size_t)-1) { + fp->_flags |= __SERR; + return (WEOF); + } +@@ -350,13 +379,14 @@ + * that the multibyte char. string ends in a null character. + */ + static wchar_t * +-__mbsconv(char *mbsarg, int prec) ++__mbsconv(char *mbsarg, int prec, locale_t loc) + { + static const mbstate_t initial; + mbstate_t mbs; + wchar_t *convbuf, *wcp; + const char *p; + size_t insize, nchars, nconv; ++ int mb_cur_max = MB_CUR_MAX_L(loc); + + if (mbsarg == NULL) + return (NULL); +@@ -374,7 +404,7 @@ + insize = nchars = 0; + mbs = initial; + while (nchars != (size_t)prec) { +- nconv = mbrlen(p, MB_CUR_MAX, &mbs); ++ nconv = mbrlen_l(p, mb_cur_max, &mbs, loc); + if (nconv == 0 || nconv == (size_t)-1 || + nconv == (size_t)-2) + break; +@@ -399,7 +429,7 @@ + p = mbsarg; + mbs = initial; + while (insize != 0) { +- nconv = mbrtowc(wcp, p, insize, &mbs); ++ nconv = mbrtowc_l(wcp, p, insize, &mbs, loc); + if (nconv == 0 || nconv == (size_t)-1 || nconv == (size_t)-2) + break; + wcp++; +@@ -425,7 +455,21 @@ + int ret; + + FLOCKFILE(fp); +- ret = __vfwprintf(fp, fmt0, ap); ++ ret = __vfwprintf(fp, __current_locale(), fmt0, ap); ++ FUNLOCKFILE(fp); ++ return (ret); +} + -+#define SETVEC(dst) \ -+{ \ -+ ap = getvec(&dst, argtable, nextarg, ap); \ -+ nextarg++; \ -+} -+#endif /* ALTIVEC */ ++int ++vfwprintf_l(FILE * __restrict fp, locale_t loc, const wchar_t * __restrict fmt0, ++ va_list ap) + - /* - * Helper function for `fprintf to unbuffered unix file': creates a - * temporary buffer. We only work on write-only files; this avoids -@@ -418,6 +474,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 -@@ -446,6 +511,9 @@ ++ NORMALIZE_LOCALE(loc); ++ FLOCKFILE(fp); ++ ret = __vfwprintf(fp, loc, fmt0, ap); + FUNLOCKFILE(fp); + return (ret); + } +@@ -474,12 +518,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 -@@ -496,6 +564,11 @@ + */ +-int +-__vfwprintf(FILE *fp, const wchar_t *fmt0, va_list ap) ++__private_extern__ int ++__vfwprintf(FILE *fp, locale_t loc, const wchar_t *fmt0, va_list ap) + { + wchar_t *fmt; /* format string */ + wchar_t ch; /* character from fmt */ +@@ -524,6 +571,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. */ + wchar_t *pct; /* Pointer to '%' at beginning of specifier. */ + wchar_t vsep; /* Vector separator character. */ @@ -135,330 +203,284 @@ u_long ulval; /* integer arguments %[diouxX] */ uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */ int base; /* base for [diouxX] conversion */ -@@ -525,6 +598,15 @@ - - static const wchar_t xdigs_lower[16] = L"0123456789abcdef"; - static const wchar_t xdigs_upper[16] = L"0123456789ABCDEF"; -+#ifdef HEXFLOAT -+#define HEXFLOATDELTA 32 -+#define HEXFLOATSTART 32 -+ static char *hexfloat = NULL; -+ static int hexfloatlen = 0; -+ const char *xdigs0; /* digits for [aA] conversion */ -+ static const char xdigs_lower0[16] = "0123456789abcdef"; -+ static const char xdigs_upper0[16] = "0123456789ABCDEF"; -+#endif /* HEXFLOAT */ - - /* - * BEWARE, these `goto error' on error, PRINT uses `n2' and -@@ -553,15 +635,6 @@ - } while(0) - - /* -- * 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. +@@ -560,7 +612,7 @@ */ -@@ -612,7 +685,6 @@ + #define PRINT(ptr, len) do { \ + for (n3 = 0; n3 < (len); n3++) \ +- __xfputwc((ptr)[n3], fp); \ ++ __xfputwc((ptr)[n3], fp, loc); \ + } while (0) + #define PAD(howmany, with) do { \ + if ((n = (howmany)) > 0) { \ +@@ -640,21 +692,22 @@ val = GETARG (int); \ } - thousands_sep = '\0'; grouping = NULL; - #ifdef FLOATING_POINT -@@ -650,6 +722,9 @@ + #ifndef NO_FLOATING_POINT +- decimal_point = localeconv()->decimal_point; ++ decimal_point = localeconv_l(loc)->decimal_point; + #endif + convbuf = NULL; + /* sorry, fwprintf(read_only_file, L"") returns WEOF, 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 = (wchar_t *)fmt0; + argtable = NULL; +@@ -678,6 +731,9 @@ } if (ch == '\0') goto done; -+#ifdef ALTIVEC ++#ifdef VECTORS + pct = fmt; -+#endif /* ALTIVEC */ ++#endif /* VECTORS */ fmt++; /* skip over '%' */ flags = 0; -@@ -658,6 +733,9 @@ +@@ -686,6 +742,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) { -@@ -673,6 +751,11 @@ +@@ -701,6 +760,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 -@@ -770,8 +853,18 @@ +@@ -721,8 +785,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++) == '*') { +@@ -796,10 +860,14 @@ + flags |= LONGINT; + /*FALLTHROUGH*/ case 'c': ++#ifdef VECTORS ++ if (flags & VECTOR) ++ break; ++#endif /* VECTORS */ if (flags & LONGINT) *(cp = buf) = (wchar_t)GETARG(wint_t); -+#ifdef ALTIVEC -+ else { -+ if (flags & VECTOR) { -+ SETVEC(vval); -+ break; -+ } -+ *(cp = buf) = (wchar_t)btowc(GETARG(int)); -+ } -+#else /* ALTIVEC */ else - *(cp = buf) = (wchar_t)btowc(GETARG(int)); -+#endif /* ALTIVEC */ +- *(cp = buf) = (wchar_t)btowc(GETARG(int)); ++ *(cp = buf) = (wchar_t)btowc_l(GETARG(int), loc); size = 1; sign = '\0'; break; -@@ -780,6 +873,12 @@ +@@ -808,6 +876,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) { -@@ -799,38 +898,74 @@ - #ifdef HEXFLOAT +@@ -826,6 +898,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; -+ xdigs0 = xdigs_lower0; - expchar = 'p'; - } else { - ox[1] = 'X'; -- xdigs = xdigs_upper; -+ xdigs0 = xdigs_upper0; - expchar = 'P'; + xdigs = xdigs_lower; +@@ -837,6 +915,12 @@ } -- /* -- * XXX We don't actually have a conversion -- * XXX routine for this yet. -- */ -+ if (!hexfloat) { -+ hexfloat = malloc(hexfloatlen = HEXFLOATSTART); -+ if (!hexfloat) -+ goto error; -+ } -+ /* one extra for integer part and another for null */ -+ if (prec > hexfloatlen - 2) { -+ int hlen = prec + HEXFLOATDELTA; -+ char *hf = realloc(hexfloat, hlen); -+ if (hf == NULL) -+ goto error; -+ hexfloat = hf; -+ hexfloatlen = hlen; -+ } + if (prec >= 0) + prec++; ++#ifdef LDBL_COMPAT ++ fparg.dbl = GETARG(double); ++ dtoaresult = ++ __hdtoa(fparg.dbl, xdigs, prec, ++ &expt, &signflag, &dtoaend); ++#else /* !LDBL_COMPAT */ if (flags & LONGDBL) { -- fparg.ldbl = (double)GETARG(long double); -- dtoaresult = -- __hldtoa(fparg.ldbl, xdigs, prec, -- &expt, &signflag, &dtoaend); -+#if __TYPE_LONGDOUBLE_IS_DOUBLE -+ fparg.dbl = (double)GETARG(long double); -+ prec = __hdtoa(fparg.dbl, xdigs0, prec, -+ hexfloat, &expt, &signflag, &dtoaend); -+#else /* ! __TYPE_LONGDOUBLE_IS_DOUBLE */ -+ fparg.ldbl = GETARG(long double); -+ prec = __hldtoa(fparg.ldbl, xdigs0, prec, -+ hexfloat, &expt, &signflag, &dtoaend); -+#endif /* __TYPE_LONGDOUBLE_IS_DOUBLE */ - } else { - fparg.dbl = GETARG(double); -- dtoaresult = -- __hdtoa(fparg.dbl, xdigs, prec, -- &expt, &signflag, &dtoaend); -+ prec = __hdtoa(fparg.dbl, xdigs0, prec, -+ hexfloat, &expt, &signflag, &dtoaend); -+ } -+ prec++; -+ if (expt == INT_MAX) { -+ ox[1] = 0; -+ hexfloat[1] = 0; -+ } else { -+ expt++; -+ *dtoaend = 0; -+ ndig = dtoaend - hexfloat; + fparg.ldbl = GETARG(long double); + dtoaresult = +@@ -848,6 +932,7 @@ + __hdtoa(fparg.dbl, xdigs, prec, + &expt, &signflag, &dtoaend); } ++#endif /* LDBL_COMPAT */ + if (prec < 0) + prec = dtoaend - dtoaresult; + if (expt == INT_MAX) +@@ -855,11 +940,17 @@ if (convbuf != NULL) free(convbuf); + ndig = dtoaend - dtoaresult; - cp = convbuf = __mbsconv(dtoaresult, -1); -- freedtoa(dtoaresult); -- goto fp_begin; -+ cp = convbuf = __mbsconv(hexfloat, -1); -+ goto hex_begin; - #endif ++ cp = convbuf = __mbsconv(dtoaresult, -1, loc); + freedtoa(dtoaresult); + 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; -@@ -839,10 +974,24 @@ +@@ -868,10 +959,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; -@@ -851,6 +1000,17 @@ +@@ -880,6 +983,14 @@ prec = DEFPREC; if (convbuf != NULL) free(convbuf); -+#if __TYPE_LONGDOUBLE_IS_DOUBLE -+ if (flags & LONGDBL) -+ fparg.ldbl = GETARG(long double); -+ else -+ fparg.dbl = GETARG(double); ++#ifdef LDBL_COMPAT ++ fparg.dbl = GETARG(double); + dtoaresult = + 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 = -@@ -864,9 +1024,13 @@ +@@ -893,8 +1004,9 @@ if (expt == 9999) expt = INT_MAX; } -+#endif /* __TYPE_LONGDOUBLE_IS_DOUBLE */ ++#endif /* LDBL_COMPAT */ ndig = dtoaend - dtoaresult; - cp = convbuf = __mbsconv(dtoaresult, -1); +- cp = convbuf = __mbsconv(dtoaresult, -1); ++ cp = convbuf = __mbsconv(dtoaresult, -1, loc); freedtoa(dtoaresult); -+#ifdef HEXFLOAT -+hex_begin: -+#endif /* HEXFLOAT */ + fp_common: if (signflag) - sign = '-'; - if (expt == INT_MAX) { /* inf or nan */ -@@ -959,6 +1123,12 @@ +@@ -989,6 +1101,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 -@@ -973,6 +1143,12 @@ +@@ -1003,6 +1119,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; -@@ -1025,6 +1201,12 @@ +@@ -1024,7 +1144,7 @@ + if ((mbp = GETARG(char *)) == NULL) + cp = L"(null)"; + else { +- convbuf = __mbsconv(mbp, prec); ++ convbuf = __mbsconv(mbp, prec, loc); + if (convbuf == NULL) { + fp->_flags |= __SERR; + goto error; +@@ -1055,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 -@@ -1037,6 +1219,12 @@ +@@ -1067,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 -@@ -1081,6 +1269,14 @@ +@@ -1111,6 +1239,11 @@ if (size > BUF) /* should never happen */ abort(); break; -+#ifdef ALTIVEC ++#ifdef VECTORS + case 'v': -+ if (hasAltivec) { -+ flags |= VECTOR; -+ goto rflag; -+ } -+ /* drop through */ -+#endif /* ALTIVEC */ ++ flags |= VECTOR; ++ goto rflag; ++#endif /* VECTORS */ default: /* "%?" prints ?, unless ? is NUL */ if (ch == '\0') goto done; -@@ -1092,6 +1288,185 @@ +@@ -1122,6 +1255,288 @@ break; } -+#ifdef ALTIVEC ++#ifdef VECTORS + if (flags & VECTOR) { + /* + * Do the minimum amount of work necessary to construct @@ -468,24 +490,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') { @@ -518,11 +548,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': @@ -533,99 +609,148 @@ + 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); \ + 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); \ ++ 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); + } + } + } @@ -636,97 +761,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 -@@ -1109,7 +1484,7 @@ - realsz = dprec > size ? dprec : size; - if (sign) - realsz++; -- else if (ox[1]) -+ if (ox[1]) - realsz += 2; - - prsize = width > realsz ? width : realsz; -@@ -1123,9 +1498,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); - } -@@ -1368,6 +1743,11 @@ +@@ -1401,6 +1816,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': -@@ -1387,6 +1767,11 @@ +@@ -1408,6 +1828,11 @@ + /*FALLTHROUGH*/ + case 'd': + case 'i': ++#ifdef VECTORS ++ if (flags & VECTOR) ++ ADDTYPE(T_VECTOR); ++ else ++#endif /* VECTORS */ + ADDSARG(); + break; + #ifndef NO_FLOATING_POINT +@@ -1418,6 +1843,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 -@@ -1415,9 +1800,19 @@ +@@ -1446,9 +1876,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': -@@ -1435,6 +1830,11 @@ +@@ -1466,6 +1906,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 */ -@@ -1520,6 +1920,12 @@ +@@ -1532,7 +1977,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); +@@ -1551,6 +1996,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;