xref: /freebsd/lib/libc/stdio/printfcommon.h (revision 0a492640)
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 	struct __siov *iovp;	/* pointer to next free slot in iov */
68 };
69 
70 static inline void
71 io_init(struct io_state *iop, FILE *fp)
72 {
73 
74 	iop->uio.uio_iov = iop->iovp = 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
85 io_print(struct io_state *iop, const CHAR * __restrict ptr, int len)
86 {
87 
88 	iop->iovp->iov_base = (char *)ptr;
89 	iop->iovp->iov_len = len;
90 	iop->uio.uio_resid += len;
91 	iop->iovp++;
92 	if (++iop->uio.uio_iovcnt >= NIOV) {
93 		iop->iovp = iop->iov;
94 		return (__sprint(iop->fp, &iop->uio));
95 	}
96 	return (0);
97 }
98 
99 /*
100  * Choose PADSIZE to trade efficiency vs. size.  If larger printf
101  * fields occur frequently, increase PADSIZE and make the initialisers
102  * below longer.
103  */
104 #define	PADSIZE	16		/* pad chunk size */
105 static const CHAR blanks[PADSIZE] =
106 {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
107 static const CHAR zeroes[PADSIZE] =
108 {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
109 
110 /*
111  * Pad with blanks or zeroes. 'with' should point to either the blanks array
112  * or the zeroes array.
113  */
114 static inline int
115 io_pad(struct io_state *iop, int howmany, const CHAR * __restrict with)
116 {
117 
118 	while (howmany > PADSIZE) {
119 		if (io_print(iop, with, PADSIZE))
120 			return (-1);
121 		howmany -= PADSIZE;
122 	}
123 	if (howmany > 0 && io_print(iop, with, howmany))
124 		return (-1);
125 	return (0);
126 }
127 
128 /*
129  * Print exactly len characters of the string spanning p to ep, truncating
130  * or padding with 'with' as necessary.
131  */
132 static inline int
133 io_printandpad(struct io_state *iop, const CHAR *p, const CHAR *ep,
134 	       int len, const CHAR * __restrict with)
135 {
136 	int p_len;
137 
138 	p_len = ep - p;
139 	if (p_len > len)
140 		p_len = len;
141 	if (p_len > 0 && io_print(iop, p, p_len))
142 		return (-1);
143 	return (io_pad(iop, len - (p_len > 0 ? p_len : 0), with));
144 }
145 
146 static inline int
147 io_flush(struct io_state *iop)
148 {
149 
150 	iop->iovp = iop->iov;
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