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