]>
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
);
168 _FILEEXT_SETUP(&fake
, &fakeext
);
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
;
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 */
181 /* do the work, then copy any error status */
182 ret
= WDECL(__vf
,printf_unlocked
)(&fake
, fmt
, ap
);
183 if (ret
>= 0 && fflush(&fake
))
185 if (fake
._flags
& __SERR
)
186 fp
->_flags
|= __SERR
;
192 * Like __fputwc, but handles fake string (__SSTR) files properly.
193 * File must already be locked.
196 __xfputwc(wchar_t wc
, FILE *fp
)
198 static const mbstate_t initial
= { 0 };
200 char buf
[MB_LEN_MAX
];
205 if ((fp
->_flags
& __SSTR
) == 0)
206 return (__fputwc_unlock(wc
, fp
));
209 if ((len
= wcrtomb(buf
, wc
, &mbs
)) == (size_t)-1) {
210 fp
->_flags
|= __SERR
;
211 return (END_OF_FILE
);
214 uio
.uio_resid
= (int)len
;
218 return (__sfvwrite(fp
, &uio
) != EOF
? (wint_t)wc
: END_OF_FILE
);
222 * Flush out all the vectors defined by the given uio,
223 * then reset it so that it can be reused.
226 __sprint(FILE *fp
, struct __suio
*uio
)
230 _DIAGASSERT(fp
!= NULL
);
231 _DIAGASSERT(uio
!= NULL
);
233 if (uio
->uio_resid
== 0) {
237 err
= __sfvwrite(fp
, uio
);
245 * Macros for converting digits to letters and vice versa
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')
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.
258 __ultoa(u_long val
, CHAR_T
*endp
, int base
, int octzero
, const char *xdigs
,
259 int needgrp
, char thousep
, const char *grp
)
266 * Handle the three cases separately, in the hope of getting
267 * better/faster code.
271 if (val
< 10) { /* many numbers are 1 digit */
272 *--cp
= to_char(val
);
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.
282 if (val
> LONG_MAX
) {
283 *--cp
= to_char(val
% 10);
285 sval
= (LONGN
)(val
/ 10);
289 *--cp
= to_char(sval
% 10);
292 * If (*grp == CHAR_MAX) then no more grouping
293 * should be performed.
295 if (needgrp
&& ndig
== *grp
&& *grp
!= CHAR_MAX
300 * If (*(grp+1) == '\0') then we have to
301 * use *grp character (last grouping rule)
304 if (*(grp
+1) != '\0')
313 *--cp
= to_char(val
& 7);
316 if (octzero
&& *cp
!= '0')
322 *--cp
= xdigs
[(size_t)val
& 15];
333 /* Identical to __ultoa, but for intmax_t. */
335 __ujtoa(uintmax_t val
, CHAR_T
*endp
, int base
, int octzero
,
336 const char *xdigs
, int needgrp
, char thousep
, const char *grp
)
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
));
350 *--cp
= to_char(val
% 10);
354 if (val
> INTMAX_MAX
) {
355 *--cp
= to_char(val
% 10);
361 *--cp
= to_char(sval
% 10);
364 * If (*grp == CHAR_MAX) then no more grouping
365 * should be performed.
367 if (needgrp
&& *grp
!= CHAR_MAX
&& ndig
== *grp
372 * If (*(grp+1) == '\0') then we have to
373 * use *grp character (last grouping rule)
376 if (*(grp
+1) != '\0')
385 *--cp
= to_char(val
& 7);
388 if (octzero
&& *cp
!= '0')
394 *--cp
= xdigs
[(size_t)val
& 15];
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.
413 __mbsconv(char *mbsarg
, int prec
)
415 static const mbstate_t initial
= { 0 };
417 wchar_t *convbuf
, *wcp
;
419 size_t insize
, nchars
, nconv
;
425 * Supplied argument is a multibyte string; convert it to wide
430 * String is not guaranteed to be NUL-terminated. Find the
431 * number of characters to print.
434 insize
= nchars
= nconv
= 0;
436 while (nchars
!= (size_t)prec
) {
437 nconv
= mbrlen(p
, MB_CUR_MAX
, &mbs
);
438 if (nconv
== 0 || nconv
== (size_t)-1 ||
445 if (nconv
== (size_t)-1 || nconv
== (size_t)-2)
448 insize
= strlen(mbsarg
);
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.
455 convbuf
= malloc((insize
+ 1) * sizeof(*convbuf
));
462 while (insize
!= 0) {
463 nconv
= mbrtowc(wcp
, p
, insize
, &mbs
);
464 if (nconv
== 0 || nconv
== (size_t)-1 || nconv
== (size_t)-2)
470 if (nconv
== (size_t)-1 || nconv
== (size_t)-2) {
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.
486 __wcsconv(wchar_t *wcsarg
, int prec
)
488 static const mbstate_t initial
= { 0 };
490 char buf
[MB_LEN_MAX
];
495 /* Allocate space for the maximum number of bytes we could output. */
499 nbytes
= wcsrtombs(NULL
, (const wchar_t **)&p
, 0, &mbs
);
500 if (nbytes
== (size_t)-1)
504 * Optimisation: if the output precision is small enough,
505 * just allocate enough memory for the maximum instead of
506 * scanning the string.
515 clen
= wcrtomb(buf
, *p
++, &mbs
);
516 if (clen
== 0 || clen
== (size_t)-1 ||
517 nbytes
+ clen
> (size_t)prec
)
523 if ((convbuf
= malloc(nbytes
+ 1)) == NULL
)
526 /* Fill the output buffer. */
529 if ((nbytes
= wcsrtombs(convbuf
, (const wchar_t **)&p
,
530 nbytes
, &mbs
)) == (size_t)-1) {
534 convbuf
[nbytes
] = '\0';
543 WDECL(vf
,printf
)(FILE * __restrict fp
, const CHAR_T
* __restrict fmt0
, va_list ap
)
548 ret
= WDECL(__vf
,printf_unlocked
)(fp
, fmt0
, ap
);
553 #ifndef NO_FLOATING_POINT
561 static int exponent(CHAR_T
*, int, int);
563 static char *cvt(double, int, int, char *, int *, int, int *);
566 #endif /* !NO_FLOATING_POINT */
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.
577 #define STATIC_ARG_TBL_SIZE 8 /* Size of static argument table. */
580 * Flags used during conversion.
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 */
598 * Non-MT-safe version
601 WDECL(__vf
,printf_unlocked
)(FILE *fp
, const CHAR_T
*fmt0
, va_list ap
)
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
616 * We can decompose the printed representation of floating
617 * point numbers into several parts, some of which may be empty:
619 * [+|-| ] [0x|0X] MMM . NNN [e|E|p|P] [+|-] ZZ
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
629 char *decimal_point
; /* locale specific decimal point */
631 int signflag
; /* true if float is negative */
632 union { /* floating point arguments %[aAeEfFgG] */
636 char *dtoaend
; /* pointer to end of converted digits */
638 double _double
; /* double precision arguments %[eEfgG] */
639 char softsign
; /* temporary negative sign for floats */
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 */
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 */
661 struct __siov
*iovp
; /* for PRINT macro */
662 struct __suio uio
; /* output information: summary */
663 struct __siov iov
[NIOV
];/* ... and individual io vectors */
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 */
676 * Choose PADSIZE to trade efficiency vs. size. If larger printf
677 * fields occur frequently, increase PADSIZE and make the initialisers
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'};
686 static const char xdigs_lower
[17] = "0123456789abcdef";
687 static const char xdigs_upper
[17] = "0123456789ABCDEF";
690 * BEWARE, these `goto error' on error, PRINT uses `n2' and
694 #define PRINT(ptr, len) do { \
695 for (n3 = 0; n3 < (len); n3++) \
696 __xfputwc((ptr)[n3], fp); \
697 } while (/*CONSTCOND*/0)
700 #define PRINT(ptr, len) do { \
701 iovp->iov_base = __UNCONST(ptr); \
702 iovp->iov_len = (len); \
703 uio.uio_resid += (len); \
705 if (++uio.uio_iovcnt >= NIOV) { \
706 if (__sprint(fp, &uio)) \
710 } while (/*CONSTCOND*/0)
711 #define FLUSH() do { \
712 if (uio.uio_resid && __sprint(fp, &uio)) \
714 uio.uio_iovcnt = 0; \
716 } while (/*CONSTCOND*/0)
719 #define PAD(howmany, with) do { \
720 if ((n = (howmany)) > 0) { \
721 while (n > PADSIZE) { \
722 PRINT(with, PADSIZE); \
727 } while (/*CONSTCOND*/0)
728 #define PRINTANDPAD(p, ep, len, with) do { \
734 PAD((len) - (n2 > 0 ? n2 : 0), (with)); \
735 } while(/*CONSTCOND*/0)
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).
742 #define GETARG(type) \
743 ((/*CONSTCOND*/argtable != NULL) ? *((type*)(void*)(&argtable[nextarg++])) : \
744 (nextarg++, va_arg(ap, type)))
747 * To extend shorts properly, we need both signed and unsigned
748 * argument extraction methods.
751 ((long)(flags&LONGINT ? GETARG(long) : \
752 flags&SHORTINT ? (short)GETARG(int) : \
753 flags&CHARINT ? (signed char)GETARG(int) : \
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)))
762 #define INTMAX_SIZE (INTMAXT|SIZET|PTRDIFFT|LLONGINT)
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))
771 (flags&INTMAXT ? GETARG(uintmax_t) : \
772 flags&SIZET ? (uintmax_t)GETARG(size_t) : \
773 flags&PTRDIFFT ? (uintmax_t)GETARG(ptrdiff_t) : \
774 (uintmax_t)GETARG(unsigned long long))
777 * Get * arguments, including the form *nn$. Preserve the nextarg
778 * that the argument can be gotten once the type is determined.
780 #define GETASTER(val) \
783 while (is_digit(*cp)) { \
784 n2 = 10 * n2 + to_digit(*cp); \
788 int hold = nextarg; \
789 if (argtable == NULL) { \
790 argtable = statargtable; \
791 if (__find_arguments(fmt0, orgap, &argtable) == -1) \
795 val = GETARG (int); \
799 val = GETARG (int); \
802 _DIAGASSERT(fp
!= NULL
);
803 _DIAGASSERT(fmt0
!= NULL
);
805 _SET_ORIENTATION(fp
, -1);
807 ndig
= -1; /* XXX gcc */
809 thousands_sep
= '\0';
811 #ifndef NO_FLOATING_POINT
812 decimal_point
= localeconv()->decimal_point
;
813 expsize
= 0; /* XXXGCC -Wuninitialized [sh3,m68000] */
816 /* sorry, f{w,}printf(read_only_file, L"") returns {W,}EOF, not 0 */
819 return (END_OF_FILE
);
822 /* optimise fprintf(stderr) (and other unbuffered Unix files) */
823 if ((fp
->_flags
& (__SNBF
|__SWR
|__SRW
)) == (__SNBF
|__SWR
) &&
825 return (__sbprintf(fp
, fmt0
, ap
));
827 fmt
= (CHAR_T
*)__UNCONST(fmt0
);
832 uio
.uio_iov
= iovp
= iov
;
839 * Scan the format for conversions (`%' character).
843 const CHAR_T
*result
;
845 for (cp
= fmt
; (ch
= *fmt
) != '\0' && ch
!= '%'; fmt
++)
847 if ((n
= (int)(fmt
- cp
)) != 0) {
848 if ((unsigned)ret
+ n
> INT_MAX
) {
857 fmt
++; /* skip over '%' */
867 nseps
= nrepeats
= 0;
873 reswitch
: switch (ch
) {
876 * ``If the space and + flags both appear, the space
877 * flag will be ignored.''
888 * ``A negative field width argument is taken as a
889 * - flag followed by a positive field width.''
891 * They don't exclude field widths read from args.
906 thousands_sep
= *(localeconv()->thousands_sep
);
907 grouping
= localeconv()->grouping
;
910 if ((ch
= *fmt
++) == '*') {
915 while (is_digit(ch
)) {
916 prec
= 10 * prec
+ to_digit(ch
);
922 * ``Note that 0 is taken as a flag, not as the
923 * beginning of a field width.''
928 case '1': case '2': case '3': case '4':
929 case '5': case '6': case '7': case '8': case '9':
932 n
= 10 * n
+ to_digit(ch
);
934 } while (is_digit(ch
));
937 if (argtable
== NULL
) {
938 argtable
= statargtable
;
939 if (__find_arguments(fmt0
, orgap
,
947 #ifndef NO_FLOATING_POINT
953 if (flags
& SHORTINT
) {
963 if (flags
& LONGINT
) {
970 flags
|= LLONGINT
; /* not necessarily */
983 if (flags
& LONGINT
) {
984 static const mbstate_t initial
= { 0 };
989 mbseqlen
= wcrtomb(buf
,
990 (wchar_t)GETARG(wint_t), &mbs
);
991 if (mbseqlen
== (size_t)-1) {
992 fp
->_flags
|= __SERR
;
995 size
= (int)mbseqlen
;
997 *buf
= (char)(GETARG(int));
1001 if (flags
& LONGINT
)
1002 *buf
= (wchar_t)GETARG(wint_t);
1004 *buf
= (wchar_t)btowc(GETARG(int));
1015 if (flags
& INTMAX_SIZE
) {
1017 if ((intmax_t)ujval
< 0) {
1018 ujval
= (uintmax_t)(-((intmax_t)ujval
));
1023 if ((long)ulval
< 0) {
1024 ulval
= (u_long
)(-((long)ulval
));
1030 #ifndef NO_FLOATING_POINT
1036 xdigs
= xdigs_lower
;
1040 xdigs
= xdigs_upper
;
1045 if (flags
& LONGDBL
) {
1046 fparg
.ldbl
= GETARG(long double);
1048 __hldtoa(fparg
.ldbl
, xdigs
, prec
,
1049 &expt
, &signflag
, &dtoaend
);
1051 fparg
.dbl
= GETARG(double);
1053 __hdtoa(fparg
.dbl
, xdigs
, prec
,
1054 &expt
, &signflag
, &dtoaend
);
1056 if (dtoaresult
== NULL
)
1060 prec
= dtoaend
- dtoaresult
;
1061 if (expt
== INT_MAX
)
1063 ndig
= dtoaend
- dtoaresult
;
1064 if (convbuf
!= NULL
)
1067 result
= convbuf
= __mbsconv(dtoaresult
, -1);
1070 result
= convbuf
= strdup(dtoaresult
);
1074 __freedtoa(dtoaresult
);
1079 if (prec
< 0) /* account for digit before decpt */
1090 expchar
= ch
- ('g' - 'e');
1096 if (flags
& LONGDBL
) {
1097 fparg
.ldbl
= GETARG(long double);
1099 __ldtoa(&fparg
.ldbl
, expchar
? 2 : 3, prec
,
1100 &expt
, &signflag
, &dtoaend
);
1102 fparg
.dbl
= GETARG(double);
1104 __dtoa(fparg
.dbl
, expchar
? 2 : 3, prec
,
1105 &expt
, &signflag
, &dtoaend
);
1109 if (dtoaresult
== NULL
)
1111 ndig
= dtoaend
- dtoaresult
;
1112 if (convbuf
!= NULL
)
1115 result
= convbuf
= __mbsconv(dtoaresult
, -1);
1118 result
= convbuf
= strdup(dtoaresult
);
1122 __freedtoa(dtoaresult
);
1126 if (expt
== INT_MAX
) { /* inf or nan */
1127 if (*result
== 'N') {
1128 result
= (ch
>= 'a') ? STRCONST("nan") :
1132 result
= (ch
>= 'a') ? STRCONST("inf") :
1144 // if (prec == -1) {
1146 // } else if ((ch == 'g' || ch == 'G') && prec == 0) {
1152 if (prec
< 0) /* account for digit before decpt */
1153 prec
= DEFPREC
/* + 1*/ ;
1163 expchar
= ch
- ('g' - 'e');
1170 if (flags
& LONGDBL
) {
1171 _double
= (double) GETARG(long double);
1173 _double
= GETARG(double);
1176 /* do this before tricky precision changes */
1177 if (isinf(_double
)) {
1180 if (ch
== 'E' || ch
== 'F' || ch
== 'G')
1181 result
= STRCONST("INF");
1183 result
= STRCONST("inf");
1187 if (isnan(_double
)) {
1188 if (ch
== 'E' || ch
== 'F' || ch
== 'G')
1189 result
= STRCONST("NAN");
1191 result
= STRCONST("nan");
1197 dtoaresult
= cvt(_double
, prec
, flags
, &softsign
, &expt
, ch
, &ndig
);
1198 if (dtoaresult
== NULL
)
1200 if (convbuf
!= NULL
)
1203 result
= convbuf
= __mbsconv(dtoaresult
, -1);
1206 result
= convbuf
= strdup(dtoaresult
);
1210 __freedtoa(dtoaresult
);
1215 if (ch
== 'g' || ch
== 'G') {
1216 if (expt
> -4 && expt
<= prec
) {
1217 /* Make %[gG] smell like %[fF] */
1227 * Make %[gG] smell like %[eE], but
1228 * trim trailing zeroes if no # flag.
1235 expsize
= exponent(expstr
, expt
- 1, expchar
);
1236 size
= expsize
+ prec
;
1237 if (prec
> 1 || flags
& ALT
)
1240 /* space for digits before decimal point */
1245 /* space for decimal pt and following digits */
1246 if (prec
|| flags
& ALT
)
1248 if (grouping
&& expt
> 0) {
1249 /* space for thousands' grouping */
1250 nseps
= nrepeats
= 0;
1252 while (*grouping
!= CHAR_MAX
) {
1253 if (lead
<= *grouping
)
1256 if (*(grouping
+1)) {
1262 size
+= nseps
+ nrepeats
;
1267 #endif /* !NO_FLOATING_POINT */
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.
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
;
1289 *GETARG(int *) = ret
;
1290 continue; /* no output */
1295 if (flags
& INTMAX_SIZE
)
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-
1309 ujval
= (uintmax_t)GETARG(void *);
1311 xdigs
= xdigs_lower
;
1312 flags
= flags
| INTMAXT
;
1319 if ((flags
& LONGINT
) != MULTI
) {
1320 if ((result
= GETARG(CHAR_T
*)) == NULL
)
1321 result
= STRCONST("(null)");
1325 if (convbuf
!= NULL
)
1327 if ((mc
= GETARG(MCHAR_T
*)) == NULL
)
1328 result
= STRCONST("(null)");
1330 convbuf
= SCONV(mc
, prec
);
1331 if (convbuf
== NULL
) {
1332 fp
->_flags
|= __SERR
;
1341 * can't use STRLEN; can only look for the
1342 * NUL in the first `prec' characters, and
1343 * STRLEN() will go further.
1345 CHAR_T
*p
= MEMCHR(result
, 0, (size_t)prec
);
1354 size
= (int)STRLEN(result
);
1361 if (flags
& INTMAX_SIZE
)
1368 xdigs
= xdigs_upper
;
1371 xdigs
= xdigs_lower
;
1373 if (flags
& INTMAX_SIZE
)
1378 /* leading 0x/X only if non-zero */
1380 (flags
& INTMAX_SIZE
? ujval
!= 0 : ulval
!= 0))
1384 /* unsigned conversions */
1385 nosign
: sign
= '\0';
1387 * ``... diouXx conversions ... if a precision is
1388 * specified, the 0 flag will be ignored.''
1391 number
: if ((dprec
= prec
) >= 0)
1395 * ``The result of converting a zero value with an
1396 * explicit precision of zero is no characters.''
1399 * ``The C Standard is clear enough as is. The call
1400 * printf("%#.0o", 0) should print 0.''
1401 * -- Defect Report #151
1403 result
= cp
= buf
+ BUF
;
1404 if (flags
& INTMAX_SIZE
) {
1405 if (ujval
!= 0 || prec
!= 0 ||
1406 (flags
& ALT
&& base
== 8))
1408 result
= __ujtoa(ujval
, cp
, base
,
1410 flags
& GROUPING
, thousands_sep
,
1414 if (ulval
!= 0 || prec
!= 0 ||
1415 (flags
& ALT
&& base
== 8))
1416 result
= __ultoa(ulval
, cp
, base
,
1418 flags
& GROUPING
, thousands_sep
,
1421 size
= buf
+ BUF
- result
;
1422 if (size
> BUF
) /* should never happen */
1425 default: /* "%?" prints ?, unless ? is NUL */
1428 /* pretend it was %c with argument ch */
1437 * All reasonable formats wind up here. At this point, `result'
1438 * points to a string which (if not flags&LADJUST) should be
1439 * padded out to `width' places. If flags&ZEROPAD, it should
1440 * first be prefixed by any sign or other prefix; otherwise,
1441 * it should be blank padded before the prefix is emitted.
1442 * After any left-hand padding and prefixing, emit zeroes
1443 * required by a decimal [diouxX] precision, then print the
1444 * string proper, then emit zeroes required by any leftover
1445 * floating precision; finally, if LADJUST, pad with blanks.
1447 * Compute actual size, so we know how much to pad.
1448 * size excludes decimal prec; realsz includes it.
1450 realsz
= dprec
> size
? dprec
: size
;
1456 prsize
= width
> realsz
? width
: realsz
;
1457 if ((unsigned)ret
+ prsize
> INT_MAX
) {
1462 /* right-adjusting blank padding */
1463 if ((flags
& (LADJUST
|ZEROPAD
)) == 0)
1464 PAD(width
- realsz
, blanks
);
1470 if (ox
[1]) { /* ox[1] is either x, X, or \0 */
1475 /* right-adjusting zero padding */
1476 if ((flags
& (LADJUST
|ZEROPAD
)) == ZEROPAD
)
1477 PAD(width
- realsz
, zeroes
);
1479 /* leading zeroes from decimal precision */
1480 PAD(dprec
- size
, zeroes
);
1482 /* the string or number proper */
1483 #ifndef NO_FLOATING_POINT
1484 if ((flags
& FPT
) == 0) {
1485 PRINT(result
, size
);
1486 } else { /* glue together f_p fragments */
1487 if (!expchar
) { /* %[fF] or sufficiently short %[gG] */
1490 if (prec
|| flags
& ALT
)
1491 PRINT(decimal_point
, 1);
1493 /* already handled initial 0's */
1496 PRINTANDPAD(result
, convbuf
+ ndig
,
1500 while (nseps
>0 || nrepeats
>0) {
1507 PRINT(&thousands_sep
,
1512 result
+= *grouping
;
1514 if (result
> convbuf
+ ndig
)
1515 result
= convbuf
+ ndig
;
1517 if (prec
|| flags
& ALT
) {
1518 buf
[0] = *decimal_point
;
1522 PRINTANDPAD(result
, convbuf
+ ndig
, prec
,
1524 } else { /* %[eE] or sufficiently long %[gG] */
1525 if (prec
> 1 || flags
& ALT
) {
1527 buf
[1] = *decimal_point
;
1529 PRINT(result
, ndig
-1);
1530 PAD(prec
- ndig
, zeroes
);
1533 PRINT(expstr
, expsize
);
1537 PRINT(result
, size
);
1539 /* left-adjusting padding (always blank) */
1540 if (flags
& LADJUST
)
1541 PAD(width
- realsz
, blanks
);
1543 /* finally, adjust ret */
1551 if (convbuf
!= NULL
)
1555 if ((argtable
!= NULL
) && (argtable
!= statargtable
))
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.
1572 __find_arguments(const CHAR_T
*fmt0
, va_list ap
, union arg
**argtable
)
1574 CHAR_T
*fmt
; /* format string */
1575 int ch
; /* character from fmt */
1576 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 */
1586 * Add an argument type to the table, expanding if necessary.
1588 #define ADDTYPE(type) \
1590 if (nextarg >= tablesize) \
1591 if (__grow_type_table(nextarg, &typetable, \
1592 &tablesize) == -1) \
1594 if (nextarg > tablemax) \
1595 tablemax = nextarg; \
1596 typetable[nextarg++] = type; \
1597 } while (/*CONSTCOND*/0)
1601 if (flags & INTMAXT) \
1602 ADDTYPE(T_INTMAXT); \
1603 else if (flags & SIZET) \
1605 else if (flags & PTRDIFFT) \
1606 ADDTYPE(T_PTRDIFFT); \
1607 else if (flags & LLONGINT) \
1609 else if (flags & LONGINT) \
1613 } while (/*CONSTCOND*/0)
1617 if (flags & INTMAXT) \
1618 ADDTYPE(T_UINTMAXT); \
1619 else if (flags & 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); \
1629 } while (/*CONSTCOND*/0)
1631 * Add * arguments to the type array.
1633 #define ADDASTER() \
1636 while (is_digit(*cp)) { \
1637 n2 = 10 * n2 + to_digit(*cp); \
1641 int hold = nextarg; \
1649 fmt
= (CHAR_T
*)__UNCONST(fmt0
);
1650 typetable
= stattypetable
;
1651 tablesize
= STATIC_ARG_TBL_SIZE
;
1654 for (n
= 0; n
< STATIC_ARG_TBL_SIZE
; n
++)
1655 typetable
[n
] = T_UNUSED
;
1658 * Scan the format for conversions (`%' character).
1661 for (cp
= fmt
; (ch
= *fmt
) != '\0' && ch
!= '%'; fmt
++)
1665 fmt
++; /* skip over '%' */
1670 reswitch
: switch (ch
) {
1682 if ((ch
= *fmt
++) == '*') {
1686 while (is_digit(ch
)) {
1692 case '1': case '2': case '3': case '4':
1693 case '5': case '6': case '7': case '8': case '9':
1696 n
= 10 * n
+ to_digit(ch
);
1698 } while (is_digit(ch
));
1704 #ifndef NO_FLOATING_POINT
1710 if (flags
& SHORTINT
) {
1720 if (flags
& LONGINT
) {
1727 flags
|= LLONGINT
; /* not necessarily */
1739 if (flags
& LONGINT
)
1751 #ifndef NO_FLOATING_POINT
1759 if (flags
& LONGDBL
)
1760 ADDTYPE(T_LONG_DOUBLE
);
1764 #endif /* !NO_FLOATING_POINT */
1766 if (flags
& INTMAXT
)
1767 ADDTYPE(TP_INTMAXT
);
1768 else if (flags
& PTRDIFFT
)
1769 ADDTYPE(TP_PTRDIFFT
);
1770 else if (flags
& SIZET
)
1772 else if (flags
& LLONGINT
)
1774 else if (flags
& LONGINT
)
1776 else if (flags
& SHORTINT
)
1778 else if (flags
& CHARINT
)
1782 continue; /* no output */
1796 if (flags
& LONGINT
)
1809 default: /* "%?" prints ?, unless ? is NUL */
1817 * Build the argument table.
1819 if (tablemax
>= STATIC_ARG_TBL_SIZE
) {
1820 *argtable
= (union arg
*)
1821 malloc (sizeof (union arg
) * (tablemax
+ 1));
1822 if (*argtable
== NULL
)
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);
1833 (*argtable
) [n
].pschararg
= va_arg (ap
, signed char *);
1836 (*argtable
) [n
].pshortarg
= va_arg (ap
, short *);
1839 (*argtable
) [n
].intarg
= va_arg (ap
, int);
1842 (*argtable
) [n
].uintarg
= va_arg (ap
, unsigned int);
1845 (*argtable
) [n
].pintarg
= va_arg (ap
, int *);
1848 (*argtable
) [n
].longarg
= va_arg (ap
, long);
1851 (*argtable
) [n
].ulongarg
= va_arg (ap
, unsigned long);
1854 (*argtable
) [n
].plongarg
= va_arg (ap
, long *);
1857 (*argtable
) [n
].longlongarg
= va_arg (ap
, long long);
1860 (*argtable
) [n
].ulonglongarg
= va_arg (ap
, unsigned long long);
1863 (*argtable
) [n
].plonglongarg
= va_arg (ap
, long long *);
1866 (*argtable
) [n
].ptrdiffarg
= va_arg (ap
, ptrdiff_t);
1869 (*argtable
) [n
].pptrdiffarg
= va_arg (ap
, ptrdiff_t *);
1872 (*argtable
) [n
].sizearg
= va_arg (ap
, size_t);
1875 (*argtable
) [n
].psizearg
= va_arg (ap
, size_t *);
1878 (*argtable
) [n
].intmaxarg
= va_arg (ap
, intmax_t);
1881 (*argtable
) [n
].uintmaxarg
= va_arg (ap
, uintmax_t);
1884 (*argtable
) [n
].pintmaxarg
= va_arg (ap
, intmax_t *);
1887 #ifndef NO_FLOATING_POINT
1888 (*argtable
) [n
].doublearg
= va_arg (ap
, double);
1892 #ifndef NO_FLOATING_POINT
1893 (*argtable
) [n
].longdoublearg
= va_arg (ap
, long double);
1897 (*argtable
) [n
].pchararg
= va_arg (ap
, char *);
1900 (*argtable
) [n
].pvoidarg
= va_arg (ap
, void *);
1903 (*argtable
) [n
].wintarg
= va_arg (ap
, wint_t);
1906 (*argtable
) [n
].pwchararg
= va_arg (ap
, wchar_t *);
1911 if ((typetable
!= NULL
) && (typetable
!= stattypetable
))
1917 * Increase the size of the type table.
1920 __grow_type_table (int nextarg
, enum typeid **typetable
, int *tablesize
)
1922 enum typeid *const oldtable
= *typetable
;
1923 const int oldsize
= *tablesize
;
1924 enum typeid *newtable
;
1925 int n
, newsize
= oldsize
* 2;
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
)
1932 memcpy(newtable
, oldtable
, oldsize
* sizeof(enum typeid));
1934 newtable
= realloc(oldtable
, newsize
* sizeof(enum typeid));
1935 if (newtable
== NULL
) {
1940 for (n
= oldsize
; n
< newsize
; n
++)
1941 newtable
[n
] = T_UNUSED
;
1943 *typetable
= newtable
;
1944 *tablesize
= newsize
;
1949 #ifndef NO_FLOATING_POINT
1952 cvt(double value
, int ndigits
, int flags
, char *sign
, int *decpt
, int ch
,
1956 char *digits
, *bp
, *rve
;
1958 _DIAGASSERT(decpt
!= NULL
);
1959 _DIAGASSERT(length
!= NULL
);
1960 _DIAGASSERT(sign
!= NULL
);
1963 mode
= 3; /* ndigits after the decimal point */
1965 /* To obtain ndigits after the decimal point for the 'e'
1966 * and 'E' formats, round to ndigits + 1 significant
1969 if (ch
== 'e' || ch
== 'E') {
1972 mode
= 2; /* ndigits significant digits */
1975 digits
= __dtoa(value
, mode
, ndigits
, decpt
, &dsgn
, &rve
);
1983 if ((ch
!= 'g' && ch
!= 'G') || flags
& ALT
) { /* Print trailing zeros */
1984 bp
= digits
+ ndigits
;
1986 if (*digits
== '0' && value
)
1987 *decpt
= -ndigits
+ 1;
1990 if (value
== 0) /* kludge for __dtoa irregularity */
1995 *length
= rve
- digits
;
2001 exponent(CHAR_T
*p0
, int expo
, int fmtch
)
2004 CHAR_T expbuf
[MAXEXPDIG
];
2014 t
= expbuf
+ MAXEXPDIG
;
2017 *--t
= to_char(expo
% 10);
2018 } while ((expo
/= 10) > 9);
2019 *--t
= to_char(expo
);
2020 for (; t
< expbuf
+ MAXEXPDIG
; *p
++ = *t
++);
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.
2029 if (fmtch
== 'e' || fmtch
== 'E')
2031 *p
++ = to_char(expo
);
2035 #endif /* !NO_FLOATING_POINT */