1 --- vfprintf.c.orig Sun May 30 01:12:48 2004
2 +++ vfprintf.c Sun May 30 01:18:16 2004
10 #include "un-namespace.h"
16 +#include <machine/cpu_capabilities.h>
18 +#define VECTORTYPE vector unsigned char
29 + VECTORTYPE vectorarg;
30 + unsigned char vuchararg[16];
31 + signed char vchararg[16];
32 + unsigned short vushortarg[8];
33 + signed short vshortarg[8];
34 + unsigned int vuintarg[4];
35 + signed int vintarg[4];
42 T_LONG, T_U_LONG, TP_LONG, T_LLONG, T_U_LLONG, TP_LLONG,
43 T_PTRDIFFT, TP_PTRDIFFT, T_SIZET, TP_SIZET,
44 T_INTMAXT, T_UINTMAXT, TP_INTMAXT, TP_VOID, TP_CHAR, TP_SCHAR,
46 + T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR, T_VECTOR
47 +#else /* ! ALTIVEC */
48 T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR
52 static int __sprint(FILE *, struct __suio *);
54 static void __find_arguments(const char *, va_list, union arg **);
55 static void __grow_type_table(int, enum typeid **, int *);
58 + * Get the argument indexed by nextarg. If the argument table is
59 + * built, use it to get the argument. If its not, get the next
60 + * argument (and arguments must be gotten sequentially).
62 +#define GETARG(type) \
63 + ((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : \
64 + (nextarg++, va_arg(ap, type)))
67 +#define hasAltivec (_cpu_capabilities & kHasAltivec)
68 +/*-----------------------------------------------------------------------
69 + * getvec() must be a real subroutine. If it is a #define, then __vfprintf()
70 + * would have its calling sequence changed by Altivec so that a non-Altivec
71 + * processor would crash on illegal instruction. By isolating the calling
72 + * sequence in getvec(), __vprintf() is callable by a non-Altivec processor.
73 + *-----------------------------------------------------------------------*/
75 +getvec(union arg *dst, const union arg *argtable, int nextarg, va_list ap)
77 + dst->vectorarg = GETARG(VECTORTYPE);
81 +#define SETVEC(dst) \
83 + ap = getvec(&dst, argtable, nextarg, ap); \
89 * Flush out all the vectors defined by the given uio,
90 * then reset it so that it can be reused.
92 #define PTRDIFFT 0x800 /* ptrdiff_t */
93 #define INTMAXT 0x1000 /* intmax_t */
94 #define CHARINT 0x2000 /* print char using int format */
96 +#define VECTOR 0x4000 /* Altivec vector */
100 * Non-MT-safe version
102 int nseps; /* number of group separators with ' */
103 int nrepeats; /* number of repeats of the last group */
106 + union arg vval; /* Vector argument. */
107 + char *pct; /* Pointer to '%' at beginning of specifier. */
108 + char vsep; /* Vector separator character. */
110 u_long ulval; /* integer arguments %[diouxX] */
111 uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */
112 int base; /* base for [diouxX] conversion */
117 - * Get the argument indexed by nextarg. If the argument table is
118 - * built, use it to get the argument. If its not, get the next
119 - * argument (and arguments must be gotten sequentially).
121 -#define GETARG(type) \
122 - ((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : \
123 - (nextarg++, va_arg(ap, type)))
126 * To extend shorts properly, we need both signed and unsigned
127 * argument extraction methods.
130 val = GETARG (int); \
134 thousands_sep = '\0';
138 decimal_point = localeconv()->decimal_point;
140 /* sorry, fprintf(read_only_file, "") returns EOF, not 0 */
142 + if (cantwrite(fp)) {
147 /* optimise fprintf(stderr) (and other unbuffered Unix files) */
148 if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
155 +#endif /* ALTIVEC */
156 fmt++; /* skip over '%' */
164 + vsep = 'X'; /* Illegal value, changed to defaults later. */
165 +#endif /* ALTIVEC */
168 reswitch: switch (ch) {
174 + case ',': case ';': case ':': case '_':
177 +#endif /* ALTIVEC */
180 * ``A negative field width argument is taken as a
186 + if (flags & VECTOR) {
190 +#endif /* ALTIVEC */
191 if (flags & LONGINT) {
192 static const mbstate_t initial;
199 + if (flags & VECTOR) {
203 +#endif /* ALTIVEC */
204 if (flags & INTMAX_SIZE) {
206 if ((intmax_t)ujval < 0) {
208 #ifndef NO_FLOATING_POINT
212 + if (flags & VECTOR) {
217 +#endif /* ALTIVEC */
226 + if (flags & VECTOR) {
231 +#endif /* ALTIVEC */
233 if (prec < 0) /* account for digit before decpt */
235 @@ -874,10 +963,24 @@
240 + if (flags & VECTOR) {
245 +#endif /* ALTIVEC */
251 + if (flags & VECTOR) {
256 +#endif /* ALTIVEC */
257 expchar = ch - ('g' - 'e');
260 @@ -993,6 +1096,12 @@
265 + if (flags & VECTOR) {
269 +#endif /* ALTIVEC */
270 if (flags & INTMAX_SIZE)
273 @@ -1007,6 +1116,12 @@
278 + if (flags & VECTOR) {
282 +#endif /* ALTIVEC */
283 ujval = (uintmax_t)(uintptr_t)GETARG(void *);
286 @@ -1056,6 +1171,12 @@
291 + if (flags & VECTOR) {
295 +#endif /* ALTIVEC */
296 if (flags & INTMAX_SIZE)
299 @@ -1068,6 +1189,12 @@
304 + if (flags & VECTOR) {
308 +#endif /* ALTIVEC */
309 if (flags & INTMAX_SIZE)
312 @@ -1112,6 +1239,14 @@
313 if (size > BUF) /* should never happen */
323 +#endif /* ALTIVEC */
324 default: /* "%?" prints ?, unless ? is NUL */
327 @@ -1123,6 +1258,184 @@
332 + if (flags & VECTOR) {
334 + * Do the minimum amount of work necessary to construct
335 + * a format specifier that can be used to recursively
336 + * call vfprintf() for each element in the vector.
338 + int i, j; /* Counter. */
339 + int vcnt; /* Number of elements in vector. */
340 + char *vfmt; /* Pointer to format specifier. */
341 + char vfmt_buf[32]; /* Static buffer for format spec. */
342 + int vwidth = 0; /* Width specified via '*'. */
343 + int vprec = 0; /* Precision specified via '*'. */
344 + union { /* Element. */
348 + char *vstr; /* Used for asprintf(). */
349 + int vlen; /* Length returned by asprintf(). */
352 + * Set vfmt. If vfmt_buf may not be big enough,
353 + * malloc() space, taking care to free it later.
355 + if (&fmt[-1] - pct < sizeof(vfmt_buf))
358 + vfmt = (char *)malloc(&fmt[-1] - pct + 1);
360 + /* Set the separator character, if not specified. */
368 + /* Create the format specifier. */
369 + for (i = j = 0; i < &fmt[-1] - pct; i++) {
371 + case ',': case ';': case ':': case '_':
372 + case 'v': case 'h': case 'l':
376 + if (pct[i - 1] != '.')
382 + vfmt[j++] = pct[i];
387 + * Determine the number of elements in the vector and
388 + * finish up the format specifier.
390 + if (flags & SHORTINT) {
394 + } else if (flags & LONGINT) {
411 + * The default case should never
428 +/* Get a vector element. */
429 +#define VPRINT(cnt, ind, args...) do { \
430 + if (flags & FPT) { \
431 + velm.f = vval.vfloatarg[ind]; \
432 + vlen = asprintf(&vstr, vfmt , ## args, velm.f); \
436 + /* The default case should never happen. */ \
438 + velm.i = (unsigned)vval.vintarg[ind]; \
441 + velm.i = (unsigned short)vval.vshortarg[ind]; \
444 + velm.i = (unsigned char)vval.vchararg[ind]; \
447 + vlen = asprintf(&vstr, vfmt , ## args, velm.i); \
450 + PRINT(vstr, vlen); \
455 + /* Actually print. */
458 + /* First element. */
460 + for (i = 1; i < vcnt; i++) {
468 + /* First element. */
469 + VPRINT(vcnt, 0, prec);
470 + for (i = 1; i < vcnt; i++) {
475 + VPRINT(vcnt, i, prec);
480 + /* First element. */
481 + VPRINT(vcnt, 0, width);
482 + for (i = 1; i < vcnt; i++) {
487 + VPRINT(vcnt, i, width);
490 + /* First element. */
491 + VPRINT(vcnt, 0, width, prec);
492 + for (i = 1; i < vcnt; i++) {
497 + VPRINT(vcnt, i, width, prec);
503 + if (vfmt != vfmt_buf)
508 +#endif /* ALTIVEC */
510 * All reasonable formats wind up here. At this point, `cp'
511 * points to a string which (if not flags&LADJUST) should be
512 @@ -1405,6 +1718,11 @@
517 + if (flags & VECTOR)
520 +#endif /* ALTIVEC */
524 @@ -1412,6 +1730,11 @@
529 + if (flags & VECTOR)
535 #ifndef NO_FLOATING_POINT
536 @@ -1422,6 +1745,11 @@
541 + if (flags & VECTOR)
544 +#endif /* ALTIVEC */
546 ADDTYPE(T_LONG_DOUBLE);
548 @@ -1450,9 +1778,19 @@
553 + if (flags & VECTOR)
556 +#endif /* ALTIVEC */
561 + if (flags & VECTOR)
564 +#endif /* ALTIVEC */
568 @@ -1470,6 +1808,11 @@
573 + if (flags & VECTOR)
576 +#endif /* ALTIVEC */
579 default: /* "%?" prints ?, unless ? is NUL */
580 @@ -1555,6 +1898,12 @@
581 (*argtable) [n].longdoublearg = va_arg (ap, long double);
587 + ap = getvec( &((*argtable) [n]), NULL, 0, ap );
589 +#endif /* ALTIVEC */
591 (*argtable) [n].pchararg = va_arg (ap, char *);