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