2 * Copyright (c) 2005 Poul-Henning Kamp
3 * Copyright (c) 1990, 1993
4 * The Regents of the University of California. All rights reserved.
6 * This code is derived from software contributed to Berkeley by
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 #include <namespace.h>
44 #define freedtoa __freedtoa
51 #include <un-namespace.h>
54 * The size of the buffer we use as scratch space for integer
55 * conversions, among other things. Technically, we would need the
56 * most space for base 10 conversions with thousands' grouping
57 * characters between each pair of digits. 100 bytes is a
58 * conservative overestimate even for a 128-bit uintmax_t.
62 #define DEFPREC 6 /* Default FP precision */
65 /* various globals ---------------------------------------------------*/
68 /* padding function---------------------------------------------------*/
70 #define PRINTANDPAD(p, ep, len, with) do { \
75 ret += __printf_puts(io, (p), n2); \
76 ret += __printf_pad(io, (len) - (n2 > 0 ? n2 : 0), (with)); \
79 /* misc --------------------------------------------------------------*/
81 #define to_char(n) ((n) + '0')
84 exponent(char *p0, int expo, int fmtch)
87 char expbuf[MAXEXPDIG];
97 t = expbuf + MAXEXPDIG;
100 *--t = to_char(expo % 10);
101 } while ((expo /= 10) > 9);
102 *--t = to_char(expo);
103 for (; t < expbuf + MAXEXPDIG; *p++ = *t++)
108 * Exponents for decimal floating point conversions
109 * (%[eEgG]) must be at least two characters long,
110 * whereas exponents for hexadecimal conversions can
111 * be only one character long.
113 if (fmtch == 'e' || fmtch == 'E')
115 *p++ = to_char(expo);
120 /* 'f' ---------------------------------------------------------------*/
123 __printf_arginfo_float(const struct printf_info *pi, size_t n, int *argt)
127 if (pi->is_long_double)
128 argt[0] |= PA_FLAG_LONG_DOUBLE;
133 * We can decompose the printed representation of floating
134 * point numbers into several parts, some of which may be empty:
136 * [+|-| ] [0x|0X] MMM . NNN [e|E|p|P] [+|-] ZZ
139 * A: 'sign' holds this value if present; '\0' otherwise
140 * B: ox[1] holds the 'x' or 'X'; '\0' if not hexadecimal
141 * C: cp points to the string MMMNNN. Leading and trailing
142 * zeros are not in the string and must be added.
143 * D: expchar holds this character; '\0' if no exponent, e.g. %f
144 * F: at least two digits for decimal, at least one digit for hex
148 __printf_render_float(struct __printf_io *io, const struct printf_info *pi, const void *const *arg)
150 int prec; /* precision from format; <0 for N/A */
151 char *dtoaresult; /* buffer allocated by dtoa */
152 char expchar; /* exponent character: [eEpP\0] */
154 int expt; /* integer value of exponent */
155 int signflag; /* true if float is negative */
156 char *dtoaend; /* pointer to end of converted digits */
157 char sign; /* sign prefix (' ', '+', '-', or \0) */
158 int size; /* size of converted field or string */
159 int ndig; /* actual number of digits returned by dtoa */
160 int expsize; /* character count for expstr */
161 char expstr[MAXEXPDIG+2]; /* buffer for exponent string: e+ZZZ */
162 int nseps; /* number of group separators with ' */
163 int nrepeats; /* number of repeats of the last group */
164 const char *grouping; /* locale specific numeric grouping rules */
165 int lead; /* sig figs before decimal or group sep */
168 int realsz; /* field size expanded by dprec, sign, etc */
169 int dprec; /* a copy of prec if [diouxX], 0 otherwise */
170 char ox[2]; /* space for 0x; ox[1] is either x, X, or \0 */
171 int prsize; /* max size of printed field */
172 int ret; /* return value accumulator */
173 char *decimal_point; /* locale specific decimal point */
174 int n2; /* XXX: for PRINTANDPAD */
175 char thousands_sep; /* locale specific thousands separator */
176 char buf[BUF]; /* buffer with space for digits of uintmax_t */
186 thousands_sep = *(localeconv()->thousands_sep);
189 grouping = localeconv()->grouping;
190 decimal_point = localeconv()->decimal_point;
196 if (pi->spec == 'a') {
198 xdigs = __lowercase_hex;
202 xdigs = __uppercase_hex;
207 if (pi->is_long_double) {
208 ld = *((long double *)arg[0]);
210 __hldtoa(ld, xdigs, prec,
211 &expt, &signflag, &dtoaend);
213 d = *((double *)arg[0]);
215 __hdtoa(d, xdigs, prec,
216 &expt, &signflag, &dtoaend);
226 if (prec < 0) /* account for digit before decpt */
237 expchar = pi->spec - ('g' - 'e');
242 assert(pi->spec == 'f');
247 if (pi->is_long_double) {
248 ld = *((long double *)arg[0]);
250 __ldtoa(&ld, expchar ? 2 : 3, prec,
251 &expt, &signflag, &dtoaend);
253 d = *((double *)arg[0]);
255 dtoa(d, expchar ? 2 : 3, prec,
256 &expt, &signflag, &dtoaend);
263 if (expt == INT_MAX) { /* inf or nan */
265 cp = (pi->spec >= 'a') ? "nan" : "NAN";
268 cp = (pi->spec >= 'a') ? "inf" : "INF";
274 if (pi->spec == 'g' || pi->spec == 'G') {
275 if (expt > -4 && expt <= prec) {
276 /* Make %[gG] smell like %[fF] */
286 * Make %[gG] smell like %[eE], but
287 * trim trailing zeroes if no # flag.
294 expsize = exponent(expstr, expt - 1, expchar);
295 size = expsize + prec;
296 if (prec > 1 || pi->alt)
299 /* space for digits before decimal point */
304 /* space for decimal pt and following digits */
307 if (grouping && expt > 0) {
308 /* space for thousands' grouping */
309 nseps = nrepeats = 0;
311 while (*grouping != CHAR_MAX) {
312 if (lead <= *grouping)
321 size += nseps + nrepeats;
328 * All reasonable formats wind up here. At this point, `cp'
329 * points to a string which (if not flags&LADJUST) should be
330 * padded out to `width' places. If flags&ZEROPAD, it should
331 * first be prefixed by any sign or other prefix; otherwise,
332 * it should be blank padded before the prefix is emitted.
333 * After any left-hand padding and prefixing, emit zeroes
334 * required by a decimal [diouxX] precision, then print the
335 * string proper, then emit zeroes required by any leftover
336 * floating precision; finally, if LADJUST, pad with blanks.
338 * Compute actual size, so we know how much to pad.
339 * size excludes decimal prec; realsz includes it.
341 realsz = dprec > size ? dprec : size;
347 prsize = pi->width > realsz ? pi->width : realsz;
349 /* right-adjusting blank padding */
350 if (pi->pad != '0' && pi->left == 0)
351 ret += __printf_pad(io, pi->width - realsz, 0);
355 ret += __printf_puts(io, &sign, 1);
357 if (ox[1]) { /* ox[1] is either x, X, or \0 */
359 ret += __printf_puts(io, ox, 2);
362 /* right-adjusting zero padding */
363 if (pi->pad == '0' && pi->left == 0)
364 ret += __printf_pad(io, pi->width - realsz, 1);
366 /* leading zeroes from decimal precision */
367 ret += __printf_pad(io, dprec - size, 1);
370 ret += __printf_puts(io, cp, size);
372 /* glue together f_p fragments */
373 if (!expchar) { /* %[fF] or sufficiently short %[gG] */
375 ret += __printf_puts(io, "0", 1);
377 ret += __printf_puts(io, decimal_point, 1);
378 ret += __printf_pad(io, -expt, 1);
379 /* already handled initial 0's */
382 PRINTANDPAD(cp, dtoaend, lead, 1);
385 while (nseps>0 || nrepeats>0) {
392 ret += __printf_puts(io, &thousands_sep, 1);
393 PRINTANDPAD(cp,dtoaend,
401 ret += __printf_puts(io, decimal_point,1);
403 PRINTANDPAD(cp, dtoaend, prec, 1);
404 } else { /* %[eE] or sufficiently long %[gG] */
405 if (prec > 1 || pi->alt) {
407 buf[1] = *decimal_point;
408 ret += __printf_puts(io, buf, 2);
409 ret += __printf_puts(io, cp, ndig-1);
410 ret += __printf_pad(io, prec - ndig, 1);
412 ret += __printf_puts(io, cp, 1);
413 ret += __printf_puts(io, expstr, expsize);
416 /* left-adjusting padding (always blank) */
418 ret += __printf_pad(io, pi->width - realsz, 0);
421 if (dtoaresult != NULL)
422 freedtoa(dtoaresult);