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