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