]> git.saurik.com Git - apple/libc.git/blob - stdio/vfprintf-fbsd.c
Libc-498.tar.gz
[apple/libc.git] / stdio / vfprintf-fbsd.c
1 /*-
2 * Copyright (c) 1990, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37 #if defined(LIBC_SCCS) && !defined(lint)
38 static char sccsid[] = "@(#)vfprintf.c 8.1 (Berkeley) 6/4/93";
39 #endif /* LIBC_SCCS and not lint */
40 #include <sys/cdefs.h>
41 __FBSDID("$FreeBSD: src/lib/libc/stdio/vfprintf.c,v 1.68 2004/08/26 06:25:28 des Exp $");
42
43 #include "xlocale_private.h"
44
45 /*
46 * Actual printf innards.
47 *
48 * This code is large and complicated...
49 */
50
51 #include "namespace.h"
52 #include <sys/types.h>
53
54 #include <ctype.h>
55 #include <limits.h>
56 #include <locale.h>
57 #include <stddef.h>
58 #include <stdint.h>
59 #include <stdio.h>
60 #include <stdlib.h>
61 #include <string.h>
62 #include <wchar.h>
63 #include <errno.h>
64
65 #include <stdarg.h>
66 #include "un-namespace.h"
67
68 #include "libc_private.h"
69 #include "local.h"
70 #include "fvwrite.h"
71
72 #ifdef VECTORS
73 typedef __attribute__ ((vector_size(16))) unsigned char VECTORTYPE;
74 #ifdef __SSE2__
75 #define V64TYPE
76 #endif /* __SSE2__ */
77 #endif /* VECTORS */
78
79 union arg {
80 int intarg;
81 u_int uintarg;
82 long longarg;
83 u_long ulongarg;
84 long long longlongarg;
85 unsigned long long ulonglongarg;
86 ptrdiff_t ptrdiffarg;
87 size_t sizearg;
88 intmax_t intmaxarg;
89 uintmax_t uintmaxarg;
90 void *pvoidarg;
91 char *pchararg;
92 signed char *pschararg;
93 short *pshortarg;
94 int *pintarg;
95 long *plongarg;
96 long long *plonglongarg;
97 ptrdiff_t *pptrdiffarg;
98 size_t *psizearg;
99 intmax_t *pintmaxarg;
100 #ifndef NO_FLOATING_POINT
101 double doublearg;
102 long double longdoublearg;
103 #endif
104 wint_t wintarg;
105 wchar_t *pwchararg;
106 #ifdef VECTORS
107 VECTORTYPE vectorarg;
108 unsigned char vuchararg[16];
109 signed char vchararg[16];
110 unsigned short vushortarg[8];
111 signed short vshortarg[8];
112 unsigned int vuintarg[4];
113 signed int vintarg[4];
114 float vfloatarg[4];
115 #ifdef V64TYPE
116 double vdoublearg[2];
117 unsigned long long vulonglongarg[2];
118 long long vlonglongarg[2];
119 #endif /* V64TYPE */
120 #endif /* VECTORS */
121 };
122
123 /*
124 * Type ids for argument type table.
125 */
126 enum typeid {
127 T_UNUSED, TP_SHORT, T_INT, T_U_INT, TP_INT,
128 T_LONG, T_U_LONG, TP_LONG, T_LLONG, T_U_LLONG, TP_LLONG,
129 T_PTRDIFFT, TP_PTRDIFFT, T_SIZET, TP_SIZET,
130 T_INTMAXT, T_UINTMAXT, TP_INTMAXT, TP_VOID, TP_CHAR, TP_SCHAR,
131 #ifdef VECTORS
132 T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR, T_VECTOR
133 #else /* ! VECTORS */
134 T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR
135 #endif /* VECTORS */
136 };
137
138 static int __sprint(FILE *, struct __suio *);
139 static int __sbprintf(FILE *, locale_t, const char *, va_list) __printflike(3, 0);
140 static char *__ujtoa(uintmax_t, char *, int, int, const char *, int, char,
141 const char *);
142 static char *__ultoa(u_long, char *, int, int, const char *, int, char,
143 const char *);
144 static char *__wcsconv(wchar_t *, int, locale_t);
145 static void __find_arguments(const char *, va_list, union arg **);
146 static void __grow_type_table(int, enum typeid **, int *);
147
148 /*
149 * Flush out all the vectors defined by the given uio,
150 * then reset it so that it can be reused.
151 */
152 static int
153 __sprint(FILE *fp, struct __suio *uio)
154 {
155 int err;
156
157 if (uio->uio_resid == 0) {
158 uio->uio_iovcnt = 0;
159 return (0);
160 }
161 err = __sfvwrite(fp, uio);
162 uio->uio_resid = 0;
163 uio->uio_iovcnt = 0;
164 return (err);
165 }
166
167 /*
168 * Helper function for `fprintf to unbuffered unix file': creates a
169 * temporary buffer. We only work on write-only files; this avoids
170 * worries about ungetc buffers and so forth.
171 */
172 static int
173 __sbprintf(FILE *fp, locale_t loc, const char *fmt, va_list ap)
174 {
175 int ret;
176 FILE fake;
177 unsigned char buf[BUFSIZ];
178
179 /* copy the important variables */
180 fake._flags = fp->_flags & ~__SNBF;
181 fake._file = fp->_file;
182 fake._cookie = fp->_cookie;
183 fake._write = fp->_write;
184 fake._extra = fp->_extra;
185
186 /* set up the buffer */
187 fake._bf._base = fake._p = buf;
188 fake._bf._size = fake._w = sizeof(buf);
189 fake._lbfsize = 0; /* not actually used, but Just In Case */
190
191 /* do the work, then copy any error status */
192 ret = __vfprintf(&fake, loc, fmt, ap);
193 if (ret >= 0 && __fflush(&fake))
194 ret = EOF;
195 if (fake._flags & __SERR)
196 fp->_flags |= __SERR;
197 return (ret);
198 }
199
200 /*
201 * Macros for converting digits to letters and vice versa
202 */
203 #define to_digit(c) ((c) - '0')
204 #define is_digit(c) ((unsigned)to_digit(c) <= 9)
205 #define to_char(n) ((n) + '0')
206
207 /*
208 * Convert an unsigned long to ASCII for printf purposes, returning
209 * a pointer to the first character of the string representation.
210 * Octal numbers can be forced to have a leading zero; hex numbers
211 * use the given digits.
212 */
213 static char *
214 __ultoa(u_long val, char *endp, int base, int octzero, const char *xdigs,
215 int needgrp, char thousep, const char *grp)
216 {
217 char *cp = endp;
218 long sval;
219 int ndig;
220
221 /*
222 * Handle the three cases separately, in the hope of getting
223 * better/faster code.
224 */
225 switch (base) {
226 case 10:
227 if (val < 10) { /* many numbers are 1 digit */
228 *--cp = to_char(val);
229 return (cp);
230 }
231 ndig = 0;
232 /*
233 * On many machines, unsigned arithmetic is harder than
234 * signed arithmetic, so we do at most one unsigned mod and
235 * divide; this is sufficient to reduce the range of
236 * the incoming value to where signed arithmetic works.
237 */
238 if (val > LONG_MAX) {
239 *--cp = to_char(val % 10);
240 ndig++;
241 sval = val / 10;
242 } else
243 sval = val;
244 do {
245 *--cp = to_char(sval % 10);
246 ndig++;
247 /*
248 * If (*grp == CHAR_MAX) then no more grouping
249 * should be performed.
250 */
251 if (needgrp && ndig == *grp && *grp != CHAR_MAX
252 && sval > 9) {
253 *--cp = thousep;
254 ndig = 0;
255 /*
256 * If (*(grp+1) == '\0') then we have to
257 * use *grp character (last grouping rule)
258 * for all next cases
259 */
260 if (*(grp+1) != '\0')
261 grp++;
262 }
263 sval /= 10;
264 } while (sval != 0);
265 break;
266
267 case 8:
268 do {
269 *--cp = to_char(val & 7);
270 val >>= 3;
271 } while (val);
272 if (octzero && *cp != '0')
273 *--cp = '0';
274 break;
275
276 case 16:
277 do {
278 *--cp = xdigs[val & 15];
279 val >>= 4;
280 } while (val);
281 break;
282
283 default: /* oops */
284 abort();
285 }
286 return (cp);
287 }
288
289 /* Identical to __ultoa, but for intmax_t. */
290 static char *
291 __ujtoa(uintmax_t val, char *endp, int base, int octzero, const char *xdigs,
292 int needgrp, char thousep, const char *grp)
293 {
294 char *cp = endp;
295 intmax_t sval;
296 int ndig;
297
298 /* quick test for small values; __ultoa is typically much faster */
299 /* (perhaps instead we should run until small, then call __ultoa?) */
300 if (val <= ULONG_MAX)
301 return (__ultoa((u_long)val, endp, base, octzero, xdigs,
302 needgrp, thousep, grp));
303 switch (base) {
304 case 10:
305 if (val < 10) {
306 *--cp = to_char(val % 10);
307 return (cp);
308 }
309 ndig = 0;
310 if (val > INTMAX_MAX) {
311 *--cp = to_char(val % 10);
312 ndig++;
313 sval = val / 10;
314 } else
315 sval = val;
316 do {
317 *--cp = to_char(sval % 10);
318 ndig++;
319 /*
320 * If (*grp == CHAR_MAX) then no more grouping
321 * should be performed.
322 */
323 if (needgrp && *grp != CHAR_MAX && ndig == *grp
324 && sval > 9) {
325 *--cp = thousep;
326 ndig = 0;
327 /*
328 * If (*(grp+1) == '\0') then we have to
329 * use *grp character (last grouping rule)
330 * for all next cases
331 */
332 if (*(grp+1) != '\0')
333 grp++;
334 }
335 sval /= 10;
336 } while (sval != 0);
337 break;
338
339 case 8:
340 do {
341 *--cp = to_char(val & 7);
342 val >>= 3;
343 } while (val);
344 if (octzero && *cp != '0')
345 *--cp = '0';
346 break;
347
348 case 16:
349 do {
350 *--cp = xdigs[val & 15];
351 val >>= 4;
352 } while (val);
353 break;
354
355 default:
356 abort();
357 }
358 return (cp);
359 }
360
361 /*
362 * Convert a wide character string argument for the %ls format to a multibyte
363 * string representation. ``prec'' specifies the maximum number of bytes
364 * to output. If ``prec'' is greater than or equal to zero, we can't assume
365 * that the wide char. string ends in a null character.
366 */
367 static char *
368 __wcsconv(wchar_t *wcsarg, int prec, locale_t loc)
369 {
370 static const mbstate_t initial;
371 mbstate_t mbs;
372 char buf[MB_LEN_MAX];
373 wchar_t *p;
374 char *convbuf, *mbp;
375 size_t clen = 0, nbytes;
376
377 /*
378 * Determine the number of bytes to output and allocate space for
379 * the output.
380 */
381 if (prec >= 0) {
382 nbytes = 0;
383 p = wcsarg;
384 mbs = initial;
385 for (;;) {
386 clen = wcrtomb_l(buf, *p++, &mbs, loc);
387 if (clen == 0 || clen == (size_t)-1 ||
388 nbytes + clen > prec)
389 break;
390 nbytes += clen;
391 }
392 } else {
393 p = wcsarg;
394 mbs = initial;
395 nbytes = wcsrtombs_l(NULL, (const wchar_t **)&p, 0, &mbs, loc);
396 if (nbytes == (size_t)-1)
397 return (NULL);
398 }
399 if ((convbuf = malloc(nbytes + 1)) == NULL)
400 return (NULL);
401
402 /*
403 * Fill the output buffer with the multibyte representations of as
404 * many wide characters as will fit.
405 */
406 mbp = convbuf;
407 p = wcsarg;
408 mbs = initial;
409 while (mbp - convbuf < nbytes) {
410 clen = wcrtomb_l(mbp, *p++, &mbs, loc);
411 if (clen == 0 || clen == (size_t)-1)
412 break;
413 mbp += clen;
414 }
415 if (clen == (size_t)-1) {
416 free(convbuf);
417 return (NULL);
418 }
419 *mbp = '\0';
420
421 return (convbuf);
422 }
423
424 /*
425 * MT-safe version
426 */
427 __private_extern__ const char *__fix_nogrouping(const char *);
428
429 int
430 vfprintf(FILE * __restrict fp, const char * __restrict fmt0, va_list ap)
431
432 {
433 int ret;
434
435 FLOCKFILE(fp);
436 ret = __vfprintf(fp, __current_locale(), fmt0, ap);
437 FUNLOCKFILE(fp);
438 return (ret);
439 }
440
441 int
442 vfprintf_l(FILE * __restrict fp, locale_t loc, const char * __restrict fmt0,
443 va_list ap)
444
445 {
446 int ret;
447
448 NORMALIZE_LOCALE(loc);
449 FLOCKFILE(fp);
450 ret = __vfprintf(fp, loc, fmt0, ap);
451 FUNLOCKFILE(fp);
452 return (ret);
453 }
454
455 #ifndef NO_FLOATING_POINT
456
457 #define dtoa __dtoa
458 #define freedtoa __freedtoa
459
460 #include <float.h>
461 #include <math.h>
462 #include "floatio.h"
463 #include "gdtoa.h"
464
465 #define DEFPREC 6
466
467 static int exponent(char *, int, int);
468
469 #endif /* !NO_FLOATING_POINT */
470
471 /*
472 * The size of the buffer we use as scratch space for integer
473 * conversions, among other things. Technically, we would need the
474 * most space for base 10 conversions with thousands' grouping
475 * characters between each pair of digits. 100 bytes is a
476 * conservative overestimate even for a 128-bit uintmax_t.
477 */
478 #define BUF 100
479
480 #define STATIC_ARG_TBL_SIZE 8 /* Size of static argument table. */
481
482 /*
483 * Flags used during conversion.
484 */
485 #define ALT 0x001 /* alternate form */
486 #define LADJUST 0x004 /* left adjustment */
487 #define LONGDBL 0x008 /* long double */
488 #define LONGINT 0x010 /* long integer */
489 #define LLONGINT 0x020 /* long long integer */
490 #define SHORTINT 0x040 /* short integer */
491 #define ZEROPAD 0x080 /* zero (as opposed to blank) pad */
492 #define FPT 0x100 /* Floating point number */
493 #define GROUPING 0x200 /* use grouping ("'" flag) */
494 /* C99 additional size modifiers: */
495 #define SIZET 0x400 /* size_t */
496 #define PTRDIFFT 0x800 /* ptrdiff_t */
497 #define INTMAXT 0x1000 /* intmax_t */
498 #define CHARINT 0x2000 /* print char using int format */
499 #ifdef VECTORS
500 #define VECTOR 0x4000 /* Altivec or SSE vector */
501 #endif /* VECTORS */
502
503 /*
504 * Non-MT-safe version
505 */
506 __private_extern__ int
507 __vfprintf(FILE *fp, locale_t loc, const char *fmt0, va_list ap)
508 {
509 char *fmt; /* format string */
510 int ch; /* character from fmt */
511 int n, n2; /* handy integer (short term usage) */
512 char *cp; /* handy char pointer (short term usage) */
513 struct __siov *iovp; /* for PRINT macro */
514 int flags; /* flags as above */
515 int ret; /* return value accumulator */
516 int width; /* width from format (%8d), or 0 */
517 int prec; /* precision from format; <0 for N/A */
518 char sign; /* sign prefix (' ', '+', '-', or \0) */
519 char thousands_sep; /* locale specific thousands separator */
520 const char *grouping; /* locale specific numeric grouping rules */
521 #ifndef NO_FLOATING_POINT
522 /*
523 * We can decompose the printed representation of floating
524 * point numbers into several parts, some of which may be empty:
525 *
526 * [+|-| ] [0x|0X] MMM . NNN [e|E|p|P] [+|-] ZZ
527 * A B ---C--- D E F
528 *
529 * A: 'sign' holds this value if present; '\0' otherwise
530 * B: ox[1] holds the 'x' or 'X'; '\0' if not hexadecimal
531 * C: cp points to the string MMMNNN. Leading and trailing
532 * zeros are not in the string and must be added.
533 * D: expchar holds this character; '\0' if no exponent, e.g. %f
534 * F: at least two digits for decimal, at least one digit for hex
535 */
536 char *decimal_point; /* locale specific decimal point */
537 int signflag; /* true if float is negative */
538 union { /* floating point arguments %[aAeEfFgG] */
539 double dbl;
540 long double ldbl;
541 } fparg;
542 int expt; /* integer value of exponent */
543 char expchar; /* exponent character: [eEpP\0] */
544 char *dtoaend; /* pointer to end of converted digits */
545 int expsize; /* character count for expstr */
546 int lead; /* sig figs before decimal or group sep */
547 int ndig; /* actual number of digits returned by dtoa */
548 char expstr[MAXEXPDIG+2]; /* buffer for exponent string: e+ZZZ */
549 char *dtoaresult; /* buffer allocated by dtoa */
550 int nseps; /* number of group separators with ' */
551 int nrepeats; /* number of repeats of the last group */
552 #endif
553 #ifdef VECTORS
554 union arg vval; /* Vector argument. */
555 char *pct; /* Pointer to '%' at beginning of specifier. */
556 char vsep; /* Vector separator character. */
557 #endif
558 u_long ulval; /* integer arguments %[diouxX] */
559 uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */
560 int base; /* base for [diouxX] conversion */
561 int dprec; /* a copy of prec if [diouxX], 0 otherwise */
562 int realsz; /* field size expanded by dprec, sign, etc */
563 int size; /* size of converted field or string */
564 int prsize; /* max size of printed field */
565 const char *xdigs; /* digits for %[xX] conversion */
566 #define NIOV 8
567 struct __suio uio; /* output information: summary */
568 struct __siov iov[NIOV];/* ... and individual io vectors */
569 char buf[BUF]; /* buffer with space for digits of uintmax_t */
570 char ox[2]; /* space for 0x; ox[1] is either x, X, or \0 */
571 union arg *argtable; /* args, built due to positional arg */
572 union arg statargtable [STATIC_ARG_TBL_SIZE];
573 int nextarg; /* 1-based argument index */
574 va_list orgap; /* original argument pointer */
575 char *convbuf; /* wide to multibyte conversion result */
576
577 /*
578 * Choose PADSIZE to trade efficiency vs. size. If larger printf
579 * fields occur frequently, increase PADSIZE and make the initialisers
580 * below longer.
581 */
582 #define PADSIZE 16 /* pad chunk size */
583 static char blanks[PADSIZE] =
584 {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
585 static char zeroes[PADSIZE] =
586 {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
587
588 static const char xdigs_lower[16] = "0123456789abcdef";
589 static const char xdigs_upper[16] = "0123456789ABCDEF";
590
591 /*
592 * BEWARE, these `goto error' on error, and PAD uses `n'.
593 */
594 #define PRINT(ptr, len) { \
595 iovp->iov_base = (ptr); \
596 iovp->iov_len = (len); \
597 uio.uio_resid += (len); \
598 iovp++; \
599 if (++uio.uio_iovcnt >= NIOV) { \
600 if (__sprint(fp, &uio)) \
601 goto error; \
602 iovp = iov; \
603 } \
604 }
605 #define PAD(howmany, with) { \
606 if ((n = (howmany)) > 0) { \
607 while (n > PADSIZE) { \
608 PRINT(with, PADSIZE); \
609 n -= PADSIZE; \
610 } \
611 PRINT(with, n); \
612 } \
613 }
614 #define PRINTANDPAD(p, ep, len, with) do { \
615 n2 = (ep) - (p); \
616 if (n2 > (len)) \
617 n2 = (len); \
618 if (n2 > 0) \
619 PRINT((p), n2); \
620 PAD((len) - (n2 > 0 ? n2 : 0), (with)); \
621 } while(0)
622 #define FLUSH() { \
623 if (uio.uio_resid && __sprint(fp, &uio)) \
624 goto error; \
625 uio.uio_iovcnt = 0; \
626 iovp = iov; \
627 }
628
629 /*
630 * Get the argument indexed by nextarg. If the argument table is
631 * built, use it to get the argument. If its not, get the next
632 * argument (and arguments must be gotten sequentially).
633 */
634 #define GETARG(type) \
635 ((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : \
636 (nextarg++, va_arg(ap, type)))
637
638 /*
639 * To extend shorts properly, we need both signed and unsigned
640 * argument extraction methods.
641 */
642 #define SARG() \
643 (flags&LONGINT ? GETARG(long) : \
644 flags&SHORTINT ? (long)(short)GETARG(int) : \
645 flags&CHARINT ? (long)(signed char)GETARG(int) : \
646 (long)GETARG(int))
647 #define UARG() \
648 (flags&LONGINT ? GETARG(u_long) : \
649 flags&SHORTINT ? (u_long)(u_short)GETARG(int) : \
650 flags&CHARINT ? (u_long)(u_char)GETARG(int) : \
651 (u_long)GETARG(u_int))
652 #define INTMAX_SIZE (INTMAXT|SIZET|PTRDIFFT|LLONGINT)
653 #define SJARG() \
654 (flags&INTMAXT ? GETARG(intmax_t) : \
655 flags&SIZET ? (intmax_t)GETARG(ssize_t) : \
656 flags&PTRDIFFT ? (intmax_t)GETARG(ptrdiff_t) : \
657 (intmax_t)GETARG(long long))
658 #define UJARG() \
659 (flags&INTMAXT ? GETARG(uintmax_t) : \
660 flags&SIZET ? (uintmax_t)GETARG(size_t) : \
661 flags&PTRDIFFT ? (uintmax_t)GETARG(ptrdiff_t) : \
662 (uintmax_t)GETARG(unsigned long long))
663
664 /*
665 * Get * arguments, including the form *nn$. Preserve the nextarg
666 * that the argument can be gotten once the type is determined.
667 */
668 #define GETASTER(val) \
669 n2 = 0; \
670 cp = fmt; \
671 while (is_digit(*cp)) { \
672 n2 = 10 * n2 + to_digit(*cp); \
673 cp++; \
674 } \
675 if (*cp == '$') { \
676 int hold = nextarg; \
677 if (argtable == NULL) { \
678 argtable = statargtable; \
679 __find_arguments (fmt0, orgap, &argtable); \
680 } \
681 nextarg = n2; \
682 val = GETARG (int); \
683 nextarg = hold; \
684 fmt = ++cp; \
685 } else { \
686 val = GETARG (int); \
687 }
688
689 thousands_sep = '\0';
690 grouping = NULL;
691 convbuf = NULL;
692 #ifndef NO_FLOATING_POINT
693 dtoaresult = NULL;
694 decimal_point = localeconv_l(loc)->decimal_point;
695 #endif
696 /* sorry, fprintf(read_only_file, "") returns EOF, not 0 */
697 if (prepwrite(fp) != 0) {
698 errno = EBADF;
699 return (EOF);
700 }
701 ORIENT(fp, -1);
702
703 /* optimise fprintf(stderr) (and other unbuffered Unix files) */
704 if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
705 fp->_file >= 0)
706 return (__sbprintf(fp, loc, fmt0, ap));
707
708 fmt = (char *)fmt0;
709 argtable = NULL;
710 nextarg = 1;
711 va_copy(orgap, ap);
712 uio.uio_iov = iovp = iov;
713 uio.uio_resid = 0;
714 uio.uio_iovcnt = 0;
715 ret = 0;
716
717 /*
718 * Scan the format for conversions (`%' character).
719 */
720 for (;;) {
721 for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)
722 /* void */;
723 if ((n = fmt - cp) != 0) {
724 if ((unsigned)ret + n > INT_MAX) {
725 ret = EOF;
726 goto error;
727 }
728 PRINT(cp, n);
729 ret += n;
730 }
731 if (ch == '\0')
732 goto done;
733 #ifdef VECTORS
734 pct = fmt;
735 #endif /* VECTORS */
736 fmt++; /* skip over '%' */
737
738 flags = 0;
739 dprec = 0;
740 width = 0;
741 prec = -1;
742 sign = '\0';
743 ox[1] = '\0';
744 #ifdef VECTORS
745 vsep = 'X'; /* Illegal value, changed to defaults later. */
746 #endif /* VECTORS */
747
748 rflag: ch = *fmt++;
749 reswitch: switch (ch) {
750 case ' ':
751 /*-
752 * ``If the space and + flags both appear, the space
753 * flag will be ignored.''
754 * -- ANSI X3J11
755 */
756 if (!sign)
757 sign = ' ';
758 goto rflag;
759 case '#':
760 flags |= ALT;
761 goto rflag;
762 #ifdef VECTORS
763 case ',': case ';': case ':': case '_':
764 vsep = ch;
765 goto rflag;
766 #endif /* VECTORS */
767 case '*':
768 /*-
769 * ``A negative field width argument is taken as a
770 * - flag followed by a positive field width.''
771 * -- ANSI X3J11
772 * They don't exclude field widths read from args.
773 */
774 GETASTER (width);
775 if (width >= 0)
776 goto rflag;
777 width = -width;
778 /* FALLTHROUGH */
779 case '-':
780 flags |= LADJUST;
781 goto rflag;
782 case '+':
783 sign = '+';
784 goto rflag;
785 case '\'':
786 flags |= GROUPING;
787 thousands_sep = *(localeconv_l(loc)->thousands_sep);
788 grouping = __fix_nogrouping(localeconv_l(loc)->grouping);
789 goto rflag;
790 case '.':
791 if ((ch = *fmt++) == '*') {
792 GETASTER (prec);
793 goto rflag;
794 }
795 prec = 0;
796 while (is_digit(ch)) {
797 prec = 10 * prec + to_digit(ch);
798 ch = *fmt++;
799 }
800 goto reswitch;
801 case '0':
802 /*-
803 * ``Note that 0 is taken as a flag, not as the
804 * beginning of a field width.''
805 * -- ANSI X3J11
806 */
807 flags |= ZEROPAD;
808 goto rflag;
809 case '1': case '2': case '3': case '4':
810 case '5': case '6': case '7': case '8': case '9':
811 n = 0;
812 do {
813 n = 10 * n + to_digit(ch);
814 ch = *fmt++;
815 } while (is_digit(ch));
816 if (ch == '$') {
817 nextarg = n;
818 if (argtable == NULL) {
819 argtable = statargtable;
820 __find_arguments (fmt0, orgap,
821 &argtable);
822 }
823 goto rflag;
824 }
825 width = n;
826 goto reswitch;
827 #ifndef NO_FLOATING_POINT
828 case 'L':
829 flags |= LONGDBL;
830 goto rflag;
831 #endif
832 case 'h':
833 if (flags & SHORTINT) {
834 flags &= ~SHORTINT;
835 flags |= CHARINT;
836 } else
837 flags |= SHORTINT;
838 goto rflag;
839 case 'j':
840 flags |= INTMAXT;
841 goto rflag;
842 case 'l':
843 if (flags & LONGINT) {
844 flags &= ~LONGINT;
845 flags |= LLONGINT;
846 } else
847 flags |= LONGINT;
848 goto rflag;
849 case 'q':
850 flags |= LLONGINT; /* not necessarily */
851 goto rflag;
852 case 't':
853 flags |= PTRDIFFT;
854 goto rflag;
855 case 'z':
856 flags |= SIZET;
857 goto rflag;
858 case 'C':
859 flags |= LONGINT;
860 /*FALLTHROUGH*/
861 case 'c':
862 #ifdef VECTORS
863 if (flags & VECTOR)
864 break;
865 #endif /* VECTORS */
866 if (flags & LONGINT) {
867 static const mbstate_t initial;
868 mbstate_t mbs;
869 size_t mbseqlen;
870
871 mbs = initial;
872 mbseqlen = wcrtomb_l(cp = buf,
873 (wchar_t)GETARG(wint_t), &mbs, loc);
874 if (mbseqlen == (size_t)-1) {
875 fp->_flags |= __SERR;
876 goto error;
877 }
878 size = (int)mbseqlen;
879 } else {
880 *(cp = buf) = GETARG(int);
881 size = 1;
882 }
883 sign = '\0';
884 break;
885 case 'D':
886 flags |= LONGINT;
887 /*FALLTHROUGH*/
888 case 'd':
889 case 'i':
890 #ifdef VECTORS
891 if (flags & VECTOR)
892 break;
893 #endif /* VECTORS */
894 if (flags & INTMAX_SIZE) {
895 ujval = SJARG();
896 if ((intmax_t)ujval < 0) {
897 ujval = -ujval;
898 sign = '-';
899 }
900 } else {
901 ulval = SARG();
902 if ((long)ulval < 0) {
903 ulval = -ulval;
904 sign = '-';
905 }
906 }
907 base = 10;
908 goto number;
909 #ifndef NO_FLOATING_POINT
910 case 'a':
911 case 'A':
912 #ifdef VECTORS
913 if (flags & VECTOR) {
914 flags |= FPT;
915 break;
916 }
917 #endif /* VECTORS */
918 if (ch == 'a') {
919 ox[1] = 'x';
920 xdigs = xdigs_lower;
921 expchar = 'p';
922 } else {
923 ox[1] = 'X';
924 xdigs = xdigs_upper;
925 expchar = 'P';
926 }
927 if (prec >= 0)
928 prec++;
929 if (dtoaresult != NULL)
930 freedtoa(dtoaresult);
931 #ifdef LDBL_COMPAT
932 fparg.dbl = GETARG(double);
933 dtoaresult = cp =
934 __hdtoa(fparg.dbl, xdigs, prec,
935 &expt, &signflag, &dtoaend);
936 #else /* !LDBL_COMPAT */
937 if (flags & LONGDBL) {
938 fparg.ldbl = GETARG(long double);
939 dtoaresult = cp =
940 __hldtoa(fparg.ldbl, xdigs, prec,
941 &expt, &signflag, &dtoaend);
942 } else {
943 fparg.dbl = GETARG(double);
944 dtoaresult = cp =
945 __hdtoa(fparg.dbl, xdigs, prec,
946 &expt, &signflag, &dtoaend);
947 }
948 #endif /* LDBL_COMPAT */
949 if (prec < 0)
950 prec = dtoaend - cp;
951 if (expt == INT_MAX)
952 ox[1] = '\0';
953 goto fp_common;
954 case 'e':
955 case 'E':
956 #ifdef VECTORS
957 if (flags & VECTOR) {
958 flags |= FPT;
959 break;
960 }
961 #endif /* VECTORS */
962 expchar = ch;
963 if (prec < 0) /* account for digit before decpt */
964 prec = DEFPREC + 1;
965 else
966 prec++;
967 goto fp_begin;
968 case 'f':
969 case 'F':
970 #ifdef VECTORS
971 if (flags & VECTOR) {
972 flags |= FPT;
973 break;
974 }
975 #endif /* VECTORS */
976 expchar = '\0';
977 goto fp_begin;
978 case 'g':
979 case 'G':
980 #ifdef VECTORS
981 if (flags & VECTOR) {
982 flags |= FPT;
983 break;
984 }
985 #endif /* VECTORS */
986 expchar = ch - ('g' - 'e');
987 if (prec == 0)
988 prec = 1;
989 fp_begin:
990 if (prec < 0)
991 prec = DEFPREC;
992 if (dtoaresult != NULL)
993 freedtoa(dtoaresult);
994 #ifdef LDBL_COMPAT
995 fparg.dbl = GETARG(double);
996 dtoaresult = cp =
997 dtoa(fparg.dbl, expchar ? 2 : 3, prec,
998 &expt, &signflag, &dtoaend);
999 if (expt == 9999)
1000 expt = INT_MAX;
1001 #else /* !LDBL_COMPAT */
1002 if (flags & LONGDBL) {
1003 fparg.ldbl = GETARG(long double);
1004 dtoaresult = cp =
1005 __ldtoa(&fparg.ldbl, expchar ? 2 : 3, prec,
1006 &expt, &signflag, &dtoaend);
1007 } else {
1008 fparg.dbl = GETARG(double);
1009 dtoaresult = cp =
1010 dtoa(fparg.dbl, expchar ? 2 : 3, prec,
1011 &expt, &signflag, &dtoaend);
1012 if (expt == 9999)
1013 expt = INT_MAX;
1014 }
1015 #endif /* LDBL_COMPAT */
1016 fp_common:
1017 if (signflag)
1018 sign = '-';
1019 if (expt == INT_MAX) { /* inf or nan */
1020 if (*cp == 'N') {
1021 cp = (ch >= 'a') ? "nan" : "NAN";
1022 sign = '\0';
1023 } else
1024 cp = (ch >= 'a') ? "inf" : "INF";
1025 size = 3;
1026 break;
1027 }
1028 flags |= FPT;
1029 ndig = dtoaend - cp;
1030 if (ch == 'g' || ch == 'G') {
1031 if (expt > -4 && expt <= prec) {
1032 /* Make %[gG] smell like %[fF] */
1033 expchar = '\0';
1034 if (flags & ALT)
1035 prec -= expt;
1036 else
1037 prec = ndig - expt;
1038 if (prec < 0)
1039 prec = 0;
1040 } else {
1041 /*
1042 * Make %[gG] smell like %[eE], but
1043 * trim trailing zeroes if no # flag.
1044 */
1045 if (!(flags & ALT))
1046 prec = ndig;
1047 }
1048 }
1049 if (expchar) {
1050 expsize = exponent(expstr, expt - 1, expchar);
1051 size = expsize + prec;
1052 if (prec > 1 || flags & ALT)
1053 ++size;
1054 } else {
1055 /* space for digits before decimal point */
1056 if (expt > 0)
1057 size = expt;
1058 else /* "0" */
1059 size = 1;
1060 /* space for decimal pt and following digits */
1061 if (prec || flags & ALT)
1062 size += prec + 1;
1063 if (grouping && expt > 0) {
1064 /* space for thousands' grouping */
1065 nseps = nrepeats = 0;
1066 lead = expt;
1067 while (*grouping != CHAR_MAX) {
1068 if (lead <= *grouping)
1069 break;
1070 lead -= *grouping;
1071 if (*(grouping+1)) {
1072 nseps++;
1073 grouping++;
1074 } else
1075 nrepeats++;
1076 }
1077 size += nseps + nrepeats;
1078 } else
1079 lead = expt;
1080 }
1081 break;
1082 #endif /* !NO_FLOATING_POINT */
1083 case 'n':
1084 /*
1085 * Assignment-like behavior is specified if the
1086 * value overflows or is otherwise unrepresentable.
1087 * C99 says to use `signed char' for %hhn conversions.
1088 */
1089 if (flags & LLONGINT)
1090 *GETARG(long long *) = ret;
1091 else if (flags & SIZET)
1092 *GETARG(ssize_t *) = (ssize_t)ret;
1093 else if (flags & PTRDIFFT)
1094 *GETARG(ptrdiff_t *) = ret;
1095 else if (flags & INTMAXT)
1096 *GETARG(intmax_t *) = ret;
1097 else if (flags & LONGINT)
1098 *GETARG(long *) = ret;
1099 else if (flags & SHORTINT)
1100 *GETARG(short *) = ret;
1101 else if (flags & CHARINT)
1102 *GETARG(signed char *) = ret;
1103 else
1104 *GETARG(int *) = ret;
1105 continue; /* no output */
1106 case 'O':
1107 flags |= LONGINT;
1108 /*FALLTHROUGH*/
1109 case 'o':
1110 #ifdef VECTORS
1111 if (flags & VECTOR)
1112 break;
1113 #endif /* VECTORS */
1114 if (flags & INTMAX_SIZE)
1115 ujval = UJARG();
1116 else
1117 ulval = UARG();
1118 base = 8;
1119 goto nosign;
1120 case 'p':
1121 /*-
1122 * ``The argument shall be a pointer to void. The
1123 * value of the pointer is converted to a sequence
1124 * of printable characters, in an implementation-
1125 * defined manner.''
1126 * -- ANSI X3J11
1127 */
1128 #ifdef VECTORS
1129 if (flags & VECTOR)
1130 break;
1131 #endif /* VECTORS */
1132 ujval = (uintmax_t)(uintptr_t)GETARG(void *);
1133 base = 16;
1134 xdigs = xdigs_lower;
1135 flags = flags | INTMAXT;
1136 ox[1] = 'x';
1137 goto nosign;
1138 case 'S':
1139 flags |= LONGINT;
1140 /*FALLTHROUGH*/
1141 case 's':
1142 if (flags & LONGINT) {
1143 wchar_t *wcp;
1144
1145 if (convbuf != NULL)
1146 free(convbuf);
1147 if ((wcp = GETARG(wchar_t *)) == NULL)
1148 cp = "(null)";
1149 else {
1150 convbuf = __wcsconv(wcp, prec, loc);
1151 if (convbuf == NULL) {
1152 fp->_flags |= __SERR;
1153 goto error;
1154 }
1155 cp = convbuf;
1156 }
1157 } else if ((cp = GETARG(char *)) == NULL)
1158 cp = "(null)";
1159 if (prec >= 0) {
1160 /*
1161 * can't use strlen; can only look for the
1162 * NUL in the first `prec' characters, and
1163 * strlen() will go further.
1164 */
1165 char *p = memchr(cp, 0, (size_t)prec);
1166
1167 if (p != NULL) {
1168 size = p - cp;
1169 if (size > prec)
1170 size = prec;
1171 } else
1172 size = prec;
1173 } else
1174 size = strlen(cp);
1175 sign = '\0';
1176 break;
1177 case 'U':
1178 flags |= LONGINT;
1179 /*FALLTHROUGH*/
1180 case 'u':
1181 #ifdef VECTORS
1182 if (flags & VECTOR)
1183 break;
1184 #endif /* VECTORS */
1185 if (flags & INTMAX_SIZE)
1186 ujval = UJARG();
1187 else
1188 ulval = UARG();
1189 base = 10;
1190 goto nosign;
1191 case 'X':
1192 xdigs = xdigs_upper;
1193 goto hex;
1194 case 'x':
1195 xdigs = xdigs_lower;
1196 hex:
1197 #ifdef VECTORS
1198 if (flags & VECTOR)
1199 break;
1200 #endif /* VECTORS */
1201 if (flags & INTMAX_SIZE)
1202 ujval = UJARG();
1203 else
1204 ulval = UARG();
1205 base = 16;
1206 /* leading 0x/X only if non-zero */
1207 if (flags & ALT &&
1208 (flags & INTMAX_SIZE ? ujval != 0 : ulval != 0))
1209 ox[1] = ch;
1210
1211 flags &= ~GROUPING;
1212 /* unsigned conversions */
1213 nosign: sign = '\0';
1214 /*-
1215 * ``... diouXx conversions ... if a precision is
1216 * specified, the 0 flag will be ignored.''
1217 * -- ANSI X3J11
1218 */
1219 number: if ((dprec = prec) >= 0)
1220 flags &= ~ZEROPAD;
1221
1222 /*-
1223 * ``The result of converting a zero value with an
1224 * explicit precision of zero is no characters.''
1225 * -- ANSI X3J11
1226 * except for %#.0o and zero value
1227 */
1228 cp = buf + BUF;
1229 if (flags & INTMAX_SIZE) {
1230 if (ujval != 0 || prec != 0)
1231 cp = __ujtoa(ujval, cp, base,
1232 flags & ALT, xdigs,
1233 flags & GROUPING, thousands_sep,
1234 grouping);
1235 } else {
1236 if (ulval != 0 || prec != 0 || (flags & ALT))
1237 cp = __ultoa(ulval, cp, base,
1238 flags & ALT, xdigs,
1239 flags & GROUPING, thousands_sep,
1240 grouping);
1241 }
1242 size = buf + BUF - cp;
1243 if (size > BUF) /* should never happen */
1244 abort();
1245 break;
1246 #ifdef VECTORS
1247 case 'v':
1248 flags |= VECTOR;
1249 goto rflag;
1250 #endif /* VECTORS */
1251 default: /* "%?" prints ?, unless ? is NUL */
1252 if (ch == '\0')
1253 goto done;
1254 /* pretend it was %c with argument ch */
1255 cp = buf;
1256 *cp = ch;
1257 size = 1;
1258 sign = '\0';
1259 break;
1260 }
1261
1262 #ifdef VECTORS
1263 if (flags & VECTOR) {
1264 /*
1265 * Do the minimum amount of work necessary to construct
1266 * a format specifier that can be used to recursively
1267 * call vfprintf() for each element in the vector.
1268 */
1269 int i, j; /* Counter. */
1270 int vcnt; /* Number of elements in vector. */
1271 char *vfmt; /* Pointer to format specifier. */
1272 #define EXTRAHH 2
1273 char vfmt_buf[32 + EXTRAHH]; /* Static buffer for format spec. */
1274 int vwidth = 0; /* Width specified via '*'. */
1275 int vprec = 0; /* Precision specified via '*'. */
1276 char *vstr; /* Used for asprintf(). */
1277 int vlen; /* Length returned by asprintf(). */
1278 enum {
1279 V_CHAR, V_SHORT, V_INT,
1280 V_PCHAR, V_PSHORT, V_PINT,
1281 V_FLOAT,
1282 #ifdef V64TYPE
1283 V_LONGLONG, V_PLONGLONG,
1284 V_DOUBLE,
1285 #endif /* V64TYPE */
1286 } vtype;
1287
1288 vval.vectorarg = GETARG(VECTORTYPE);
1289 /*
1290 * Set vfmt. If vfmt_buf may not be big enough,
1291 * malloc() space, taking care to free it later.
1292 * (EXTRAHH is for possible extra "hh")
1293 */
1294 if (&fmt[-1] - pct + EXTRAHH < sizeof(vfmt_buf))
1295 vfmt = vfmt_buf;
1296 else
1297 vfmt = (char *)malloc(&fmt[-1] - pct + EXTRAHH + 1);
1298
1299 /* Set the separator character, if not specified. */
1300 if (vsep == 'X') {
1301 if (ch == 'c')
1302 vsep = '\0';
1303 else
1304 vsep = ' ';
1305 }
1306
1307 /* Create the format specifier. */
1308 for (i = j = 0; i < &fmt[-1] - pct; i++) {
1309 switch (pct[i]) {
1310 case ',': case ';': case ':': case '_':
1311 case 'v': case 'h': case 'l':
1312 /* Ignore. */
1313 break;
1314 case '*':
1315 if (pct[i - 1] != '.')
1316 vwidth = 1;
1317 else
1318 vprec = 1;
1319 /* FALLTHROUGH */
1320 default:
1321 vfmt[j++] = pct[i];
1322 }
1323 }
1324
1325 /*
1326 * Determine the number of elements in the vector and
1327 * finish up the format specifier.
1328 */
1329 if (flags & SHORTINT) {
1330 switch (ch) {
1331 case 'c':
1332 vtype = V_SHORT;
1333 break;
1334 case 'p':
1335 vtype = V_PSHORT;
1336 break;
1337 default:
1338 vfmt[j++] = 'h';
1339 vtype = V_SHORT;
1340 break;
1341 }
1342 vcnt = 8;
1343 } else if (flags & LONGINT) {
1344 vcnt = 4;
1345 vtype = (ch == 'p') ? V_PINT : V_INT;
1346 #ifdef V64TYPE
1347 } else if (flags & LLONGINT) {
1348 switch (ch) {
1349 case 'a':
1350 case 'A':
1351 case 'e':
1352 case 'E':
1353 case 'f':
1354 case 'g':
1355 case 'G':
1356 vcnt = 2;
1357 vtype = V_DOUBLE;
1358 break;
1359 case 'd':
1360 case 'i':
1361 case 'u':
1362 case 'o':
1363 case 'p':
1364 case 'x':
1365 case 'X':
1366 vfmt[j++] = 'l';
1367 vfmt[j++] = 'l';
1368 vcnt = 2;
1369 vtype = (ch == 'p') ? V_PLONGLONG : V_LONGLONG;
1370 break;
1371 default:
1372 /*
1373 * The default case should never
1374 * happen.
1375 */
1376 case 'c':
1377 vcnt = 16;
1378 vtype = V_CHAR;
1379 }
1380 #endif /* V64TYPE */
1381 } else {
1382 switch (ch) {
1383 case 'a':
1384 case 'A':
1385 case 'e':
1386 case 'E':
1387 case 'f':
1388 case 'g':
1389 case 'G':
1390 vcnt = 4;
1391 vtype = V_FLOAT;
1392 break;
1393 default:
1394 /*
1395 * The default case should never
1396 * happen.
1397 */
1398 case 'd':
1399 case 'i':
1400 case 'u':
1401 case 'o':
1402 case 'x':
1403 case 'X':
1404 vfmt[j++] = 'h';
1405 vfmt[j++] = 'h';
1406 /* drop through */
1407 case 'p':
1408 case 'c':
1409 vcnt = 16;
1410 vtype = (ch == 'p') ? V_PCHAR : V_CHAR;
1411 }
1412 }
1413 vfmt[j++] = ch;
1414 vfmt[j++] = '\0';
1415
1416 /* Get a vector element. */
1417 #ifdef V64TYPE
1418 #define VPRINT(type, ind, args...) do { \
1419 switch (type) { \
1420 case V_CHAR: \
1421 vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vuchararg[ind]); \
1422 break; \
1423 case V_PCHAR: \
1424 vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vuchararg[ind]); \
1425 break; \
1426 case V_SHORT: \
1427 vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vushortarg[ind]); \
1428 break; \
1429 case V_PSHORT: \
1430 vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vushortarg[ind]); \
1431 break; \
1432 case V_INT: \
1433 vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vuintarg[ind]); \
1434 break; \
1435 case V_PINT: \
1436 vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vuintarg[ind]); \
1437 break; \
1438 case V_LONGLONG: \
1439 vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vulonglongarg[ind]); \
1440 break; \
1441 case V_PLONGLONG: \
1442 vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vulonglongarg[ind]); \
1443 break; \
1444 case V_FLOAT: \
1445 vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vfloatarg[ind]); \
1446 break; \
1447 case V_DOUBLE: \
1448 vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vdoublearg[ind]); \
1449 break; \
1450 } \
1451 ret += vlen; \
1452 PRINT(vstr, vlen); \
1453 FLUSH(); \
1454 free(vstr); \
1455 } while (0)
1456 #else /* !V64TYPE */
1457 #define VPRINT(type, ind, args...) do { \
1458 switch (type) { \
1459 case V_CHAR: \
1460 vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vuchararg[ind]); \
1461 break; \
1462 case V_PCHAR: \
1463 vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vuchararg[ind]); \
1464 break; \
1465 case V_SHORT: \
1466 vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vushortarg[ind]); \
1467 break; \
1468 case V_PSHORT: \
1469 vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vushortarg[ind]); \
1470 break; \
1471 case V_INT: \
1472 vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vuintarg[ind]); \
1473 break; \
1474 case V_PINT: \
1475 vlen = asprintf_l(&vstr, loc, vfmt , ## args, (void *)(long)vval.vuintarg[ind]); \
1476 break; \
1477 case V_FLOAT: \
1478 vlen = asprintf_l(&vstr, loc, vfmt , ## args, vval.vfloatarg[ind]); \
1479 break; \
1480 } \
1481 ret += vlen; \
1482 PRINT(vstr, vlen); \
1483 FLUSH(); \
1484 free(vstr); \
1485 } while (0)
1486 #endif /* V64TYPE */
1487
1488 /* Actually print. */
1489 if (vwidth == 0) {
1490 if (vprec == 0) {
1491 /* First element. */
1492 VPRINT(vtype, 0);
1493 for (i = 1; i < vcnt; i++) {
1494 /* Separator. */
1495 if(vsep)
1496 PRINT(&vsep, 1);
1497
1498 /* Element. */
1499 VPRINT(vtype, i);
1500 }
1501 } else {
1502 /* First element. */
1503 VPRINT(vtype, 0, prec);
1504 for (i = 1; i < vcnt; i++) {
1505 /* Separator. */
1506 if(vsep)
1507 PRINT(&vsep, 1);
1508
1509 /* Element. */
1510 VPRINT(vtype, i, prec);
1511 }
1512 }
1513 } else {
1514 if (vprec == 0) {
1515 /* First element. */
1516 VPRINT(vtype, 0, width);
1517 for (i = 1; i < vcnt; i++) {
1518 /* Separator. */
1519 if(vsep)
1520 PRINT(&vsep, 1);
1521
1522 /* Element. */
1523 VPRINT(vtype, i, width);
1524 }
1525 } else {
1526 /* First element. */
1527 VPRINT(vtype, 0, width, prec);
1528 for (i = 1; i < vcnt; i++) {
1529 /* Separator. */
1530 if(vsep)
1531 PRINT(&vsep, 1);
1532
1533 /* Element. */
1534 VPRINT(vtype, i, width, prec);
1535 }
1536 }
1537 }
1538 #undef VPRINT
1539
1540 if (vfmt != vfmt_buf)
1541 free(vfmt);
1542
1543 continue;
1544 }
1545 #endif /* VECTORS */
1546 /*
1547 * All reasonable formats wind up here. At this point, `cp'
1548 * points to a string which (if not flags&LADJUST) should be
1549 * padded out to `width' places. If flags&ZEROPAD, it should
1550 * first be prefixed by any sign or other prefix; otherwise,
1551 * it should be blank padded before the prefix is emitted.
1552 * After any left-hand padding and prefixing, emit zeroes
1553 * required by a decimal [diouxX] precision, then print the
1554 * string proper, then emit zeroes required by any leftover
1555 * floating precision; finally, if LADJUST, pad with blanks.
1556 *
1557 * Compute actual size, so we know how much to pad.
1558 * size excludes decimal prec; realsz includes it.
1559 */
1560 realsz = dprec > size ? dprec : size;
1561 if (sign)
1562 realsz++;
1563 if (ox[1])
1564 realsz += 2;
1565
1566 prsize = width > realsz ? width : realsz;
1567 if ((unsigned)ret + prsize > INT_MAX) {
1568 ret = EOF;
1569 goto error;
1570 }
1571
1572 /* right-adjusting blank padding */
1573 if ((flags & (LADJUST|ZEROPAD)) == 0)
1574 PAD(width - realsz, blanks);
1575
1576 /* prefix */
1577 if (sign)
1578 PRINT(&sign, 1);
1579
1580 if (ox[1]) { /* ox[1] is either x, X, or \0 */
1581 ox[0] = '0';
1582 PRINT(ox, 2);
1583 }
1584
1585 /* right-adjusting zero padding */
1586 if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)
1587 PAD(width - realsz, zeroes);
1588
1589 /* leading zeroes from decimal precision */
1590 PAD(dprec - size, zeroes);
1591
1592 /* the string or number proper */
1593 #ifndef NO_FLOATING_POINT
1594 if ((flags & FPT) == 0) {
1595 PRINT(cp, size);
1596 } else { /* glue together f_p fragments */
1597 if (!expchar) { /* %[fF] or sufficiently short %[gG] */
1598 if (expt <= 0) {
1599 PRINT(zeroes, 1);
1600 if (prec || flags & ALT)
1601 PRINT(decimal_point, strlen(decimal_point));
1602 PAD(-expt, zeroes);
1603 /* already handled initial 0's */
1604 prec += expt;
1605 } else {
1606 PRINTANDPAD(cp, dtoaend, lead, zeroes);
1607 cp += lead;
1608 if (grouping) {
1609 while (nseps>0 || nrepeats>0) {
1610 if (nrepeats > 0)
1611 nrepeats--;
1612 else {
1613 grouping--;
1614 nseps--;
1615 }
1616 PRINT(&thousands_sep,
1617 1);
1618 PRINTANDPAD(cp,dtoaend,
1619 *grouping, zeroes);
1620 cp += *grouping;
1621 }
1622 if (cp > dtoaend)
1623 cp = dtoaend;
1624 }
1625 if (prec || flags & ALT)
1626 PRINT(decimal_point, strlen(decimal_point));
1627 }
1628 PRINTANDPAD(cp, dtoaend, prec, zeroes);
1629 } else { /* %[eE] or sufficiently long %[gG] */
1630 if (prec > 1 || flags & ALT) {
1631 buf[0] = *cp++;
1632 PRINT(buf, 1);
1633 PRINT(decimal_point, strlen(decimal_point));
1634 PRINT(cp, ndig-1);
1635 PAD(prec - ndig, zeroes);
1636 } else /* XeYYY */
1637 PRINT(cp, 1);
1638 PRINT(expstr, expsize);
1639 }
1640 }
1641 #else
1642 PRINT(cp, size);
1643 #endif
1644 /* left-adjusting padding (always blank) */
1645 if (flags & LADJUST)
1646 PAD(width - realsz, blanks);
1647
1648 /* finally, adjust ret */
1649 ret += prsize;
1650
1651 FLUSH(); /* copy out the I/O vectors */
1652 }
1653 done:
1654 FLUSH();
1655 error:
1656 va_end(orgap);
1657 #ifndef NO_FLOATING_POINT
1658 if (dtoaresult != NULL)
1659 freedtoa(dtoaresult);
1660 #endif
1661 if (convbuf != NULL)
1662 free(convbuf);
1663 if (__sferror(fp))
1664 ret = EOF;
1665 if ((argtable != NULL) && (argtable != statargtable))
1666 free (argtable);
1667 return (ret);
1668 /* NOTREACHED */
1669 }
1670
1671 /*
1672 * Find all arguments when a positional parameter is encountered. Returns a
1673 * table, indexed by argument number, of pointers to each arguments. The
1674 * initial argument table should be an array of STATIC_ARG_TBL_SIZE entries.
1675 * It will be replaces with a malloc-ed one if it overflows.
1676 */
1677 static void
1678 __find_arguments (const char *fmt0, va_list ap, union arg **argtable)
1679 {
1680 char *fmt; /* format string */
1681 int ch; /* character from fmt */
1682 int n, n2; /* handy integer (short term usage) */
1683 char *cp; /* handy char pointer (short term usage) */
1684 int flags; /* flags as above */
1685 int width; /* width from format (%8d), or 0 */
1686 enum typeid *typetable; /* table of types */
1687 enum typeid stattypetable [STATIC_ARG_TBL_SIZE];
1688 int tablesize; /* current size of type table */
1689 int tablemax; /* largest used index in table */
1690 int nextarg; /* 1-based argument index */
1691
1692 /*
1693 * Add an argument type to the table, expanding if necessary.
1694 */
1695 #define ADDTYPE(type) \
1696 ((nextarg >= tablesize) ? \
1697 __grow_type_table(nextarg, &typetable, &tablesize) : (void)0, \
1698 (nextarg > tablemax) ? tablemax = nextarg : 0, \
1699 typetable[nextarg++] = type)
1700
1701 #define ADDSARG() \
1702 ((flags&INTMAXT) ? ADDTYPE(T_INTMAXT) : \
1703 ((flags&SIZET) ? ADDTYPE(T_SIZET) : \
1704 ((flags&PTRDIFFT) ? ADDTYPE(T_PTRDIFFT) : \
1705 ((flags&LLONGINT) ? ADDTYPE(T_LLONG) : \
1706 ((flags&LONGINT) ? ADDTYPE(T_LONG) : ADDTYPE(T_INT))))))
1707
1708 #define ADDUARG() \
1709 ((flags&INTMAXT) ? ADDTYPE(T_UINTMAXT) : \
1710 ((flags&SIZET) ? ADDTYPE(T_SIZET) : \
1711 ((flags&PTRDIFFT) ? ADDTYPE(T_PTRDIFFT) : \
1712 ((flags&LLONGINT) ? ADDTYPE(T_U_LLONG) : \
1713 ((flags&LONGINT) ? ADDTYPE(T_U_LONG) : ADDTYPE(T_U_INT))))))
1714
1715 /*
1716 * Add * arguments to the type array.
1717 */
1718 #define ADDASTER() \
1719 n2 = 0; \
1720 cp = fmt; \
1721 while (is_digit(*cp)) { \
1722 n2 = 10 * n2 + to_digit(*cp); \
1723 cp++; \
1724 } \
1725 if (*cp == '$') { \
1726 int hold = nextarg; \
1727 nextarg = n2; \
1728 ADDTYPE (T_INT); \
1729 nextarg = hold; \
1730 fmt = ++cp; \
1731 } else { \
1732 ADDTYPE (T_INT); \
1733 }
1734 fmt = (char *)fmt0;
1735 typetable = stattypetable;
1736 tablesize = STATIC_ARG_TBL_SIZE;
1737 tablemax = 0;
1738 nextarg = 1;
1739 for (n = 0; n < STATIC_ARG_TBL_SIZE; n++)
1740 typetable[n] = T_UNUSED;
1741
1742 /*
1743 * Scan the format for conversions (`%' character).
1744 */
1745 for (;;) {
1746 for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)
1747 /* void */;
1748 if (ch == '\0')
1749 goto done;
1750 fmt++; /* skip over '%' */
1751
1752 flags = 0;
1753 width = 0;
1754
1755 rflag: ch = *fmt++;
1756 reswitch: switch (ch) {
1757 case ' ':
1758 case '#':
1759 goto rflag;
1760 case '*':
1761 ADDASTER ();
1762 goto rflag;
1763 case '-':
1764 case '+':
1765 case '\'':
1766 goto rflag;
1767 case '.':
1768 if ((ch = *fmt++) == '*') {
1769 ADDASTER ();
1770 goto rflag;
1771 }
1772 while (is_digit(ch)) {
1773 ch = *fmt++;
1774 }
1775 goto reswitch;
1776 case '0':
1777 goto rflag;
1778 case '1': case '2': case '3': case '4':
1779 case '5': case '6': case '7': case '8': case '9':
1780 n = 0;
1781 do {
1782 n = 10 * n + to_digit(ch);
1783 ch = *fmt++;
1784 } while (is_digit(ch));
1785 if (ch == '$') {
1786 nextarg = n;
1787 goto rflag;
1788 }
1789 width = n;
1790 goto reswitch;
1791 #ifndef NO_FLOATING_POINT
1792 case 'L':
1793 flags |= LONGDBL;
1794 goto rflag;
1795 #endif
1796 case 'h':
1797 if (flags & SHORTINT) {
1798 flags &= ~SHORTINT;
1799 flags |= CHARINT;
1800 } else
1801 flags |= SHORTINT;
1802 goto rflag;
1803 case 'j':
1804 flags |= INTMAXT;
1805 goto rflag;
1806 case 'l':
1807 if (flags & LONGINT) {
1808 flags &= ~LONGINT;
1809 flags |= LLONGINT;
1810 } else
1811 flags |= LONGINT;
1812 goto rflag;
1813 case 'q':
1814 flags |= LLONGINT; /* not necessarily */
1815 goto rflag;
1816 case 't':
1817 flags |= PTRDIFFT;
1818 goto rflag;
1819 case 'z':
1820 flags |= SIZET;
1821 goto rflag;
1822 case 'C':
1823 flags |= LONGINT;
1824 /*FALLTHROUGH*/
1825 case 'c':
1826 if (flags & LONGINT)
1827 ADDTYPE(T_WINT);
1828 else
1829 #ifdef VECTORS
1830 if (flags & VECTOR)
1831 ADDTYPE(T_VECTOR);
1832 else
1833 #endif /* VECTORS */
1834 ADDTYPE(T_INT);
1835 break;
1836 case 'D':
1837 flags |= LONGINT;
1838 /*FALLTHROUGH*/
1839 case 'd':
1840 case 'i':
1841 #ifdef VECTORS
1842 if (flags & VECTOR)
1843 ADDTYPE(T_VECTOR);
1844 else
1845 #endif
1846 ADDSARG();
1847 break;
1848 #ifndef NO_FLOATING_POINT
1849 case 'a':
1850 case 'A':
1851 case 'e':
1852 case 'E':
1853 case 'f':
1854 case 'F':
1855 case 'g':
1856 case 'G':
1857 #ifdef VECTORS
1858 if (flags & VECTOR)
1859 ADDTYPE(T_VECTOR);
1860 else
1861 #endif /* VECTORS */
1862 if (flags & LONGDBL)
1863 ADDTYPE(T_LONG_DOUBLE);
1864 else
1865 ADDTYPE(T_DOUBLE);
1866 break;
1867 #endif /* !NO_FLOATING_POINT */
1868 case 'n':
1869 if (flags & INTMAXT)
1870 ADDTYPE(TP_INTMAXT);
1871 else if (flags & PTRDIFFT)
1872 ADDTYPE(TP_PTRDIFFT);
1873 else if (flags & SIZET)
1874 ADDTYPE(TP_SIZET);
1875 else if (flags & LLONGINT)
1876 ADDTYPE(TP_LLONG);
1877 else if (flags & LONGINT)
1878 ADDTYPE(TP_LONG);
1879 else if (flags & SHORTINT)
1880 ADDTYPE(TP_SHORT);
1881 else if (flags & CHARINT)
1882 ADDTYPE(TP_SCHAR);
1883 else
1884 ADDTYPE(TP_INT);
1885 continue; /* no output */
1886 case 'O':
1887 flags |= LONGINT;
1888 /*FALLTHROUGH*/
1889 case 'o':
1890 #ifdef VECTORS
1891 if (flags & VECTOR)
1892 ADDTYPE(T_VECTOR);
1893 else
1894 #endif /* VECTORS */
1895 ADDUARG();
1896 break;
1897 case 'p':
1898 #ifdef VECTORS
1899 if (flags & VECTOR)
1900 ADDTYPE(T_VECTOR);
1901 else
1902 #endif /* VECTORS */
1903 ADDTYPE(TP_VOID);
1904 break;
1905 case 'S':
1906 flags |= LONGINT;
1907 /*FALLTHROUGH*/
1908 case 's':
1909 if (flags & LONGINT)
1910 ADDTYPE(TP_WCHAR);
1911 else
1912 ADDTYPE(TP_CHAR);
1913 break;
1914 case 'U':
1915 flags |= LONGINT;
1916 /*FALLTHROUGH*/
1917 case 'u':
1918 case 'X':
1919 case 'x':
1920 #ifdef VECTORS
1921 if (flags & VECTOR)
1922 ADDTYPE(T_VECTOR);
1923 else
1924 #endif /* VECTORS */
1925 ADDUARG();
1926 break;
1927 default: /* "%?" prints ?, unless ? is NUL */
1928 if (ch == '\0')
1929 goto done;
1930 break;
1931 }
1932 }
1933 done:
1934 /*
1935 * Build the argument table.
1936 */
1937 if (tablemax >= STATIC_ARG_TBL_SIZE) {
1938 *argtable = (union arg *)
1939 malloc (sizeof (union arg) * (tablemax + 1));
1940 }
1941
1942 (*argtable) [0].intarg = 0;
1943 for (n = 1; n <= tablemax; n++) {
1944 switch (typetable [n]) {
1945 case T_UNUSED: /* whoops! */
1946 (*argtable) [n].intarg = va_arg (ap, int);
1947 break;
1948 case TP_SCHAR:
1949 (*argtable) [n].pschararg = va_arg (ap, signed char *);
1950 break;
1951 case TP_SHORT:
1952 (*argtable) [n].pshortarg = va_arg (ap, short *);
1953 break;
1954 case T_INT:
1955 (*argtable) [n].intarg = va_arg (ap, int);
1956 break;
1957 case T_U_INT:
1958 (*argtable) [n].uintarg = va_arg (ap, unsigned int);
1959 break;
1960 case TP_INT:
1961 (*argtable) [n].pintarg = va_arg (ap, int *);
1962 break;
1963 case T_LONG:
1964 (*argtable) [n].longarg = va_arg (ap, long);
1965 break;
1966 case T_U_LONG:
1967 (*argtable) [n].ulongarg = va_arg (ap, unsigned long);
1968 break;
1969 case TP_LONG:
1970 (*argtable) [n].plongarg = va_arg (ap, long *);
1971 break;
1972 case T_LLONG:
1973 (*argtable) [n].longlongarg = va_arg (ap, long long);
1974 break;
1975 case T_U_LLONG:
1976 (*argtable) [n].ulonglongarg = va_arg (ap, unsigned long long);
1977 break;
1978 case TP_LLONG:
1979 (*argtable) [n].plonglongarg = va_arg (ap, long long *);
1980 break;
1981 case T_PTRDIFFT:
1982 (*argtable) [n].ptrdiffarg = va_arg (ap, ptrdiff_t);
1983 break;
1984 case TP_PTRDIFFT:
1985 (*argtable) [n].pptrdiffarg = va_arg (ap, ptrdiff_t *);
1986 break;
1987 case T_SIZET:
1988 (*argtable) [n].sizearg = va_arg (ap, size_t);
1989 break;
1990 case TP_SIZET:
1991 (*argtable) [n].psizearg = va_arg (ap, size_t *);
1992 break;
1993 case T_INTMAXT:
1994 (*argtable) [n].intmaxarg = va_arg (ap, intmax_t);
1995 break;
1996 case T_UINTMAXT:
1997 (*argtable) [n].uintmaxarg = va_arg (ap, uintmax_t);
1998 break;
1999 case TP_INTMAXT:
2000 (*argtable) [n].pintmaxarg = va_arg (ap, intmax_t *);
2001 break;
2002 #ifndef NO_FLOATING_POINT
2003 case T_DOUBLE:
2004 (*argtable) [n].doublearg = va_arg (ap, double);
2005 break;
2006 case T_LONG_DOUBLE:
2007 (*argtable) [n].longdoublearg = va_arg (ap, long double);
2008 break;
2009 #endif
2010 #ifdef VECTORS
2011 case T_VECTOR:
2012 (*argtable) [n].vectorarg = va_arg (ap, VECTORTYPE);
2013 break;
2014 #endif /* VECTORS */
2015 case TP_CHAR:
2016 (*argtable) [n].pchararg = va_arg (ap, char *);
2017 break;
2018 case TP_VOID:
2019 (*argtable) [n].pvoidarg = va_arg (ap, void *);
2020 break;
2021 case T_WINT:
2022 (*argtable) [n].wintarg = va_arg (ap, wint_t);
2023 break;
2024 case TP_WCHAR:
2025 (*argtable) [n].pwchararg = va_arg (ap, wchar_t *);
2026 break;
2027 }
2028 }
2029
2030 if ((typetable != NULL) && (typetable != stattypetable))
2031 free (typetable);
2032 }
2033
2034 /*
2035 * Increase the size of the type table.
2036 */
2037 static void
2038 __grow_type_table (int nextarg, enum typeid **typetable, int *tablesize)
2039 {
2040 enum typeid *const oldtable = *typetable;
2041 const int oldsize = *tablesize;
2042 enum typeid *newtable;
2043 int n, newsize = oldsize * 2;
2044
2045 if (newsize < nextarg + 1)
2046 newsize = nextarg + 1;
2047 if (oldsize == STATIC_ARG_TBL_SIZE) {
2048 if ((newtable = malloc(newsize * sizeof(enum typeid))) == NULL)
2049 abort(); /* XXX handle better */
2050 bcopy(oldtable, newtable, oldsize * sizeof(enum typeid));
2051 } else {
2052 newtable = reallocf(oldtable, newsize * sizeof(enum typeid));
2053 if (newtable == NULL)
2054 abort(); /* XXX handle better */
2055 }
2056 for (n = oldsize; n < newsize; n++)
2057 newtable[n] = T_UNUSED;
2058
2059 *typetable = newtable;
2060 *tablesize = newsize;
2061 }
2062
2063
2064 #ifndef NO_FLOATING_POINT
2065
2066 static int
2067 exponent(char *p0, int exp, int fmtch)
2068 {
2069 char *p, *t;
2070 char expbuf[MAXEXPDIG];
2071
2072 p = p0;
2073 *p++ = fmtch;
2074 if (exp < 0) {
2075 exp = -exp;
2076 *p++ = '-';
2077 }
2078 else
2079 *p++ = '+';
2080 t = expbuf + MAXEXPDIG;
2081 if (exp > 9) {
2082 do {
2083 *--t = to_char(exp % 10);
2084 } while ((exp /= 10) > 9);
2085 *--t = to_char(exp);
2086 for (; t < expbuf + MAXEXPDIG; *p++ = *t++);
2087 }
2088 else {
2089 /*
2090 * Exponents for decimal floating point conversions
2091 * (%[eEgG]) must be at least two characters long,
2092 * whereas exponents for hexadecimal conversions can
2093 * be only one character long.
2094 */
2095 if (fmtch == 'e' || fmtch == 'E')
2096 *p++ = '0';
2097 *p++ = to_char(exp);
2098 }
2099 return (p - p0);
2100 }
2101 #endif /* !NO_FLOATING_POINT */