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