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