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