printfcommon.h revision 187354
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: head/lib/libc/stdio/printfcommon.h 187354 2009-01-17 05:38:14Z das $
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
53static int exponent(CHAR *, int, CHAR);
54
55#endif /* !NO_FLOATING_POINT */
56
57static CHAR	*__ujtoa(uintmax_t, CHAR *, int, int, const char *, int, char,
58		    const char *);
59static CHAR	*__ultoa(u_long, CHAR *, int, int, const char *, int, char,
60		    const char *);
61
62#define NIOV 8
63struct io_state {
64	FILE *fp;
65	struct __suio uio;	/* output information: summary */
66	struct __siov iov[NIOV];/* ... and individual io vectors */
67};
68
69static inline void
70io_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 */
83static inline int
84io_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 */
102static const CHAR blanks[PADSIZE] =
103{' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
104static 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 */
111static inline int
112io_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 */
129static inline int
130io_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
147static inline int
148io_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 */
160static 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. */
237static 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
310static int
311exponent(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