1 /*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 1990, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Chris Torek.
9 *
10 * Copyright (c) 2011 The FreeBSD Foundation
11 *
12 * Portions of this software were developed by David Chisnall
13 * under sponsorship from the FreeBSD Foundation.
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
23 * 3. Neither the name of the University nor the names of its contributors
24 * may be used to endorse or promote products derived from this software
25 * without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
38 */
39
40 /*
41 * This file defines common routines used by both printf and wprintf.
42 * You must define CHAR to either char or wchar_t prior to including this.
43 */
44
45
46
47 #define dtoa __dtoa
48 #define freedtoa __freedtoa
49
50 #include <float.h>
51 #include <math.h>
52 #include "floatio.h"
53 #include "gdtoa.h"
54
55 #define DEFPREC 6
56
57 static int exponent(CHAR *, int, CHAR);
58
59
60 static CHAR *__ujtoa(uintmax_t, CHAR *, int, int, const char *);
61 static CHAR *__ultoa(u_long, CHAR *, int, int, const char *);
62
63 #define NIOV 8
64 struct io_state {
65 FILE *fp;
66 struct __suio uio; /* output information: summary */
67 struct __siov iov[NIOV];/* ... and individual io vectors */
68 };
69
70 static inline void
io_init(struct io_state * iop,FILE * fp)71 io_init(struct io_state *iop, FILE *fp)
72 {
73
74 iop->uio.uio_iov = iop->iov;
75 iop->uio.uio_resid = 0;
76 iop->uio.uio_iovcnt = 0;
77 iop->fp = fp;
78 }
79
80 /*
81 * WARNING: The buffer passed to io_print() is not copied immediately; it must
82 * remain valid until io_flush() is called.
83 */
84 static inline int
io_print(struct io_state * iop,const CHAR * __restrict ptr,int len,locale_t locale)85 io_print(struct io_state *iop, const CHAR * __restrict ptr, int len, locale_t locale)
86 {
87
88 iop->iov[iop->uio.uio_iovcnt].iov_base = (char *)ptr;
89 iop->iov[iop->uio.uio_iovcnt].iov_len = len;
90 iop->uio.uio_resid += len;
91 if (++iop->uio.uio_iovcnt >= NIOV)
92 return (__sprint(iop->fp, &iop->uio, locale));
93 else
94 return (0);
95 }
96
97 /*
98 * Choose PADSIZE to trade efficiency vs. size. If larger printf
99 * fields occur frequently, increase PADSIZE and make the initialisers
100 * below longer.
101 */
102 #define PADSIZE 16 /* pad chunk size */
103 static const CHAR blanks[PADSIZE] =
104 {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
105 static const CHAR zeroes[PADSIZE] =
106 {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
107
108 /*
109 * Pad with blanks or zeroes. 'with' should point to either the blanks array
110 * or the zeroes array.
111 */
112 static inline int
io_pad(struct io_state * iop,int howmany,const CHAR * __restrict with,locale_t locale)113 io_pad(struct io_state *iop, int howmany, const CHAR * __restrict with,
114 locale_t locale)
115 {
116 int n;
117
118 while (howmany > 0) {
119 n = (howmany >= PADSIZE) ? PADSIZE : howmany;
120 if (io_print(iop, with, n, locale))
121 return (-1);
122 howmany -= n;
123 }
124 return (0);
125 }
126
127 /*
128 * Print exactly len characters of the string spanning p to ep, truncating
129 * or padding with 'with' as necessary.
130 */
131 static inline int
io_printandpad(struct io_state * iop,const CHAR * p,const CHAR * ep,int len,const CHAR * __restrict with,locale_t locale)132 io_printandpad(struct io_state *iop, const CHAR *p, const CHAR *ep,
133 int len, const CHAR * __restrict with, locale_t locale)
134 {
135 int p_len;
136
137 p_len = ep - p;
138 if (p_len > len)
139 p_len = len;
140 if (p_len > 0) {
141 if (io_print(iop, p, p_len, locale))
142 return (-1);
143 } else {
144 p_len = 0;
145 }
146 return (io_pad(iop, len - p_len, with, locale));
147 }
148
149 static inline int
io_flush(struct io_state * iop,locale_t locale)150 io_flush(struct io_state *iop, locale_t locale)
151 {
152
153 return (__sprint(iop->fp, &iop->uio, locale));
154 }
155
156 /*
157 * Convert an unsigned long to ASCII for printf purposes, returning
158 * a pointer to the first character of the string representation.
159 * Octal numbers can be forced to have a leading zero; hex numbers
160 * use the given digits.
161 */
162 static CHAR *
__ultoa(u_long val,CHAR * endp,int base,int octzero,const char * xdigs)163 __ultoa(u_long val, CHAR *endp, int base, int octzero, const char *xdigs)
164 {
165 CHAR *cp = endp;
166 long sval;
167
168 /*
169 * Handle the three cases separately, in the hope of getting
170 * better/faster code.
171 */
172 switch (base) {
173 case 10:
174 if (val < 10) { /* many numbers are 1 digit */
175 *--cp = to_char(val);
176 return (cp);
177 }
178 /*
179 * On many machines, unsigned arithmetic is harder than
180 * signed arithmetic, so we do at most one unsigned mod and
181 * divide; this is sufficient to reduce the range of
182 * the incoming value to where signed arithmetic works.
183 */
184 if (val > LONG_MAX) {
185 *--cp = to_char(val % 10);
186 sval = val / 10;
187 } else
188 sval = val;
189 do {
190 *--cp = to_char(sval % 10);
191 sval /= 10;
192 } while (sval != 0);
193 break;
194
195 case 2:
196 do {
197 *--cp = to_char(val & 1);
198 val >>= 1;
199 } while (val);
200 break;
201
202 case 8:
203 do {
204 *--cp = to_char(val & 7);
205 val >>= 3;
206 } while (val);
207 if (octzero && *cp != '0')
208 *--cp = '0';
209 break;
210
211 case 16:
212 do {
213 *--cp = xdigs[val & 15];
214 val >>= 4;
215 } while (val);
216 break;
217
218 default: /* oops */
219 abort();
220 }
221 return (cp);
222 }
223
224 /* Identical to __ultoa, but for intmax_t. */
225 static CHAR *
__ujtoa(uintmax_t val,CHAR * endp,int base,int octzero,const char * xdigs)226 __ujtoa(uintmax_t val, CHAR *endp, int base, int octzero, const char *xdigs)
227 {
228 CHAR *cp = endp;
229 intmax_t sval;
230
231 /* quick test for small values; __ultoa is typically much faster */
232 /* (perhaps instead we should run until small, then call __ultoa?) */
233 if (val <= ULONG_MAX)
234 return (__ultoa((u_long)val, endp, base, octzero, xdigs));
235 switch (base) {
236 case 10:
237 if (val < 10) {
238 *--cp = to_char(val % 10);
239 return (cp);
240 }
241 if (val > INTMAX_MAX) {
242 *--cp = to_char(val % 10);
243 sval = val / 10;
244 } else
245 sval = val;
246 do {
247 *--cp = to_char(sval % 10);
248 sval /= 10;
249 } while (sval != 0);
250 break;
251
252 case 2:
253 do {
254 *--cp = to_char(val & 1);
255 val >>= 1;
256 } while (val);
257 break;
258
259 case 8:
260 do {
261 *--cp = to_char(val & 7);
262 val >>= 3;
263 } while (val);
264 if (octzero && *cp != '0')
265 *--cp = '0';
266 break;
267
268 case 16:
269 do {
270 *--cp = xdigs[val & 15];
271 val >>= 4;
272 } while (val);
273 break;
274
275 default:
276 abort();
277 }
278 return (cp);
279 }
280
281
282 static int
exponent(CHAR * p0,int exp,CHAR fmtch)283 exponent(CHAR *p0, int exp, CHAR fmtch)
284 {
285 CHAR *p, *t;
286 CHAR expbuf[MAXEXPDIG];
287
288 p = p0;
289 *p++ = fmtch;
290 if (exp < 0) {
291 exp = -exp;
292 *p++ = '-';
293 }
294 else
295 *p++ = '+';
296 t = expbuf + MAXEXPDIG;
297 if (exp > 9) {
298 do {
299 *--t = to_char(exp % 10);
300 } while ((exp /= 10) > 9);
301 *--t = to_char(exp);
302 for (; t < expbuf + MAXEXPDIG; *p++ = *t++);
303 }
304 else {
305 /*
306 * Exponents for decimal floating point conversions
307 * (%[eEgG]) must be at least two characters long,
308 * whereas exponents for hexadecimal conversions can
309 * be only one character long.
310 */
311 if (fmtch == 'e' || fmtch == 'E')
312 *p++ = '0';
313 *p++ = to_char(exp);
314 }
315 return (p - p0);
316 }
317
318