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