]> git.saurik.com Git - apple/libc.git/blob - stdio/FreeBSD/vfwprintf.c.patch
Libc-391.tar.gz
[apple/libc.git] / stdio / FreeBSD / vfwprintf.c.patch
1 --- vfwprintf.c.orig 2004-11-25 11:38:36.000000000 -0800
2 +++ vfwprintf.c 2005-02-24 15:17:14.000000000 -0800
3 @@ -42,6 +42,8 @@
4 #include <sys/cdefs.h>
5 __FBSDID("$FreeBSD: src/lib/libc/stdio/vfwprintf.c,v 1.23 2004/08/26 06:25:28 des Exp $");
6
7 +#include "xlocale_private.h"
8 +
9 /*
10 * Actual wprintf innards.
11 *
12 @@ -63,12 +65,19 @@
13 #include <string.h>
14 #include <wchar.h>
15 #include <wctype.h>
16 +#include <errno.h>
17 #include "un-namespace.h"
18
19 #include "libc_private.h"
20 #include "local.h"
21 #include "fvwrite.h"
22
23 +#ifdef ALTIVEC
24 +#include <machine/cpu_capabilities.h>
25 +
26 +#define VECTORTYPE vector unsigned char
27 +#endif /* ALTIVEC */
28 +
29 union arg {
30 int intarg;
31 u_int uintarg;
32 @@ -96,6 +105,16 @@
33 #endif
34 wint_t wintarg;
35 wchar_t *pwchararg;
36 +#ifdef ALTIVEC
37 + VECTORTYPE vectorarg;
38 + unsigned char vuchararg[16];
39 + signed char vchararg[16];
40 + unsigned short vushortarg[8];
41 + signed short vshortarg[8];
42 + unsigned int vuintarg[4];
43 + signed int vintarg[4];
44 + float vfloatarg[4];
45 +#endif /* ALTIVEC */
46 };
47
48 /*
49 @@ -106,26 +125,63 @@
50 T_LONG, T_U_LONG, TP_LONG, T_LLONG, T_U_LLONG, TP_LLONG,
51 T_PTRDIFFT, TP_PTRDIFFT, T_SIZET, TP_SIZET,
52 T_INTMAXT, T_UINTMAXT, TP_INTMAXT, TP_VOID, TP_CHAR, TP_SCHAR,
53 +#ifdef ALTIVEC
54 + T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR, T_VECTOR
55 +#else /* ! ALTIVEC */
56 T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR
57 +#endif /* ALTIVEC */
58 };
59
60 -static int __sbprintf(FILE *, const wchar_t *, va_list);
61 -static wint_t __xfputwc(wchar_t, FILE *);
62 +static int __sbprintf(FILE *, locale_t, const wchar_t *, va_list);
63 +static wint_t __xfputwc(wchar_t, FILE *, locale_t);
64 static wchar_t *__ujtoa(uintmax_t, wchar_t *, int, int, const char *, int,
65 char, const char *);
66 static wchar_t *__ultoa(u_long, wchar_t *, int, int, const char *, int,
67 char, const char *);
68 -static wchar_t *__mbsconv(char *, int);
69 +static wchar_t *__mbsconv(char *, int, locale_t);
70 static void __find_arguments(const wchar_t *, va_list, union arg **);
71 static void __grow_type_table(int, enum typeid **, int *);
72
73 + /*
74 + * Get the argument indexed by nextarg. If the argument table is
75 + * built, use it to get the argument. If its not, get the next
76 + * argument (and arguments must be gotten sequentially).
77 + */
78 +#define GETARG(type) \
79 + ((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : \
80 + (nextarg++, va_arg(ap, type)))
81 +
82 +#ifdef ALTIVEC
83 +#define hasAltivec (_cpu_capabilities & kHasAltivec)
84 +/*-----------------------------------------------------------------------
85 + * getvec() must be a real subroutine. If it is a #define, then __vfprintf()
86 + * would have its calling sequence changed by Altivec so that a non-Altivec
87 + * processor would crash on illegal instruction. By isolating the calling
88 + * sequence in getvec(), __vprintf() is callable by a non-Altivec processor.
89 + *-----------------------------------------------------------------------*/
90 +static va_list getvec(union arg *, const union arg *, int, va_list) __attribute__((noinline));
91 +
92 +static va_list
93 +getvec(union arg *dst, const union arg *argtable, int nextarg, va_list ap)
94 +{
95 + dst->vectorarg = GETARG(VECTORTYPE);
96 + return ap;
97 +}
98 +
99 +#define SETVEC(dst) \
100 +{ \
101 + ap = getvec(&dst, argtable, nextarg, ap); \
102 + nextarg++; \
103 +}
104 +#endif /* ALTIVEC */
105 +
106 /*
107 * Helper function for `fprintf to unbuffered unix file': creates a
108 * temporary buffer. We only work on write-only files; this avoids
109 * worries about ungetc buffers and so forth.
110 */
111 static int
112 -__sbprintf(FILE *fp, const wchar_t *fmt, va_list ap)
113 +__sbprintf(FILE *fp, locale_t loc, const wchar_t *fmt, va_list ap)
114 {
115 int ret;
116 FILE fake;
117 @@ -144,7 +200,7 @@
118 fake._lbfsize = 0; /* not actually used, but Just In Case */
119
120 /* do the work, then copy any error status */
121 - ret = __vfwprintf(&fake, fmt, ap);
122 + ret = __vfwprintf(&fake, loc, fmt, ap);
123 if (ret >= 0 && __fflush(&fake))
124 ret = WEOF;
125 if (fake._flags & __SERR)
126 @@ -157,7 +213,7 @@
127 * File must already be locked.
128 */
129 static wint_t
130 -__xfputwc(wchar_t wc, FILE *fp)
131 +__xfputwc(wchar_t wc, FILE *fp, locale_t loc)
132 {
133 static const mbstate_t initial;
134 mbstate_t mbs;
135 @@ -167,10 +223,10 @@
136 size_t len;
137
138 if ((fp->_flags & __SSTR) == 0)
139 - return (__fputwc(wc, fp));
140 + return (__fputwc(wc, fp, loc));
141
142 mbs = initial;
143 - if ((len = wcrtomb(buf, wc, &mbs)) == (size_t)-1) {
144 + if ((len = wcrtomb_l(buf, wc, &mbs, loc)) == (size_t)-1) {
145 fp->_flags |= __SERR;
146 return (WEOF);
147 }
148 @@ -350,13 +406,14 @@
149 * that the multibyte char. string ends in a null character.
150 */
151 static wchar_t *
152 -__mbsconv(char *mbsarg, int prec)
153 +__mbsconv(char *mbsarg, int prec, locale_t loc)
154 {
155 static const mbstate_t initial;
156 mbstate_t mbs;
157 wchar_t *convbuf, *wcp;
158 const char *p;
159 size_t insize, nchars, nconv;
160 + int mb_cur_max = MB_CUR_MAX_L(loc);
161
162 if (mbsarg == NULL)
163 return (NULL);
164 @@ -374,7 +431,7 @@
165 insize = nchars = 0;
166 mbs = initial;
167 while (nchars != (size_t)prec) {
168 - nconv = mbrlen(p, MB_CUR_MAX, &mbs);
169 + nconv = mbrlen_l(p, mb_cur_max, &mbs, loc);
170 if (nconv == 0 || nconv == (size_t)-1 ||
171 nconv == (size_t)-2)
172 break;
173 @@ -399,7 +456,7 @@
174 p = mbsarg;
175 mbs = initial;
176 while (insize != 0) {
177 - nconv = mbrtowc(wcp, p, insize, &mbs);
178 + nconv = mbrtowc_l(wcp, p, insize, &mbs, loc);
179 if (nconv == 0 || nconv == (size_t)-1 || nconv == (size_t)-2)
180 break;
181 wcp++;
182 @@ -425,7 +482,21 @@
183 int ret;
184
185 FLOCKFILE(fp);
186 - ret = __vfwprintf(fp, fmt0, ap);
187 + ret = __vfwprintf(fp, __current_locale(), fmt0, ap);
188 + FUNLOCKFILE(fp);
189 + return (ret);
190 +}
191 +
192 +int
193 +vfwprintf_l(FILE * __restrict fp, locale_t loc, const wchar_t * __restrict fmt0,
194 + va_list ap)
195 +
196 +{
197 + int ret;
198 +
199 + NORMALIZE_LOCALE(loc);
200 + FLOCKFILE(fp);
201 + ret = __vfwprintf(fp, loc, fmt0, ap);
202 FUNLOCKFILE(fp);
203 return (ret);
204 }
205 @@ -474,12 +545,15 @@
206 #define PTRDIFFT 0x800 /* ptrdiff_t */
207 #define INTMAXT 0x1000 /* intmax_t */
208 #define CHARINT 0x2000 /* print char using int format */
209 +#ifdef ALTIVEC
210 +#define VECTOR 0x4000 /* Altivec vector */
211 +#endif /* ALTIVEC */
212
213 /*
214 * Non-MT-safe version
215 */
216 -int
217 -__vfwprintf(FILE *fp, const wchar_t *fmt0, va_list ap)
218 +__private_extern__ int
219 +__vfwprintf(FILE *fp, locale_t loc, const wchar_t *fmt0, va_list ap)
220 {
221 wchar_t *fmt; /* format string */
222 wchar_t ch; /* character from fmt */
223 @@ -524,6 +598,11 @@
224 int nseps; /* number of group separators with ' */
225 int nrepeats; /* number of repeats of the last group */
226 #endif
227 +#ifdef ALTIVEC
228 + union arg vval; /* Vector argument. */
229 + wchar_t *pct; /* Pointer to '%' at beginning of specifier. */
230 + wchar_t vsep; /* Vector separator character. */
231 +#endif
232 u_long ulval; /* integer arguments %[diouxX] */
233 uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */
234 int base; /* base for [diouxX] conversion */
235 @@ -560,7 +639,7 @@
236 */
237 #define PRINT(ptr, len) do { \
238 for (n3 = 0; n3 < (len); n3++) \
239 - __xfputwc((ptr)[n3], fp); \
240 + __xfputwc((ptr)[n3], fp, loc); \
241 } while (0)
242 #define PAD(howmany, with) do { \
243 if ((n = (howmany)) > 0) { \
244 @@ -581,15 +660,6 @@
245 } while(0)
246
247 /*
248 - * Get the argument indexed by nextarg. If the argument table is
249 - * built, use it to get the argument. If its not, get the next
250 - * argument (and arguments must be gotten sequentially).
251 - */
252 -#define GETARG(type) \
253 - ((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : \
254 - (nextarg++, va_arg(ap, type)))
255 -
256 - /*
257 * To extend shorts properly, we need both signed and unsigned
258 * argument extraction methods.
259 */
260 @@ -640,21 +710,22 @@
261 val = GETARG (int); \
262 }
263
264 -
265 thousands_sep = '\0';
266 grouping = NULL;
267 #ifndef NO_FLOATING_POINT
268 - decimal_point = localeconv()->decimal_point;
269 + decimal_point = localeconv_l(loc)->decimal_point;
270 #endif
271 convbuf = NULL;
272 /* sorry, fwprintf(read_only_file, L"") returns WEOF, not 0 */
273 - if (prepwrite(fp) != 0)
274 + if (prepwrite(fp) != 0) {
275 + errno = EBADF;
276 return (EOF);
277 + }
278
279 /* optimise fprintf(stderr) (and other unbuffered Unix files) */
280 if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
281 fp->_file >= 0)
282 - return (__sbprintf(fp, fmt0, ap));
283 + return (__sbprintf(fp, loc, fmt0, ap));
284
285 fmt = (wchar_t *)fmt0;
286 argtable = NULL;
287 @@ -678,6 +749,9 @@
288 }
289 if (ch == '\0')
290 goto done;
291 +#ifdef ALTIVEC
292 + pct = fmt;
293 +#endif /* ALTIVEC */
294 fmt++; /* skip over '%' */
295
296 flags = 0;
297 @@ -686,6 +760,9 @@
298 prec = -1;
299 sign = '\0';
300 ox[1] = '\0';
301 +#ifdef ALTIVEC
302 + vsep = 'X'; /* Illegal value, changed to defaults later. */
303 +#endif /* ALTIVEC */
304
305 rflag: ch = *fmt++;
306 reswitch: switch (ch) {
307 @@ -701,6 +778,11 @@
308 case '#':
309 flags |= ALT;
310 goto rflag;
311 +#ifdef ALTIVEC
312 + case ',': case ';': case ':': case '_':
313 + vsep = ch;
314 + goto rflag;
315 +#endif /* ALTIVEC */
316 case '*':
317 /*-
318 * ``A negative field width argument is taken as a
319 @@ -721,8 +803,8 @@
320 goto rflag;
321 case '\'':
322 flags |= GROUPING;
323 - thousands_sep = *(localeconv()->thousands_sep);
324 - grouping = localeconv()->grouping;
325 + thousands_sep = *(localeconv_l(loc)->thousands_sep);
326 + grouping = localeconv_l(loc)->grouping;
327 goto rflag;
328 case '.':
329 if ((ch = *fmt++) == '*') {
330 @@ -796,10 +878,16 @@
331 flags |= LONGINT;
332 /*FALLTHROUGH*/
333 case 'c':
334 +#ifdef ALTIVEC
335 + if (flags & VECTOR) {
336 + SETVEC(vval);
337 + break;
338 + }
339 +#endif /* ALTIVEC */
340 if (flags & LONGINT)
341 *(cp = buf) = (wchar_t)GETARG(wint_t);
342 else
343 - *(cp = buf) = (wchar_t)btowc(GETARG(int));
344 + *(cp = buf) = (wchar_t)btowc_l(GETARG(int), loc);
345 size = 1;
346 sign = '\0';
347 break;
348 @@ -808,6 +896,12 @@
349 /*FALLTHROUGH*/
350 case 'd':
351 case 'i':
352 +#ifdef ALTIVEC
353 + if (flags & VECTOR) {
354 + SETVEC(vval);
355 + break;
356 + }
357 +#endif /* ALTIVEC */
358 if (flags & INTMAX_SIZE) {
359 ujval = SJARG();
360 if ((intmax_t)ujval < 0) {
361 @@ -837,6 +931,12 @@
362 }
363 if (prec >= 0)
364 prec++;
365 +#ifdef LDBL_COMPAT
366 + fparg.dbl = GETARG(double);
367 + dtoaresult =
368 + __hdtoa(fparg.dbl, xdigs, prec,
369 + &expt, &signflag, &dtoaend);
370 +#else /* !LDBL_COMPAT */
371 if (flags & LONGDBL) {
372 fparg.ldbl = GETARG(long double);
373 dtoaresult =
374 @@ -848,6 +948,7 @@
375 __hdtoa(fparg.dbl, xdigs, prec,
376 &expt, &signflag, &dtoaend);
377 }
378 +#endif /* LDBL_COMPAT */
379 if (prec < 0)
380 prec = dtoaend - dtoaresult;
381 if (expt == INT_MAX)
382 @@ -855,7 +956,7 @@
383 if (convbuf != NULL)
384 free(convbuf);
385 ndig = dtoaend - dtoaresult;
386 - cp = convbuf = __mbsconv(dtoaresult, -1);
387 + cp = convbuf = __mbsconv(dtoaresult, -1, loc);
388 freedtoa(dtoaresult);
389 goto fp_common;
390 case 'e':
391 @@ -868,10 +969,24 @@
392 goto fp_begin;
393 case 'f':
394 case 'F':
395 +#ifdef ALTIVEC
396 + if (flags & VECTOR) {
397 + flags |= FPT;
398 + SETVEC(vval);
399 + break;
400 + }
401 +#endif /* ALTIVEC */
402 expchar = '\0';
403 goto fp_begin;
404 case 'g':
405 case 'G':
406 +#ifdef ALTIVEC
407 + if (flags & VECTOR) {
408 + flags |= FPT;
409 + SETVEC(vval);
410 + break;
411 + }
412 +#endif /* ALTIVEC */
413 expchar = ch - ('g' - 'e');
414 if (prec == 0)
415 prec = 1;
416 @@ -880,6 +995,14 @@
417 prec = DEFPREC;
418 if (convbuf != NULL)
419 free(convbuf);
420 +#ifdef LDBL_COMPAT
421 + fparg.dbl = GETARG(double);
422 + dtoaresult =
423 + dtoa(fparg.dbl, expchar ? 2 : 3, prec,
424 + &expt, &signflag, &dtoaend);
425 + if (expt == 9999)
426 + expt = INT_MAX;
427 +#else /* !LDBL_COMPAT */
428 if (flags & LONGDBL) {
429 fparg.ldbl = GETARG(long double);
430 dtoaresult =
431 @@ -893,8 +1016,9 @@
432 if (expt == 9999)
433 expt = INT_MAX;
434 }
435 +#endif /* LDBL_COMPAT */
436 ndig = dtoaend - dtoaresult;
437 - cp = convbuf = __mbsconv(dtoaresult, -1);
438 + cp = convbuf = __mbsconv(dtoaresult, -1, loc);
439 freedtoa(dtoaresult);
440 fp_common:
441 if (signflag)
442 @@ -989,6 +1113,12 @@
443 flags |= LONGINT;
444 /*FALLTHROUGH*/
445 case 'o':
446 +#ifdef ALTIVEC
447 + if (flags & VECTOR) {
448 + SETVEC(vval);
449 + break;
450 + }
451 +#endif /* ALTIVEC */
452 if (flags & INTMAX_SIZE)
453 ujval = UJARG();
454 else
455 @@ -1003,6 +1133,12 @@
456 * defined manner.''
457 * -- ANSI X3J11
458 */
459 +#ifdef ALTIVEC
460 + if (flags & VECTOR) {
461 + SETVEC(vval);
462 + break;
463 + }
464 +#endif /* ALTIVEC */
465 ujval = (uintmax_t)(uintptr_t)GETARG(void *);
466 base = 16;
467 xdigs = xdigs_lower;
468 @@ -1024,7 +1160,7 @@
469 if ((mbp = GETARG(char *)) == NULL)
470 cp = L"(null)";
471 else {
472 - convbuf = __mbsconv(mbp, prec);
473 + convbuf = __mbsconv(mbp, prec, loc);
474 if (convbuf == NULL) {
475 fp->_flags |= __SERR;
476 goto error;
477 @@ -1055,6 +1191,12 @@
478 flags |= LONGINT;
479 /*FALLTHROUGH*/
480 case 'u':
481 +#ifdef ALTIVEC
482 + if (flags & VECTOR) {
483 + SETVEC(vval);
484 + break;
485 + }
486 +#endif /* ALTIVEC */
487 if (flags & INTMAX_SIZE)
488 ujval = UJARG();
489 else
490 @@ -1067,6 +1209,12 @@
491 case 'x':
492 xdigs = xdigs_lower;
493 hex:
494 +#ifdef ALTIVEC
495 + if (flags & VECTOR) {
496 + SETVEC(vval);
497 + break;
498 + }
499 +#endif /* ALTIVEC */
500 if (flags & INTMAX_SIZE)
501 ujval = UJARG();
502 else
503 @@ -1111,6 +1259,14 @@
504 if (size > BUF) /* should never happen */
505 abort();
506 break;
507 +#ifdef ALTIVEC
508 + case 'v':
509 + if (hasAltivec) {
510 + flags |= VECTOR;
511 + goto rflag;
512 + }
513 + /* drop through */
514 +#endif /* ALTIVEC */
515 default: /* "%?" prints ?, unless ? is NUL */
516 if (ch == '\0')
517 goto done;
518 @@ -1122,6 +1278,183 @@
519 break;
520 }
521
522 +#ifdef ALTIVEC
523 + if (flags & VECTOR) {
524 + /*
525 + * Do the minimum amount of work necessary to construct
526 + * a format specifier that can be used to recursively
527 + * call vfprintf() for each element in the vector.
528 + */
529 + int i, j; /* Counter. */
530 + int vcnt; /* Number of elements in vector. */
531 + char *vfmt; /* Pointer to format specifier. */
532 + char vfmt_buf[32]; /* Static buffer for format spec. */
533 + int vwidth = 0; /* Width specified via '*'. */
534 + int vprec = 0; /* Precision specified via '*'. */
535 + union { /* Element. */
536 + int i;
537 + float f;
538 + } velm;
539 + char *vstr; /* Used for asprintf(). */
540 + int vlen; /* Length returned by asprintf(). */
541 +
542 + /*
543 + * Set vfmt. If vfmt_buf may not be big enough,
544 + * malloc() space, taking care to free it later.
545 + */
546 + if (&fmt[-1] - pct < sizeof(vfmt_buf))
547 + vfmt = vfmt_buf;
548 + else
549 + vfmt = (char *)malloc(&fmt[-1] - pct + 1);
550 +
551 + /* Set the separator character, if not specified. */
552 + if (vsep == 'X') {
553 + if (ch == 'c')
554 + vsep = '\0';
555 + else
556 + vsep = ' ';
557 + }
558 +
559 + /* Create the format specifier. */
560 + for (i = j = 0; i < &fmt[-1] - pct; i++) {
561 + switch (pct[i]) {
562 + case ',': case ';': case ':': case '_':
563 + case 'v': case 'h': case 'l':
564 + /* Ignore. */
565 + break;
566 + case '*':
567 + if (pct[i - 1] != '.')
568 + vwidth = 1;
569 + else
570 + vprec = 1;
571 + /* FALLTHROUGH */
572 + default:
573 + vfmt[j++] = pct[i];
574 + }
575 + }
576 +
577 + /*
578 + * Determine the number of elements in the vector and
579 + * finish up the format specifier.
580 + */
581 + if (flags & SHORTINT) {
582 + if (ch != 'c')
583 + vfmt[j++] = 'h';
584 + vcnt = 8;
585 + } else if (flags & LONGINT) {
586 + if (ch != 'c')
587 + vfmt[j++] = 'l';
588 + vcnt = 4;
589 + } else {
590 + switch (ch) {
591 + case 'a':
592 + case 'A':
593 + case 'e':
594 + case 'E':
595 + case 'f':
596 + case 'g':
597 + case 'G':
598 + vcnt = 4;
599 + break;
600 + default:
601 + /*
602 + * The default case should never
603 + * happen.
604 + */
605 + case 'c':
606 + case 'd':
607 + case 'i':
608 + case 'u':
609 + case 'o':
610 + case 'p':
611 + case 'x':
612 + case 'X':
613 + vcnt = 16;
614 + }
615 + }
616 + vfmt[j++] = ch;
617 + vfmt[j++] = '\0';
618 +
619 +/* Get a vector element. */
620 +#define VPRINT(cnt, ind, args...) do { \
621 + if (flags & FPT) { \
622 + velm.f = vval.vfloatarg[ind]; \
623 + vlen = asprintf_l(&vstr, loc, vfmt , ## args, velm.f); \
624 + } else { \
625 + switch (cnt) { \
626 + default: \
627 + /* The default case should never happen. */ \
628 + case 4: \
629 + velm.i = (unsigned)vval.vintarg[ind]; \
630 + break; \
631 + case 8: \
632 + velm.i = (unsigned short)vval.vshortarg[ind]; \
633 + break; \
634 + case 16: \
635 + velm.i = (unsigned char)vval.vchararg[ind]; \
636 + break; \
637 + } \
638 + vlen = asprintf_l(&vstr, loc, vfmt , ## args, velm.i); \
639 + } \
640 + ret += vlen; \
641 + PRINT(vstr, vlen); \
642 + free(vstr); \
643 +} while (0)
644 +
645 + /* Actually print. */
646 + if (vwidth == 0) {
647 + if (vprec == 0) {
648 + /* First element. */
649 + VPRINT(vcnt, 0);
650 + for (i = 1; i < vcnt; i++) {
651 + /* Separator. */
652 + PRINT(&vsep, 1);
653 +
654 + /* Element. */
655 + VPRINT(vcnt, i);
656 + }
657 + } else {
658 + /* First element. */
659 + VPRINT(vcnt, 0, prec);
660 + for (i = 1; i < vcnt; i++) {
661 + /* Separator. */
662 + PRINT(&vsep, 1);
663 +
664 + /* Element. */
665 + VPRINT(vcnt, i, prec);
666 + }
667 + }
668 + } else {
669 + if (vprec == 0) {
670 + /* First element. */
671 + VPRINT(vcnt, 0, width);
672 + for (i = 1; i < vcnt; i++) {
673 + /* Separator. */
674 + PRINT(&vsep, 1);
675 +
676 + /* Element. */
677 + VPRINT(vcnt, i, width);
678 + }
679 + } else {
680 + /* First element. */
681 + VPRINT(vcnt, 0, width, prec);
682 + for (i = 1; i < vcnt; i++) {
683 + /* Separator. */
684 + PRINT(&vsep, 1);
685 +
686 + /* Element. */
687 + VPRINT(vcnt, i, width, prec);
688 + }
689 + }
690 + }
691 +#undef VPRINT
692 +
693 + if (vfmt != vfmt_buf)
694 + free(vfmt);
695 +
696 + continue;
697 + }
698 +#endif /* ALTIVEC */
699 /*
700 * All reasonable formats wind up here. At this point, `cp'
701 * points to a string which (if not flags&LADJUST) should be
702 @@ -1401,6 +1734,11 @@
703 if (flags & LONGINT)
704 ADDTYPE(T_WINT);
705 else
706 +#ifdef ALTIVEC
707 + if (flags & VECTOR)
708 + ADDTYPE(T_VECTOR);
709 + else
710 +#endif /* ALTIVEC */
711 ADDTYPE(T_INT);
712 break;
713 case 'D':
714 @@ -1418,6 +1756,11 @@
715 case 'f':
716 case 'g':
717 case 'G':
718 +#ifdef ALTIVEC
719 + if (flags & VECTOR)
720 + ADDTYPE(T_VECTOR);
721 + else
722 +#endif /* ALTIVEC */
723 if (flags & LONGDBL)
724 ADDTYPE(T_LONG_DOUBLE);
725 else
726 @@ -1446,9 +1789,19 @@
727 flags |= LONGINT;
728 /*FALLTHROUGH*/
729 case 'o':
730 +#ifdef ALTIVEC
731 + if (flags & VECTOR)
732 + ADDTYPE(T_VECTOR);
733 + else
734 +#endif /* ALTIVEC */
735 ADDUARG();
736 break;
737 case 'p':
738 +#ifdef ALTIVEC
739 + if (flags & VECTOR)
740 + ADDTYPE(T_VECTOR);
741 + else
742 +#endif /* ALTIVEC */
743 ADDTYPE(TP_VOID);
744 break;
745 case 'S':
746 @@ -1466,6 +1819,11 @@
747 case 'u':
748 case 'X':
749 case 'x':
750 +#ifdef ALTIVEC
751 + if (flags & VECTOR)
752 + ADDTYPE(T_VECTOR);
753 + else
754 +#endif /* ALTIVEC */
755 ADDUARG();
756 break;
757 default: /* "%?" prints ?, unless ? is NUL */
758 @@ -1532,7 +1890,7 @@
759 (*argtable) [n].sizearg = va_arg (ap, size_t);
760 break;
761 case TP_SIZET:
762 - (*argtable) [n].psizearg = va_arg (ap, ssize_t *);
763 + (*argtable) [n].psizearg = va_arg (ap, size_t *);
764 break;
765 case T_INTMAXT:
766 (*argtable) [n].intmaxarg = va_arg (ap, intmax_t);
767 @@ -1551,6 +1909,12 @@
768 (*argtable) [n].longdoublearg = va_arg (ap, long double);
769 break;
770 #endif
771 +#ifdef ALTIVEC
772 + case T_VECTOR:
773 + if (hasAltivec)
774 + ap = getvec( &((*argtable) [n]), NULL, 0, ap );
775 + break;
776 +#endif /* ALTIVEC */
777 case TP_CHAR:
778 (*argtable) [n].pchararg = va_arg (ap, char *);
779 break;