]> git.saurik.com Git - apple/libc.git/blob - stdio/FreeBSD/vfprintf.c.patch
e0e299e8b34d2f3b3a858d064219b6575613f5a3
[apple/libc.git] / stdio / FreeBSD / vfprintf.c.patch
1 --- vfprintf.c.orig Thu Jul 24 12:42:14 2003
2 +++ vfprintf.c Tue Apr 6 17:44:49 2004
3 @@ -58,6 +58,7 @@
4 #include <stdlib.h>
5 #include <string.h>
6 #include <wchar.h>
7 +#include <errno.h>
8
9 #include <stdarg.h>
10 #include "un-namespace.h"
11 @@ -66,9 +67,20 @@
12 #include "local.h"
13 #include "fvwrite.h"
14
15 +#ifdef ALTIVEC
16 +#include <machine/cpu_capabilities.h>
17 +
18 +#define VECTORTYPE vector unsigned char
19 +#endif /* ALTIVEC */
20 +
21 /* Define FLOATING_POINT to get floating point. */
22 #define FLOATING_POINT
23
24 +/* if no floating point, turn off HEXFLOAT as well */
25 +#if defined(HEXFLOAT) && !defined(FLOATING_POINT)
26 +#undef HEXFLOAT
27 +#endif /* defined(HEXFLOAT) && !defined(FLOATING_POINT) */
28 +
29 union arg {
30 int intarg;
31 u_int uintarg;
32 @@ -88,7 +100,7 @@
33 long *plongarg;
34 long long *plonglongarg;
35 ptrdiff_t *pptrdiffarg;
36 - size_t *psizearg;
37 + ssize_t *psizearg;
38 intmax_t *pintmaxarg;
39 #ifdef FLOATING_POINT
40 double doublearg;
41 @@ -96,6 +108,16 @@
42 #endif
43 wint_t wintarg;
44 wchar_t *pwchararg;
45 +#ifdef ALTIVEC
46 + VECTORTYPE vectorarg;
47 + unsigned char vuchararg[16];
48 + signed char vchararg[16];
49 + unsigned short vushortarg[8];
50 + signed short vshortarg[8];
51 + unsigned int vuintarg[4];
52 + signed int vintarg[4];
53 + float vfloatarg[4];
54 +#endif /* ALTIVEC */
55 };
56
57 /*
58 @@ -106,7 +128,11 @@
59 T_LONG, T_U_LONG, TP_LONG, T_LLONG, T_U_LLONG, TP_LLONG,
60 T_PTRDIFFT, TP_PTRDIFFT, T_SIZET, TP_SIZET,
61 T_INTMAXT, T_UINTMAXT, TP_INTMAXT, TP_VOID, TP_CHAR, TP_SCHAR,
62 +#ifdef ALTIVEC
63 + T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR, T_VECTOR
64 +#else /* ! ALTIVEC */
65 T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR
66 +#endif /* ALTIVEC */
67 };
68
69 static int __sprint(FILE *, struct __suio *);
70 @@ -119,6 +145,37 @@
71 static void __find_arguments(const char *, va_list, union arg **);
72 static void __grow_type_table(int, enum typeid **, int *);
73
74 + /*
75 + * Get the argument indexed by nextarg. If the argument table is
76 + * built, use it to get the argument. If its not, get the next
77 + * argument (and arguments must be gotten sequentially).
78 + */
79 +#define GETARG(type) \
80 + ((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : \
81 + (nextarg++, va_arg(ap, type)))
82 +
83 +#ifdef ALTIVEC
84 +#define hasAltivec (_cpu_capabilities & kHasAltivec)
85 +/*-----------------------------------------------------------------------
86 + * getvec() must be a real subroutine. If it is a #define, then __vfprintf()
87 + * would have its calling sequence changed by Altivec so that a non-Altivec
88 + * processor would crash on illegal instruction. By isolating the calling
89 + * sequence in getvec(), __vprintf() is callable by a non-Altivec processor.
90 + *-----------------------------------------------------------------------*/
91 +static va_list
92 +getvec(union arg *dst, const union arg *argtable, int nextarg, va_list ap)
93 +{
94 + dst->vectorarg = GETARG(VECTORTYPE);
95 + return ap;
96 +}
97 +
98 +#define SETVEC(dst) \
99 +{ \
100 + ap = getvec(&dst, argtable, nextarg, ap); \
101 + nextarg++; \
102 +}
103 +#endif /* ALTIVEC */
104 +
105 /*
106 * Flush out all the vectors defined by the given uio,
107 * then reset it so that it can be reused.
108 @@ -424,6 +481,15 @@
109
110 #endif /* FLOATING_POINT */
111
112 +#ifdef HEXFLOAT
113 +extern int __hdtoa(double d, const char *xdigs, int prec, char *cp,
114 + int *expt, int *signflag, char **dtoaend);
115 +#if !__TYPE_LONGDOUBLE_IS_DOUBLE
116 +extern int __hldtoa(long double d, const char *xdigs, int prec, char *cp,
117 + int *expt, int *signflag, char **dtoaend);
118 +#endif /* !__TYPE_LONGDOUBLE_IS_DOUBLE */
119 +#endif /* HEXFLOAT */
120 +
121 /*
122 * The size of the buffer we use as scratch space for integer
123 * conversions, among other things. Technically, we would need the
124 @@ -452,6 +518,9 @@
125 #define PTRDIFFT 0x800 /* ptrdiff_t */
126 #define INTMAXT 0x1000 /* intmax_t */
127 #define CHARINT 0x2000 /* print char using int format */
128 +#ifdef ALTIVEC
129 +#define VECTOR 0x4000 /* Altivec vector */
130 +#endif /* ALTIVEC */
131
132 /*
133 * Non-MT-safe version
134 @@ -503,6 +572,11 @@
135 int nseps; /* number of group separators with ' */
136 int nrepeats; /* number of repeats of the last group */
137 #endif
138 +#ifdef ALTIVEC
139 + union arg vval; /* Vector argument. */
140 + char *pct; /* Pointer to '%' at beginning of specifier. */
141 + char vsep; /* Vector separator character. */
142 +#endif
143 u_long ulval; /* integer arguments %[diouxX] */
144 uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */
145 int base; /* base for [diouxX] conversion */
146 @@ -535,6 +609,12 @@
147
148 static const char xdigs_lower[16] = "0123456789abcdef";
149 static const char xdigs_upper[16] = "0123456789ABCDEF";
150 +#ifdef HEXFLOAT
151 +#define HEXFLOATDELTA 32
152 +#define HEXFLOATSTART 32
153 + static char *hexfloat = NULL;
154 + static int hexfloatlen = 0;
155 +#endif /* HEXFLOAT */
156
157 /*
158 * BEWARE, these `goto error' on error, and PAD uses `n'.
159 @@ -575,15 +655,6 @@
160 }
161
162 /*
163 - * Get the argument indexed by nextarg. If the argument table is
164 - * built, use it to get the argument. If its not, get the next
165 - * argument (and arguments must be gotten sequentially).
166 - */
167 -#define GETARG(type) \
168 - ((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : \
169 - (nextarg++, va_arg(ap, type)))
170 -
171 - /*
172 * To extend shorts properly, we need both signed and unsigned
173 * argument extraction methods.
174 */
175 @@ -634,7 +705,6 @@
176 val = GETARG (int); \
177 }
178
179 -
180 thousands_sep = '\0';
181 grouping = NULL;
182 convbuf = NULL;
183 @@ -643,8 +713,10 @@
184 decimal_point = localeconv()->decimal_point;
185 #endif
186 /* sorry, fprintf(read_only_file, "") returns EOF, not 0 */
187 - if (cantwrite(fp))
188 + if (cantwrite(fp)) {
189 + errno = EBADF;
190 return (EOF);
191 + }
192
193 /* optimise fprintf(stderr) (and other unbuffered Unix files) */
194 if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
195 @@ -676,6 +748,9 @@
196 }
197 if (ch == '\0')
198 goto done;
199 +#ifdef ALTIVEC
200 + pct = fmt;
201 +#endif /* ALTIVEC */
202 fmt++; /* skip over '%' */
203
204 flags = 0;
205 @@ -684,6 +759,9 @@
206 prec = -1;
207 sign = '\0';
208 ox[1] = '\0';
209 +#ifdef ALTIVEC
210 + vsep = 'X'; /* Illegal value, changed to defaults later. */
211 +#endif /* ALTIVEC */
212
213 rflag: ch = *fmt++;
214 reswitch: switch (ch) {
215 @@ -699,6 +777,11 @@
216 case '#':
217 flags |= ALT;
218 goto rflag;
219 +#ifdef ALTIVEC
220 + case ',': case ';': case ':': case '_':
221 + vsep = ch;
222 + goto rflag;
223 +#endif /* ALTIVEC */
224 case '*':
225 /*-
226 * ``A negative field width argument is taken as a
227 @@ -807,6 +890,12 @@
228 }
229 size = (int)mbseqlen;
230 } else {
231 +#ifdef ALTIVEC
232 + if (flags & VECTOR) {
233 + SETVEC(vval);
234 + break;
235 + }
236 +#endif /* ALTIVEC */
237 *(cp = buf) = GETARG(int);
238 size = 1;
239 }
240 @@ -817,6 +906,12 @@
241 /*FALLTHROUGH*/
242 case 'd':
243 case 'i':
244 +#ifdef ALTIVEC
245 + if (flags & VECTOR) {
246 + SETVEC(vval);
247 + break;
248 + } else
249 +#endif /* ALTIVEC */
250 if (flags & INTMAX_SIZE) {
251 ujval = SJARG();
252 if ((intmax_t)ujval < 0) {
253 @@ -836,6 +931,13 @@
254 #ifdef HEXFLOAT
255 case 'a':
256 case 'A':
257 +#ifdef ALTIVEC
258 + if (flags & VECTOR) {
259 + flags |= FPT;
260 + SETVEC(vval);
261 + break;
262 + }
263 +#endif /* ALTIVEC */
264 if (ch == 'a') {
265 ox[1] = 'x';
266 xdigs = xdigs_lower;
267 @@ -845,25 +947,51 @@
268 xdigs = xdigs_upper;
269 expchar = 'P';
270 }
271 - /*
272 - * XXX We don't actually have a conversion
273 - * XXX routine for this yet.
274 - */
275 + if (!hexfloat) {
276 + hexfloat = malloc(hexfloatlen = HEXFLOATSTART);
277 + if (!hexfloat)
278 + goto error;
279 + }
280 + if (prec > hexfloatlen - 1) {
281 + int hlen = prec + HEXFLOATDELTA;
282 + char *hf = realloc(hexfloat, hlen);
283 + if (hf == NULL)
284 + goto error;
285 + hexfloat = hf;
286 + hexfloatlen = hlen;
287 + }
288 + cp = hexfloat;
289 if (flags & LONGDBL) {
290 - fparg.ldbl = (double)GETARG(long double);
291 - dtoaresult = cp =
292 - __hldtoa(fparg.ldbl, xdigs, prec,
293 +#if __TYPE_LONGDOUBLE_IS_DOUBLE
294 + fparg.dbl = (double)GETARG(long double);
295 + prec = __hdtoa(fparg.dbl, xdigs, prec, cp,
296 &expt, &signflag, &dtoaend);
297 +#else /* ! __TYPE_LONGDOUBLE_IS_DOUBLE */
298 + fparg.ldbl = GETARG(long double);
299 + prec = __hldtoa(fparg.ldbl, xdigs, prec, cp,
300 + &expt, &signflag, &dtoaend);
301 +#endif /* __TYPE_LONGDOUBLE_IS_DOUBLE */
302 } else {
303 fparg.dbl = GETARG(double);
304 - dtoaresult = cp =
305 - __hdtoa(fparg.dbl, xdigs, prec,
306 + prec = __hdtoa(fparg.dbl, xdigs, prec, cp,
307 &expt, &signflag, &dtoaend);
308 }
309 - goto fp_begin;
310 + prec++;
311 + if (expt == INT_MAX)
312 + ox[1] = 0;
313 + else
314 + expt++;
315 + goto hex_begin;
316 #endif
317 case 'e':
318 case 'E':
319 +#ifdef ALTIVEC
320 + if (flags & VECTOR) {
321 + flags |= FPT;
322 + SETVEC(vval);
323 + break;
324 + }
325 +#endif /* ALTIVEC */
326 expchar = ch;
327 if (prec < 0) /* account for digit before decpt */
328 prec = DEFPREC + 1;
329 @@ -872,10 +1000,24 @@
330 goto fp_begin;
331 case 'f':
332 case 'F':
333 +#ifdef ALTIVEC
334 + if (flags & VECTOR) {
335 + flags |= FPT;
336 + SETVEC(vval);
337 + break;
338 + }
339 +#endif /* ALTIVEC */
340 expchar = '\0';
341 goto fp_begin;
342 case 'g':
343 case 'G':
344 +#ifdef ALTIVEC
345 + if (flags & VECTOR) {
346 + flags |= FPT;
347 + SETVEC(vval);
348 + break;
349 + }
350 +#endif /* ALTIVEC */
351 expchar = ch - ('g' - 'e');
352 if (prec == 0)
353 prec = 1;
354 @@ -884,6 +1026,17 @@
355 prec = DEFPREC;
356 if (dtoaresult != NULL)
357 freedtoa(dtoaresult);
358 +#if __TYPE_LONGDOUBLE_IS_DOUBLE
359 + if (flags & LONGDBL)
360 + fparg.dbl = (double)GETARG(long double);
361 + else
362 + fparg.dbl = GETARG(double);
363 + dtoaresult = cp =
364 + dtoa(fparg.dbl, expchar ? 2 : 3, prec,
365 + &expt, &signflag, &dtoaend);
366 + if (expt == 9999)
367 + expt = INT_MAX;
368 +#else /* ! __TYPE_LONGDOUBLE_IS_DOUBLE */
369 if (flags & LONGDBL) {
370 fparg.ldbl = GETARG(long double);
371 dtoaresult = cp =
372 @@ -897,6 +1050,10 @@
373 if (expt == 9999)
374 expt = INT_MAX;
375 }
376 +#endif /* __TYPE_LONGDOUBLE_IS_DOUBLE */
377 +#ifdef HEXFLOAT
378 +hex_begin:
379 +#endif /* HEXFLOAT */
380 if (signflag)
381 sign = '-';
382 if (expt == INT_MAX) { /* inf or nan */
383 @@ -990,6 +1147,12 @@
384 flags |= LONGINT;
385 /*FALLTHROUGH*/
386 case 'o':
387 +#ifdef ALTIVEC
388 + if (flags & VECTOR) {
389 + SETVEC(vval);
390 + break;
391 + } else
392 +#endif /* ALTIVEC */
393 if (flags & INTMAX_SIZE)
394 ujval = UJARG();
395 else
396 @@ -1004,6 +1167,12 @@
397 * defined manner.''
398 * -- ANSI X3J11
399 */
400 +#ifdef ALTIVEC
401 + if (flags & VECTOR) {
402 + SETVEC(vval);
403 + break;
404 + }
405 +#endif /* ALTIVEC */
406 ujval = (uintmax_t)(uintptr_t)GETARG(void *);
407 base = 16;
408 xdigs = xdigs_lower;
409 @@ -1053,6 +1222,12 @@
410 flags |= LONGINT;
411 /*FALLTHROUGH*/
412 case 'u':
413 +#ifdef ALTIVEC
414 + if (flags & VECTOR) {
415 + SETVEC(vval);
416 + break;
417 + } else
418 +#endif /* ALTIVEC */
419 if (flags & INTMAX_SIZE)
420 ujval = UJARG();
421 else
422 @@ -1065,6 +1240,12 @@
423 case 'x':
424 xdigs = xdigs_lower;
425 hex:
426 +#ifdef ALTIVEC
427 + if (flags & VECTOR) {
428 + SETVEC(vval);
429 + break;
430 + } else
431 +#endif /* ALTIVEC */
432 if (flags & INTMAX_SIZE)
433 ujval = UJARG();
434 else
435 @@ -1109,6 +1290,14 @@
436 if (size > BUF) /* should never happen */
437 abort();
438 break;
439 +#ifdef ALTIVEC
440 + case 'v':
441 + if (hasAltivec) {
442 + flags |= VECTOR;
443 + goto rflag;
444 + }
445 + /* drap through */
446 +#endif /* ALTIVEC */
447 default: /* "%?" prints ?, unless ? is NUL */
448 if (ch == '\0')
449 goto done;
450 @@ -1120,6 +1309,186 @@
451 break;
452 }
453
454 +#ifdef ALTIVEC
455 + if (flags & VECTOR) {
456 + /*
457 + * Do the minimum amount of work necessary to construct
458 + * a format specifier that can be used to recursively
459 + * call vfprintf() for each element in the vector.
460 + */
461 + int i, j; /* Counter. */
462 + int vcnt; /* Number of elements in vector. */
463 + char *vfmt; /* Pointer to format specifier. */
464 + char vfmt_buf[32]; /* Static buffer for format spec. */
465 + int vwidth = 0; /* Width specified via '*'. */
466 + int vprec = 0; /* Precision specified via '*'. */
467 + union { /* Element. */
468 + int i;
469 + float f;
470 + } velm;
471 + char *vstr; /* Used for asprintf(). */
472 + int vlen; /* Length returned by asprintf(). */
473 +
474 + /*
475 + * Set vfmt. If vfmt_buf may not be big enough,
476 + * malloc() space, taking care to free it later.
477 + */
478 + if (&fmt[-1] - pct < sizeof(vfmt_buf))
479 + vfmt = vfmt_buf;
480 + else
481 + vfmt = (char *)malloc(&fmt[-1] - pct + 1);
482 +
483 + /* Set the separator character, if not specified. */
484 + if (vsep == 'X') {
485 + if (ch == 'c')
486 + vsep = '\0';
487 + else
488 + vsep = ' ';
489 + }
490 +
491 + /* Create the format specifier. */
492 + for (i = j = 0; i < &fmt[-1] - pct; i++) {
493 + switch (pct[i]) {
494 + case ',': case ';': case ':': case '_':
495 + case 'v': case 'h': case 'l':
496 + /* Ignore. */
497 + break;
498 + case '*':
499 + if (pct[i - 1] != '.')
500 + vwidth = 1;
501 + else
502 + vprec = 1;
503 + /* FALLTHROUGH */
504 + default:
505 + vfmt[j++] = pct[i];
506 + }
507 + }
508 +
509 + /*
510 + * Determine the number of elements in the vector and
511 + * finish up the format specifier.
512 + */
513 + if (flags & SHORTINT) {
514 + vfmt[j++] = 'h';
515 + vcnt = 8;
516 + } else if (flags & LONGINT) {
517 + vfmt[j++] = 'l';
518 + vcnt = 4;
519 + } else {
520 + switch (ch) {
521 + case 'a':
522 + case 'A':
523 + case 'e':
524 + case 'E':
525 + case 'f':
526 + case 'g':
527 + case 'G':
528 + vcnt = 4;
529 + break;
530 + default:
531 + /*
532 + * The default case should never
533 + * happen.
534 + */
535 + case 'c':
536 + case 'd':
537 + case 'i':
538 + case 'u':
539 + case 'o':
540 + case 'p':
541 + case 'x':
542 + case 'X':
543 + vcnt = 16;
544 + }
545 + }
546 + vfmt[j++] = ch;
547 + vfmt[j++] = '\0';
548 +
549 +/* Get a vector element. */
550 +#define VPRINT(cnt, ind, args...) do { \
551 + if (flags & FPT) { \
552 + velm.f = vval.vfloatarg[ind]; \
553 + vlen = asprintf(&vstr, vfmt , ## args, velm.f); \
554 + } else { \
555 + switch (cnt) { \
556 + default: \
557 + /* The default case should never happen. */ \
558 + case 4: \
559 + velm.i = (unsigned)vval.vintarg[ind]; \
560 + break; \
561 + case 8: \
562 + velm.i = (unsigned short)vval.vshortarg[ind]; \
563 + break; \
564 + case 16: \
565 + velm.i = (unsigned char)vval.vchararg[ind]; \
566 + break; \
567 + } \
568 + vlen = asprintf(&vstr, vfmt , ## args, velm.i); \
569 + } \
570 + ret += vlen; \
571 + PRINT(vstr, vlen); \
572 + FLUSH(); \
573 + free(vstr); \
574 +} while (0)
575 +
576 + /* Actually print. */
577 + if (vwidth == 0) {
578 + if (vprec == 0) {
579 + /* First element. */
580 + VPRINT(vcnt, 0);
581 + for (i = 1; i < vcnt; i++) {
582 + /* Separator. */
583 + if (vsep)
584 + PRINT(&vsep, 1);
585 +
586 + /* Element. */
587 + VPRINT(vcnt, i);
588 + }
589 + } else {
590 + /* First element. */
591 + VPRINT(vcnt, 0, prec);
592 + for (i = 1; i < vcnt; i++) {
593 + /* Separator. */
594 + if (vsep)
595 + PRINT(&vsep, 1);
596 +
597 + /* Element. */
598 + VPRINT(vcnt, i, prec);
599 + }
600 + }
601 + } else {
602 + if (vprec == 0) {
603 + /* First element. */
604 + VPRINT(vcnt, 0, width);
605 + for (i = 1; i < vcnt; i++) {
606 + /* Separator. */
607 + if (vsep)
608 + PRINT(&vsep, 1);
609 +
610 + /* Element. */
611 + VPRINT(vcnt, i, width);
612 + }
613 + } else {
614 + /* First element. */
615 + VPRINT(vcnt, 0, width, prec);
616 + for (i = 1; i < vcnt; i++) {
617 + /* Separator. */
618 + if (vsep)
619 + PRINT(&vsep, 1);
620 +
621 + /* Element. */
622 + VPRINT(vcnt, i, width, prec);
623 + }
624 + }
625 + }
626 +#undef VPRINT
627 +
628 + if (vfmt != vfmt_buf)
629 + free(vfmt);
630 +
631 + continue;
632 + }
633 +#endif /* ALTIVEC */
634 /*
635 * All reasonable formats wind up here. At this point, `cp'
636 * points to a string which (if not flags&LADJUST) should be
637 @@ -1137,7 +1506,7 @@
638 realsz = dprec > size ? dprec : size;
639 if (sign)
640 realsz++;
641 - else if (ox[1])
642 + if (ox[1])
643 realsz += 2;
644
645 prsize = width > realsz ? width : realsz;
646 @@ -1151,9 +1520,9 @@
647 PAD(width - realsz, blanks);
648
649 /* prefix */
650 - if (sign) {
651 + if (sign)
652 PRINT(&sign, 1);
653 - } else if (ox[1]) { /* ox[1] is either x, X, or \0 */
654 + if (ox[1]) { /* ox[1] is either x, X, or \0 */
655 ox[0] = '0';
656 PRINT(ox, 2);
657 }
658 @@ -1400,6 +1769,11 @@
659 if (flags & LONGINT)
660 ADDTYPE(T_WINT);
661 else
662 +#ifdef ALTIVEC
663 + if (flags & VECTOR)
664 + ADDTYPE(T_VECTOR);
665 + else
666 +#endif /* ALTIVEC */
667 ADDTYPE(T_INT);
668 break;
669 case 'D':
670 @@ -1407,6 +1781,11 @@
671 /*FALLTHROUGH*/
672 case 'd':
673 case 'i':
674 +#ifdef ALTIVEC
675 + if (flags & VECTOR)
676 + ADDTYPE(T_VECTOR);
677 + else
678 +#endif
679 ADDSARG();
680 break;
681 #ifdef FLOATING_POINT
682 @@ -1419,6 +1798,11 @@
683 case 'f':
684 case 'g':
685 case 'G':
686 +#ifdef ALTIVEC
687 + if (flags & VECTOR)
688 + ADDTYPE(T_VECTOR);
689 + else
690 +#endif /* ALTIVEC */
691 if (flags & LONGDBL)
692 ADDTYPE(T_LONG_DOUBLE);
693 else
694 @@ -1447,9 +1831,19 @@
695 flags |= LONGINT;
696 /*FALLTHROUGH*/
697 case 'o':
698 +#ifdef ALTIVEC
699 + if (flags & VECTOR)
700 + ADDTYPE(T_VECTOR);
701 + else
702 +#endif /* ALTIVEC */
703 ADDUARG();
704 break;
705 case 'p':
706 +#ifdef ALTIVEC
707 + if (flags & VECTOR)
708 + ADDTYPE(T_VECTOR);
709 + else
710 +#endif /* ALTIVEC */
711 ADDTYPE(TP_VOID);
712 break;
713 case 'S':
714 @@ -1467,6 +1861,11 @@
715 case 'u':
716 case 'X':
717 case 'x':
718 +#ifdef ALTIVEC
719 + if (flags & VECTOR)
720 + ADDTYPE(T_VECTOR);
721 + else
722 +#endif /* ALTIVEC */
723 ADDUARG();
724 break;
725 default: /* "%?" prints ?, unless ? is NUL */
726 @@ -1552,6 +1951,12 @@
727 (*argtable) [n].longdoublearg = va_arg (ap, long double);
728 break;
729 #endif
730 +#ifdef ALTIVEC
731 + case T_VECTOR:
732 + if (hasAltivec)
733 + ap = getvec( &((*argtable) [n]), NULL, 0, ap );
734 + break;
735 +#endif /* ALTIVEC */
736 case TP_CHAR:
737 (*argtable) [n].pchararg = va_arg (ap, char *);
738 break;