]> git.saurik.com Git - apple/libc.git/blame - stdio/FreeBSD/vfprintf.c.patch
Libc-320.1.3.tar.gz
[apple/libc.git] / stdio / FreeBSD / vfprintf.c.patch
CommitLineData
9385eb3d 1--- vfprintf.c.orig Thu Jul 24 12:42:14 2003
51631861
A
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 @@
9385eb3d
A
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;
51631861 32@@ -88,7 +100,7 @@
9385eb3d
A
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;
51631861 41@@ -96,6 +108,16 @@
9385eb3d
A
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 /*
51631861 58@@ -106,7 +128,11 @@
9385eb3d
A
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 *);
51631861 70@@ -119,6 +145,37 @@
9385eb3d
A
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.
51631861 108@@ -424,6 +481,15 @@
9385eb3d
A
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
51631861 124@@ -452,6 +518,9 @@
9385eb3d
A
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
51631861 134@@ -503,6 +572,11 @@
9385eb3d
A
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 */
51631861 146@@ -535,6 +609,12 @@
9385eb3d
A
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'.
51631861 159@@ -575,15 +655,6 @@
9385eb3d
A
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 */
51631861 175@@ -634,7 +705,6 @@
9385eb3d
A
176 val = GETARG (int); \
177 }
178
179-
180 thousands_sep = '\0';
181 grouping = NULL;
182 convbuf = NULL;
51631861
A
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 @@
9385eb3d
A
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;
51631861 205@@ -684,6 +759,9 @@
9385eb3d
A
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) {
51631861 215@@ -699,6 +777,11 @@
9385eb3d
A
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
51631861 227@@ -807,6 +890,12 @@
9385eb3d
A
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 }
51631861 240@@ -817,6 +906,12 @@
9385eb3d
A
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) {
51631861 253@@ -836,6 +931,13 @@
9385eb3d
A
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;
51631861 267@@ -845,25 +947,51 @@
9385eb3d
A
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;
51631861 329@@ -872,10 +1000,24 @@
9385eb3d
A
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;
51631861 354@@ -884,6 +1026,17 @@
9385eb3d
A
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 =
51631861 372@@ -897,6 +1050,10 @@
9385eb3d
A
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 */
51631861 383@@ -990,6 +1147,12 @@
9385eb3d
A
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
51631861 396@@ -1004,6 +1167,12 @@
9385eb3d
A
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;
51631861 409@@ -1053,6 +1222,12 @@
9385eb3d
A
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
51631861 422@@ -1065,6 +1240,12 @@
9385eb3d
A
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
51631861 435@@ -1109,6 +1290,14 @@
9385eb3d
A
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;
51631861 450@@ -1120,6 +1309,186 @@
9385eb3d
A
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
51631861 637@@ -1137,7 +1506,7 @@
9385eb3d
A
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;
51631861 646@@ -1151,9 +1520,9 @@
9385eb3d
A
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 }
51631861 658@@ -1400,6 +1769,11 @@
9385eb3d
A
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':
51631861 670@@ -1407,6 +1781,11 @@
9385eb3d
A
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
51631861 682@@ -1419,6 +1798,11 @@
9385eb3d
A
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
51631861 694@@ -1447,9 +1831,19 @@
9385eb3d
A
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':
51631861 714@@ -1467,6 +1861,11 @@
9385eb3d
A
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 */
51631861 726@@ -1552,6 +1951,12 @@
9385eb3d
A
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;