]> git.saurik.com Git - apple/libc.git/blame - stdio/FreeBSD/vfprintf.c.patch
Libc-498.1.7.tar.gz
[apple/libc.git] / stdio / FreeBSD / vfprintf.c.patch
CommitLineData
224c7076
A
1--- vfprintf.c.orig 2006-10-01 00:03:16.000000000 -0700
2+++ vfprintf.c 2006-10-01 00:21:05.000000000 -0700
3d9156a7
A
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 @@
51631861
A
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"
eb1cde05 20@@ -66,6 +69,13 @@
9385eb3d
A
21 #include "local.h"
22 #include "fvwrite.h"
23
eb1cde05
A
24+#ifdef VECTORS
25+typedef __attribute__ ((vector_size(16))) unsigned char VECTORTYPE;
26+#ifdef __SSE2__
27+#define V64TYPE
28+#endif /* __SSE2__ */
29+#endif /* VECTORS */
9385eb3d
A
30+
31 union arg {
32 int intarg;
33 u_int uintarg;
eb1cde05 34@@ -93,6 +103,21 @@
9385eb3d
A
35 #endif
36 wint_t wintarg;
37 wchar_t *pwchararg;
eb1cde05 38+#ifdef VECTORS
9385eb3d
A
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];
eb1cde05
A
47+#ifdef V64TYPE
48+ double vdoublearg[2];
49+ unsigned long long vulonglongarg[2];
50+ long long vlonglongarg[2];
51+#endif /* V64TYPE */
52+#endif /* VECTORS */
9385eb3d
A
53 };
54
55 /*
eb1cde05 56@@ -103,16 +128,20 @@
9385eb3d
A
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,
eb1cde05 60+#ifdef VECTORS
9385eb3d 61+ T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR, T_VECTOR
eb1cde05 62+#else /* ! VECTORS */
9385eb3d 63 T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR
eb1cde05 64+#endif /* VECTORS */
9385eb3d
A
65 };
66
67 static int __sprint(FILE *, struct __suio *);
3d9156a7
A
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);
9385eb3d
A
76 static void __find_arguments(const char *, va_list, union arg **);
77 static void __grow_type_table(int, enum typeid **, int *);
78
eb1cde05 79@@ -141,7 +170,7 @@
3d9156a7
A
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;
eb1cde05 88@@ -160,7 +189,7 @@
3d9156a7
A
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)
224c7076 97@@ -336,14 +365,14 @@
3d9156a7
A
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;
224c7076
A
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
eb1cde05 114@@ -354,7 +383,7 @@
3d9156a7
A
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;
eb1cde05 123@@ -363,7 +392,7 @@
3d9156a7
A
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 }
eb1cde05 132@@ -378,7 +407,7 @@
3d9156a7
A
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;
224c7076
A
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 @@
3d9156a7
A
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 }
224c7076 173@@ -451,12 +496,15 @@
9385eb3d
A
174 #define PTRDIFFT 0x800 /* ptrdiff_t */
175 #define INTMAXT 0x1000 /* intmax_t */
176 #define CHARINT 0x2000 /* print char using int format */
eb1cde05
A
177+#ifdef VECTORS
178+#define VECTOR 0x4000 /* Altivec or SSE vector */
179+#endif /* VECTORS */
9385eb3d
A
180
181 /*
182 * Non-MT-safe version
3d9156a7
A
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 */
224c7076 191@@ -502,6 +550,11 @@
9385eb3d
A
192 int nseps; /* number of group separators with ' */
193 int nrepeats; /* number of repeats of the last group */
194 #endif
eb1cde05 195+#ifdef VECTORS
9385eb3d
A
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 */
224c7076
A
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 @@
9385eb3d
A
213 val = GETARG (int); \
214 }
215
216-
217 thousands_sep = '\0';
218 grouping = NULL;
219 convbuf = NULL;
3d9156a7
A
220 #ifndef NO_FLOATING_POINT
221 dtoaresult = NULL;
222- decimal_point = localeconv()->decimal_point;
223+ decimal_point = localeconv_l(loc)->decimal_point;
51631861
A
224 #endif
225 /* sorry, fprintf(read_only_file, "") returns EOF, not 0 */
3d9156a7
A
226- if (prepwrite(fp) != 0)
227+ if (prepwrite(fp) != 0) {
51631861
A
228+ errno = EBADF;
229 return (EOF);
230+ }
224c7076 231+ ORIENT(fp, -1);
51631861
A
232
233 /* optimise fprintf(stderr) (and other unbuffered Unix files) */
234 if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
3d9156a7
A
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;
224c7076 241@@ -675,6 +730,9 @@
9385eb3d
A
242 }
243 if (ch == '\0')
244 goto done;
eb1cde05 245+#ifdef VECTORS
9385eb3d 246+ pct = fmt;
eb1cde05 247+#endif /* VECTORS */
9385eb3d
A
248 fmt++; /* skip over '%' */
249
250 flags = 0;
224c7076 251@@ -683,6 +741,9 @@
9385eb3d
A
252 prec = -1;
253 sign = '\0';
254 ox[1] = '\0';
eb1cde05 255+#ifdef VECTORS
9385eb3d 256+ vsep = 'X'; /* Illegal value, changed to defaults later. */
eb1cde05 257+#endif /* VECTORS */
9385eb3d
A
258
259 rflag: ch = *fmt++;
260 reswitch: switch (ch) {
224c7076 261@@ -698,6 +759,11 @@
9385eb3d
A
262 case '#':
263 flags |= ALT;
264 goto rflag;
eb1cde05 265+#ifdef VECTORS
9385eb3d
A
266+ case ',': case ';': case ':': case '_':
267+ vsep = ch;
268+ goto rflag;
eb1cde05 269+#endif /* VECTORS */
9385eb3d
A
270 case '*':
271 /*-
272 * ``A negative field width argument is taken as a
224c7076 273@@ -718,8 +784,8 @@
3d9156a7
A
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);
224c7076 280+ grouping = __fix_nogrouping(localeconv_l(loc)->grouping);
3d9156a7
A
281 goto rflag;
282 case '.':
283 if ((ch = *fmt++) == '*') {
224c7076 284@@ -793,14 +859,18 @@
59e0d9fe
A
285 flags |= LONGINT;
286 /*FALLTHROUGH*/
287 case 'c':
eb1cde05
A
288+#ifdef VECTORS
289+ if (flags & VECTOR)
59e0d9fe 290+ break;
eb1cde05 291+#endif /* VECTORS */
59e0d9fe
A
292 if (flags & LONGINT) {
293 static const mbstate_t initial;
294 mbstate_t mbs;
3d9156a7
A
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;
224c7076 305@@ -817,6 +887,10 @@
9385eb3d
A
306 /*FALLTHROUGH*/
307 case 'd':
308 case 'i':
eb1cde05
A
309+#ifdef VECTORS
310+ if (flags & VECTOR)
9385eb3d 311+ break;
eb1cde05 312+#endif /* VECTORS */
9385eb3d
A
313 if (flags & INTMAX_SIZE) {
314 ujval = SJARG();
315 if ((intmax_t)ujval < 0) {
224c7076 316@@ -835,6 +909,12 @@
59e0d9fe 317 #ifndef NO_FLOATING_POINT
9385eb3d
A
318 case 'a':
319 case 'A':
eb1cde05 320+#ifdef VECTORS
9385eb3d
A
321+ if (flags & VECTOR) {
322+ flags |= FPT;
9385eb3d
A
323+ break;
324+ }
eb1cde05 325+#endif /* VECTORS */
9385eb3d
A
326 if (ch == 'a') {
327 ox[1] = 'x';
328 xdigs = xdigs_lower;
224c7076 329@@ -848,6 +928,12 @@
3d9156a7
A
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 =
224c7076 342@@ -859,6 +945,7 @@
3d9156a7
A
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)
224c7076 350@@ -866,6 +953,12 @@
59e0d9fe 351 goto fp_common;
9385eb3d
A
352 case 'e':
353 case 'E':
eb1cde05 354+#ifdef VECTORS
9385eb3d
A
355+ if (flags & VECTOR) {
356+ flags |= FPT;
9385eb3d
A
357+ break;
358+ }
eb1cde05 359+#endif /* VECTORS */
9385eb3d
A
360 expchar = ch;
361 if (prec < 0) /* account for digit before decpt */
362 prec = DEFPREC + 1;
224c7076 363@@ -874,10 +967,22 @@
9385eb3d
A
364 goto fp_begin;
365 case 'f':
366 case 'F':
eb1cde05 367+#ifdef VECTORS
9385eb3d
A
368+ if (flags & VECTOR) {
369+ flags |= FPT;
9385eb3d
A
370+ break;
371+ }
eb1cde05 372+#endif /* VECTORS */
9385eb3d
A
373 expchar = '\0';
374 goto fp_begin;
375 case 'g':
376 case 'G':
eb1cde05 377+#ifdef VECTORS
9385eb3d
A
378+ if (flags & VECTOR) {
379+ flags |= FPT;
9385eb3d
A
380+ break;
381+ }
eb1cde05 382+#endif /* VECTORS */
9385eb3d
A
383 expchar = ch - ('g' - 'e');
384 if (prec == 0)
385 prec = 1;
224c7076 386@@ -886,6 +991,14 @@
3d9156a7
A
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 =
224c7076 401@@ -899,6 +1012,7 @@
3d9156a7
A
402 if (expt == 9999)
403 expt = INT_MAX;
404 }
405+#endif /* LDBL_COMPAT */
406 fp_common:
407 if (signflag)
408 sign = '-';
224c7076 409@@ -993,6 +1107,10 @@
9385eb3d
A
410 flags |= LONGINT;
411 /*FALLTHROUGH*/
412 case 'o':
eb1cde05
A
413+#ifdef VECTORS
414+ if (flags & VECTOR)
9385eb3d 415+ break;
eb1cde05 416+#endif /* VECTORS */
9385eb3d
A
417 if (flags & INTMAX_SIZE)
418 ujval = UJARG();
419 else
224c7076 420@@ -1007,6 +1125,10 @@
9385eb3d
A
421 * defined manner.''
422 * -- ANSI X3J11
423 */
eb1cde05
A
424+#ifdef VECTORS
425+ if (flags & VECTOR)
9385eb3d 426+ break;
eb1cde05 427+#endif /* VECTORS */
9385eb3d
A
428 ujval = (uintmax_t)(uintptr_t)GETARG(void *);
429 base = 16;
430 xdigs = xdigs_lower;
224c7076 431@@ -1025,7 +1147,7 @@
3d9156a7
A
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;
224c7076 440@@ -1056,6 +1178,10 @@
9385eb3d
A
441 flags |= LONGINT;
442 /*FALLTHROUGH*/
443 case 'u':
eb1cde05
A
444+#ifdef VECTORS
445+ if (flags & VECTOR)
9385eb3d 446+ break;
eb1cde05 447+#endif /* VECTORS */
9385eb3d
A
448 if (flags & INTMAX_SIZE)
449 ujval = UJARG();
450 else
224c7076 451@@ -1068,6 +1194,10 @@
9385eb3d
A
452 case 'x':
453 xdigs = xdigs_lower;
454 hex:
eb1cde05
A
455+#ifdef VECTORS
456+ if (flags & VECTOR)
9385eb3d 457+ break;
eb1cde05 458+#endif /* VECTORS */
9385eb3d
A
459 if (flags & INTMAX_SIZE)
460 ujval = UJARG();
461 else
224c7076
A
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 @@
9385eb3d
A
480 if (size > BUF) /* should never happen */
481 abort();
482 break;
eb1cde05 483+#ifdef VECTORS
9385eb3d 484+ case 'v':
eb1cde05
A
485+ flags |= VECTOR;
486+ goto rflag;
487+#endif /* VECTORS */
9385eb3d
A
488 default: /* "%?" prints ?, unless ? is NUL */
489 if (ch == '\0')
490 goto done;
224c7076 491@@ -1123,6 +1259,290 @@
9385eb3d
A
492 break;
493 }
494
eb1cde05 495+#ifdef VECTORS
9385eb3d
A
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. */
eb1cde05
A
505+#define EXTRAHH 2
506+ char vfmt_buf[32 + EXTRAHH]; /* Static buffer for format spec. */
9385eb3d
A
507+ int vwidth = 0; /* Width specified via '*'. */
508+ int vprec = 0; /* Precision specified via '*'. */
9385eb3d
A
509+ char *vstr; /* Used for asprintf(). */
510+ int vlen; /* Length returned by asprintf(). */
eb1cde05
A
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;
9385eb3d 520+
eb1cde05 521+ vval.vectorarg = GETARG(VECTORTYPE);
9385eb3d
A
522+ /*
523+ * Set vfmt. If vfmt_buf may not be big enough,
524+ * malloc() space, taking care to free it later.
eb1cde05 525+ * (EXTRAHH is for possible extra "hh")
9385eb3d 526+ */
eb1cde05 527+ if (&fmt[-1] - pct + EXTRAHH < sizeof(vfmt_buf))
9385eb3d
A
528+ vfmt = vfmt_buf;
529+ else
eb1cde05 530+ vfmt = (char *)malloc(&fmt[-1] - pct + EXTRAHH + 1);
9385eb3d
A
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) {
eb1cde05
A
563+ switch (ch) {
564+ case 'c':
565+ vtype = V_SHORT;
566+ break;
567+ case 'p':
568+ vtype = V_PSHORT;
569+ break;
570+ default:
59e0d9fe 571+ vfmt[j++] = 'h';
eb1cde05
A
572+ vtype = V_SHORT;
573+ break;
574+ }
9385eb3d
A
575+ vcnt = 8;
576+ } else if (flags & LONGINT) {
f74c7596 577+ vcnt = 4;
eb1cde05
A
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 */
9385eb3d
A
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;
eb1cde05 624+ vtype = V_FLOAT;
9385eb3d
A
625+ break;
626+ default:
627+ /*
628+ * The default case should never
629+ * happen.
630+ */
9385eb3d
A
631+ case 'd':
632+ case 'i':
633+ case 'u':
634+ case 'o':
9385eb3d
A
635+ case 'x':
636+ case 'X':
eb1cde05
A
637+ vfmt[j++] = 'h';
638+ vfmt[j++] = 'h';
639+ /* drop through */
640+ case 'p':
641+ case 'c':
9385eb3d 642+ vcnt = 16;
eb1cde05 643+ vtype = (ch == 'p') ? V_PCHAR : V_CHAR;
9385eb3d
A
644+ }
645+ }
646+ vfmt[j++] = ch;
647+ vfmt[j++] = '\0';
648+
649+/* Get a vector element. */
eb1cde05
A
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; \
9385eb3d
A
713+ } \
714+ ret += vlen; \
715+ PRINT(vstr, vlen); \
716+ FLUSH(); \
717+ free(vstr); \
718+} while (0)
eb1cde05 719+#endif /* V64TYPE */
9385eb3d
A
720+
721+ /* Actually print. */
722+ if (vwidth == 0) {
723+ if (vprec == 0) {
724+ /* First element. */
eb1cde05 725+ VPRINT(vtype, 0);
9385eb3d
A
726+ for (i = 1; i < vcnt; i++) {
727+ /* Separator. */
eb1cde05
A
728+ if(vsep)
729+ PRINT(&vsep, 1);
9385eb3d
A
730+
731+ /* Element. */
eb1cde05 732+ VPRINT(vtype, i);
9385eb3d
A
733+ }
734+ } else {
735+ /* First element. */
eb1cde05 736+ VPRINT(vtype, 0, prec);
9385eb3d
A
737+ for (i = 1; i < vcnt; i++) {
738+ /* Separator. */
eb1cde05
A
739+ if(vsep)
740+ PRINT(&vsep, 1);
9385eb3d
A
741+
742+ /* Element. */
eb1cde05 743+ VPRINT(vtype, i, prec);
9385eb3d
A
744+ }
745+ }
746+ } else {
747+ if (vprec == 0) {
748+ /* First element. */
eb1cde05 749+ VPRINT(vtype, 0, width);
9385eb3d
A
750+ for (i = 1; i < vcnt; i++) {
751+ /* Separator. */
eb1cde05
A
752+ if(vsep)
753+ PRINT(&vsep, 1);
9385eb3d
A
754+
755+ /* Element. */
eb1cde05 756+ VPRINT(vtype, i, width);
9385eb3d
A
757+ }
758+ } else {
759+ /* First element. */
eb1cde05 760+ VPRINT(vtype, 0, width, prec);
9385eb3d
A
761+ for (i = 1; i < vcnt; i++) {
762+ /* Separator. */
eb1cde05
A
763+ if(vsep)
764+ PRINT(&vsep, 1);
9385eb3d
A
765+
766+ /* Element. */
eb1cde05 767+ VPRINT(vtype, i, width, prec);
9385eb3d
A
768+ }
769+ }
770+ }
771+#undef VPRINT
772+
773+ if (vfmt != vfmt_buf)
774+ free(vfmt);
775+
776+ continue;
777+ }
eb1cde05 778+#endif /* VECTORS */
9385eb3d
A
779 /*
780 * All reasonable formats wind up here. At this point, `cp'
781 * points to a string which (if not flags&LADJUST) should be
224c7076
A
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 @@
9385eb3d
A
810 if (flags & LONGINT)
811 ADDTYPE(T_WINT);
812 else
eb1cde05 813+#ifdef VECTORS
9385eb3d
A
814+ if (flags & VECTOR)
815+ ADDTYPE(T_VECTOR);
816+ else
eb1cde05 817+#endif /* VECTORS */
9385eb3d
A
818 ADDTYPE(T_INT);
819 break;
820 case 'D':
224c7076 821@@ -1413,6 +1838,11 @@
9385eb3d
A
822 /*FALLTHROUGH*/
823 case 'd':
824 case 'i':
eb1cde05 825+#ifdef VECTORS
9385eb3d
A
826+ if (flags & VECTOR)
827+ ADDTYPE(T_VECTOR);
828+ else
829+#endif
830 ADDSARG();
831 break;
59e0d9fe 832 #ifndef NO_FLOATING_POINT
224c7076
A
833@@ -1421,8 +1851,14 @@
834 case 'e':
835 case 'E':
9385eb3d 836 case 'f':
224c7076 837+ case 'F':
9385eb3d
A
838 case 'g':
839 case 'G':
eb1cde05 840+#ifdef VECTORS
9385eb3d
A
841+ if (flags & VECTOR)
842+ ADDTYPE(T_VECTOR);
843+ else
eb1cde05 844+#endif /* VECTORS */
9385eb3d
A
845 if (flags & LONGDBL)
846 ADDTYPE(T_LONG_DOUBLE);
847 else
224c7076 848@@ -1451,9 +1887,19 @@
9385eb3d
A
849 flags |= LONGINT;
850 /*FALLTHROUGH*/
851 case 'o':
eb1cde05 852+#ifdef VECTORS
9385eb3d
A
853+ if (flags & VECTOR)
854+ ADDTYPE(T_VECTOR);
855+ else
eb1cde05 856+#endif /* VECTORS */
9385eb3d
A
857 ADDUARG();
858 break;
859 case 'p':
eb1cde05 860+#ifdef VECTORS
9385eb3d
A
861+ if (flags & VECTOR)
862+ ADDTYPE(T_VECTOR);
863+ else
eb1cde05 864+#endif /* VECTORS */
9385eb3d
A
865 ADDTYPE(TP_VOID);
866 break;
867 case 'S':
224c7076 868@@ -1471,6 +1917,11 @@
9385eb3d
A
869 case 'u':
870 case 'X':
871 case 'x':
eb1cde05 872+#ifdef VECTORS
9385eb3d
A
873+ if (flags & VECTOR)
874+ ADDTYPE(T_VECTOR);
875+ else
eb1cde05 876+#endif /* VECTORS */
9385eb3d
A
877 ADDUARG();
878 break;
879 default: /* "%?" prints ?, unless ? is NUL */
224c7076 880@@ -1537,7 +1988,7 @@
3d9156a7
A
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);
224c7076 889@@ -1556,6 +2007,11 @@
9385eb3d
A
890 (*argtable) [n].longdoublearg = va_arg (ap, long double);
891 break;
892 #endif
eb1cde05 893+#ifdef VECTORS
9385eb3d 894+ case T_VECTOR:
eb1cde05 895+ (*argtable) [n].vectorarg = va_arg (ap, VECTORTYPE);
9385eb3d 896+ break;
eb1cde05 897+#endif /* VECTORS */
9385eb3d
A
898 case TP_CHAR:
899 (*argtable) [n].pchararg = va_arg (ap, char *);
900 break;