]> git.saurik.com Git - apple/libc.git/blob - stdio/FreeBSD/vfprintf.c.patch
ab4a546f5da81d4ad31e9f26c953389b23187ad9
[apple/libc.git] / stdio / FreeBSD / vfprintf.c.patch
1 --- vfprintf.c.orig 2006-10-01 00:03:16.000000000 -0700
2 +++ vfprintf.c 2006-10-01 00:21:05.000000000 -0700
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,14 +365,14 @@
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 char buf[MB_LEN_MAX];
107 wchar_t *p;
108 char *convbuf, *mbp;
109 - size_t clen, nbytes;
110 + size_t clen = 0, nbytes;
111
112 /*
113 * Determine the number of bytes to output and allocate space for
114 @@ -354,7 +383,7 @@
115 p = wcsarg;
116 mbs = initial;
117 for (;;) {
118 - clen = wcrtomb(buf, *p++, &mbs);
119 + clen = wcrtomb_l(buf, *p++, &mbs, loc);
120 if (clen == 0 || clen == (size_t)-1 ||
121 nbytes + clen > prec)
122 break;
123 @@ -363,7 +392,7 @@
124 } else {
125 p = wcsarg;
126 mbs = initial;
127 - nbytes = wcsrtombs(NULL, (const wchar_t **)&p, 0, &mbs);
128 + nbytes = wcsrtombs_l(NULL, (const wchar_t **)&p, 0, &mbs, loc);
129 if (nbytes == (size_t)-1)
130 return (NULL);
131 }
132 @@ -378,7 +407,7 @@
133 p = wcsarg;
134 mbs = initial;
135 while (mbp - convbuf < nbytes) {
136 - clen = wcrtomb(mbp, *p++, &mbs);
137 + clen = wcrtomb_l(mbp, *p++, &mbs, loc);
138 if (clen == 0 || clen == (size_t)-1)
139 break;
140 mbp += clen;
141 @@ -395,6 +424,8 @@
142 /*
143 * MT-safe version
144 */
145 +__private_extern__ const char *__fix_nogrouping(const char *);
146 +
147 int
148 vfprintf(FILE * __restrict fp, const char * __restrict fmt0, va_list ap)
149
150 @@ -402,7 +433,21 @@
151 int ret;
152
153 FLOCKFILE(fp);
154 - ret = __vfprintf(fp, fmt0, ap);
155 + ret = __vfprintf(fp, __current_locale(), fmt0, ap);
156 + FUNLOCKFILE(fp);
157 + return (ret);
158 +}
159 +
160 +int
161 +vfprintf_l(FILE * __restrict fp, locale_t loc, const char * __restrict fmt0,
162 + va_list ap)
163 +
164 +{
165 + int ret;
166 +
167 + NORMALIZE_LOCALE(loc);
168 + FLOCKFILE(fp);
169 + ret = __vfprintf(fp, loc, fmt0, ap);
170 FUNLOCKFILE(fp);
171 return (ret);
172 }
173 @@ -451,12 +496,15 @@
174 #define PTRDIFFT 0x800 /* ptrdiff_t */
175 #define INTMAXT 0x1000 /* intmax_t */
176 #define CHARINT 0x2000 /* print char using int format */
177 +#ifdef VECTORS
178 +#define VECTOR 0x4000 /* Altivec or SSE vector */
179 +#endif /* VECTORS */
180
181 /*
182 * Non-MT-safe version
183 */
184 -int
185 -__vfprintf(FILE *fp, const char *fmt0, va_list ap)
186 +__private_extern__ int
187 +__vfprintf(FILE *fp, locale_t loc, const char *fmt0, va_list ap)
188 {
189 char *fmt; /* format string */
190 int ch; /* character from fmt */
191 @@ -502,6 +550,11 @@
192 int nseps; /* number of group separators with ' */
193 int nrepeats; /* number of repeats of the last group */
194 #endif
195 +#ifdef VECTORS
196 + union arg vval; /* Vector argument. */
197 + char *pct; /* Pointer to '%' at beginning of specifier. */
198 + char vsep; /* Vector separator character. */
199 +#endif
200 u_long ulval; /* integer arguments %[diouxX] */
201 uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */
202 int base; /* base for [diouxX] conversion */
203 @@ -599,7 +652,7 @@
204 #define INTMAX_SIZE (INTMAXT|SIZET|PTRDIFFT|LLONGINT)
205 #define SJARG() \
206 (flags&INTMAXT ? GETARG(intmax_t) : \
207 - flags&SIZET ? (intmax_t)GETARG(size_t) : \
208 + flags&SIZET ? (intmax_t)GETARG(ssize_t) : \
209 flags&PTRDIFFT ? (intmax_t)GETARG(ptrdiff_t) : \
210 (intmax_t)GETARG(long long))
211 #define UJARG() \
212 @@ -633,22 +686,24 @@
213 val = GETARG (int); \
214 }
215
216 -
217 thousands_sep = '\0';
218 grouping = NULL;
219 convbuf = NULL;
220 #ifndef NO_FLOATING_POINT
221 dtoaresult = NULL;
222 - decimal_point = localeconv()->decimal_point;
223 + decimal_point = localeconv_l(loc)->decimal_point;
224 #endif
225 /* sorry, fprintf(read_only_file, "") returns EOF, not 0 */
226 - if (prepwrite(fp) != 0)
227 + if (prepwrite(fp) != 0) {
228 + errno = EBADF;
229 return (EOF);
230 + }
231 + ORIENT(fp, -1);
232
233 /* optimise fprintf(stderr) (and other unbuffered Unix files) */
234 if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
235 fp->_file >= 0)
236 - return (__sbprintf(fp, fmt0, ap));
237 + return (__sbprintf(fp, loc, fmt0, ap));
238
239 fmt = (char *)fmt0;
240 argtable = NULL;
241 @@ -675,6 +730,9 @@
242 }
243 if (ch == '\0')
244 goto done;
245 +#ifdef VECTORS
246 + pct = fmt;
247 +#endif /* VECTORS */
248 fmt++; /* skip over '%' */
249
250 flags = 0;
251 @@ -683,6 +741,9 @@
252 prec = -1;
253 sign = '\0';
254 ox[1] = '\0';
255 +#ifdef VECTORS
256 + vsep = 'X'; /* Illegal value, changed to defaults later. */
257 +#endif /* VECTORS */
258
259 rflag: ch = *fmt++;
260 reswitch: switch (ch) {
261 @@ -698,6 +759,11 @@
262 case '#':
263 flags |= ALT;
264 goto rflag;
265 +#ifdef VECTORS
266 + case ',': case ';': case ':': case '_':
267 + vsep = ch;
268 + goto rflag;
269 +#endif /* VECTORS */
270 case '*':
271 /*-
272 * ``A negative field width argument is taken as a
273 @@ -718,8 +784,8 @@
274 goto rflag;
275 case '\'':
276 flags |= GROUPING;
277 - thousands_sep = *(localeconv()->thousands_sep);
278 - grouping = localeconv()->grouping;
279 + thousands_sep = *(localeconv_l(loc)->thousands_sep);
280 + grouping = __fix_nogrouping(localeconv_l(loc)->grouping);
281 goto rflag;
282 case '.':
283 if ((ch = *fmt++) == '*') {
284 @@ -793,14 +859,18 @@
285 flags |= LONGINT;
286 /*FALLTHROUGH*/
287 case 'c':
288 +#ifdef VECTORS
289 + if (flags & VECTOR)
290 + break;
291 +#endif /* VECTORS */
292 if (flags & LONGINT) {
293 static const mbstate_t initial;
294 mbstate_t mbs;
295 size_t mbseqlen;
296
297 mbs = initial;
298 - mbseqlen = wcrtomb(cp = buf,
299 - (wchar_t)GETARG(wint_t), &mbs);
300 + mbseqlen = wcrtomb_l(cp = buf,
301 + (wchar_t)GETARG(wint_t), &mbs, loc);
302 if (mbseqlen == (size_t)-1) {
303 fp->_flags |= __SERR;
304 goto error;
305 @@ -817,6 +887,10 @@
306 /*FALLTHROUGH*/
307 case 'd':
308 case 'i':
309 +#ifdef VECTORS
310 + if (flags & VECTOR)
311 + break;
312 +#endif /* VECTORS */
313 if (flags & INTMAX_SIZE) {
314 ujval = SJARG();
315 if ((intmax_t)ujval < 0) {
316 @@ -835,6 +909,12 @@
317 #ifndef NO_FLOATING_POINT
318 case 'a':
319 case 'A':
320 +#ifdef VECTORS
321 + if (flags & VECTOR) {
322 + flags |= FPT;
323 + break;
324 + }
325 +#endif /* VECTORS */
326 if (ch == 'a') {
327 ox[1] = 'x';
328 xdigs = xdigs_lower;
329 @@ -848,6 +928,12 @@
330 prec++;
331 if (dtoaresult != NULL)
332 freedtoa(dtoaresult);
333 +#ifdef LDBL_COMPAT
334 + fparg.dbl = GETARG(double);
335 + dtoaresult = cp =
336 + __hdtoa(fparg.dbl, xdigs, prec,
337 + &expt, &signflag, &dtoaend);
338 +#else /* !LDBL_COMPAT */
339 if (flags & LONGDBL) {
340 fparg.ldbl = GETARG(long double);
341 dtoaresult = cp =
342 @@ -859,6 +945,7 @@
343 __hdtoa(fparg.dbl, xdigs, prec,
344 &expt, &signflag, &dtoaend);
345 }
346 +#endif /* LDBL_COMPAT */
347 if (prec < 0)
348 prec = dtoaend - cp;
349 if (expt == INT_MAX)
350 @@ -866,6 +953,12 @@
351 goto fp_common;
352 case 'e':
353 case 'E':
354 +#ifdef VECTORS
355 + if (flags & VECTOR) {
356 + flags |= FPT;
357 + break;
358 + }
359 +#endif /* VECTORS */
360 expchar = ch;
361 if (prec < 0) /* account for digit before decpt */
362 prec = DEFPREC + 1;
363 @@ -874,10 +967,22 @@
364 goto fp_begin;
365 case 'f':
366 case 'F':
367 +#ifdef VECTORS
368 + if (flags & VECTOR) {
369 + flags |= FPT;
370 + break;
371 + }
372 +#endif /* VECTORS */
373 expchar = '\0';
374 goto fp_begin;
375 case 'g':
376 case 'G':
377 +#ifdef VECTORS
378 + if (flags & VECTOR) {
379 + flags |= FPT;
380 + break;
381 + }
382 +#endif /* VECTORS */
383 expchar = ch - ('g' - 'e');
384 if (prec == 0)
385 prec = 1;
386 @@ -886,6 +991,14 @@
387 prec = DEFPREC;
388 if (dtoaresult != NULL)
389 freedtoa(dtoaresult);
390 +#ifdef LDBL_COMPAT
391 + fparg.dbl = GETARG(double);
392 + dtoaresult = cp =
393 + dtoa(fparg.dbl, expchar ? 2 : 3, prec,
394 + &expt, &signflag, &dtoaend);
395 + if (expt == 9999)
396 + expt = INT_MAX;
397 +#else /* !LDBL_COMPAT */
398 if (flags & LONGDBL) {
399 fparg.ldbl = GETARG(long double);
400 dtoaresult = cp =
401 @@ -899,6 +1012,7 @@
402 if (expt == 9999)
403 expt = INT_MAX;
404 }
405 +#endif /* LDBL_COMPAT */
406 fp_common:
407 if (signflag)
408 sign = '-';
409 @@ -993,6 +1107,10 @@
410 flags |= LONGINT;
411 /*FALLTHROUGH*/
412 case 'o':
413 +#ifdef VECTORS
414 + if (flags & VECTOR)
415 + break;
416 +#endif /* VECTORS */
417 if (flags & INTMAX_SIZE)
418 ujval = UJARG();
419 else
420 @@ -1007,6 +1125,10 @@
421 * defined manner.''
422 * -- ANSI X3J11
423 */
424 +#ifdef VECTORS
425 + if (flags & VECTOR)
426 + break;
427 +#endif /* VECTORS */
428 ujval = (uintmax_t)(uintptr_t)GETARG(void *);
429 base = 16;
430 xdigs = xdigs_lower;
431 @@ -1025,7 +1147,7 @@
432 if ((wcp = GETARG(wchar_t *)) == NULL)
433 cp = "(null)";
434 else {
435 - convbuf = __wcsconv(wcp, prec);
436 + convbuf = __wcsconv(wcp, prec, loc);
437 if (convbuf == NULL) {
438 fp->_flags |= __SERR;
439 goto error;
440 @@ -1056,6 +1178,10 @@
441 flags |= LONGINT;
442 /*FALLTHROUGH*/
443 case 'u':
444 +#ifdef VECTORS
445 + if (flags & VECTOR)
446 + break;
447 +#endif /* VECTORS */
448 if (flags & INTMAX_SIZE)
449 ujval = UJARG();
450 else
451 @@ -1068,6 +1194,10 @@
452 case 'x':
453 xdigs = xdigs_lower;
454 hex:
455 +#ifdef VECTORS
456 + if (flags & VECTOR)
457 + break;
458 +#endif /* VECTORS */
459 if (flags & INTMAX_SIZE)
460 ujval = UJARG();
461 else
462 @@ -1093,6 +1223,7 @@
463 * ``The result of converting a zero value with an
464 * explicit precision of zero is no characters.''
465 * -- ANSI X3J11
466 + * except for %#.0o and zero value
467 */
468 cp = buf + BUF;
469 if (flags & INTMAX_SIZE) {
470 @@ -1102,7 +1233,7 @@
471 flags & GROUPING, thousands_sep,
472 grouping);
473 } else {
474 - if (ulval != 0 || prec != 0)
475 + if (ulval != 0 || prec != 0 || (flags & ALT))
476 cp = __ultoa(ulval, cp, base,
477 flags & ALT, xdigs,
478 flags & GROUPING, thousands_sep,
479 @@ -1112,6 +1243,11 @@
480 if (size > BUF) /* should never happen */
481 abort();
482 break;
483 +#ifdef VECTORS
484 + case 'v':
485 + flags |= VECTOR;
486 + goto rflag;
487 +#endif /* VECTORS */
488 default: /* "%?" prints ?, unless ? is NUL */
489 if (ch == '\0')
490 goto done;
491 @@ -1123,6 +1259,290 @@
492 break;
493 }
494
495 +#ifdef VECTORS
496 + if (flags & VECTOR) {
497 + /*
498 + * Do the minimum amount of work necessary to construct
499 + * a format specifier that can be used to recursively
500 + * call vfprintf() for each element in the vector.
501 + */
502 + int i, j; /* Counter. */
503 + int vcnt; /* Number of elements in vector. */
504 + char *vfmt; /* Pointer to format specifier. */
505 +#define EXTRAHH 2
506 + char vfmt_buf[32 + EXTRAHH]; /* Static buffer for format spec. */
507 + int vwidth = 0; /* Width specified via '*'. */
508 + int vprec = 0; /* Precision specified via '*'. */
509 + char *vstr; /* Used for asprintf(). */
510 + int vlen; /* Length returned by asprintf(). */
511 + enum {
512 + V_CHAR, V_SHORT, V_INT,
513 + V_PCHAR, V_PSHORT, V_PINT,
514 + V_FLOAT,
515 +#ifdef V64TYPE
516 + V_LONGLONG, V_PLONGLONG,
517 + V_DOUBLE,
518 +#endif /* V64TYPE */
519 + } vtype;
520 +
521 + vval.vectorarg = GETARG(VECTORTYPE);
522 + /*
523 + * Set vfmt. If vfmt_buf may not be big enough,
524 + * malloc() space, taking care to free it later.
525 + * (EXTRAHH is for possible extra "hh")
526 + */
527 + if (&fmt[-1] - pct + EXTRAHH < sizeof(vfmt_buf))
528 + vfmt = vfmt_buf;
529 + else
530 + vfmt = (char *)malloc(&fmt[-1] - pct + EXTRAHH + 1);
531 +
532 + /* Set the separator character, if not specified. */
533 + if (vsep == 'X') {
534 + if (ch == 'c')
535 + vsep = '\0';
536 + else
537 + vsep = ' ';
538 + }
539 +
540 + /* Create the format specifier. */
541 + for (i = j = 0; i < &fmt[-1] - pct; i++) {
542 + switch (pct[i]) {
543 + case ',': case ';': case ':': case '_':
544 + case 'v': case 'h': case 'l':
545 + /* Ignore. */
546 + break;
547 + case '*':
548 + if (pct[i - 1] != '.')
549 + vwidth = 1;
550 + else
551 + vprec = 1;
552 + /* FALLTHROUGH */
553 + default:
554 + vfmt[j++] = pct[i];
555 + }
556 + }
557 +
558 + /*
559 + * Determine the number of elements in the vector and
560 + * finish up the format specifier.
561 + */
562 + if (flags & SHORTINT) {
563 + switch (ch) {
564 + case 'c':
565 + vtype = V_SHORT;
566 + break;
567 + case 'p':
568 + vtype = V_PSHORT;
569 + break;
570 + default:
571 + vfmt[j++] = 'h';
572 + vtype = V_SHORT;
573 + break;
574 + }
575 + vcnt = 8;
576 + } else if (flags & LONGINT) {
577 + vcnt = 4;
578 + vtype = (ch == 'p') ? V_PINT : V_INT;
579 +#ifdef V64TYPE
580 + } else if (flags & LLONGINT) {
581 + switch (ch) {
582 + case 'a':
583 + case 'A':
584 + case 'e':
585 + case 'E':
586 + case 'f':
587 + case 'g':
588 + case 'G':
589 + vcnt = 2;
590 + vtype = V_DOUBLE;
591 + break;
592 + case 'd':
593 + case 'i':
594 + case 'u':
595 + case 'o':
596 + case 'p':
597 + case 'x':
598 + case 'X':
599 + vfmt[j++] = 'l';
600 + vfmt[j++] = 'l';
601 + vcnt = 2;
602 + vtype = (ch == 'p') ? V_PLONGLONG : V_LONGLONG;
603 + break;
604 + default:
605 + /*
606 + * The default case should never
607 + * happen.
608 + */
609 + case 'c':
610 + vcnt = 16;
611 + vtype = V_CHAR;
612 + }
613 +#endif /* V64TYPE */
614 + } else {
615 + switch (ch) {
616 + case 'a':
617 + case 'A':
618 + case 'e':
619 + case 'E':
620 + case 'f':
621 + case 'g':
622 + case 'G':
623 + vcnt = 4;
624 + vtype = V_FLOAT;
625 + break;
626 + default:
627 + /*
628 + * The default case should never
629 + * happen.
630 + */
631 + case 'd':
632 + case 'i':
633 + case 'u':
634 + case 'o':
635 + case 'x':
636 + case 'X':
637 + vfmt[j++] = 'h';
638 + vfmt[j++] = 'h';
639 + /* drop through */
640 + case 'p':
641 + case 'c':
642 + vcnt = 16;
643 + vtype = (ch == 'p') ? V_PCHAR : V_CHAR;
644 + }
645 + }
646 + vfmt[j++] = ch;
647 + vfmt[j++] = '\0';
648 +
649 +/* Get a vector element. */
650 +#ifdef V64TYPE
651 +#define VPRINT(type, ind, args...) do { \
652 + switch (type) { \
653 + case V_CHAR: \
654 + vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vuchararg[ind]); \
655 + break; \
656 + case V_PCHAR: \
657 + vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vuchararg[ind]); \
658 + break; \
659 + case V_SHORT: \
660 + vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vushortarg[ind]); \
661 + break; \
662 + case V_PSHORT: \
663 + vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vushortarg[ind]); \
664 + break; \
665 + case V_INT: \
666 + vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vuintarg[ind]); \
667 + break; \
668 + case V_PINT: \
669 + vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vuintarg[ind]); \
670 + break; \
671 + case V_LONGLONG: \
672 + vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vulonglongarg[ind]); \
673 + break; \
674 + case V_PLONGLONG: \
675 + vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vulonglongarg[ind]); \
676 + break; \
677 + case V_FLOAT: \
678 + vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vfloatarg[ind]); \
679 + break; \
680 + case V_DOUBLE: \
681 + vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vdoublearg[ind]); \
682 + break; \
683 + } \
684 + ret += vlen; \
685 + PRINT(vstr, vlen); \
686 + FLUSH(); \
687 + free(vstr); \
688 +} while (0)
689 +#else /* !V64TYPE */
690 +#define VPRINT(type, ind, args...) do { \
691 + switch (type) { \
692 + case V_CHAR: \
693 + vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vuchararg[ind]); \
694 + break; \
695 + case V_PCHAR: \
696 + vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vuchararg[ind]); \
697 + break; \
698 + case V_SHORT: \
699 + vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vushortarg[ind]); \
700 + break; \
701 + case V_PSHORT: \
702 + vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vushortarg[ind]); \
703 + break; \
704 + case V_INT: \
705 + vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vuintarg[ind]); \
706 + break; \
707 + case V_PINT: \
708 + vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vuintarg[ind]); \
709 + break; \
710 + case V_FLOAT: \
711 + vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vfloatarg[ind]); \
712 + break; \
713 + } \
714 + ret += vlen; \
715 + PRINT(vstr, vlen); \
716 + FLUSH(); \
717 + free(vstr); \
718 +} while (0)
719 +#endif /* V64TYPE */
720 +
721 + /* Actually print. */
722 + if (vwidth == 0) {
723 + if (vprec == 0) {
724 + /* First element. */
725 + VPRINT(vtype, 0);
726 + for (i = 1; i < vcnt; i++) {
727 + /* Separator. */
728 + if(vsep)
729 + PRINT(&vsep, 1);
730 +
731 + /* Element. */
732 + VPRINT(vtype, i);
733 + }
734 + } else {
735 + /* First element. */
736 + VPRINT(vtype, 0, prec);
737 + for (i = 1; i < vcnt; i++) {
738 + /* Separator. */
739 + if(vsep)
740 + PRINT(&vsep, 1);
741 +
742 + /* Element. */
743 + VPRINT(vtype, i, prec);
744 + }
745 + }
746 + } else {
747 + if (vprec == 0) {
748 + /* First element. */
749 + VPRINT(vtype, 0, width);
750 + for (i = 1; i < vcnt; i++) {
751 + /* Separator. */
752 + if(vsep)
753 + PRINT(&vsep, 1);
754 +
755 + /* Element. */
756 + VPRINT(vtype, i, width);
757 + }
758 + } else {
759 + /* First element. */
760 + VPRINT(vtype, 0, width, prec);
761 + for (i = 1; i < vcnt; i++) {
762 + /* Separator. */
763 + if(vsep)
764 + PRINT(&vsep, 1);
765 +
766 + /* Element. */
767 + VPRINT(vtype, i, width, prec);
768 + }
769 + }
770 + }
771 +#undef VPRINT
772 +
773 + if (vfmt != vfmt_buf)
774 + free(vfmt);
775 +
776 + continue;
777 + }
778 +#endif /* VECTORS */
779 /*
780 * All reasonable formats wind up here. At this point, `cp'
781 * points to a string which (if not flags&LADJUST) should be
782 @@ -1178,7 +1598,7 @@
783 if (expt <= 0) {
784 PRINT(zeroes, 1);
785 if (prec || flags & ALT)
786 - PRINT(decimal_point, 1);
787 + PRINT(decimal_point, strlen(decimal_point));
788 PAD(-expt, zeroes);
789 /* already handled initial 0's */
790 prec += expt;
791 @@ -1203,14 +1623,14 @@
792 cp = dtoaend;
793 }
794 if (prec || flags & ALT)
795 - PRINT(decimal_point,1);
796 + PRINT(decimal_point, strlen(decimal_point));
797 }
798 PRINTANDPAD(cp, dtoaend, prec, zeroes);
799 } else { /* %[eE] or sufficiently long %[gG] */
800 if (prec > 1 || flags & ALT) {
801 buf[0] = *cp++;
802 - buf[1] = *decimal_point;
803 - PRINT(buf, 2);
804 + PRINT(buf, 1);
805 + PRINT(decimal_point, strlen(decimal_point));
806 PRINT(cp, ndig-1);
807 PAD(prec - ndig, zeroes);
808 } else /* XeYYY */
809 @@ -1406,6 +1826,11 @@
810 if (flags & LONGINT)
811 ADDTYPE(T_WINT);
812 else
813 +#ifdef VECTORS
814 + if (flags & VECTOR)
815 + ADDTYPE(T_VECTOR);
816 + else
817 +#endif /* VECTORS */
818 ADDTYPE(T_INT);
819 break;
820 case 'D':
821 @@ -1413,6 +1838,11 @@
822 /*FALLTHROUGH*/
823 case 'd':
824 case 'i':
825 +#ifdef VECTORS
826 + if (flags & VECTOR)
827 + ADDTYPE(T_VECTOR);
828 + else
829 +#endif
830 ADDSARG();
831 break;
832 #ifndef NO_FLOATING_POINT
833 @@ -1421,8 +1851,14 @@
834 case 'e':
835 case 'E':
836 case 'f':
837 + case 'F':
838 case 'g':
839 case 'G':
840 +#ifdef VECTORS
841 + if (flags & VECTOR)
842 + ADDTYPE(T_VECTOR);
843 + else
844 +#endif /* VECTORS */
845 if (flags & LONGDBL)
846 ADDTYPE(T_LONG_DOUBLE);
847 else
848 @@ -1451,9 +1887,19 @@
849 flags |= LONGINT;
850 /*FALLTHROUGH*/
851 case 'o':
852 +#ifdef VECTORS
853 + if (flags & VECTOR)
854 + ADDTYPE(T_VECTOR);
855 + else
856 +#endif /* VECTORS */
857 ADDUARG();
858 break;
859 case 'p':
860 +#ifdef VECTORS
861 + if (flags & VECTOR)
862 + ADDTYPE(T_VECTOR);
863 + else
864 +#endif /* VECTORS */
865 ADDTYPE(TP_VOID);
866 break;
867 case 'S':
868 @@ -1471,6 +1917,11 @@
869 case 'u':
870 case 'X':
871 case 'x':
872 +#ifdef VECTORS
873 + if (flags & VECTOR)
874 + ADDTYPE(T_VECTOR);
875 + else
876 +#endif /* VECTORS */
877 ADDUARG();
878 break;
879 default: /* "%?" prints ?, unless ? is NUL */
880 @@ -1537,7 +1988,7 @@
881 (*argtable) [n].sizearg = va_arg (ap, size_t);
882 break;
883 case TP_SIZET:
884 - (*argtable) [n].psizearg = va_arg (ap, ssize_t *);
885 + (*argtable) [n].psizearg = va_arg (ap, size_t *);
886 break;
887 case T_INTMAXT:
888 (*argtable) [n].intmaxarg = va_arg (ap, intmax_t);
889 @@ -1556,6 +2007,11 @@
890 (*argtable) [n].longdoublearg = va_arg (ap, long double);
891 break;
892 #endif
893 +#ifdef VECTORS
894 + case T_VECTOR:
895 + (*argtable) [n].vectorarg = va_arg (ap, VECTORTYPE);
896 + break;
897 +#endif /* VECTORS */
898 case TP_CHAR:
899 (*argtable) [n].pchararg = va_arg (ap, char *);
900 break;