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