xref: /minix3/external/bsd/bind/dist/lib/isc/print.c (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
1*00b67f09SDavid van Moolenbroek /*	$NetBSD: print.c,v 1.5 2015/07/08 17:28:59 christos Exp $	*/
2*00b67f09SDavid van Moolenbroek 
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek  * Copyright (C) 2004-2008, 2010, 2014, 2015  Internet Systems Consortium, Inc. ("ISC")
5*00b67f09SDavid van Moolenbroek  * Copyright (C) 1999-2001, 2003  Internet Software Consortium.
6*00b67f09SDavid van Moolenbroek  *
7*00b67f09SDavid van Moolenbroek  * Permission to use, copy, modify, and/or distribute this software for any
8*00b67f09SDavid van Moolenbroek  * purpose with or without fee is hereby granted, provided that the above
9*00b67f09SDavid van Moolenbroek  * copyright notice and this permission notice appear in all copies.
10*00b67f09SDavid van Moolenbroek  *
11*00b67f09SDavid van Moolenbroek  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12*00b67f09SDavid van Moolenbroek  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13*00b67f09SDavid van Moolenbroek  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14*00b67f09SDavid van Moolenbroek  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15*00b67f09SDavid van Moolenbroek  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16*00b67f09SDavid van Moolenbroek  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*00b67f09SDavid van Moolenbroek  * PERFORMANCE OF THIS SOFTWARE.
18*00b67f09SDavid van Moolenbroek  */
19*00b67f09SDavid van Moolenbroek 
20*00b67f09SDavid van Moolenbroek /* Id: print.c,v 1.37 2010/10/18 23:47:08 tbox Exp  */
21*00b67f09SDavid van Moolenbroek 
22*00b67f09SDavid van Moolenbroek /*! \file */
23*00b67f09SDavid van Moolenbroek 
24*00b67f09SDavid van Moolenbroek #include <config.h>
25*00b67f09SDavid van Moolenbroek 
26*00b67f09SDavid van Moolenbroek #include <ctype.h>
27*00b67f09SDavid van Moolenbroek #include <stdio.h>		/* for sprintf() */
28*00b67f09SDavid van Moolenbroek #include <string.h>		/* for strlen() */
29*00b67f09SDavid van Moolenbroek 
30*00b67f09SDavid van Moolenbroek #define	ISC__PRINT_SOURCE	/* Used to get the isc_print_* prototypes. */
31*00b67f09SDavid van Moolenbroek 
32*00b67f09SDavid van Moolenbroek #include <isc/assertions.h>
33*00b67f09SDavid van Moolenbroek #include <isc/int.h>
34*00b67f09SDavid van Moolenbroek #include <isc/msgs.h>
35*00b67f09SDavid van Moolenbroek #include <isc/print.h>
36*00b67f09SDavid van Moolenbroek #include <isc/stdlib.h>
37*00b67f09SDavid van Moolenbroek #include <isc/util.h>
38*00b67f09SDavid van Moolenbroek 
39*00b67f09SDavid van Moolenbroek int
isc_print_sprintf(char * str,const char * format,...)40*00b67f09SDavid van Moolenbroek isc_print_sprintf(char *str, const char *format, ...) {
41*00b67f09SDavid van Moolenbroek 	va_list ap;
42*00b67f09SDavid van Moolenbroek 
43*00b67f09SDavid van Moolenbroek 	va_start(ap, format);
44*00b67f09SDavid van Moolenbroek 	vsprintf(str, format, ap);
45*00b67f09SDavid van Moolenbroek 	va_end(ap);
46*00b67f09SDavid van Moolenbroek 	return (strlen(str));
47*00b67f09SDavid van Moolenbroek }
48*00b67f09SDavid van Moolenbroek 
49*00b67f09SDavid van Moolenbroek /*!
50*00b67f09SDavid van Moolenbroek  * Return length of string that would have been written if not truncated.
51*00b67f09SDavid van Moolenbroek  */
52*00b67f09SDavid van Moolenbroek 
53*00b67f09SDavid van Moolenbroek int
isc_print_snprintf(char * str,size_t size,const char * format,...)54*00b67f09SDavid van Moolenbroek isc_print_snprintf(char *str, size_t size, const char *format, ...) {
55*00b67f09SDavid van Moolenbroek 	va_list ap;
56*00b67f09SDavid van Moolenbroek 	int ret;
57*00b67f09SDavid van Moolenbroek 
58*00b67f09SDavid van Moolenbroek 	va_start(ap, format);
59*00b67f09SDavid van Moolenbroek 	ret = vsnprintf(str, size, format, ap);
60*00b67f09SDavid van Moolenbroek 	va_end(ap);
61*00b67f09SDavid van Moolenbroek 	return (ret);
62*00b67f09SDavid van Moolenbroek 
63*00b67f09SDavid van Moolenbroek }
64*00b67f09SDavid van Moolenbroek 
65*00b67f09SDavid van Moolenbroek /*!
66*00b67f09SDavid van Moolenbroek  * Return length of string that would have been written if not truncated.
67*00b67f09SDavid van Moolenbroek  */
68*00b67f09SDavid van Moolenbroek 
69*00b67f09SDavid van Moolenbroek int
isc_print_vsnprintf(char * str,size_t size,const char * format,va_list ap)70*00b67f09SDavid van Moolenbroek isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
71*00b67f09SDavid van Moolenbroek 	int h;
72*00b67f09SDavid van Moolenbroek 	int l;
73*00b67f09SDavid van Moolenbroek 	int q;
74*00b67f09SDavid van Moolenbroek 	int alt;
75*00b67f09SDavid van Moolenbroek 	int zero;
76*00b67f09SDavid van Moolenbroek 	int left;
77*00b67f09SDavid van Moolenbroek 	int plus;
78*00b67f09SDavid van Moolenbroek 	int space;
79*00b67f09SDavid van Moolenbroek 	int neg;
80*00b67f09SDavid van Moolenbroek 	isc_int64_t tmpi;
81*00b67f09SDavid van Moolenbroek 	isc_uint64_t tmpui;
82*00b67f09SDavid van Moolenbroek 	unsigned long width;
83*00b67f09SDavid van Moolenbroek 	unsigned long precision;
84*00b67f09SDavid van Moolenbroek 	unsigned int length;
85*00b67f09SDavid van Moolenbroek 	char buf[1024];
86*00b67f09SDavid van Moolenbroek 	char c;
87*00b67f09SDavid van Moolenbroek 	void *v;
88*00b67f09SDavid van Moolenbroek 	char *save = str;
89*00b67f09SDavid van Moolenbroek 	const char *cp;
90*00b67f09SDavid van Moolenbroek 	const char *head;
91*00b67f09SDavid van Moolenbroek 	int count = 0;
92*00b67f09SDavid van Moolenbroek 	int pad;
93*00b67f09SDavid van Moolenbroek 	int zeropad;
94*00b67f09SDavid van Moolenbroek 	int dot;
95*00b67f09SDavid van Moolenbroek 	double dbl;
96*00b67f09SDavid van Moolenbroek #ifdef HAVE_LONG_DOUBLE
97*00b67f09SDavid van Moolenbroek 	long double ldbl;
98*00b67f09SDavid van Moolenbroek #endif
99*00b67f09SDavid van Moolenbroek 	char fmt[32];
100*00b67f09SDavid van Moolenbroek 
101*00b67f09SDavid van Moolenbroek 	INSIST(str != NULL);
102*00b67f09SDavid van Moolenbroek 	INSIST(format != NULL);
103*00b67f09SDavid van Moolenbroek 
104*00b67f09SDavid van Moolenbroek 	while (*format != '\0') {
105*00b67f09SDavid van Moolenbroek 		if (*format != '%') {
106*00b67f09SDavid van Moolenbroek 			if (size > 1) {
107*00b67f09SDavid van Moolenbroek 				*str++ = *format;
108*00b67f09SDavid van Moolenbroek 				size--;
109*00b67f09SDavid van Moolenbroek 			}
110*00b67f09SDavid van Moolenbroek 			count++;
111*00b67f09SDavid van Moolenbroek 			format++;
112*00b67f09SDavid van Moolenbroek 			continue;
113*00b67f09SDavid van Moolenbroek 		}
114*00b67f09SDavid van Moolenbroek 		format++;
115*00b67f09SDavid van Moolenbroek 
116*00b67f09SDavid van Moolenbroek 		/*
117*00b67f09SDavid van Moolenbroek 		 * Reset flags.
118*00b67f09SDavid van Moolenbroek 		 */
119*00b67f09SDavid van Moolenbroek 		dot = neg = space = plus = left = zero = alt = h = l = q = 0;
120*00b67f09SDavid van Moolenbroek 		width = precision = 0;
121*00b67f09SDavid van Moolenbroek 		head = "";
122*00b67f09SDavid van Moolenbroek 		pad = zeropad = 0;
123*00b67f09SDavid van Moolenbroek 
124*00b67f09SDavid van Moolenbroek 		do {
125*00b67f09SDavid van Moolenbroek 			if (*format == '#') {
126*00b67f09SDavid van Moolenbroek 				alt = 1;
127*00b67f09SDavid van Moolenbroek 				format++;
128*00b67f09SDavid van Moolenbroek 			} else if (*format == '-') {
129*00b67f09SDavid van Moolenbroek 				left = 1;
130*00b67f09SDavid van Moolenbroek 				zero = 0;
131*00b67f09SDavid van Moolenbroek 				format++;
132*00b67f09SDavid van Moolenbroek 			} else if (*format == ' ') {
133*00b67f09SDavid van Moolenbroek 				if (!plus)
134*00b67f09SDavid van Moolenbroek 					space = 1;
135*00b67f09SDavid van Moolenbroek 				format++;
136*00b67f09SDavid van Moolenbroek 			} else if (*format == '+') {
137*00b67f09SDavid van Moolenbroek 				plus = 1;
138*00b67f09SDavid van Moolenbroek 				space = 0;
139*00b67f09SDavid van Moolenbroek 				format++;
140*00b67f09SDavid van Moolenbroek 			} else if (*format == '0') {
141*00b67f09SDavid van Moolenbroek 				if (!left)
142*00b67f09SDavid van Moolenbroek 					zero = 1;
143*00b67f09SDavid van Moolenbroek 				format++;
144*00b67f09SDavid van Moolenbroek 			} else
145*00b67f09SDavid van Moolenbroek 				break;
146*00b67f09SDavid van Moolenbroek 		} while (1);
147*00b67f09SDavid van Moolenbroek 
148*00b67f09SDavid van Moolenbroek 		/*
149*00b67f09SDavid van Moolenbroek 		 * Width.
150*00b67f09SDavid van Moolenbroek 		 */
151*00b67f09SDavid van Moolenbroek 		if (*format == '*') {
152*00b67f09SDavid van Moolenbroek 			width = va_arg(ap, int);
153*00b67f09SDavid van Moolenbroek 			format++;
154*00b67f09SDavid van Moolenbroek 		} else if (isdigit((unsigned char)*format)) {
155*00b67f09SDavid van Moolenbroek 			char *e;
156*00b67f09SDavid van Moolenbroek 			width = strtoul(format, &e, 10);
157*00b67f09SDavid van Moolenbroek 			format = e;
158*00b67f09SDavid van Moolenbroek 		}
159*00b67f09SDavid van Moolenbroek 
160*00b67f09SDavid van Moolenbroek 		/*
161*00b67f09SDavid van Moolenbroek 		 * Precision.
162*00b67f09SDavid van Moolenbroek 		 */
163*00b67f09SDavid van Moolenbroek 		if (*format == '.') {
164*00b67f09SDavid van Moolenbroek 			format++;
165*00b67f09SDavid van Moolenbroek 			dot = 1;
166*00b67f09SDavid van Moolenbroek 			if (*format == '*') {
167*00b67f09SDavid van Moolenbroek 				precision = va_arg(ap, int);
168*00b67f09SDavid van Moolenbroek 				format++;
169*00b67f09SDavid van Moolenbroek 			} else if (isdigit((unsigned char)*format)) {
170*00b67f09SDavid van Moolenbroek 				char *e;
171*00b67f09SDavid van Moolenbroek 				precision = strtoul(format, &e, 10);
172*00b67f09SDavid van Moolenbroek 				format = e;
173*00b67f09SDavid van Moolenbroek 			}
174*00b67f09SDavid van Moolenbroek 		}
175*00b67f09SDavid van Moolenbroek 
176*00b67f09SDavid van Moolenbroek 		switch (*format) {
177*00b67f09SDavid van Moolenbroek 		case '\0':
178*00b67f09SDavid van Moolenbroek 			continue;
179*00b67f09SDavid van Moolenbroek 		case '%':
180*00b67f09SDavid van Moolenbroek 			if (size > 1) {
181*00b67f09SDavid van Moolenbroek 				*str++ = *format;
182*00b67f09SDavid van Moolenbroek 				size--;
183*00b67f09SDavid van Moolenbroek 			}
184*00b67f09SDavid van Moolenbroek 			count++;
185*00b67f09SDavid van Moolenbroek 			break;
186*00b67f09SDavid van Moolenbroek 		case 'q':
187*00b67f09SDavid van Moolenbroek 			q = 1;
188*00b67f09SDavid van Moolenbroek 			format++;
189*00b67f09SDavid van Moolenbroek 			goto doint;
190*00b67f09SDavid van Moolenbroek 		case 'h':
191*00b67f09SDavid van Moolenbroek 			h = 1;
192*00b67f09SDavid van Moolenbroek 			format++;
193*00b67f09SDavid van Moolenbroek 			goto doint;
194*00b67f09SDavid van Moolenbroek 		case 'l':
195*00b67f09SDavid van Moolenbroek 			l = 1;
196*00b67f09SDavid van Moolenbroek 			format++;
197*00b67f09SDavid van Moolenbroek 			if (*format == 'l') {
198*00b67f09SDavid van Moolenbroek 				q = 1;
199*00b67f09SDavid van Moolenbroek 				format++;
200*00b67f09SDavid van Moolenbroek 			}
201*00b67f09SDavid van Moolenbroek 			goto doint;
202*00b67f09SDavid van Moolenbroek 		case 'n':
203*00b67f09SDavid van Moolenbroek 		case 'i':
204*00b67f09SDavid van Moolenbroek 		case 'd':
205*00b67f09SDavid van Moolenbroek 		case 'o':
206*00b67f09SDavid van Moolenbroek 		case 'u':
207*00b67f09SDavid van Moolenbroek 		case 'x':
208*00b67f09SDavid van Moolenbroek 		case 'X':
209*00b67f09SDavid van Moolenbroek 		doint:
210*00b67f09SDavid van Moolenbroek 			if (precision != 0)
211*00b67f09SDavid van Moolenbroek 				zero = 0;
212*00b67f09SDavid van Moolenbroek 			switch (*format) {
213*00b67f09SDavid van Moolenbroek 			case 'n':
214*00b67f09SDavid van Moolenbroek 				if (h) {
215*00b67f09SDavid van Moolenbroek 					short int *p;
216*00b67f09SDavid van Moolenbroek 					p = va_arg(ap, short *);
217*00b67f09SDavid van Moolenbroek 					REQUIRE(p != NULL);
218*00b67f09SDavid van Moolenbroek 					*p = str - save;
219*00b67f09SDavid van Moolenbroek 				} else if (l) {
220*00b67f09SDavid van Moolenbroek 					long int *p;
221*00b67f09SDavid van Moolenbroek 					p = va_arg(ap, long *);
222*00b67f09SDavid van Moolenbroek 					REQUIRE(p != NULL);
223*00b67f09SDavid van Moolenbroek 					*p = str - save;
224*00b67f09SDavid van Moolenbroek 				} else {
225*00b67f09SDavid van Moolenbroek 					int *p;
226*00b67f09SDavid van Moolenbroek 					p = va_arg(ap, int *);
227*00b67f09SDavid van Moolenbroek 					REQUIRE(p != NULL);
228*00b67f09SDavid van Moolenbroek 					*p = str - save;
229*00b67f09SDavid van Moolenbroek 				}
230*00b67f09SDavid van Moolenbroek 				break;
231*00b67f09SDavid van Moolenbroek 			case 'i':
232*00b67f09SDavid van Moolenbroek 			case 'd':
233*00b67f09SDavid van Moolenbroek 				if (q)
234*00b67f09SDavid van Moolenbroek 					tmpi = va_arg(ap, isc_int64_t);
235*00b67f09SDavid van Moolenbroek 				else if (l)
236*00b67f09SDavid van Moolenbroek 					tmpi = va_arg(ap, long int);
237*00b67f09SDavid van Moolenbroek 				else
238*00b67f09SDavid van Moolenbroek 					tmpi = va_arg(ap, int);
239*00b67f09SDavid van Moolenbroek 				if (tmpi < 0) {
240*00b67f09SDavid van Moolenbroek 					head = "-";
241*00b67f09SDavid van Moolenbroek 					tmpui = -tmpi;
242*00b67f09SDavid van Moolenbroek 				} else {
243*00b67f09SDavid van Moolenbroek 					if (plus)
244*00b67f09SDavid van Moolenbroek 						head = "+";
245*00b67f09SDavid van Moolenbroek 					else if (space)
246*00b67f09SDavid van Moolenbroek 						head = " ";
247*00b67f09SDavid van Moolenbroek 					else
248*00b67f09SDavid van Moolenbroek 						head = "";
249*00b67f09SDavid van Moolenbroek 					tmpui = tmpi;
250*00b67f09SDavid van Moolenbroek 				}
251*00b67f09SDavid van Moolenbroek 				if (tmpui <= 0xffffffffU)
252*00b67f09SDavid van Moolenbroek 					sprintf(buf, "%lu",
253*00b67f09SDavid van Moolenbroek 						(unsigned long)tmpui);
254*00b67f09SDavid van Moolenbroek 				else {
255*00b67f09SDavid van Moolenbroek 					unsigned long mid;
256*00b67f09SDavid van Moolenbroek 					unsigned long lo;
257*00b67f09SDavid van Moolenbroek 					unsigned long hi;
258*00b67f09SDavid van Moolenbroek 					lo = tmpui % 1000000000;
259*00b67f09SDavid van Moolenbroek 					tmpui /= 1000000000;
260*00b67f09SDavid van Moolenbroek 					mid = tmpui % 1000000000;
261*00b67f09SDavid van Moolenbroek 					hi = tmpui / 1000000000;
262*00b67f09SDavid van Moolenbroek 					if (hi != 0)
263*00b67f09SDavid van Moolenbroek 						sprintf(buf, "%lu", hi);
264*00b67f09SDavid van Moolenbroek 					else
265*00b67f09SDavid van Moolenbroek 						buf[0] = '\0';
266*00b67f09SDavid van Moolenbroek 					sprintf(buf + strlen(buf), "%lu", mid);
267*00b67f09SDavid van Moolenbroek 					sprintf(buf + strlen(buf), "%lu", lo);
268*00b67f09SDavid van Moolenbroek 				}
269*00b67f09SDavid van Moolenbroek 				goto printint;
270*00b67f09SDavid van Moolenbroek 			case 'o':
271*00b67f09SDavid van Moolenbroek 				if (q)
272*00b67f09SDavid van Moolenbroek 					tmpui = va_arg(ap, isc_uint64_t);
273*00b67f09SDavid van Moolenbroek 				else if (l)
274*00b67f09SDavid van Moolenbroek 					tmpui = va_arg(ap, long int);
275*00b67f09SDavid van Moolenbroek 				else
276*00b67f09SDavid van Moolenbroek 					tmpui = va_arg(ap, int);
277*00b67f09SDavid van Moolenbroek 				if (tmpui <= 0xffffffffU)
278*00b67f09SDavid van Moolenbroek 					sprintf(buf, alt ?  "%#lo" : "%lo",
279*00b67f09SDavid van Moolenbroek 						(unsigned long)tmpui);
280*00b67f09SDavid van Moolenbroek 				else {
281*00b67f09SDavid van Moolenbroek 					unsigned long mid;
282*00b67f09SDavid van Moolenbroek 					unsigned long lo;
283*00b67f09SDavid van Moolenbroek 					unsigned long hi;
284*00b67f09SDavid van Moolenbroek 					lo = tmpui % 010000000000;
285*00b67f09SDavid van Moolenbroek 					tmpui /= 010000000000;
286*00b67f09SDavid van Moolenbroek 					mid = tmpui % 010000000000;
287*00b67f09SDavid van Moolenbroek 					hi = tmpui / 010000000000;
288*00b67f09SDavid van Moolenbroek 					if (hi != 0) {
289*00b67f09SDavid van Moolenbroek 						sprintf(buf,
290*00b67f09SDavid van Moolenbroek 							alt ?  "%#lo" : "%lo",
291*00b67f09SDavid van Moolenbroek 							hi);
292*00b67f09SDavid van Moolenbroek 						sprintf(buf + strlen(buf),
293*00b67f09SDavid van Moolenbroek 							"%lo", mid);
294*00b67f09SDavid van Moolenbroek 					} else
295*00b67f09SDavid van Moolenbroek 						sprintf(buf,
296*00b67f09SDavid van Moolenbroek 							alt ?  "%#lo" : "%lo",
297*00b67f09SDavid van Moolenbroek 							mid);
298*00b67f09SDavid van Moolenbroek 					sprintf(buf + strlen(buf), "%lo", lo);
299*00b67f09SDavid van Moolenbroek 				}
300*00b67f09SDavid van Moolenbroek 				goto printint;
301*00b67f09SDavid van Moolenbroek 			case 'u':
302*00b67f09SDavid van Moolenbroek 				if (q)
303*00b67f09SDavid van Moolenbroek 					tmpui = va_arg(ap, isc_uint64_t);
304*00b67f09SDavid van Moolenbroek 				else if (l)
305*00b67f09SDavid van Moolenbroek 					tmpui = va_arg(ap, unsigned long int);
306*00b67f09SDavid van Moolenbroek 				else
307*00b67f09SDavid van Moolenbroek 					tmpui = va_arg(ap, unsigned int);
308*00b67f09SDavid van Moolenbroek 				if (tmpui <= 0xffffffffU)
309*00b67f09SDavid van Moolenbroek 					sprintf(buf, "%lu",
310*00b67f09SDavid van Moolenbroek 						(unsigned long)tmpui);
311*00b67f09SDavid van Moolenbroek 				else {
312*00b67f09SDavid van Moolenbroek 					unsigned long mid;
313*00b67f09SDavid van Moolenbroek 					unsigned long lo;
314*00b67f09SDavid van Moolenbroek 					unsigned long hi;
315*00b67f09SDavid van Moolenbroek 					lo = tmpui % 1000000000;
316*00b67f09SDavid van Moolenbroek 					tmpui /= 1000000000;
317*00b67f09SDavid van Moolenbroek 					mid = tmpui % 1000000000;
318*00b67f09SDavid van Moolenbroek 					hi = tmpui / 1000000000;
319*00b67f09SDavid van Moolenbroek 					if (hi != 0)
320*00b67f09SDavid van Moolenbroek 						sprintf(buf, "%lu", hi);
321*00b67f09SDavid van Moolenbroek 					else
322*00b67f09SDavid van Moolenbroek 						buf[0] = '\0';
323*00b67f09SDavid van Moolenbroek 					sprintf(buf + strlen(buf), "%lu", mid);
324*00b67f09SDavid van Moolenbroek 					sprintf(buf + strlen(buf), "%lu", lo);
325*00b67f09SDavid van Moolenbroek 				}
326*00b67f09SDavid van Moolenbroek 				goto printint;
327*00b67f09SDavid van Moolenbroek 			case 'x':
328*00b67f09SDavid van Moolenbroek 				if (q)
329*00b67f09SDavid van Moolenbroek 					tmpui = va_arg(ap, isc_uint64_t);
330*00b67f09SDavid van Moolenbroek 				else if (l)
331*00b67f09SDavid van Moolenbroek 					tmpui = va_arg(ap, unsigned long int);
332*00b67f09SDavid van Moolenbroek 				else
333*00b67f09SDavid van Moolenbroek 					tmpui = va_arg(ap, unsigned int);
334*00b67f09SDavid van Moolenbroek 				if (alt) {
335*00b67f09SDavid van Moolenbroek 					head = "0x";
336*00b67f09SDavid van Moolenbroek 					if (precision > 2)
337*00b67f09SDavid van Moolenbroek 						precision -= 2;
338*00b67f09SDavid van Moolenbroek 				}
339*00b67f09SDavid van Moolenbroek 				if (tmpui <= 0xffffffffU)
340*00b67f09SDavid van Moolenbroek 					sprintf(buf, "%lx",
341*00b67f09SDavid van Moolenbroek 						(unsigned long)tmpui);
342*00b67f09SDavid van Moolenbroek 				else {
343*00b67f09SDavid van Moolenbroek 					unsigned long hi = tmpui>>32;
344*00b67f09SDavid van Moolenbroek 					unsigned long lo = tmpui & 0xffffffff;
345*00b67f09SDavid van Moolenbroek 					sprintf(buf, "%lx", hi);
346*00b67f09SDavid van Moolenbroek 					sprintf(buf + strlen(buf), "%lx", lo);
347*00b67f09SDavid van Moolenbroek 				}
348*00b67f09SDavid van Moolenbroek 				goto printint;
349*00b67f09SDavid van Moolenbroek 			case 'X':
350*00b67f09SDavid van Moolenbroek 				if (q)
351*00b67f09SDavid van Moolenbroek 					tmpui = va_arg(ap, isc_uint64_t);
352*00b67f09SDavid van Moolenbroek 				else if (l)
353*00b67f09SDavid van Moolenbroek 					tmpui = va_arg(ap, unsigned long int);
354*00b67f09SDavid van Moolenbroek 				else
355*00b67f09SDavid van Moolenbroek 					tmpui = va_arg(ap, unsigned int);
356*00b67f09SDavid van Moolenbroek 				if (alt) {
357*00b67f09SDavid van Moolenbroek 					head = "0X";
358*00b67f09SDavid van Moolenbroek 					if (precision > 2)
359*00b67f09SDavid van Moolenbroek 						precision -= 2;
360*00b67f09SDavid van Moolenbroek 				}
361*00b67f09SDavid van Moolenbroek 				if (tmpui <= 0xffffffffU)
362*00b67f09SDavid van Moolenbroek 					sprintf(buf, "%lX",
363*00b67f09SDavid van Moolenbroek 						(unsigned long)tmpui);
364*00b67f09SDavid van Moolenbroek 				else  {
365*00b67f09SDavid van Moolenbroek 					unsigned long hi = tmpui>>32;
366*00b67f09SDavid van Moolenbroek 					unsigned long lo = tmpui & 0xffffffff;
367*00b67f09SDavid van Moolenbroek 					sprintf(buf, "%lX", hi);
368*00b67f09SDavid van Moolenbroek 					sprintf(buf + strlen(buf), "%lX", lo);
369*00b67f09SDavid van Moolenbroek 				}
370*00b67f09SDavid van Moolenbroek 				goto printint;
371*00b67f09SDavid van Moolenbroek 			printint:
372*00b67f09SDavid van Moolenbroek 				if (precision != 0 || width != 0) {
373*00b67f09SDavid van Moolenbroek 					length = strlen(buf);
374*00b67f09SDavid van Moolenbroek 					if (length < precision)
375*00b67f09SDavid van Moolenbroek 						zeropad = precision - length;
376*00b67f09SDavid van Moolenbroek 					else if (length < width && zero)
377*00b67f09SDavid van Moolenbroek 						zeropad = width - length;
378*00b67f09SDavid van Moolenbroek 					if (width != 0) {
379*00b67f09SDavid van Moolenbroek 						pad = width - length -
380*00b67f09SDavid van Moolenbroek 						      zeropad - strlen(head);
381*00b67f09SDavid van Moolenbroek 						if (pad < 0)
382*00b67f09SDavid van Moolenbroek 							pad = 0;
383*00b67f09SDavid van Moolenbroek 					}
384*00b67f09SDavid van Moolenbroek 				}
385*00b67f09SDavid van Moolenbroek 				count += strlen(head) + strlen(buf) + pad +
386*00b67f09SDavid van Moolenbroek 					 zeropad;
387*00b67f09SDavid van Moolenbroek 				if (!left) {
388*00b67f09SDavid van Moolenbroek 					while (pad > 0 && size > 1) {
389*00b67f09SDavid van Moolenbroek 						*str++ = ' ';
390*00b67f09SDavid van Moolenbroek 						size--;
391*00b67f09SDavid van Moolenbroek 						pad--;
392*00b67f09SDavid van Moolenbroek 					}
393*00b67f09SDavid van Moolenbroek 				}
394*00b67f09SDavid van Moolenbroek 				cp = head;
395*00b67f09SDavid van Moolenbroek 				while (*cp != '\0' && size > 1) {
396*00b67f09SDavid van Moolenbroek 					*str++ = *cp++;
397*00b67f09SDavid van Moolenbroek 					size--;
398*00b67f09SDavid van Moolenbroek 				}
399*00b67f09SDavid van Moolenbroek 				while (zeropad > 0 && size > 1) {
400*00b67f09SDavid van Moolenbroek 					*str++ = '0';
401*00b67f09SDavid van Moolenbroek 					size--;
402*00b67f09SDavid van Moolenbroek 					zeropad--;
403*00b67f09SDavid van Moolenbroek 				}
404*00b67f09SDavid van Moolenbroek 				cp = buf;
405*00b67f09SDavid van Moolenbroek 				while (*cp != '\0' && size > 1) {
406*00b67f09SDavid van Moolenbroek 					*str++ = *cp++;
407*00b67f09SDavid van Moolenbroek 					size--;
408*00b67f09SDavid van Moolenbroek 				}
409*00b67f09SDavid van Moolenbroek 				while (pad > 0 && size > 1) {
410*00b67f09SDavid van Moolenbroek 					*str++ = ' ';
411*00b67f09SDavid van Moolenbroek 					size--;
412*00b67f09SDavid van Moolenbroek 					pad--;
413*00b67f09SDavid van Moolenbroek 				}
414*00b67f09SDavid van Moolenbroek 				break;
415*00b67f09SDavid van Moolenbroek 			default:
416*00b67f09SDavid van Moolenbroek 				break;
417*00b67f09SDavid van Moolenbroek 			}
418*00b67f09SDavid van Moolenbroek 			break;
419*00b67f09SDavid van Moolenbroek 		case 's':
420*00b67f09SDavid van Moolenbroek 			cp = va_arg(ap, char *);
421*00b67f09SDavid van Moolenbroek 			REQUIRE(cp != NULL);
422*00b67f09SDavid van Moolenbroek 
423*00b67f09SDavid van Moolenbroek 			if (precision != 0) {
424*00b67f09SDavid van Moolenbroek 				/*
425*00b67f09SDavid van Moolenbroek 				 * cp need not be NULL terminated.
426*00b67f09SDavid van Moolenbroek 				 */
427*00b67f09SDavid van Moolenbroek 				const char *tp;
428*00b67f09SDavid van Moolenbroek 				unsigned long n;
429*00b67f09SDavid van Moolenbroek 
430*00b67f09SDavid van Moolenbroek 				n = precision;
431*00b67f09SDavid van Moolenbroek 				tp = cp;
432*00b67f09SDavid van Moolenbroek 				while (n != 0 && *tp != '\0')
433*00b67f09SDavid van Moolenbroek 					n--, tp++;
434*00b67f09SDavid van Moolenbroek 				length = precision - n;
435*00b67f09SDavid van Moolenbroek 			} else {
436*00b67f09SDavid van Moolenbroek 				length = strlen(cp);
437*00b67f09SDavid van Moolenbroek 			}
438*00b67f09SDavid van Moolenbroek 			if (width != 0) {
439*00b67f09SDavid van Moolenbroek 				pad = width - length;
440*00b67f09SDavid van Moolenbroek 				if (pad < 0)
441*00b67f09SDavid van Moolenbroek 					pad = 0;
442*00b67f09SDavid van Moolenbroek 			}
443*00b67f09SDavid van Moolenbroek 			count += pad + length;
444*00b67f09SDavid van Moolenbroek 			if (!left)
445*00b67f09SDavid van Moolenbroek 				while (pad > 0 && size > 1) {
446*00b67f09SDavid van Moolenbroek 					*str++ = ' ';
447*00b67f09SDavid van Moolenbroek 					size--;
448*00b67f09SDavid van Moolenbroek 					pad--;
449*00b67f09SDavid van Moolenbroek 				}
450*00b67f09SDavid van Moolenbroek 			if (precision != 0)
451*00b67f09SDavid van Moolenbroek 				while (precision > 0 && *cp != '\0' &&
452*00b67f09SDavid van Moolenbroek 				       size > 1) {
453*00b67f09SDavid van Moolenbroek 					*str++ = *cp++;
454*00b67f09SDavid van Moolenbroek 					size--;
455*00b67f09SDavid van Moolenbroek 					precision--;
456*00b67f09SDavid van Moolenbroek 				}
457*00b67f09SDavid van Moolenbroek 			else
458*00b67f09SDavid van Moolenbroek 				while (*cp != '\0' && size > 1) {
459*00b67f09SDavid van Moolenbroek 					*str++ = *cp++;
460*00b67f09SDavid van Moolenbroek 					size--;
461*00b67f09SDavid van Moolenbroek 				}
462*00b67f09SDavid van Moolenbroek 			while (pad > 0 && size > 1) {
463*00b67f09SDavid van Moolenbroek 				*str++ = ' ';
464*00b67f09SDavid van Moolenbroek 				size--;
465*00b67f09SDavid van Moolenbroek 				pad--;
466*00b67f09SDavid van Moolenbroek 			}
467*00b67f09SDavid van Moolenbroek 			break;
468*00b67f09SDavid van Moolenbroek 		case 'c':
469*00b67f09SDavid van Moolenbroek 			c = va_arg(ap, int);
470*00b67f09SDavid van Moolenbroek 			if (width > 0) {
471*00b67f09SDavid van Moolenbroek 				count += width;
472*00b67f09SDavid van Moolenbroek 				width--;
473*00b67f09SDavid van Moolenbroek 				if (left && size > 1) {
474*00b67f09SDavid van Moolenbroek 					*str++ = c;
475*00b67f09SDavid van Moolenbroek 					size--;
476*00b67f09SDavid van Moolenbroek 				}
477*00b67f09SDavid van Moolenbroek 				while (width-- > 0 && size > 1) {
478*00b67f09SDavid van Moolenbroek 					*str++ = ' ';
479*00b67f09SDavid van Moolenbroek 					size--;
480*00b67f09SDavid van Moolenbroek 				}
481*00b67f09SDavid van Moolenbroek 				if (!left && size > 1) {
482*00b67f09SDavid van Moolenbroek 					*str++ = c;
483*00b67f09SDavid van Moolenbroek 					size--;
484*00b67f09SDavid van Moolenbroek 				}
485*00b67f09SDavid van Moolenbroek 			} else {
486*00b67f09SDavid van Moolenbroek 				count++;
487*00b67f09SDavid van Moolenbroek 				if (size > 1) {
488*00b67f09SDavid van Moolenbroek 					*str++ = c;
489*00b67f09SDavid van Moolenbroek 					size--;
490*00b67f09SDavid van Moolenbroek 				}
491*00b67f09SDavid van Moolenbroek 			}
492*00b67f09SDavid van Moolenbroek 			break;
493*00b67f09SDavid van Moolenbroek 		case 'p':
494*00b67f09SDavid van Moolenbroek 			v = va_arg(ap, void *);
495*00b67f09SDavid van Moolenbroek 			sprintf(buf, "%p", v);
496*00b67f09SDavid van Moolenbroek 			length = strlen(buf);
497*00b67f09SDavid van Moolenbroek 			if (precision > length)
498*00b67f09SDavid van Moolenbroek 				zeropad = precision - length;
499*00b67f09SDavid van Moolenbroek 			if (width > 0) {
500*00b67f09SDavid van Moolenbroek 				pad = width - length - zeropad;
501*00b67f09SDavid van Moolenbroek 				if (pad < 0)
502*00b67f09SDavid van Moolenbroek 					pad = 0;
503*00b67f09SDavid van Moolenbroek 			}
504*00b67f09SDavid van Moolenbroek 			count += length + pad + zeropad;
505*00b67f09SDavid van Moolenbroek 			if (!left)
506*00b67f09SDavid van Moolenbroek 				while (pad > 0 && size > 1) {
507*00b67f09SDavid van Moolenbroek 					*str++ = ' ';
508*00b67f09SDavid van Moolenbroek 					size--;
509*00b67f09SDavid van Moolenbroek 					pad--;
510*00b67f09SDavid van Moolenbroek 				}
511*00b67f09SDavid van Moolenbroek 			cp = buf;
512*00b67f09SDavid van Moolenbroek 			if (zeropad > 0 && buf[0] == '0' &&
513*00b67f09SDavid van Moolenbroek 			    (buf[1] == 'x' || buf[1] == 'X')) {
514*00b67f09SDavid van Moolenbroek 				if (size > 1) {
515*00b67f09SDavid van Moolenbroek 					*str++ = *cp++;
516*00b67f09SDavid van Moolenbroek 					size--;
517*00b67f09SDavid van Moolenbroek 				}
518*00b67f09SDavid van Moolenbroek 				if (size > 1) {
519*00b67f09SDavid van Moolenbroek 					*str++ = *cp++;
520*00b67f09SDavid van Moolenbroek 					size--;
521*00b67f09SDavid van Moolenbroek 				}
522*00b67f09SDavid van Moolenbroek 				while (zeropad > 0 && size > 1) {
523*00b67f09SDavid van Moolenbroek 					*str++ = '0';
524*00b67f09SDavid van Moolenbroek 					size--;
525*00b67f09SDavid van Moolenbroek 					zeropad--;
526*00b67f09SDavid van Moolenbroek 				}
527*00b67f09SDavid van Moolenbroek 			}
528*00b67f09SDavid van Moolenbroek 			while (*cp != '\0' && size > 1) {
529*00b67f09SDavid van Moolenbroek 				*str++ = *cp++;
530*00b67f09SDavid van Moolenbroek 				size--;
531*00b67f09SDavid van Moolenbroek 			}
532*00b67f09SDavid van Moolenbroek 			while (pad > 0 && size > 1) {
533*00b67f09SDavid van Moolenbroek 				*str++ = ' ';
534*00b67f09SDavid van Moolenbroek 				size--;
535*00b67f09SDavid van Moolenbroek 				pad--;
536*00b67f09SDavid van Moolenbroek 			}
537*00b67f09SDavid van Moolenbroek 			break;
538*00b67f09SDavid van Moolenbroek 		case 'D':	/*deprecated*/
539*00b67f09SDavid van Moolenbroek 			INSIST("use %ld instead of %D" == NULL);
540*00b67f09SDavid van Moolenbroek 		case 'O':	/*deprecated*/
541*00b67f09SDavid van Moolenbroek 			INSIST("use %lo instead of %O" == NULL);
542*00b67f09SDavid van Moolenbroek 		case 'U':	/*deprecated*/
543*00b67f09SDavid van Moolenbroek 			INSIST("use %lu instead of %U" == NULL);
544*00b67f09SDavid van Moolenbroek 
545*00b67f09SDavid van Moolenbroek 		case 'L':
546*00b67f09SDavid van Moolenbroek #ifdef HAVE_LONG_DOUBLE
547*00b67f09SDavid van Moolenbroek 			l = 1;
548*00b67f09SDavid van Moolenbroek #else
549*00b67f09SDavid van Moolenbroek 			INSIST("long doubles are not supported" == NULL);
550*00b67f09SDavid van Moolenbroek #endif
551*00b67f09SDavid van Moolenbroek 			/*FALLTHROUGH*/
552*00b67f09SDavid van Moolenbroek 		case 'e':
553*00b67f09SDavid van Moolenbroek 		case 'E':
554*00b67f09SDavid van Moolenbroek 		case 'f':
555*00b67f09SDavid van Moolenbroek 		case 'g':
556*00b67f09SDavid van Moolenbroek 		case 'G':
557*00b67f09SDavid van Moolenbroek 			if (!dot)
558*00b67f09SDavid van Moolenbroek 				precision = 6;
559*00b67f09SDavid van Moolenbroek 			/*
560*00b67f09SDavid van Moolenbroek 			 * IEEE floating point.
561*00b67f09SDavid van Moolenbroek 			 * MIN 2.2250738585072014E-308
562*00b67f09SDavid van Moolenbroek 			 * MAX 1.7976931348623157E+308
563*00b67f09SDavid van Moolenbroek 			 * VAX floating point has a smaller range than IEEE.
564*00b67f09SDavid van Moolenbroek 			 *
565*00b67f09SDavid van Moolenbroek 			 * precisions > 324 don't make much sense.
566*00b67f09SDavid van Moolenbroek 			 * if we cap the precision at 512 we will not
567*00b67f09SDavid van Moolenbroek 			 * overflow buf.
568*00b67f09SDavid van Moolenbroek 			 */
569*00b67f09SDavid van Moolenbroek 			if (precision > 512)
570*00b67f09SDavid van Moolenbroek 				precision = 512;
571*00b67f09SDavid van Moolenbroek 			sprintf(fmt, "%%%s%s.%lu%s%c", alt ? "#" : "",
572*00b67f09SDavid van Moolenbroek 				plus ? "+" : space ? " " : "",
573*00b67f09SDavid van Moolenbroek 				precision, l ? "L" : "", *format);
574*00b67f09SDavid van Moolenbroek 			switch (*format) {
575*00b67f09SDavid van Moolenbroek 			case 'e':
576*00b67f09SDavid van Moolenbroek 			case 'E':
577*00b67f09SDavid van Moolenbroek 			case 'f':
578*00b67f09SDavid van Moolenbroek 			case 'g':
579*00b67f09SDavid van Moolenbroek 			case 'G':
580*00b67f09SDavid van Moolenbroek #ifdef HAVE_LONG_DOUBLE
581*00b67f09SDavid van Moolenbroek 				if (l) {
582*00b67f09SDavid van Moolenbroek 					ldbl = va_arg(ap, long double);
583*00b67f09SDavid van Moolenbroek 					sprintf(buf, fmt, ldbl);
584*00b67f09SDavid van Moolenbroek 				} else
585*00b67f09SDavid van Moolenbroek #endif
586*00b67f09SDavid van Moolenbroek 				{
587*00b67f09SDavid van Moolenbroek 					dbl = va_arg(ap, double);
588*00b67f09SDavid van Moolenbroek 					sprintf(buf, fmt, dbl);
589*00b67f09SDavid van Moolenbroek 				}
590*00b67f09SDavid van Moolenbroek 				length = strlen(buf);
591*00b67f09SDavid van Moolenbroek 				if (width > 0) {
592*00b67f09SDavid van Moolenbroek 					pad = width - length;
593*00b67f09SDavid van Moolenbroek 					if (pad < 0)
594*00b67f09SDavid van Moolenbroek 						pad = 0;
595*00b67f09SDavid van Moolenbroek 				}
596*00b67f09SDavid van Moolenbroek 				count += length + pad;
597*00b67f09SDavid van Moolenbroek 				if (!left)
598*00b67f09SDavid van Moolenbroek 					while (pad > 0 && size > 1) {
599*00b67f09SDavid van Moolenbroek 						*str++ = ' ';
600*00b67f09SDavid van Moolenbroek 						size--;
601*00b67f09SDavid van Moolenbroek 						pad--;
602*00b67f09SDavid van Moolenbroek 					}
603*00b67f09SDavid van Moolenbroek 				cp = buf;
604*00b67f09SDavid van Moolenbroek 				while (*cp != ' ' && size > 1) {
605*00b67f09SDavid van Moolenbroek 					*str++ = *cp++;
606*00b67f09SDavid van Moolenbroek 					size--;
607*00b67f09SDavid van Moolenbroek 				}
608*00b67f09SDavid van Moolenbroek 				while (pad > 0 && size > 1) {
609*00b67f09SDavid van Moolenbroek 					*str++ = ' ';
610*00b67f09SDavid van Moolenbroek 					size--;
611*00b67f09SDavid van Moolenbroek 					pad--;
612*00b67f09SDavid van Moolenbroek 				}
613*00b67f09SDavid van Moolenbroek 				break;
614*00b67f09SDavid van Moolenbroek 			default:
615*00b67f09SDavid van Moolenbroek 				continue;
616*00b67f09SDavid van Moolenbroek 			}
617*00b67f09SDavid van Moolenbroek 			break;
618*00b67f09SDavid van Moolenbroek 		default:
619*00b67f09SDavid van Moolenbroek 			continue;
620*00b67f09SDavid van Moolenbroek 		}
621*00b67f09SDavid van Moolenbroek 		format++;
622*00b67f09SDavid van Moolenbroek 	}
623*00b67f09SDavid van Moolenbroek 	if (size > 0)
624*00b67f09SDavid van Moolenbroek 		*str = '\0';
625*00b67f09SDavid van Moolenbroek 	return (count);
626*00b67f09SDavid van Moolenbroek }
627