]>
git.proxmox.com Git - mirror_edk2.git/blob - StdLib/LibC/Stdio/vfwprintf.c
2 Implementation of internals for printf and wprintf.
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.
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.
13 Copyright (c) 1990, 1993
14 The Regents of the University of California. All rights reserved.
16 This code is derived from software contributed to Berkeley by
19 Redistribution and use in source and binary forms, with or without
20 modification, are permitted provided that the following conditions
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.
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.
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
46 #include <LibConfig.h>
48 #include "namespace.h"
49 #include <sys/types.h>
65 #include "reentrant.h"
71 // Keep compiler quiet about conversions from larger to smaller types.
72 #pragma warning ( disable : 4244 )
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
86 #define MCHAR_T wchar_t
88 #define STRLEN(a) strlen(a)
89 #define MEMCHR(a, b, c) memchr(a, b, c)
90 #define SCONV(a, b) __wcsconv(a, b)
92 #define WDECL(a, b) a ## b
93 #define END_OF_FILE EOF
101 unsigned long ulongarg
;
102 long long longlongarg
;
103 unsigned long long ulonglongarg
;
104 ptrdiff_t ptrdiffarg
;
107 uintmax_t uintmaxarg
;
110 signed char *pschararg
;
114 long long *plonglongarg
;
115 ptrdiff_t *pptrdiffarg
;
117 intmax_t *pintmaxarg
;
118 #ifndef NO_FLOATING_POINT
120 long double longdoublearg
;
127 * Type ids for argument type table.
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
137 static int __sbprintf(FILE *, const CHAR_T
*, va_list);
138 static CHAR_T
*__ujtoa(uintmax_t, CHAR_T
*, int, int, const char *, int,
140 static CHAR_T
*__ultoa(u_long
, CHAR_T
*, int, int, const char *, int,
143 static CHAR_T
*__mbsconv(char *, int);
144 static wint_t __xfputwc(CHAR_T
, FILE *);
146 static char *__wcsconv(wchar_t *, int);
147 static int __sprint(FILE *, struct __suio
*);
149 static int __find_arguments(const CHAR_T
*, va_list, union arg
**);
150 static int __grow_type_table(int, enum typeid **, int *);
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.
158 __sbprintf(FILE *fp
, const CHAR_T
*fmt
, va_list ap
)
162 struct __sfileext fakeext
;
163 unsigned char buf
[BUFSIZ
];
165 _DIAGASSERT(fp
!= NULL
);
166 _DIAGASSERT(fmt
!= NULL
);
172 _FILEEXT_SETUP(&fake
, &fakeext
);
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
;
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 */
185 /* do the work, then copy any error status */
186 ret
= WDECL(__vf
,printf_unlocked
)(&fake
, fmt
, ap
);
187 if (ret
>= 0 && fflush(&fake
))
189 if (fake
._flags
& __SERR
)
190 fp
->_flags
|= __SERR
;
196 * Like __fputwc, but handles fake string (__SSTR) files properly.
197 * File must already be locked.
200 __xfputwc(wchar_t wc
, FILE *fp
)
202 static const mbstate_t initial
= { 0 };
204 char buf
[MB_LEN_MAX
];
209 if ((fp
->_flags
& __SSTR
) == 0)
210 return (__fputwc_unlock(wc
, fp
));
213 if ((len
= wcrtomb(buf
, wc
, &mbs
)) == (size_t)-1) {
214 fp
->_flags
|= __SERR
;
215 return (END_OF_FILE
);
218 uio
.uio_resid
= (int)len
;
222 return (__sfvwrite(fp
, &uio
) != EOF
? (wint_t)wc
: END_OF_FILE
);
226 * Flush out all the vectors defined by the given uio,
227 * then reset it so that it can be reused.
230 __sprint(FILE *fp
, struct __suio
*uio
)
234 _DIAGASSERT(fp
!= NULL
);
235 _DIAGASSERT(uio
!= NULL
);
241 if (uio
->uio_resid
== 0) {
245 err
= __sfvwrite(fp
, uio
);
253 * Macros for converting digits to letters and vice versa
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')
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.
266 __ultoa(u_long val
, CHAR_T
*endp
, int base
, int octzero
, const char *xdigs
,
267 int needgrp
, char thousep
, const char *grp
)
274 * Handle the three cases separately, in the hope of getting
275 * better/faster code.
279 if (val
< 10) { /* many numbers are 1 digit */
280 *--cp
= to_char(val
);
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.
290 if (val
> LONG_MAX
) {
291 *--cp
= to_char(val
% 10);
293 sval
= (LONGN
)(val
/ 10);
297 *--cp
= to_char(sval
% 10);
300 * If (*grp == CHAR_MAX) then no more grouping
301 * should be performed.
303 if (needgrp
&& ndig
== *grp
&& *grp
!= CHAR_MAX
308 * If (*(grp+1) == '\0') then we have to
309 * use *grp character (last grouping rule)
312 if (*(grp
+1) != '\0')
321 *--cp
= to_char(val
& 7);
324 if (octzero
&& *cp
!= '0')
330 *--cp
= xdigs
[(size_t)val
& 15];
341 /* Identical to __ultoa, but for intmax_t. */
343 __ujtoa(uintmax_t val
, CHAR_T
*endp
, int base
, int octzero
,
344 const char *xdigs
, int needgrp
, char thousep
, const char *grp
)
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
));
358 *--cp
= to_char(val
% 10);
362 if (val
> INTMAX_MAX
) {
363 *--cp
= to_char(val
% 10);
369 *--cp
= to_char(sval
% 10);
372 * If (*grp == CHAR_MAX) then no more grouping
373 * should be performed.
375 if (needgrp
&& *grp
!= CHAR_MAX
&& ndig
== *grp
380 * If (*(grp+1) == '\0') then we have to
381 * use *grp character (last grouping rule)
384 if (*(grp
+1) != '\0')
393 *--cp
= to_char(val
& 7);
396 if (octzero
&& *cp
!= '0')
402 *--cp
= xdigs
[(size_t)val
& 15];
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.
421 __mbsconv(char *mbsarg
, int prec
)
423 static const mbstate_t initial
= { 0 };
425 wchar_t *convbuf
, *wcp
;
427 size_t insize
, nchars
, nconv
;
433 * Supplied argument is a multibyte string; convert it to wide
438 * String is not guaranteed to be NUL-terminated. Find the
439 * number of characters to print.
442 insize
= nchars
= nconv
= 0;
444 while (nchars
!= (size_t)prec
) {
445 nconv
= mbrlen(p
, MB_CUR_MAX
, &mbs
);
446 if (nconv
== 0 || nconv
== (size_t)-1 ||
453 if (nconv
== (size_t)-1 || nconv
== (size_t)-2)
456 insize
= strlen(mbsarg
);
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.
463 convbuf
= malloc((insize
+ 1) * sizeof(*convbuf
));
470 while (insize
!= 0) {
471 nconv
= mbrtowc(wcp
, p
, insize
, &mbs
);
472 if (nconv
== 0 || nconv
== (size_t)-1 || nconv
== (size_t)-2)
478 if (nconv
== (size_t)-1 || nconv
== (size_t)-2) {
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.
494 __wcsconv(wchar_t *wcsarg
, int prec
)
496 static const mbstate_t initial
= { 0 };
498 char buf
[MB_LEN_MAX
];
503 /* Allocate space for the maximum number of bytes we could output. */
507 nbytes
= wcsrtombs(NULL
, (const wchar_t **)&p
, 0, &mbs
);
508 if (nbytes
== (size_t)-1)
512 * Optimisation: if the output precision is small enough,
513 * just allocate enough memory for the maximum instead of
514 * scanning the string.
523 clen
= wcrtomb(buf
, *p
++, &mbs
);
524 if (clen
== 0 || clen
== (size_t)-1 ||
525 nbytes
+ clen
> (size_t)prec
)
531 if ((convbuf
= malloc(nbytes
+ 1)) == NULL
)
534 /* Fill the output buffer. */
537 if ((nbytes
= wcsrtombs(convbuf
, (const wchar_t **)&p
,
538 nbytes
, &mbs
)) == (size_t)-1) {
542 convbuf
[nbytes
] = '\0';
551 WDECL(vf
,printf
)(FILE * __restrict fp
, const CHAR_T
* __restrict fmt0
, va_list ap
)
560 ret
= WDECL(__vf
,printf_unlocked
)(fp
, fmt0
, ap
);
565 #ifndef NO_FLOATING_POINT
573 static int exponent(CHAR_T
*, int, int);
575 static char *cvt(double, int, int, char *, int *, int, int *);
578 #endif /* !NO_FLOATING_POINT */
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.
589 #define STATIC_ARG_TBL_SIZE 8 /* Size of static argument table. */
592 * Flags used during conversion.
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 */
610 * Non-MT-safe version
613 WDECL(__vf
,printf_unlocked
)(FILE *fp
, const CHAR_T
*fmt0
, va_list ap
)
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
628 * We can decompose the printed representation of floating
629 * point numbers into several parts, some of which may be empty:
631 * [+|-| ] [0x|0X] MMM . NNN [e|E|p|P] [+|-] ZZ
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
641 char *decimal_point
; /* locale specific decimal point */
643 int signflag
; /* true if float is negative */
644 union { /* floating point arguments %[aAeEfFgG] */
648 char *dtoaend
; /* pointer to end of converted digits */
650 double _double
; /* double precision arguments %[eEfgG] */
651 char softsign
; /* temporary negative sign for floats */
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 */
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 */
673 struct __siov
*iovp
; /* for PRINT macro */
674 struct __suio uio
; /* output information: summary */
675 struct __siov iov
[NIOV
];/* ... and individual io vectors */
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 */
688 * Choose PADSIZE to trade efficiency vs. size. If larger printf
689 * fields occur frequently, increase PADSIZE and make the initialisers
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'};
698 static const char xdigs_lower
[17] = "0123456789abcdef";
699 static const char xdigs_upper
[17] = "0123456789ABCDEF";
702 * BEWARE, these `goto error' on error, PRINT uses `n2' and
706 #define PRINT(ptr, len) do { \
707 for (n3 = 0; n3 < (len); n3++) \
708 __xfputwc((ptr)[n3], fp); \
709 } while (/*CONSTCOND*/0)
712 #define PRINT(ptr, len) do { \
713 iovp->iov_base = __UNCONST(ptr); \
714 iovp->iov_len = (len); \
715 uio.uio_resid += (len); \
717 if (++uio.uio_iovcnt >= NIOV) { \
718 if (__sprint(fp, &uio)) \
722 } while (/*CONSTCOND*/0)
723 #define FLUSH() do { \
724 if (uio.uio_resid && __sprint(fp, &uio)) \
726 uio.uio_iovcnt = 0; \
728 } while (/*CONSTCOND*/0)
731 #define PAD(howmany, with) do { \
732 if ((n = (howmany)) > 0) { \
733 while (n > PADSIZE) { \
734 PRINT(with, PADSIZE); \
739 } while (/*CONSTCOND*/0)
740 #define PRINTANDPAD(p, ep, len, with) do { \
746 PAD((len) - (n2 > 0 ? n2 : 0), (with)); \
747 } while(/*CONSTCOND*/0)
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).
754 #define GETARG(type) \
755 ((/*CONSTCOND*/argtable != NULL) ? *((type*)(void*)(&argtable[nextarg++])) : \
756 (nextarg++, va_arg(ap, type)))
759 * To extend shorts properly, we need both signed and unsigned
760 * argument extraction methods.
763 ((long)(flags&LONGINT ? GETARG(long) : \
764 flags&SHORTINT ? (short)GETARG(int) : \
765 flags&CHARINT ? (signed char)GETARG(int) : \
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)))
774 #define INTMAX_SIZE (INTMAXT|SIZET|PTRDIFFT|LLONGINT)
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))
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))
789 * Get * arguments, including the form *nn$. Preserve the nextarg
790 * that the argument can be gotten once the type is determined.
792 #define GETASTER(val) \
795 while (is_digit(*cp)) { \
796 n2 = 10 * n2 + to_digit(*cp); \
800 int hold = nextarg; \
801 if (argtable == NULL) { \
802 argtable = statargtable; \
803 if (__find_arguments(fmt0, orgap, &argtable) == -1) \
807 val = GETARG (int); \
811 val = GETARG (int); \
814 _DIAGASSERT(fp
!= NULL
);
815 _DIAGASSERT(fmt0
!= NULL
);
821 _SET_ORIENTATION(fp
, -1);
823 ndig
= -1; /* XXX gcc */
825 thousands_sep
= '\0';
827 #ifndef NO_FLOATING_POINT
828 decimal_point
= localeconv()->decimal_point
;
829 expsize
= 0; /* XXXGCC -Wuninitialized [sh3,m68000] */
832 /* sorry, f{w,}printf(read_only_file, L"") returns {W,}EOF, not 0 */
835 return (END_OF_FILE
);
838 /* optimise fprintf(stderr) (and other unbuffered Unix files) */
839 if ((fp
->_flags
& (__SNBF
|__SWR
|__SRW
)) == (__SNBF
|__SWR
) &&
841 return (__sbprintf(fp
, fmt0
, ap
));
843 fmt
= (CHAR_T
*)__UNCONST(fmt0
);
848 uio
.uio_iov
= iovp
= iov
;
855 * Scan the format for conversions (`%' character).
859 const CHAR_T
*result
;
861 for (cp
= fmt
; (ch
= *fmt
) != '\0' && ch
!= '%'; fmt
++)
863 if ((n
= (int)(fmt
- cp
)) != 0) {
864 if ((unsigned)ret
+ n
> INT_MAX
) {
873 fmt
++; /* skip over '%' */
883 nseps
= nrepeats
= 0;
889 reswitch
: switch (ch
) {
892 * ``If the space and + flags both appear, the space
893 * flag will be ignored.''
904 * ``A negative field width argument is taken as a
905 * - flag followed by a positive field width.''
907 * They don't exclude field widths read from args.
922 thousands_sep
= *(localeconv()->thousands_sep
);
923 grouping
= localeconv()->grouping
;
926 if ((ch
= *fmt
++) == '*') {
931 while (is_digit(ch
)) {
932 prec
= 10 * prec
+ to_digit(ch
);
938 * ``Note that 0 is taken as a flag, not as the
939 * beginning of a field width.''
944 case '1': case '2': case '3': case '4':
945 case '5': case '6': case '7': case '8': case '9':
948 n
= 10 * n
+ to_digit(ch
);
950 } while (is_digit(ch
));
953 if (argtable
== NULL
) {
954 argtable
= statargtable
;
955 if (__find_arguments(fmt0
, orgap
,
963 #ifndef NO_FLOATING_POINT
969 if (flags
& SHORTINT
) {
979 if (flags
& LONGINT
) {
986 flags
|= LLONGINT
; /* not necessarily */
999 if (flags
& LONGINT
) {
1000 static const mbstate_t initial
= { 0 };
1005 mbseqlen
= wcrtomb(buf
,
1006 /* The compiler "knows" that wint_t may be smaller than an int so
1007 it warns about it when used as the type argument to va_arg().
1008 Since any type of parameter smaller than an int is promoted to an int on a
1009 function call, we must call GETARG with type int instead of wint_t.
1011 (wchar_t)GETARG(int), &mbs
);
1012 if (mbseqlen
== (size_t)-1) {
1013 fp
->_flags
|= __SERR
;
1016 size
= (int)mbseqlen
;
1018 *buf
= (char)(GETARG(int));
1022 if (flags
& LONGINT
)
1023 *buf
= (wchar_t)GETARG(int);
1025 *buf
= (wchar_t)btowc(GETARG(int));
1036 if (flags
& INTMAX_SIZE
) {
1038 if ((intmax_t)ujval
< 0) {
1039 ujval
= (uintmax_t)(-((intmax_t)ujval
));
1044 if ((long)ulval
< 0) {
1045 ulval
= (u_long
)(-((long)ulval
));
1051 #ifndef NO_FLOATING_POINT
1057 xdigs
= xdigs_lower
;
1061 xdigs
= xdigs_upper
;
1064 if (flags
& LONGDBL
) {
1065 fparg
.ldbl
= GETARG(long double);
1067 __hldtoa(fparg
.ldbl
, xdigs
, prec
,
1068 &expt
, &signflag
, &dtoaend
);
1070 fparg
.dbl
= GETARG(double);
1072 __hdtoa(fparg
.dbl
, xdigs
, prec
,
1073 &expt
, &signflag
, &dtoaend
);
1075 if (dtoaresult
== NULL
)
1079 prec
= dtoaend
- dtoaresult
;
1080 if (expt
== INT_MAX
)
1082 ndig
= dtoaend
- dtoaresult
;
1083 if (convbuf
!= NULL
)
1086 result
= convbuf
= __mbsconv(dtoaresult
, -1);
1089 result
= convbuf
= strdup(dtoaresult
);
1093 __freedtoa(dtoaresult
);
1107 expchar
= ch
- ('g' - 'e');
1113 if (flags
& LONGDBL
) {
1114 fparg
.ldbl
= GETARG(long double);
1116 __ldtoa(&fparg
.ldbl
, expchar
? 2 : 3, prec
,
1117 &expt
, &signflag
, &dtoaend
);
1119 fparg
.dbl
= GETARG(double);
1121 __dtoa(fparg
.dbl
, expchar
? 2 : 3, prec
,
1122 &expt
, &signflag
, &dtoaend
);
1126 if (dtoaresult
== NULL
)
1128 ndig
= dtoaend
- dtoaresult
;
1129 if (convbuf
!= NULL
)
1132 result
= convbuf
= __mbsconv(dtoaresult
, -1);
1135 result
= convbuf
= strdup(dtoaresult
);
1139 __freedtoa(dtoaresult
);
1143 if (expt
== INT_MAX
) { /* inf or nan */
1144 if (*result
== 'N') {
1145 result
= (ch
>= 'a') ? STRCONST("nan") :
1149 result
= (ch
>= 'a') ? STRCONST("inf") :
1161 // if (prec == -1) {
1163 // } else if ((ch == 'g' || ch == 'G') && prec == 0) {
1178 expchar
= ch
- ('g' - 'e');
1185 if (flags
& LONGDBL
) {
1186 _double
= (double) GETARG(long double);
1188 _double
= GETARG(double);
1191 /* do this before tricky precision changes */
1192 if (isinf(_double
)) {
1195 if (ch
== 'E' || ch
== 'F' || ch
== 'G')
1196 result
= STRCONST("INF");
1198 result
= STRCONST("inf");
1202 if (isnan(_double
)) {
1203 if (ch
== 'E' || ch
== 'F' || ch
== 'G')
1204 result
= STRCONST("NAN");
1206 result
= STRCONST("nan");
1212 dtoaresult
= cvt(_double
, prec
, flags
, &softsign
, &expt
, ch
, &ndig
);
1213 if (dtoaresult
== NULL
)
1215 if (convbuf
!= NULL
)
1218 result
= convbuf
= __mbsconv(dtoaresult
, -1);
1221 result
= convbuf
= strdup(dtoaresult
);
1225 __freedtoa(dtoaresult
);
1230 if (ch
== 'g' || ch
== 'G') {
1231 if (expt
> -4 && expt
<= prec
) {
1232 /* Make %[gG] smell like %[fF] */
1242 * Make %[gG] smell like %[eE], but
1243 * trim trailing zeroes if no # flag.
1245 * Note: The precision field used with [gG] is the number significant
1246 * digits to print. When converting to [eE] the digit before the
1247 * decimal must not be included in the precision value.
1254 dprec
= prec
; /* In some cases dprec will not be set. Make sure it is set now */
1255 expsize
= exponent(expstr
, expt
- 1, expchar
);
1256 size
= expsize
+ prec
+ 1; /* Leading digit + exponent string + precision */
1257 if (prec
>= 1 || flags
& ALT
)
1258 ++size
; /* Decimal point is added to character count */
1260 /* space for digits before decimal point */
1265 /* space for decimal pt and following digits */
1266 if (prec
|| flags
& ALT
)
1268 if (grouping
&& expt
> 0) {
1269 /* space for thousands' grouping */
1270 nseps
= nrepeats
= 0;
1272 while (*grouping
!= CHAR_MAX
) {
1273 if (lead
<= *grouping
)
1276 if (*(grouping
+1)) {
1282 size
+= nseps
+ nrepeats
;
1287 #endif /* !NO_FLOATING_POINT */
1290 * Assignment-like behavior is specified if the
1291 * value overflows or is otherwise unrepresentable.
1292 * C99 says to use `signed char' for %hhn conversions.
1294 if (flags
& LLONGINT
)
1295 *GETARG(long long *) = ret
;
1296 else if (flags
& SIZET
)
1297 *GETARG(ssize_t
*) = (ssize_t
)ret
;
1298 else if (flags
& PTRDIFFT
)
1299 *GETARG(ptrdiff_t *) = ret
;
1300 else if (flags
& INTMAXT
)
1301 *GETARG(intmax_t *) = ret
;
1302 else if (flags
& LONGINT
)
1303 *GETARG(long *) = ret
;
1304 else if (flags
& SHORTINT
)
1305 *GETARG(short *) = ret
;
1306 else if (flags
& CHARINT
)
1307 *GETARG(signed char *) = ret
;
1309 *GETARG(int *) = ret
;
1310 continue; /* no output */
1315 if (flags
& INTMAX_SIZE
)
1323 * ``The argument shall be a pointer to void. The
1324 * value of the pointer is converted to a sequence
1325 * of printable characters, in an implementation-
1329 ujval
= (uintmax_t) (UINTN
) GETARG(void *);
1331 xdigs
= xdigs_lower
;
1332 flags
= flags
| INTMAXT
;
1339 if (((flags
& LONGINT
) ? 1:0) != MULTI
) {
1340 if ((result
= GETARG(CHAR_T
*)) == NULL
)
1341 result
= STRCONST("(null)");
1345 if (convbuf
!= NULL
)
1347 if ((mc
= GETARG(MCHAR_T
*)) == NULL
)
1348 result
= STRCONST("(null)");
1350 convbuf
= SCONV(mc
, prec
);
1351 if (convbuf
== NULL
) {
1352 fp
->_flags
|= __SERR
;
1361 * can't use STRLEN; can only look for the
1362 * NUL in the first `prec' characters, and
1363 * STRLEN() will go further.
1365 CHAR_T
*p
= MEMCHR(result
, 0, (size_t)prec
);
1374 size
= (int)STRLEN(result
);
1381 if (flags
& INTMAX_SIZE
)
1388 xdigs
= xdigs_upper
;
1391 xdigs
= xdigs_lower
;
1393 if (flags
& INTMAX_SIZE
)
1398 /* leading 0x/X only if non-zero */
1400 (flags
& INTMAX_SIZE
? ujval
!= 0 : ulval
!= 0))
1404 /* unsigned conversions */
1405 nosign
: sign
= '\0';
1407 * ``... diouXx conversions ... if a precision is
1408 * specified, the 0 flag will be ignored.''
1411 number
: if ((dprec
= prec
) >= 0)
1415 * ``The result of converting a zero value with an
1416 * explicit precision of zero is no characters.''
1419 * ``The C Standard is clear enough as is. The call
1420 * printf("%#.0o", 0) should print 0.''
1421 * -- Defect Report #151
1423 result
= cp
= buf
+ BUF
;
1424 if (flags
& INTMAX_SIZE
) {
1425 if (ujval
!= 0 || prec
!= 0 ||
1426 (flags
& ALT
&& base
== 8))
1428 result
= __ujtoa(ujval
, cp
, base
,
1430 flags
& GROUPING
, thousands_sep
,
1434 if (ulval
!= 0 || prec
!= 0 ||
1435 (flags
& ALT
&& base
== 8))
1436 result
= __ultoa(ulval
, cp
, base
,
1438 flags
& GROUPING
, thousands_sep
,
1441 size
= buf
+ BUF
- result
;
1442 if (size
> BUF
) /* should never happen */
1445 default: /* "%?" prints ?, unless ? is NUL */
1448 /* pretend it was %c with argument ch */
1457 * All reasonable formats wind up here. At this point, `result'
1458 * points to a string which (if not flags&LADJUST) should be
1459 * padded out to `width' places. If flags&ZEROPAD, it should
1460 * first be prefixed by any sign or other prefix; otherwise,
1461 * it should be blank padded before the prefix is emitted.
1462 * After any left-hand padding and prefixing, emit zeroes
1463 * required by a decimal [diouxX] precision, then print the
1464 * string proper, then emit zeroes required by any leftover
1465 * floating precision; finally, if LADJUST, pad with blanks.
1467 * Compute actual size, so we know how much to pad.
1468 * size excludes decimal prec; realsz includes it.
1470 realsz
= dprec
> size
? dprec
: size
;
1476 prsize
= width
> realsz
? width
: realsz
;
1477 if ((unsigned)ret
+ prsize
> INT_MAX
) {
1482 /* right-adjusting blank padding */
1483 if ((flags
& (LADJUST
|ZEROPAD
)) == 0)
1484 PAD(width
- realsz
, blanks
);
1490 if (ox
[1]) { /* ox[1] is either x, X, or \0 */
1495 /* right-adjusting zero padding */
1496 if ((flags
& (LADJUST
|ZEROPAD
)) == ZEROPAD
)
1497 PAD(width
- realsz
, zeroes
);
1499 /* leading zeroes from decimal precision */
1500 PAD(dprec
- size
, zeroes
);
1502 /* the string or number proper */
1503 #ifndef NO_FLOATING_POINT
1504 if ((flags
& FPT
) == 0) {
1505 PRINT(result
, size
);
1506 } else { /* glue together f_p fragments */
1507 if (!expchar
) { /* %[fF] or sufficiently short %[gG] */
1510 if (prec
|| flags
& ALT
)
1511 PRINT(decimal_point
, 1);
1513 /* already handled initial 0's */
1516 PRINTANDPAD(result
, convbuf
+ ndig
,
1520 while (nseps
>0 || nrepeats
>0) {
1527 PRINT(&thousands_sep
,
1532 result
+= *grouping
;
1534 if (result
> convbuf
+ ndig
)
1535 result
= convbuf
+ ndig
;
1537 if (prec
|| flags
& ALT
) {
1538 buf
[0] = *decimal_point
;
1542 PRINTANDPAD(result
, convbuf
+ ndig
, prec
,
1544 } else { /* %[eE] or sufficiently long %[gG] */
1545 if (prec
>= 1 || flags
& ALT
) {
1547 buf
[1] = *decimal_point
;
1549 PRINT(result
, ndig
-1);
1550 PAD(prec
- ndig
, zeroes
);
1553 PRINT(expstr
, expsize
);
1557 PRINT(result
, size
);
1559 /* left-adjusting padding (always blank) */
1560 if (flags
& LADJUST
)
1561 PAD(width
- realsz
, blanks
);
1563 /* finally, adjust ret */
1571 if (convbuf
!= NULL
)
1575 if ((argtable
!= NULL
) && (argtable
!= statargtable
))
1586 * Find all arguments when a positional parameter is encountered. Returns a
1587 * table, indexed by argument number, of pointers to each arguments. The
1588 * initial argument table should be an array of STATIC_ARG_TBL_SIZE entries.
1589 * It will be replaces with a malloc-ed one if it overflows.
1592 __find_arguments(const CHAR_T
*fmt0
, va_list ap
, union arg
**argtable
)
1594 CHAR_T
*fmt
; /* format string */
1595 int ch
; /* character from fmt */
1596 int n
, n2
; /* handy integer (short term usage) */
1597 CHAR_T
*cp
; /* handy char pointer (short term usage) */
1598 int flags
; /* flags as above */
1599 enum typeid *typetable
; /* table of types */
1600 enum typeid stattypetable
[STATIC_ARG_TBL_SIZE
];
1601 int tablesize
; /* current size of type table */
1602 int tablemax
; /* largest used index in table */
1603 int nextarg
; /* 1-based argument index */
1606 * Add an argument type to the table, expanding if necessary.
1608 #define ADDTYPE(type) \
1610 if (nextarg >= tablesize) \
1611 if (__grow_type_table(nextarg, &typetable, \
1612 &tablesize) == -1) \
1614 if (nextarg > tablemax) \
1615 tablemax = nextarg; \
1616 typetable[nextarg++] = type; \
1617 } while (/*CONSTCOND*/0)
1621 if (flags & INTMAXT) \
1622 ADDTYPE(T_INTMAXT); \
1623 else if (flags & SIZET) \
1625 else if (flags & PTRDIFFT) \
1626 ADDTYPE(T_PTRDIFFT); \
1627 else if (flags & LLONGINT) \
1629 else if (flags & LONGINT) \
1633 } while (/*CONSTCOND*/0)
1637 if (flags & INTMAXT) \
1638 ADDTYPE(T_UINTMAXT); \
1639 else if (flags & SIZET) \
1641 else if (flags & PTRDIFFT) \
1642 ADDTYPE(T_PTRDIFFT); \
1643 else if (flags & LLONGINT) \
1644 ADDTYPE(T_U_LLONG); \
1645 else if (flags & LONGINT) \
1646 ADDTYPE(T_U_LONG); \
1649 } while (/*CONSTCOND*/0)
1651 * Add * arguments to the type array.
1653 #define ADDASTER() \
1656 while (is_digit(*cp)) { \
1657 n2 = 10 * n2 + to_digit(*cp); \
1661 int hold = nextarg; \
1669 fmt
= (CHAR_T
*)__UNCONST(fmt0
);
1670 typetable
= stattypetable
;
1671 tablesize
= STATIC_ARG_TBL_SIZE
;
1674 for (n
= 0; n
< STATIC_ARG_TBL_SIZE
; n
++)
1675 typetable
[n
] = T_UNUSED
;
1678 * Scan the format for conversions (`%' character).
1681 for (cp
= fmt
; (ch
= *fmt
) != '\0' && ch
!= '%'; fmt
++)
1685 fmt
++; /* skip over '%' */
1690 reswitch
: switch (ch
) {
1702 if ((ch
= *fmt
++) == '*') {
1706 while (is_digit(ch
)) {
1712 case '1': case '2': case '3': case '4':
1713 case '5': case '6': case '7': case '8': case '9':
1716 n
= 10 * n
+ to_digit(ch
);
1718 } while (is_digit(ch
));
1724 #ifndef NO_FLOATING_POINT
1730 if (flags
& SHORTINT
) {
1740 if (flags
& LONGINT
) {
1747 flags
|= LLONGINT
; /* not necessarily */
1759 if (flags
& LONGINT
)
1771 #ifndef NO_FLOATING_POINT
1779 if (flags
& LONGDBL
)
1780 ADDTYPE(T_LONG_DOUBLE
);
1784 #endif /* !NO_FLOATING_POINT */
1786 if (flags
& INTMAXT
)
1787 ADDTYPE(TP_INTMAXT
);
1788 else if (flags
& PTRDIFFT
)
1789 ADDTYPE(TP_PTRDIFFT
);
1790 else if (flags
& SIZET
)
1792 else if (flags
& LLONGINT
)
1794 else if (flags
& LONGINT
)
1796 else if (flags
& SHORTINT
)
1798 else if (flags
& CHARINT
)
1802 continue; /* no output */
1816 if (flags
& LONGINT
)
1829 default: /* "%?" prints ?, unless ? is NUL */
1837 * Build the argument table.
1839 if (tablemax
>= STATIC_ARG_TBL_SIZE
) {
1840 *argtable
= (union arg
*)
1841 malloc (sizeof (union arg
) * (tablemax
+ 1));
1842 if (*argtable
== NULL
)
1846 (*argtable
) [0].intarg
= 0;
1847 for (n
= 1; n
<= tablemax
; n
++) {
1848 switch (typetable
[n
]) {
1849 case T_UNUSED
: /* whoops! */
1850 (*argtable
) [n
].intarg
= va_arg (ap
, int);
1853 (*argtable
) [n
].pschararg
= va_arg (ap
, signed char *);
1856 (*argtable
) [n
].pshortarg
= va_arg (ap
, short *);
1859 (*argtable
) [n
].intarg
= va_arg (ap
, int);
1862 (*argtable
) [n
].uintarg
= va_arg (ap
, unsigned int);
1865 (*argtable
) [n
].pintarg
= va_arg (ap
, int *);
1868 (*argtable
) [n
].longarg
= va_arg (ap
, long);
1871 (*argtable
) [n
].ulongarg
= va_arg (ap
, unsigned long);
1874 (*argtable
) [n
].plongarg
= va_arg (ap
, long *);
1877 (*argtable
) [n
].longlongarg
= va_arg (ap
, long long);
1880 (*argtable
) [n
].ulonglongarg
= va_arg (ap
, unsigned long long);
1883 (*argtable
) [n
].plonglongarg
= va_arg (ap
, long long *);
1886 (*argtable
) [n
].ptrdiffarg
= va_arg (ap
, ptrdiff_t);
1889 (*argtable
) [n
].pptrdiffarg
= va_arg (ap
, ptrdiff_t *);
1892 (*argtable
) [n
].sizearg
= va_arg (ap
, size_t);
1895 (*argtable
) [n
].psizearg
= va_arg (ap
, size_t *);
1898 (*argtable
) [n
].intmaxarg
= va_arg (ap
, intmax_t);
1901 (*argtable
) [n
].uintmaxarg
= va_arg (ap
, uintmax_t);
1904 (*argtable
) [n
].pintmaxarg
= va_arg (ap
, intmax_t *);
1907 #ifndef NO_FLOATING_POINT
1908 (*argtable
) [n
].doublearg
= va_arg (ap
, double);
1912 #ifndef NO_FLOATING_POINT
1913 (*argtable
) [n
].longdoublearg
= va_arg (ap
, long double);
1917 (*argtable
) [n
].pchararg
= va_arg (ap
, char *);
1920 (*argtable
) [n
].pvoidarg
= va_arg (ap
, void *);
1923 (*argtable
) [n
].wintarg
= va_arg (ap
, int);
1926 (*argtable
) [n
].pwchararg
= va_arg (ap
, wchar_t *);
1931 if ((typetable
!= NULL
) && (typetable
!= stattypetable
))
1937 * Increase the size of the type table.
1940 __grow_type_table (int nextarg
, enum typeid **typetable
, int *tablesize
)
1942 enum typeid *const oldtable
= *typetable
;
1943 const int oldsize
= *tablesize
;
1944 enum typeid *newtable
;
1945 int n
, newsize
= oldsize
* 2;
1947 if (newsize
< nextarg
+ 1)
1948 newsize
= nextarg
+ 1;
1949 if (oldsize
== STATIC_ARG_TBL_SIZE
) {
1950 if ((newtable
= malloc(newsize
* sizeof(enum typeid))) == NULL
)
1952 memcpy(newtable
, oldtable
, oldsize
* sizeof(enum typeid));
1954 newtable
= realloc(oldtable
, newsize
* sizeof(enum typeid));
1955 if (newtable
== NULL
) {
1960 for (n
= oldsize
; n
< newsize
; n
++)
1961 newtable
[n
] = T_UNUSED
;
1963 *typetable
= newtable
;
1964 *tablesize
= newsize
;
1969 #ifndef NO_FLOATING_POINT
1972 cvt(double value
, int ndigits
, int flags
, char *sign
, int *decpt
, int ch
,
1976 char *digits
, *bp
, *rve
;
1978 _DIAGASSERT(decpt
!= NULL
);
1979 _DIAGASSERT(length
!= NULL
);
1980 _DIAGASSERT(sign
!= NULL
);
1983 mode
= 3; /* ndigits after the decimal point */
1985 /* To obtain ndigits after the decimal point for the 'e'
1986 * and 'E' formats, round to ndigits + 1 significant
1989 if (ch
== 'e' || ch
== 'E') {
1992 mode
= 2; /* ndigits significant digits */
1995 digits
= __dtoa(value
, mode
, ndigits
, decpt
, &dsgn
, &rve
);
2003 if ((ch
!= 'g' && ch
!= 'G') || flags
& ALT
) { /* Print trailing zeros */
2004 bp
= digits
+ ndigits
;
2006 if (*digits
== '0' && value
)
2007 *decpt
= -ndigits
+ 1;
2013 *length
= rve
- digits
;
2019 exponent(CHAR_T
*p0
, int expo
, int fmtch
)
2022 CHAR_T expbuf
[MAXEXPDIG
];
2032 t
= expbuf
+ MAXEXPDIG
;
2035 *--t
= to_char(expo
% 10);
2036 } while ((expo
/= 10) > 9);
2037 *--t
= to_char(expo
);
2038 for (; t
< expbuf
+ MAXEXPDIG
; *p
++ = *t
++);
2042 * Exponents for decimal floating point conversions
2043 * (%[eEgG]) must be at least two characters long,
2044 * whereas exponents for hexadecimal conversions can
2045 * be only one character long.
2047 if (fmtch
== 'e' || fmtch
== 'E')
2049 *p
++ = to_char(expo
);
2053 #endif /* !NO_FLOATING_POINT */