__aeabi_ldivmod: fix sign logic
[minix.git] / lib / libc / stdio / vfwprintf.c
blobe814253c0fdefb40fa76a40c2b6a5705b79a6e78
1 /* $NetBSD: vfwprintf.c,v 1.30 2012/03/27 15:05:42 christos Exp $ */
3 /*-
4 * Copyright (c) 1990, 1993
5 * The Regents of the University of California. All rights reserved.
7 * This code is derived from software contributed to Berkeley by
8 * Chris Torek.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
35 #include <sys/cdefs.h>
36 #if defined(LIBC_SCCS) && !defined(lint)
37 #if 0
38 static char sccsid[] = "@(#)vfprintf.c 8.1 (Berkeley) 6/4/93";
39 __FBSDID("$FreeBSD: src/lib/libc/stdio/vfwprintf.c,v 1.27 2007/01/09 00:28:08 imp Exp $");
40 #else
41 __RCSID("$NetBSD: vfwprintf.c,v 1.30 2012/03/27 15:05:42 christos Exp $");
42 #endif
43 #endif /* LIBC_SCCS and not lint */
46 * Actual {w,}printf innards.
49 #include "namespace.h"
50 #include <sys/types.h>
52 #include <assert.h>
53 #include <ctype.h>
54 #include <limits.h>
55 #include <locale.h>
56 #include <stdarg.h>
57 #include <stddef.h>
58 #include <stdint.h>
59 #include <stdio.h>
60 #include <stdlib.h>
61 #include <string.h>
62 #include <errno.h>
63 #include <wchar.h>
64 #include <wctype.h>
66 #include "reentrant.h"
67 #include "local.h"
68 #include "extern.h"
69 #include "fvwrite.h"
71 #ifndef NARROW
72 #define MCHAR_T char
73 #define CHAR_T wchar_t
74 #define STRLEN(a) wcslen(a)
75 #define MEMCHR(a, b, c) wmemchr(a, b, c)
76 #define SCONV(a, b) __mbsconv(a, b)
77 #define STRCONST(a) L ## a
78 #define WDECL(a, b) a ## w ## b
79 #define END_OF_FILE WEOF
80 #define MULTI 0
81 #else
82 #define MCHAR_T wchar_t
83 #define CHAR_T char
84 #define STRLEN(a) strlen(a)
85 #define MEMCHR(a, b, c) memchr(a, b, c)
86 #define SCONV(a, b) __wcsconv(a, b)
87 #define STRCONST(a) a
88 #define WDECL(a, b) a ## b
89 #define END_OF_FILE EOF
90 #define MULTI LONGINT
91 #endif
93 union arg {
94 int intarg;
95 u_int uintarg;
96 long longarg;
97 u_long ulongarg;
98 long long longlongarg;
99 unsigned long long ulonglongarg;
100 ptrdiff_t ptrdiffarg;
101 ssize_t ssizearg;
102 size_t sizearg;
103 intmax_t intmaxarg;
104 uintmax_t uintmaxarg;
105 void *pvoidarg;
106 char *pchararg;
107 signed char *pschararg;
108 short *pshortarg;
109 int *pintarg;
110 long *plongarg;
111 long long *plonglongarg;
112 ptrdiff_t *pptrdiffarg;
113 size_t *psizearg;
114 intmax_t *pintmaxarg;
115 #ifndef NO_FLOATING_POINT
116 double doublearg;
117 long double longdoublearg;
118 #endif
119 wint_t wintarg;
120 wchar_t *pwchararg;
124 * Type ids for argument type table.
126 enum typeid {
127 T_UNUSED = 0, 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_SSIZET, T_SIZET, TP_SIZET,
130 T_INTMAXT, T_UINTMAXT, TP_INTMAXT, TP_VOID, TP_CHAR, TP_SCHAR,
131 T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR
134 static int __sbprintf(FILE *, const CHAR_T *, va_list);
135 static CHAR_T *__ujtoa(uintmax_t, CHAR_T *, int, int, const char *, int,
136 char, const char *);
137 static CHAR_T *__ultoa(u_long, CHAR_T *, int, int, const char *, int,
138 char, const char *);
139 #ifndef NARROW
140 static CHAR_T *__mbsconv(char *, int);
141 static wint_t __xfputwc(CHAR_T, FILE *);
142 #else
143 static char *__wcsconv(wchar_t *, int);
144 static int __sprint(FILE *, struct __suio *);
145 #endif
146 static int __find_arguments(const CHAR_T *, va_list, union arg **);
147 static int __grow_type_table(size_t, enum typeid **, size_t *);
150 * Helper function for `fprintf to unbuffered unix file': creates a
151 * temporary buffer. We only work on write-only files; this avoids
152 * worries about ungetc buffers and so forth.
154 static int
155 __sbprintf(FILE *fp, const CHAR_T *fmt, va_list ap)
157 int ret;
158 FILE fake;
159 struct __sfileext fakeext;
160 unsigned char buf[BUFSIZ];
162 _DIAGASSERT(fp != NULL);
163 _DIAGASSERT(fmt != NULL);
165 _FILEEXT_SETUP(&fake, &fakeext);
166 memset(WCIO_GET(&fake), 0, sizeof(struct wchar_io_data));
168 /* copy the important variables */
169 fake._flags = fp->_flags & ~__SNBF;
170 fake._file = fp->_file;
171 fake._cookie = fp->_cookie;
172 fake._write = fp->_write;
173 fake._flush = fp->_flush;
175 /* set up the buffer */
176 fake._bf._base = fake._p = buf;
177 fake._bf._size = fake._w = sizeof(buf);
178 fake._lbfsize = 0; /* not actually used, but Just In Case */
180 /* do the work, then copy any error status */
181 ret = WDECL(__vf,printf_unlocked)(&fake, fmt, ap);
182 if (ret >= 0 && fflush(&fake))
183 ret = END_OF_FILE;
184 if (fake._flags & __SERR)
185 fp->_flags |= __SERR;
186 return ret;
189 #ifndef NARROW
191 * Like __fputwc, but handles fake string (__SSTR) files properly.
192 * File must already be locked.
194 static wint_t
195 __xfputwc(wchar_t wc, FILE *fp)
197 static const mbstate_t initial;
198 mbstate_t mbs;
199 char buf[MB_LEN_MAX];
200 struct __suio uio;
201 struct __siov iov;
202 size_t len;
204 if ((fp->_flags & __SSTR) == 0)
205 return __fputwc_unlock(wc, fp);
207 mbs = initial;
208 if ((len = wcrtomb(buf, wc, &mbs)) == (size_t)-1) {
209 fp->_flags |= __SERR;
210 return END_OF_FILE;
212 uio.uio_iov = &iov;
213 uio.uio_resid = len;
214 uio.uio_iovcnt = 1;
215 iov.iov_base = buf;
216 iov.iov_len = len;
217 return __sfvwrite(fp, &uio) != EOF ? (wint_t)wc : END_OF_FILE;
219 #else
221 * Flush out all the vectors defined by the given uio,
222 * then reset it so that it can be reused.
224 static int
225 __sprint(FILE *fp, struct __suio *uio)
227 int err;
229 _DIAGASSERT(fp != NULL);
230 _DIAGASSERT(uio != NULL);
232 if (uio->uio_resid == 0) {
233 uio->uio_iovcnt = 0;
234 return 0;
236 err = __sfvwrite(fp, uio);
237 uio->uio_resid = 0;
238 uio->uio_iovcnt = 0;
239 return err;
241 #endif
244 * Macros for converting digits to letters and vice versa
246 #define to_digit(c) ((c) - '0')
247 #define is_digit(c) ((unsigned)to_digit(c) <= 9)
248 #define to_char(n) (CHAR_T)((n) + '0')
251 * Convert an unsigned long to ASCII for printf purposes, returning
252 * a pointer to the first character of the string representation.
253 * Octal numbers can be forced to have a leading zero; hex numbers
254 * use the given digits.
256 static CHAR_T *
257 __ultoa(u_long val, CHAR_T *endp, int base, int octzero, const char *xdigs,
258 int needgrp, char thousep, const char *grp)
260 CHAR_T *cp = endp;
261 long sval;
262 int ndig;
265 * Handle the three cases separately, in the hope of getting
266 * better/faster code.
268 switch (base) {
269 case 10:
270 if (val < 10) { /* many numbers are 1 digit */
271 *--cp = to_char(val);
272 return cp;
274 ndig = 0;
276 * On many machines, unsigned arithmetic is harder than
277 * signed arithmetic, so we do at most one unsigned mod and
278 * divide; this is sufficient to reduce the range of
279 * the incoming value to where signed arithmetic works.
281 if (val > LONG_MAX) {
282 *--cp = to_char(val % 10);
283 ndig++;
284 sval = val / 10;
285 } else
286 sval = val;
287 do {
288 *--cp = to_char(sval % 10);
289 ndig++;
291 * If (*grp == CHAR_MAX) then no more grouping
292 * should be performed.
294 if (needgrp && ndig == *grp
295 && (unsigned char)*grp != (unsigned char)CHAR_MAX
296 && sval > 9) {
297 *--cp = thousep;
298 ndig = 0;
300 * If (*(grp+1) == '\0') then we have to
301 * use *grp character (last grouping rule)
302 * for all next cases
304 if (*(grp+1) != '\0')
305 grp++;
307 sval /= 10;
308 } while (sval != 0);
309 break;
311 case 8:
312 do {
313 *--cp = to_char(val & 7);
314 val >>= 3;
315 } while (val);
316 if (octzero && *cp != '0')
317 *--cp = '0';
318 break;
320 case 16:
321 do {
322 *--cp = xdigs[(size_t)val & 15];
323 val >>= 4;
324 } while (val);
325 break;
327 default: /* oops */
328 abort();
330 return cp;
333 /* Identical to __ultoa, but for intmax_t. */
334 static CHAR_T *
335 __ujtoa(uintmax_t val, CHAR_T *endp, int base, int octzero,
336 const char *xdigs, int needgrp, char thousep, const char *grp)
338 CHAR_T *cp = endp;
339 intmax_t sval;
340 int ndig;
342 /* quick test for small values; __ultoa is typically much faster */
343 /* (perhaps instead we should run until small, then call __ultoa?) */
344 if (val <= ULONG_MAX)
345 return __ultoa((u_long)val, endp, base, octzero, xdigs,
346 needgrp, thousep, grp);
347 switch (base) {
348 case 10:
349 if (val < 10) {
350 *--cp = to_char(val % 10);
351 return cp;
353 ndig = 0;
354 if (val > INTMAX_MAX) {
355 *--cp = to_char(val % 10);
356 ndig++;
357 sval = val / 10;
358 } else
359 sval = val;
360 do {
361 *--cp = to_char(sval % 10);
362 ndig++;
364 * If (*grp == CHAR_MAX) then no more grouping
365 * should be performed.
367 if (needgrp
368 && (unsigned char)*grp != (unsigned char)CHAR_MAX
369 && ndig == *grp
370 && sval > 9) {
371 *--cp = thousep;
372 ndig = 0;
374 * If (*(grp+1) == '\0') then we have to
375 * use *grp character (last grouping rule)
376 * for all next cases
378 if (*(grp+1) != '\0')
379 grp++;
381 sval /= 10;
382 } while (sval != 0);
383 break;
385 case 8:
386 do {
387 *--cp = to_char(val & 7);
388 val >>= 3;
389 } while (val);
390 if (octzero && *cp != '0')
391 *--cp = '0';
392 break;
394 case 16:
395 do {
396 *--cp = xdigs[(size_t)val & 15];
397 val >>= 4;
398 } while (val);
399 break;
401 default:
402 abort();
404 return cp;
407 #ifndef NARROW
409 * Convert a multibyte character string argument for the %s format to a wide
410 * string representation. ``prec'' specifies the maximum number of bytes
411 * to output. If ``prec'' is greater than or equal to zero, we can't assume
412 * that the multibyte char. string ends in a null character.
414 static wchar_t *
415 __mbsconv(char *mbsarg, int prec)
417 static const mbstate_t initial;
418 mbstate_t mbs;
419 wchar_t *convbuf, *wcp;
420 const char *p;
421 size_t insize, nchars, nconv;
423 if (mbsarg == NULL)
424 return NULL;
427 * Supplied argument is a multibyte string; convert it to wide
428 * characters first.
430 if (prec >= 0) {
432 * String is not guaranteed to be NUL-terminated. Find the
433 * number of characters to print.
435 p = mbsarg;
436 insize = nchars = nconv = 0;
437 mbs = initial;
438 while (nchars != (size_t)prec) {
439 nconv = mbrlen(p, MB_CUR_MAX, &mbs);
440 if (nconv == 0 || nconv == (size_t)-1 ||
441 nconv == (size_t)-2)
442 break;
443 p += nconv;
444 nchars++;
445 insize += nconv;
447 if (nconv == (size_t)-1 || nconv == (size_t)-2)
448 return NULL;
449 } else
450 insize = strlen(mbsarg);
453 * Allocate buffer for the result and perform the conversion,
454 * converting at most `size' bytes of the input multibyte string to
455 * wide characters for printing.
457 convbuf = malloc((insize + 1) * sizeof(*convbuf));
458 if (convbuf == NULL)
459 return NULL;
460 wcp = convbuf;
461 p = mbsarg;
462 mbs = initial;
463 nconv = 0;
464 while (insize != 0) {
465 nconv = mbrtowc(wcp, p, insize, &mbs);
466 if (nconv == 0 || nconv == (size_t)-1 || nconv == (size_t)-2)
467 break;
468 wcp++;
469 p += nconv;
470 insize -= nconv;
472 if (nconv == (size_t)-1 || nconv == (size_t)-2) {
473 free(convbuf);
474 return NULL;
476 *wcp = L'\0';
478 return convbuf;
480 #else
482 * Convert a wide-character string argument for the %ls format to a multibyte
483 * string representation. If not -1, prec specifies the maximum number of
484 * bytes to output, and also means that we can't assume that the wide-char.
485 * string ends is null-terminated.
487 static char *
488 __wcsconv(wchar_t *wcsarg, int prec)
490 static const mbstate_t initial;
491 mbstate_t mbs;
492 char buf[MB_LEN_MAX];
493 wchar_t *p;
494 char *convbuf;
495 size_t clen, nbytes;
497 /* Allocate space for the maximum number of bytes we could output. */
498 if (prec < 0) {
499 p = wcsarg;
500 mbs = initial;
501 nbytes = wcsrtombs(NULL, (void *)&p, 0, &mbs);
502 if (nbytes == (size_t)-1)
503 return NULL;
504 } else {
506 * Optimisation: if the output precision is small enough,
507 * just allocate enough memory for the maximum instead of
508 * scanning the string.
510 if (prec < 128)
511 nbytes = prec;
512 else {
513 nbytes = 0;
514 p = wcsarg;
515 mbs = initial;
516 for (;;) {
517 clen = wcrtomb(buf, *p++, &mbs);
518 if (clen == 0 || clen == (size_t)-1 ||
519 nbytes + clen > (size_t)prec)
520 break;
521 nbytes += clen;
525 if ((convbuf = malloc(nbytes + 1)) == NULL)
526 return NULL;
528 /* Fill the output buffer. */
529 p = wcsarg;
530 mbs = initial;
531 if ((nbytes = wcsrtombs(convbuf, (void *)&p,
532 nbytes, &mbs)) == (size_t)-1) {
533 free(convbuf);
534 return NULL;
536 convbuf[nbytes] = '\0';
537 return convbuf;
539 #endif
542 * MT-safe version
545 WDECL(vf,printf)(FILE * __restrict fp, const CHAR_T * __restrict fmt0, va_list ap)
547 int ret;
549 FLOCKFILE(fp);
550 ret = WDECL(__vf,printf_unlocked)(fp, fmt0, ap);
551 FUNLOCKFILE(fp);
552 return ret;
555 #ifndef NO_FLOATING_POINT
557 #include <float.h>
558 #include <math.h>
559 #include "floatio.h"
561 #define DEFPREC 6
563 static int exponent(CHAR_T *, int, int);
564 #ifndef WIDE_DOUBLE
565 static char *cvt(double, int, int, char *, int *, int, int *);
566 #endif
568 #endif /* !NO_FLOATING_POINT */
571 * The size of the buffer we use as scratch space for integer
572 * conversions, among other things. Technically, we would need the
573 * most space for base 10 conversions with thousands' grouping
574 * characters between each pair of digits. 100 bytes is a
575 * conservative overestimate even for a 128-bit uintmax_t.
577 #define BUF 100
579 #define STATIC_ARG_TBL_SIZE 8 /* Size of static argument table. */
582 * Flags used during conversion.
584 #define ALT 0x001 /* alternate form */
585 #define LADJUST 0x004 /* left adjustment */
586 #define LONGDBL 0x008 /* long double */
587 #define LONGINT 0x010 /* long integer */
588 #define LLONGINT 0x020 /* long long integer */
589 #define SHORTINT 0x040 /* short integer */
590 #define ZEROPAD 0x080 /* zero (as opposed to blank) pad */
591 #define FPT 0x100 /* Floating point number */
592 #define GROUPING 0x200 /* use grouping ("'" flag) */
593 /* C99 additional size modifiers: */
594 #define SIZET 0x400 /* size_t */
595 #define PTRDIFFT 0x800 /* ptrdiff_t */
596 #define INTMAXT 0x1000 /* intmax_t */
597 #define CHARINT 0x2000 /* print char using int format */
600 * Non-MT-safe version
603 WDECL(__vf,printf_unlocked)(FILE *fp, const CHAR_T *fmt0, va_list ap)
605 CHAR_T *fmt; /* format string */
606 int ch; /* character from fmt */
607 int n, n2; /* handy integer (short term usage) */
608 CHAR_T *cp; /* handy char pointer (short term usage) */
609 int flags; /* flags as above */
610 int ret; /* return value accumulator */
611 int width; /* width from format (%8d), or 0 */
612 int prec; /* precision from format; <0 for N/A */
613 CHAR_T sign; /* sign prefix (' ', '+', '-', or \0) */
614 char thousands_sep; /* locale specific thousands separator */
615 const char *grouping; /* locale specific numeric grouping rules */
616 #ifndef NO_FLOATING_POINT
618 * We can decompose the printed representation of floating
619 * point numbers into several parts, some of which may be empty:
621 * [+|-| ] [0x|0X] MMM . NNN [e|E|p|P] [+|-] ZZ
622 * A B ---C--- D E F
624 * A: 'sign' holds this value if present; '\0' otherwise
625 * B: ox[1] holds the 'x' or 'X'; '\0' if not hexadecimal
626 * C: cp points to the string MMMNNN. Leading and trailing
627 * zeros are not in the string and must be added.
628 * D: expchar holds this character; '\0' if no exponent, e.g. %f
629 * F: at least two digits for decimal, at least one digit for hex
631 char *decimal_point; /* locale specific decimal point */
632 #ifdef WIDE_DOUBLE
633 int signflag; /* true if float is negative */
634 union { /* floating point arguments %[aAeEfFgG] */
635 double dbl;
636 long double ldbl;
637 } fparg;
638 char *dtoaend; /* pointer to end of converted digits */
639 #else
640 double _double; /* double precision arguments %[eEfgG] */
641 char softsign; /* temporary negative sign for floats */
642 #endif
643 char *dtoaresult; /* buffer allocated by dtoa */
644 int expt; /* integer value of exponent */
645 char expchar; /* exponent character: [eEpP\0] */
646 int expsize; /* character count for expstr */
647 int lead; /* sig figs before decimal or group sep */
648 int ndig; /* actual number of digits returned by dtoa */
649 CHAR_T expstr[MAXEXPDIG+2]; /* buffer for exponent string: e+ZZZ */
650 int nseps; /* number of group separators with ' */
651 int nrepeats; /* number of repeats of the last group */
652 #endif
653 u_long ulval; /* integer arguments %[diouxX] */
654 uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */
655 int base; /* base for [diouxX] conversion */
656 int dprec; /* a copy of prec if [diouxX], 0 otherwise */
657 int realsz; /* field size expanded by dprec, sign, etc */
658 int size; /* size of converted field or string */
659 int prsize; /* max size of printed field */
660 const char *xdigs; /* digits for %[xX] conversion */
661 #ifdef NARROW
662 #define NIOV 8
663 struct __siov *iovp; /* for PRINT macro */
664 struct __suio uio; /* output information: summary */
665 struct __siov iov[NIOV];/* ... and individual io vectors */
666 #else
667 int n3;
668 #endif
669 CHAR_T buf[BUF]; /* buffer with space for digits of uintmax_t */
670 CHAR_T ox[2]; /* space for 0x hex-prefix */
671 union arg *argtable; /* args, built due to positional arg */
672 union arg statargtable [STATIC_ARG_TBL_SIZE];
673 int nextarg; /* 1-based argument index */
674 va_list orgap; /* original argument pointer */
675 CHAR_T *convbuf; /* multibyte to wide conversion result */
678 * Choose PADSIZE to trade efficiency vs. size. If larger printf
679 * fields occur frequently, increase PADSIZE and make the initialisers
680 * below longer.
682 #define PADSIZE 16 /* pad chunk size */
683 static CHAR_T blanks[PADSIZE] =
684 {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
685 static CHAR_T zeroes[PADSIZE] =
686 {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
688 static const char xdigs_lower[16] = "0123456789abcdef";
689 static const char xdigs_upper[16] = "0123456789ABCDEF";
692 * BEWARE, these `goto error' on error, PRINT uses `n2' and
693 * PAD uses `n'.
695 #ifndef NARROW
696 #define PRINT(ptr, len) do { \
697 for (n3 = 0; n3 < (len); n3++) \
698 __xfputwc((ptr)[n3], fp); \
699 } while (/*CONSTCOND*/0)
700 #define FLUSH()
701 #else
702 #define PRINT(ptr, len) do { \
703 iovp->iov_base = __UNCONST(ptr); \
704 iovp->iov_len = (len); \
705 uio.uio_resid += (len); \
706 iovp++; \
707 if (++uio.uio_iovcnt >= NIOV) { \
708 if (__sprint(fp, &uio)) \
709 goto error; \
710 iovp = iov; \
712 } while (/*CONSTCOND*/0)
713 #define FLUSH() do { \
714 if (uio.uio_resid && __sprint(fp, &uio)) \
715 goto error; \
716 uio.uio_iovcnt = 0; \
717 iovp = iov; \
718 } while (/*CONSTCOND*/0)
719 #endif /* NARROW */
721 #define PAD(howmany, with) do { \
722 if ((n = (howmany)) > 0) { \
723 while (n > PADSIZE) { \
724 PRINT(with, PADSIZE); \
725 n -= PADSIZE; \
727 PRINT(with, n); \
729 } while (/*CONSTCOND*/0)
730 #define PRINTANDPAD(p, ep, len, with) do { \
731 ptrdiff_t td = (ep) - (p); \
732 _DIAGASSERT(__type_fit(int, td)); \
733 n2 = (int)td; \
734 if (n2 > (len)) \
735 n2 = (len); \
736 if (n2 > 0) \
737 PRINT((p), n2); \
738 PAD((len) - (n2 > 0 ? n2 : 0), (with)); \
739 } while(/*CONSTCOND*/0)
742 * Get the argument indexed by nextarg. If the argument table is
743 * built, use it to get the argument. If its not, get the next
744 * argument (and arguments must be gotten sequentially).
746 #define GETARG(type) \
747 ((/*CONSTCOND*/argtable != NULL) ? *((type*)(void*)(&argtable[nextarg++])) : \
748 (nextarg++, va_arg(ap, type)))
751 * To extend shorts properly, we need both signed and unsigned
752 * argument extraction methods.
754 #define SARG() \
755 (flags&LONGINT ? GETARG(long) : \
756 flags&SHORTINT ? (long)(short)GETARG(int) : \
757 flags&CHARINT ? (long)(signed char)GETARG(int) : \
758 (long)GETARG(int))
759 #define UARG() \
760 (flags&LONGINT ? GETARG(u_long) : \
761 flags&SHORTINT ? (u_long)(u_short)GETARG(int) : \
762 flags&CHARINT ? (u_long)(u_char)GETARG(int) : \
763 (u_long)GETARG(u_int))
764 #define INTMAX_SIZE (INTMAXT|SIZET|PTRDIFFT|LLONGINT)
765 #define SJARG() \
766 (flags&INTMAXT ? GETARG(intmax_t) : \
767 flags&SIZET ? (intmax_t)GETARG(ssize_t) : \
768 flags&PTRDIFFT ? (intmax_t)GETARG(ptrdiff_t) : \
769 (intmax_t)GETARG(long long))
770 #define UJARG() \
771 (flags&INTMAXT ? GETARG(uintmax_t) : \
772 flags&SIZET ? (uintmax_t)GETARG(size_t) : \
773 flags&PTRDIFFT ? (uintmax_t)GETARG(ptrdiff_t) : \
774 (uintmax_t)GETARG(unsigned long long))
777 * Get * arguments, including the form *nn$. Preserve the nextarg
778 * that the argument can be gotten once the type is determined.
780 #define GETASTER(val) \
781 n2 = 0; \
782 cp = fmt; \
783 while (is_digit(*cp)) { \
784 n2 = 10 * n2 + to_digit(*cp); \
785 cp++; \
787 if (*cp == '$') { \
788 int hold = nextarg; \
789 if (argtable == NULL) { \
790 argtable = statargtable; \
791 if (__find_arguments(fmt0, orgap, &argtable) == -1) \
792 goto oomem; \
794 nextarg = n2; \
795 val = GETARG (int); \
796 nextarg = hold; \
797 fmt = ++cp; \
798 } else { \
799 val = GETARG (int); \
802 _DIAGASSERT(fp != NULL);
803 _DIAGASSERT(fmt0 != NULL);
805 _SET_ORIENTATION(fp, -1);
807 ndig = -1; /* XXX gcc */
809 thousands_sep = '\0';
810 grouping = NULL;
811 #ifndef NO_FLOATING_POINT
812 decimal_point = localeconv()->decimal_point;
813 expsize = 0; /* XXXGCC -Wuninitialized [sh3,m68000] */
814 #endif
815 convbuf = NULL;
816 /* sorry, f{w,}printf(read_only_file, L"") returns {W,}EOF, not 0 */
817 if (cantwrite(fp)) {
818 errno = EBADF;
819 return END_OF_FILE;
822 /* optimise fprintf(stderr) (and other unbuffered Unix files) */
823 if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
824 __sfileno(fp) != -1)
825 return __sbprintf(fp, fmt0, ap);
827 fmt = (CHAR_T *)__UNCONST(fmt0);
828 argtable = NULL;
829 nextarg = 1;
830 va_copy(orgap, ap);
831 #ifdef NARROW
832 uio.uio_iov = iovp = iov;
833 uio.uio_resid = 0;
834 uio.uio_iovcnt = 0;
835 #endif
836 ret = 0;
839 * Scan the format for conversions (`%' character).
841 for (;;) {
842 const CHAR_T *result;
844 for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)
845 continue;
846 _DIAGASSERT(__type_fit(int, fmt - cp));
847 if ((n = (int)(fmt - cp)) != 0) {
848 if ((unsigned)ret + n > INT_MAX) {
849 ret = END_OF_FILE;
850 goto error;
852 PRINT(cp, n);
853 ret += n;
855 if (ch == '\0')
856 goto done;
857 fmt++; /* skip over '%' */
859 flags = 0;
860 dprec = 0;
861 width = 0;
862 prec = -1;
863 sign = '\0';
864 ox[1] = '\0';
865 expchar = '\0';
866 lead = 0;
867 nseps = nrepeats = 0;
868 ulval = 0;
869 ujval = 0;
870 xdigs = NULL;
872 rflag: ch = *fmt++;
873 reswitch: switch (ch) {
874 case ' ':
876 * ``If the space and + flags both appear, the space
877 * flag will be ignored.''
878 * -- ANSI X3J11
880 if (!sign)
881 sign = ' ';
882 goto rflag;
883 case '#':
884 flags |= ALT;
885 goto rflag;
886 case '*':
888 * ``A negative field width argument is taken as a
889 * - flag followed by a positive field width.''
890 * -- ANSI X3J11
891 * They don't exclude field widths read from args.
893 GETASTER (width);
894 if (width >= 0)
895 goto rflag;
896 width = -width;
897 /* FALLTHROUGH */
898 case '-':
899 flags |= LADJUST;
900 goto rflag;
901 case '+':
902 sign = '+';
903 goto rflag;
904 case '\'':
905 flags |= GROUPING;
906 thousands_sep = *(localeconv()->thousands_sep);
907 grouping = localeconv()->grouping;
908 /* If the locale doesn't define the above, use sane
909 * defaults - otherwise silly things happen! */
910 if (thousands_sep == 0)
911 thousands_sep = ',';
912 if (!grouping || !*grouping)
913 grouping = "\3";
914 goto rflag;
915 case '.':
916 if ((ch = *fmt++) == '*') {
917 GETASTER (prec);
918 goto rflag;
920 prec = 0;
921 while (is_digit(ch)) {
922 prec = 10 * prec + to_digit(ch);
923 ch = *fmt++;
925 goto reswitch;
926 case '0':
928 * ``Note that 0 is taken as a flag, not as the
929 * beginning of a field width.''
930 * -- ANSI X3J11
932 flags |= ZEROPAD;
933 goto rflag;
934 case '1': case '2': case '3': case '4':
935 case '5': case '6': case '7': case '8': case '9':
936 n = 0;
937 do {
938 n = 10 * n + to_digit(ch);
939 ch = *fmt++;
940 } while (is_digit(ch));
941 if (ch == '$') {
942 nextarg = n;
943 if (argtable == NULL) {
944 argtable = statargtable;
945 if (__find_arguments(fmt0, orgap,
946 &argtable) == -1)
947 goto oomem;
949 goto rflag;
951 width = n;
952 goto reswitch;
953 #ifndef NO_FLOATING_POINT
954 case 'L':
955 flags |= LONGDBL;
956 goto rflag;
957 #endif
958 case 'h':
959 if (flags & SHORTINT) {
960 flags &= ~SHORTINT;
961 flags |= CHARINT;
962 } else
963 flags |= SHORTINT;
964 goto rflag;
965 case 'j':
966 flags |= INTMAXT;
967 goto rflag;
968 case 'l':
969 if (flags & LONGINT) {
970 flags &= ~LONGINT;
971 flags |= LLONGINT;
972 } else
973 flags |= LONGINT;
974 goto rflag;
975 case 'q':
976 flags |= LLONGINT; /* not necessarily */
977 goto rflag;
978 case 't':
979 flags |= PTRDIFFT;
980 goto rflag;
981 case 'z':
982 flags |= SIZET;
983 goto rflag;
984 case 'C':
985 flags |= LONGINT;
986 /*FALLTHROUGH*/
987 case 'c':
988 #ifdef NARROW
989 if (flags & LONGINT) {
990 static const mbstate_t initial;
991 mbstate_t mbs;
992 size_t mbseqlen;
994 mbs = initial;
995 mbseqlen = wcrtomb(buf,
996 (wchar_t)GETARG(wint_t), &mbs);
997 if (mbseqlen == (size_t)-1) {
998 fp->_flags |= __SERR;
999 goto error;
1001 size = (int)mbseqlen;
1002 } else {
1003 *buf = GETARG(int);
1004 size = 1;
1006 #else
1007 if (flags & LONGINT)
1008 *buf = (wchar_t)GETARG(wint_t);
1009 else
1010 *buf = (wchar_t)btowc(GETARG(int));
1011 size = 1;
1012 #endif
1013 result = buf;
1014 sign = '\0';
1015 break;
1016 case 'D':
1017 flags |= LONGINT;
1018 /*FALLTHROUGH*/
1019 case 'd':
1020 case 'i':
1021 if (flags & INTMAX_SIZE) {
1022 ujval = SJARG();
1023 if ((intmax_t)ujval < 0) {
1024 ujval = -ujval;
1025 sign = '-';
1027 } else {
1028 ulval = SARG();
1029 if ((long)ulval < 0) {
1030 ulval = -ulval;
1031 sign = '-';
1034 base = 10;
1035 goto number;
1036 #ifndef NO_FLOATING_POINT
1037 #ifdef WIDE_DOUBLE
1038 case 'a':
1039 case 'A':
1040 if (ch == 'a') {
1041 ox[1] = 'x';
1042 xdigs = xdigs_lower;
1043 expchar = 'p';
1044 } else {
1045 ox[1] = 'X';
1046 xdigs = xdigs_upper;
1047 expchar = 'P';
1049 if (prec >= 0)
1050 prec++;
1051 if (flags & LONGDBL) {
1052 fparg.ldbl = GETARG(long double);
1053 dtoaresult =
1054 __hldtoa(fparg.ldbl, xdigs, prec,
1055 &expt, &signflag, &dtoaend);
1056 } else {
1057 fparg.dbl = GETARG(double);
1058 dtoaresult =
1059 __hdtoa(fparg.dbl, xdigs, prec,
1060 &expt, &signflag, &dtoaend);
1062 if (dtoaresult == NULL)
1063 goto oomem;
1065 if (prec < 0) {
1066 _DIAGASSERT(__type_fit(int,
1067 dtoaend - dtoaresult));
1068 prec = (int)(dtoaend - dtoaresult);
1070 if (expt == INT_MAX)
1071 ox[1] = '\0';
1072 _DIAGASSERT(__type_fit(int, dtoaend - dtoaresult));
1073 ndig = (int)(dtoaend - dtoaresult);
1074 if (convbuf != NULL)
1075 free(convbuf);
1076 #ifndef NARROW
1077 result = convbuf = __mbsconv(dtoaresult, -1);
1078 #else
1079 /*XXX inefficient*/
1080 result = convbuf = strdup(dtoaresult);
1081 #endif
1082 if (result == NULL)
1083 goto oomem;
1084 __freedtoa(dtoaresult);
1085 goto fp_common;
1086 case 'e':
1087 case 'E':
1088 expchar = ch;
1089 if (prec < 0) /* account for digit before decpt */
1090 prec = DEFPREC + 1;
1091 else
1092 prec++;
1093 goto fp_begin;
1094 case 'f':
1095 case 'F':
1096 expchar = '\0';
1097 goto fp_begin;
1098 case 'g':
1099 case 'G':
1100 expchar = ch - ('g' - 'e');
1101 if (prec == 0)
1102 prec = 1;
1103 fp_begin:
1104 if (prec < 0)
1105 prec = DEFPREC;
1106 if (flags & LONGDBL) {
1107 fparg.ldbl = GETARG(long double);
1108 dtoaresult =
1109 __ldtoa(&fparg.ldbl, expchar ? 2 : 3, prec,
1110 &expt, &signflag, &dtoaend);
1111 } else {
1112 fparg.dbl = GETARG(double);
1113 dtoaresult =
1114 __dtoa(fparg.dbl, expchar ? 2 : 3, prec,
1115 &expt, &signflag, &dtoaend);
1116 if (expt == 9999)
1117 expt = INT_MAX;
1119 if (dtoaresult == NULL)
1120 goto oomem;
1121 _DIAGASSERT(__type_fit(int, dtoaend - dtoaresult));
1122 ndig = (int)(dtoaend - dtoaresult);
1123 if (convbuf != NULL)
1124 free(convbuf);
1125 #ifndef NARROW
1126 result = convbuf = __mbsconv(dtoaresult, -1);
1127 #else
1128 /*XXX inefficient*/
1129 result = convbuf = strdup(dtoaresult);
1130 #endif
1131 if (result == NULL)
1132 goto oomem;
1133 __freedtoa(dtoaresult);
1134 fp_common:
1135 if (signflag)
1136 sign = '-';
1137 if (expt == INT_MAX) { /* inf or nan */
1138 if (*result == 'N') {
1139 result = (ch >= 'a') ? STRCONST("nan") :
1140 STRCONST("NAN");
1141 sign = '\0';
1142 } else
1143 result = (ch >= 'a') ? STRCONST("inf") :
1144 STRCONST("INF");
1145 size = 3;
1146 flags &= ~ZEROPAD;
1147 break;
1149 #else
1150 case 'e':
1151 case 'E':
1152 case 'f':
1153 case 'F':
1154 case 'g':
1155 case 'G':
1156 if (prec == -1) {
1157 prec = DEFPREC;
1158 } else if ((ch == 'g' || ch == 'G') && prec == 0) {
1159 prec = 1;
1162 if (flags & LONGDBL) {
1163 _double = (double) GETARG(long double);
1164 } else {
1165 _double = GETARG(double);
1168 /* do this before tricky precision changes */
1169 if (isinf(_double)) {
1170 if (_double < 0)
1171 sign = '-';
1172 if (ch == 'E' || ch == 'F' || ch == 'G')
1173 result = STRCONST("INF");
1174 else
1175 result = STRCONST("inf");
1176 size = 3;
1177 flags &= ~ZEROPAD;
1178 break;
1180 if (isnan(_double)) {
1181 if (ch == 'E' || ch == 'F' || ch == 'G')
1182 result = STRCONST("NAN");
1183 else
1184 result = STRCONST("nan");
1185 size = 3;
1186 flags &= ~ZEROPAD;
1187 break;
1190 flags |= FPT;
1191 dtoaresult = cvt(_double, prec, flags, &softsign,
1192 &expt, ch, &ndig);
1193 if (dtoaresult == NULL)
1194 goto oomem;
1195 if (convbuf != NULL)
1196 free(convbuf);
1197 #ifndef NARROW
1198 result = convbuf = __mbsconv(dtoaresult, -1);
1199 #else
1200 /*XXX inefficient*/
1201 result = convbuf = strdup(dtoaresult);
1202 #endif
1203 if (result == NULL)
1204 goto oomem;
1205 __freedtoa(dtoaresult);
1206 if (softsign)
1207 sign = '-';
1208 #endif
1209 flags |= FPT;
1210 if (ch == 'g' || ch == 'G') {
1211 if (expt > -4 && expt <= prec) {
1212 /* Make %[gG] smell like %[fF] */
1213 expchar = '\0';
1214 if (flags & ALT)
1215 prec -= expt;
1216 else
1217 prec = ndig - expt;
1218 if (prec < 0)
1219 prec = 0;
1220 } else {
1222 * Make %[gG] smell like %[eE], but
1223 * trim trailing zeroes if no # flag.
1225 if (!(flags & ALT))
1226 prec = ndig;
1229 if (expchar) {
1230 expsize = exponent(expstr, expt - 1, expchar);
1231 size = expsize + prec;
1232 if (prec > 1 || flags & ALT)
1233 ++size;
1234 } else {
1235 /* space for digits before decimal point */
1236 if (expt > 0)
1237 size = expt;
1238 else /* "0" */
1239 size = 1;
1240 /* space for decimal pt and following digits */
1241 if (prec || flags & ALT)
1242 size += prec + 1;
1243 if (grouping && expt > 0) {
1244 /* space for thousands' grouping */
1245 nseps = nrepeats = 0;
1246 lead = expt;
1247 while ((unsigned char)*grouping
1248 != (unsigned char)CHAR_MAX) {
1249 if (lead <= *grouping)
1250 break;
1251 lead -= *grouping;
1252 if (*(grouping+1)) {
1253 nseps++;
1254 grouping++;
1255 } else
1256 nrepeats++;
1258 size += nseps + nrepeats;
1259 } else
1260 lead = expt;
1262 break;
1263 #endif /* !NO_FLOATING_POINT */
1264 case 'n':
1266 * Assignment-like behavior is specified if the
1267 * value overflows or is otherwise unrepresentable.
1268 * C99 says to use `signed char' for %hhn conversions.
1270 if (flags & LLONGINT)
1271 *GETARG(long long *) = ret;
1272 else if (flags & SIZET)
1273 *GETARG(ssize_t *) = (ssize_t)ret;
1274 else if (flags & PTRDIFFT)
1275 *GETARG(ptrdiff_t *) = ret;
1276 else if (flags & INTMAXT)
1277 *GETARG(intmax_t *) = ret;
1278 else if (flags & LONGINT)
1279 *GETARG(long *) = ret;
1280 else if (flags & SHORTINT)
1281 *GETARG(short *) = ret;
1282 else if (flags & CHARINT)
1283 *GETARG(signed char *) = ret;
1284 else
1285 *GETARG(int *) = ret;
1286 continue; /* no output */
1287 case 'O':
1288 flags |= LONGINT;
1289 /*FALLTHROUGH*/
1290 case 'o':
1291 if (flags & INTMAX_SIZE)
1292 ujval = UJARG();
1293 else
1294 ulval = UARG();
1295 base = 8;
1296 goto nosign;
1297 case 'p':
1299 * ``The argument shall be a pointer to void. The
1300 * value of the pointer is converted to a sequence
1301 * of printable characters, in an implementation-
1302 * defined manner.''
1303 * -- ANSI X3J11
1305 ujval = (uintmax_t)(uintptr_t)GETARG(void *);
1306 base = 16;
1307 xdigs = xdigs_lower;
1308 flags = flags | INTMAXT;
1309 ox[1] = 'x';
1310 goto nosign;
1311 case 'S':
1312 flags |= LONGINT;
1313 /*FALLTHROUGH*/
1314 case 's':
1315 if ((flags & LONGINT) != MULTI) {
1316 if ((result = GETARG(CHAR_T *)) == NULL)
1317 result = STRCONST("(null)");
1318 } else {
1319 MCHAR_T *mc;
1321 if (convbuf != NULL)
1322 free(convbuf);
1323 if ((mc = GETARG(MCHAR_T *)) == NULL)
1324 result = STRCONST("(null)");
1325 else {
1326 convbuf = SCONV(mc, prec);
1327 if (convbuf == NULL) {
1328 fp->_flags |= __SERR;
1329 goto error;
1331 result = convbuf;
1335 if (prec >= 0) {
1337 * can't use STRLEN; can only look for the
1338 * NUL in the first `prec' characters, and
1339 * STRLEN() will go further.
1341 CHAR_T *p = MEMCHR(result, 0, (size_t)prec);
1343 if (p != NULL) {
1344 _DIAGASSERT(__type_fit(int,
1345 p - result));
1346 size = (int)(p - result);
1347 if (size > prec)
1348 size = prec;
1349 } else
1350 size = prec;
1351 } else {
1352 size_t rlen = STRLEN(result);
1353 _DIAGASSERT(__type_fit(int, rlen));
1354 size = (int)rlen;
1356 sign = '\0';
1357 break;
1358 case 'U':
1359 flags |= LONGINT;
1360 /*FALLTHROUGH*/
1361 case 'u':
1362 if (flags & INTMAX_SIZE)
1363 ujval = UJARG();
1364 else
1365 ulval = UARG();
1366 base = 10;
1367 goto nosign;
1368 case 'X':
1369 xdigs = xdigs_upper;
1370 goto hex;
1371 case 'x':
1372 xdigs = xdigs_lower;
1373 hex:
1374 if (flags & INTMAX_SIZE)
1375 ujval = UJARG();
1376 else
1377 ulval = UARG();
1378 base = 16;
1379 /* leading 0x/X only if non-zero */
1380 if (flags & ALT &&
1381 (flags & INTMAX_SIZE ? ujval != 0 : ulval != 0))
1382 ox[1] = ch;
1384 flags &= ~GROUPING;
1385 /* unsigned conversions */
1386 nosign: sign = '\0';
1388 * ``... diouXx conversions ... if a precision is
1389 * specified, the 0 flag will be ignored.''
1390 * -- ANSI X3J11
1392 number: if ((dprec = prec) >= 0)
1393 flags &= ~ZEROPAD;
1396 * ``The result of converting a zero value with an
1397 * explicit precision of zero is no characters.''
1398 * -- ANSI X3J11
1400 * ``The C Standard is clear enough as is. The call
1401 * printf("%#.0o", 0) should print 0.''
1402 * -- Defect Report #151
1404 result = cp = buf + BUF;
1405 if (flags & INTMAX_SIZE) {
1406 if (ujval != 0 || prec != 0 ||
1407 (flags & ALT && base == 8))
1408 result = __ujtoa(ujval, cp, base,
1409 flags & ALT, xdigs,
1410 flags & GROUPING, thousands_sep,
1411 grouping);
1412 } else {
1413 if (ulval != 0 || prec != 0 ||
1414 (flags & ALT && base == 8))
1415 result = __ultoa(ulval, cp, base,
1416 flags & ALT, xdigs,
1417 flags & GROUPING, thousands_sep,
1418 grouping);
1420 _DIAGASSERT(__type_fit(int, buf + BUF - result));
1421 size = (int)(buf + BUF - result);
1422 if (size > BUF) /* should never happen */
1423 abort();
1424 break;
1425 default: /* "%?" prints ?, unless ? is NUL */
1426 if (ch == '\0')
1427 goto done;
1428 /* pretend it was %c with argument ch */
1429 *buf = ch;
1430 result = buf;
1431 size = 1;
1432 sign = '\0';
1433 break;
1437 * All reasonable formats wind up here. At this point, `result'
1438 * points to a string which (if not flags&LADJUST) should be
1439 * padded out to `width' places. If flags&ZEROPAD, it should
1440 * first be prefixed by any sign or other prefix; otherwise,
1441 * it should be blank padded before the prefix is emitted.
1442 * After any left-hand padding and prefixing, emit zeroes
1443 * required by a decimal [diouxX] precision, then print the
1444 * string proper, then emit zeroes required by any leftover
1445 * floating precision; finally, if LADJUST, pad with blanks.
1447 * Compute actual size, so we know how much to pad.
1448 * size excludes decimal prec; realsz includes it.
1450 realsz = dprec > size ? dprec : size;
1451 if (sign)
1452 realsz++;
1453 if (ox[1])
1454 realsz += 2;
1456 prsize = width > realsz ? width : realsz;
1457 if ((unsigned)ret + prsize > INT_MAX) {
1458 ret = END_OF_FILE;
1459 goto error;
1462 /* right-adjusting blank padding */
1463 if ((flags & (LADJUST|ZEROPAD)) == 0)
1464 PAD(width - realsz, blanks);
1466 /* prefix */
1467 if (sign)
1468 PRINT(&sign, 1);
1470 if (ox[1]) { /* ox[1] is either x, X, or \0 */
1471 ox[0] = '0';
1472 PRINT(ox, 2);
1475 /* right-adjusting zero padding */
1476 if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)
1477 PAD(width - realsz, zeroes);
1479 /* leading zeroes from decimal precision */
1480 PAD(dprec - size, zeroes);
1482 /* the string or number proper */
1483 #ifndef NO_FLOATING_POINT
1484 if ((flags & FPT) == 0) {
1485 PRINT(result, size);
1486 } else { /* glue together f_p fragments */
1487 if (!expchar) { /* %[fF] or sufficiently short %[gG] */
1488 if (expt <= 0) {
1489 PRINT(zeroes, 1);
1490 if (prec || flags & ALT)
1491 PRINT(decimal_point, 1);
1492 PAD(-expt, zeroes);
1493 /* already handled initial 0's */
1494 prec += expt;
1495 } else {
1496 PRINTANDPAD(result, convbuf + ndig,
1497 lead, zeroes);
1498 result += lead;
1499 if (grouping) {
1500 while (nseps>0 || nrepeats>0) {
1501 if (nrepeats > 0)
1502 nrepeats--;
1503 else {
1504 grouping--;
1505 nseps--;
1507 PRINT(&thousands_sep,
1509 PRINTANDPAD(result,
1510 convbuf + ndig,
1511 *grouping, zeroes);
1512 result += *grouping;
1514 if (result > convbuf + ndig)
1515 result = convbuf + ndig;
1517 if (prec || flags & ALT) {
1518 buf[0] = *decimal_point;
1519 PRINT(buf, 1);
1522 PRINTANDPAD(result, convbuf + ndig, prec,
1523 zeroes);
1524 } else { /* %[eE] or sufficiently long %[gG] */
1525 if (prec > 1 || flags & ALT) {
1526 buf[0] = *result++;
1527 buf[1] = *decimal_point;
1528 PRINT(buf, 2);
1529 PRINT(result, ndig-1);
1530 PAD(prec - ndig, zeroes);
1531 } else /* XeYYY */
1532 PRINT(result, 1);
1533 PRINT(expstr, expsize);
1536 #else
1537 PRINT(result, size);
1538 #endif
1539 /* left-adjusting padding (always blank) */
1540 if (flags & LADJUST)
1541 PAD(width - realsz, blanks);
1543 /* finally, adjust ret */
1544 ret += prsize;
1545 FLUSH();
1547 done:
1548 FLUSH();
1549 error:
1550 va_end(orgap);
1551 if (convbuf != NULL)
1552 free(convbuf);
1553 if (__sferror(fp))
1554 ret = END_OF_FILE;
1555 if ((argtable != NULL) && (argtable != statargtable))
1556 free (argtable);
1557 return ret;
1558 /* NOTREACHED */
1559 oomem:
1560 errno = ENOMEM;
1561 ret = END_OF_FILE;
1562 goto error;
1566 * Find all arguments when a positional parameter is encountered. Returns a
1567 * table, indexed by argument number, of pointers to each arguments. The
1568 * initial argument table should be an array of STATIC_ARG_TBL_SIZE entries.
1569 * It will be replaces with a malloc-ed one if it overflows.
1571 static int
1572 __find_arguments(const CHAR_T *fmt0, va_list ap, union arg **argtable)
1574 CHAR_T *fmt; /* format string */
1575 int ch; /* character from fmt */
1576 size_t n, n2; /* handy index (short term usage) */
1577 CHAR_T *cp; /* handy char pointer (short term usage) */
1578 int flags; /* flags as above */
1579 enum typeid *typetable; /* table of types */
1580 enum typeid stattypetable [STATIC_ARG_TBL_SIZE];
1581 size_t tablesize; /* current size of type table */
1582 size_t tablemax; /* largest used index in table */
1583 size_t nextarg; /* 1-based argument index */
1584 size_t nitems; /* number of items we picked from the stack */
1587 * Add an argument type to the table, expanding if necessary.
1588 * Check for overflow.
1590 #define ADDTYPE(type) \
1591 do { \
1592 if (nextarg > SIZE_MAX / sizeof(**argtable)) { \
1593 if (typetable != stattypetable) \
1594 free(typetable); \
1595 return -1; \
1597 if (nextarg >= tablesize) \
1598 if (__grow_type_table(nextarg, &typetable, \
1599 &tablesize) == -1) \
1600 return -1; \
1601 if (nextarg > tablemax) \
1602 tablemax = nextarg; \
1603 typetable[nextarg++] = type; \
1604 nitems++; \
1605 } while (/*CONSTCOND*/0)
1607 #define ADDSARG() \
1608 do { \
1609 if (flags & INTMAXT) \
1610 ADDTYPE(T_INTMAXT); \
1611 else if (flags & SIZET) \
1612 ADDTYPE(T_SSIZET); \
1613 else if (flags & PTRDIFFT) \
1614 ADDTYPE(T_PTRDIFFT); \
1615 else if (flags & LLONGINT) \
1616 ADDTYPE(T_LLONG); \
1617 else if (flags & LONGINT) \
1618 ADDTYPE(T_LONG); \
1619 else \
1620 ADDTYPE(T_INT); \
1621 } while (/*CONSTCOND*/0)
1623 #define ADDUARG() \
1624 do { \
1625 if (flags & INTMAXT) \
1626 ADDTYPE(T_UINTMAXT); \
1627 else if (flags & SIZET) \
1628 ADDTYPE(T_SIZET); \
1629 else if (flags & PTRDIFFT) \
1630 ADDTYPE(T_PTRDIFFT); \
1631 else if (flags & LLONGINT) \
1632 ADDTYPE(T_U_LLONG); \
1633 else if (flags & LONGINT) \
1634 ADDTYPE(T_U_LONG); \
1635 else \
1636 ADDTYPE(T_U_INT); \
1637 } while (/*CONSTCOND*/0)
1639 * Add * arguments to the type array.
1641 #define ADDASTER() \
1642 n2 = 0; \
1643 cp = fmt; \
1644 while (is_digit(*cp)) { \
1645 n2 = 10 * n2 + to_digit(*cp); \
1646 cp++; \
1648 if (*cp == '$') { \
1649 size_t hold = nextarg; \
1650 nextarg = n2; \
1651 ADDTYPE(T_INT); \
1652 nextarg = hold; \
1653 fmt = ++cp; \
1654 } else { \
1655 ADDTYPE(T_INT); \
1657 fmt = (CHAR_T *)__UNCONST(fmt0);
1658 memset(stattypetable, 0, sizeof(stattypetable));
1659 typetable = stattypetable;
1660 tablesize = STATIC_ARG_TBL_SIZE;
1661 tablemax = 0;
1662 nextarg = 1;
1663 nitems = 1;
1666 * Scan the format for conversions (`%' character).
1668 for (;;) {
1669 for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)
1670 /* void */;
1671 if (ch == '\0')
1672 goto done;
1673 fmt++; /* skip over '%' */
1675 flags = 0;
1677 rflag: ch = *fmt++;
1678 reswitch: switch (ch) {
1679 case ' ':
1680 case '#':
1681 goto rflag;
1682 case '*':
1683 ADDASTER ();
1684 goto rflag;
1685 case '-':
1686 case '+':
1687 case '\'':
1688 goto rflag;
1689 case '.':
1690 if ((ch = *fmt++) == '*') {
1691 ADDASTER ();
1692 goto rflag;
1694 while (is_digit(ch)) {
1695 ch = *fmt++;
1697 goto reswitch;
1698 case '0':
1699 goto rflag;
1700 case '1': case '2': case '3': case '4':
1701 case '5': case '6': case '7': case '8': case '9':
1702 n = 0;
1703 do {
1704 n = 10 * n + to_digit(ch);
1705 ch = *fmt++;
1706 } while (is_digit(ch));
1707 if (ch == '$') {
1708 nextarg = n;
1709 goto rflag;
1711 goto reswitch;
1712 #ifndef NO_FLOATING_POINT
1713 case 'L':
1714 flags |= LONGDBL;
1715 goto rflag;
1716 #endif
1717 case 'h':
1718 if (flags & SHORTINT) {
1719 flags &= ~SHORTINT;
1720 flags |= CHARINT;
1721 } else
1722 flags |= SHORTINT;
1723 goto rflag;
1724 case 'j':
1725 flags |= INTMAXT;
1726 goto rflag;
1727 case 'l':
1728 if (flags & LONGINT) {
1729 flags &= ~LONGINT;
1730 flags |= LLONGINT;
1731 } else
1732 flags |= LONGINT;
1733 goto rflag;
1734 case 'q':
1735 flags |= LLONGINT; /* not necessarily */
1736 goto rflag;
1737 case 't':
1738 flags |= PTRDIFFT;
1739 goto rflag;
1740 case 'z':
1741 flags |= SIZET;
1742 goto rflag;
1743 case 'C':
1744 flags |= LONGINT;
1745 /*FALLTHROUGH*/
1746 case 'c':
1747 if (flags & LONGINT)
1748 ADDTYPE(T_WINT);
1749 else
1750 ADDTYPE(T_INT);
1751 break;
1752 case 'D':
1753 flags |= LONGINT;
1754 /*FALLTHROUGH*/
1755 case 'd':
1756 case 'i':
1757 ADDSARG();
1758 break;
1759 #ifndef NO_FLOATING_POINT
1760 case 'a':
1761 case 'A':
1762 case 'e':
1763 case 'E':
1764 case 'f':
1765 case 'g':
1766 case 'G':
1767 if (flags & LONGDBL)
1768 ADDTYPE(T_LONG_DOUBLE);
1769 else
1770 ADDTYPE(T_DOUBLE);
1771 break;
1772 #endif /* !NO_FLOATING_POINT */
1773 case 'n':
1774 if (flags & INTMAXT)
1775 ADDTYPE(TP_INTMAXT);
1776 else if (flags & PTRDIFFT)
1777 ADDTYPE(TP_PTRDIFFT);
1778 else if (flags & SIZET)
1779 ADDTYPE(TP_SIZET);
1780 else if (flags & LLONGINT)
1781 ADDTYPE(TP_LLONG);
1782 else if (flags & LONGINT)
1783 ADDTYPE(TP_LONG);
1784 else if (flags & SHORTINT)
1785 ADDTYPE(TP_SHORT);
1786 else if (flags & CHARINT)
1787 ADDTYPE(TP_SCHAR);
1788 else
1789 ADDTYPE(TP_INT);
1790 continue; /* no output */
1791 case 'O':
1792 flags |= LONGINT;
1793 /*FALLTHROUGH*/
1794 case 'o':
1795 ADDUARG();
1796 break;
1797 case 'p':
1798 ADDTYPE(TP_VOID);
1799 break;
1800 case 'S':
1801 flags |= LONGINT;
1802 /*FALLTHROUGH*/
1803 case 's':
1804 if (flags & LONGINT)
1805 ADDTYPE(TP_WCHAR);
1806 else
1807 ADDTYPE(TP_CHAR);
1808 break;
1809 case 'U':
1810 flags |= LONGINT;
1811 /*FALLTHROUGH*/
1812 case 'u':
1813 case 'X':
1814 case 'x':
1815 ADDUARG();
1816 break;
1817 default: /* "%?" prints ?, unless ? is NUL */
1818 if (ch == '\0')
1819 goto done;
1820 break;
1823 done:
1825 * nitems contains the number of arguments we picked from the stack.
1826 * If tablemax is larger, this means that some positional argument,
1827 * tried to pick an argument the number of arguments possibly supplied.
1828 * Since positional arguments are typically used to swap the order of
1829 * the printf arguments and not to pick random arguments from strange
1830 * positions in the stack, we assume that if the positional argument
1831 * is trying to pick beyond the end of arguments, then this is wrong.
1832 * Alternatively we could find a way to figure out when va_arg() runs
1833 * out, but how to do that?
1835 if (nitems < tablemax) {
1836 if (typetable != stattypetable)
1837 free(typetable);
1838 return -1;
1841 * Build the argument table.
1843 if (tablemax >= STATIC_ARG_TBL_SIZE) {
1844 *argtable = malloc(sizeof(**argtable) * (tablemax + 1));
1845 if (*argtable == NULL) {
1846 free(typetable);
1847 return -1;
1851 (*argtable) [0].intarg = 0;
1852 for (n = 1; n <= tablemax; n++) {
1853 switch (typetable [n]) {
1854 case T_UNUSED: /* whoops! */
1855 (*argtable) [n].intarg = va_arg (ap, int);
1856 break;
1857 case TP_SCHAR:
1858 (*argtable) [n].pschararg = va_arg (ap, signed char *);
1859 break;
1860 case TP_SHORT:
1861 (*argtable) [n].pshortarg = va_arg (ap, short *);
1862 break;
1863 case T_INT:
1864 (*argtable) [n].intarg = va_arg (ap, int);
1865 break;
1866 case T_U_INT:
1867 (*argtable) [n].uintarg = va_arg (ap, unsigned int);
1868 break;
1869 case TP_INT:
1870 (*argtable) [n].pintarg = va_arg (ap, int *);
1871 break;
1872 case T_LONG:
1873 (*argtable) [n].longarg = va_arg (ap, long);
1874 break;
1875 case T_U_LONG:
1876 (*argtable) [n].ulongarg = va_arg (ap, unsigned long);
1877 break;
1878 case TP_LONG:
1879 (*argtable) [n].plongarg = va_arg (ap, long *);
1880 break;
1881 case T_LLONG:
1882 (*argtable) [n].longlongarg = va_arg (ap, long long);
1883 break;
1884 case T_U_LLONG:
1885 (*argtable) [n].ulonglongarg = va_arg (ap, unsigned long long);
1886 break;
1887 case TP_LLONG:
1888 (*argtable) [n].plonglongarg = va_arg (ap, long long *);
1889 break;
1890 case T_PTRDIFFT:
1891 (*argtable) [n].ptrdiffarg = va_arg (ap, ptrdiff_t);
1892 break;
1893 case TP_PTRDIFFT:
1894 (*argtable) [n].pptrdiffarg = va_arg (ap, ptrdiff_t *);
1895 break;
1896 case T_SSIZET:
1897 (*argtable) [n].ssizearg = va_arg (ap, ssize_t);
1898 break;
1899 case T_SIZET:
1900 (*argtable) [n].sizearg = va_arg (ap, size_t);
1901 break;
1902 case TP_SIZET:
1903 (*argtable) [n].psizearg = va_arg (ap, size_t *);
1904 break;
1905 case T_INTMAXT:
1906 (*argtable) [n].intmaxarg = va_arg (ap, intmax_t);
1907 break;
1908 case T_UINTMAXT:
1909 (*argtable) [n].uintmaxarg = va_arg (ap, uintmax_t);
1910 break;
1911 case TP_INTMAXT:
1912 (*argtable) [n].pintmaxarg = va_arg (ap, intmax_t *);
1913 break;
1914 case T_DOUBLE:
1915 #ifndef NO_FLOATING_POINT
1916 (*argtable) [n].doublearg = va_arg (ap, double);
1917 #endif
1918 break;
1919 case T_LONG_DOUBLE:
1920 #ifndef NO_FLOATING_POINT
1921 (*argtable) [n].longdoublearg = va_arg (ap, long double);
1922 #endif
1923 break;
1924 case TP_CHAR:
1925 (*argtable) [n].pchararg = va_arg (ap, char *);
1926 break;
1927 case TP_VOID:
1928 (*argtable) [n].pvoidarg = va_arg (ap, void *);
1929 break;
1930 case T_WINT:
1931 (*argtable) [n].wintarg = va_arg (ap, wint_t);
1932 break;
1933 case TP_WCHAR:
1934 (*argtable) [n].pwchararg = va_arg (ap, wchar_t *);
1935 break;
1939 if (typetable != stattypetable)
1940 free (typetable);
1941 return 0;
1945 * Increase the size of the type table.
1947 static int
1948 __grow_type_table (size_t nextarg, enum typeid **typetable, size_t *tablesize)
1950 enum typeid *const oldtable = *typetable;
1951 const size_t oldsize = *tablesize;
1952 enum typeid *newtable;
1953 size_t newsize = oldsize * 2;
1955 if (newsize < nextarg + 1)
1956 newsize = nextarg + 1;
1957 if (oldsize == STATIC_ARG_TBL_SIZE) {
1958 if ((newtable = malloc(newsize * sizeof(*newtable))) == NULL)
1959 return -1;
1960 memcpy(newtable, oldtable, oldsize * sizeof(*newtable));
1961 } else {
1962 newtable = realloc(oldtable, newsize * sizeof(*newtable));
1963 if (newtable == NULL) {
1964 free(oldtable);
1965 return -1;
1968 memset(&newtable[oldsize], 0, (newsize - oldsize) * sizeof(*newtable));
1970 *typetable = newtable;
1971 *tablesize = newsize;
1972 return 0;
1976 #ifndef NO_FLOATING_POINT
1977 #ifndef WIDE_DOUBLE
1978 static char *
1979 cvt(double value, int ndigits, int flags, char *sign, int *decpt, int ch,
1980 int *length)
1982 int mode, dsgn;
1983 char *digits, *bp, *rve;
1985 _DIAGASSERT(decpt != NULL);
1986 _DIAGASSERT(length != NULL);
1987 _DIAGASSERT(sign != NULL);
1989 if (ch == 'f') {
1990 mode = 3; /* ndigits after the decimal point */
1991 } else {
1992 /* To obtain ndigits after the decimal point for the 'e'
1993 * and 'E' formats, round to ndigits + 1 significant
1994 * figures.
1996 if (ch == 'e' || ch == 'E') {
1997 ndigits++;
1999 mode = 2; /* ndigits significant digits */
2002 digits = __dtoa(value, mode, ndigits, decpt, &dsgn, &rve);
2003 if (digits == NULL)
2004 return NULL;
2005 if (dsgn) {
2006 value = -value;
2007 *sign = '-';
2008 } else
2009 *sign = '\000';
2010 if ((ch != 'g' && ch != 'G') || flags & ALT) { /* Print trailing zeros */
2011 bp = digits + ndigits;
2012 if (ch == 'f') {
2013 if (*digits == '0' && value)
2014 *decpt = -ndigits + 1;
2015 bp += *decpt;
2017 if (value == 0) /* kludge for __dtoa irregularity */
2018 rve = bp;
2019 while (rve < bp)
2020 *rve++ = '0';
2022 *length = rve - digits;
2023 return digits;
2025 #endif
2027 static int
2028 exponent(CHAR_T *p0, int expo, int fmtch)
2030 CHAR_T *p, *t;
2031 CHAR_T expbuf[MAXEXPDIG];
2033 p = p0;
2034 *p++ = fmtch;
2035 if (expo < 0) {
2036 expo = -expo;
2037 *p++ = '-';
2039 else
2040 *p++ = '+';
2041 t = expbuf + MAXEXPDIG;
2042 if (expo > 9) {
2043 do {
2044 *--t = to_char(expo % 10);
2045 } while ((expo /= 10) > 9);
2046 *--t = to_char(expo);
2047 for (; t < expbuf + MAXEXPDIG; *p++ = *t++);
2049 else {
2051 * Exponents for decimal floating point conversions
2052 * (%[eEgG]) must be at least two characters long,
2053 * whereas exponents for hexadecimal conversions can
2054 * be only one character long.
2056 if (fmtch == 'e' || fmtch == 'E')
2057 *p++ = '0';
2058 *p++ = to_char(expo);
2060 _DIAGASSERT(__type_fit(int, p - p0));
2061 return (int)(p - p0);
2063 #endif /* !NO_FLOATING_POINT */