xref: /dflybsd-src/stand/lib/printf.c (revision 479ab7f0492f2a51b48e8537e4f1dc686fc6014b)
1*479ab7f0SSascha Wildner /*-
2*479ab7f0SSascha Wildner  * Copyright (c) 1986, 1988, 1991, 1993
3*479ab7f0SSascha Wildner  *	The Regents of the University of California.  All rights reserved.
4*479ab7f0SSascha Wildner  * (c) UNIX System Laboratories, Inc.
5*479ab7f0SSascha Wildner  * All or some portions of this file are derived from material licensed
6*479ab7f0SSascha Wildner  * to the University of California by American Telephone and Telegraph
7*479ab7f0SSascha Wildner  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8*479ab7f0SSascha Wildner  * the permission of UNIX System Laboratories, Inc.
9*479ab7f0SSascha Wildner  *
10*479ab7f0SSascha Wildner  * Redistribution and use in source and binary forms, with or without
11*479ab7f0SSascha Wildner  * modification, are permitted provided that the following conditions
12*479ab7f0SSascha Wildner  * are met:
13*479ab7f0SSascha Wildner  * 1. Redistributions of source code must retain the above copyright
14*479ab7f0SSascha Wildner  *    notice, this list of conditions and the following disclaimer.
15*479ab7f0SSascha Wildner  * 2. Redistributions in binary form must reproduce the above copyright
16*479ab7f0SSascha Wildner  *    notice, this list of conditions and the following disclaimer in the
17*479ab7f0SSascha Wildner  *    documentation and/or other materials provided with the distribution.
18*479ab7f0SSascha Wildner  * 3. Neither the name of the University nor the names of its contributors
19*479ab7f0SSascha Wildner  *    may be used to endorse or promote products derived from this software
20*479ab7f0SSascha Wildner  *    without specific prior written permission.
21*479ab7f0SSascha Wildner  *
22*479ab7f0SSascha Wildner  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23*479ab7f0SSascha Wildner  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24*479ab7f0SSascha Wildner  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25*479ab7f0SSascha Wildner  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26*479ab7f0SSascha Wildner  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27*479ab7f0SSascha Wildner  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28*479ab7f0SSascha Wildner  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29*479ab7f0SSascha Wildner  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30*479ab7f0SSascha Wildner  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31*479ab7f0SSascha Wildner  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32*479ab7f0SSascha Wildner  * SUCH DAMAGE.
33*479ab7f0SSascha Wildner  *
34*479ab7f0SSascha Wildner  *	@(#)subr_prf.c	8.3 (Berkeley) 1/21/94
35*479ab7f0SSascha Wildner  * $FreeBSD: src/lib/libstand/printf.c,v 1.14 2010/07/12 15:32:45 jkim Exp $
36*479ab7f0SSascha Wildner  */
37*479ab7f0SSascha Wildner 
38*479ab7f0SSascha Wildner /*
39*479ab7f0SSascha Wildner  * Standaloneified version of the FreeBSD kernel printf family.
40*479ab7f0SSascha Wildner  */
41*479ab7f0SSascha Wildner 
42*479ab7f0SSascha Wildner #include <sys/types.h>
43*479ab7f0SSascha Wildner #include <sys/stdint.h>
44*479ab7f0SSascha Wildner #include <limits.h>
45*479ab7f0SSascha Wildner #include <stddef.h>
46*479ab7f0SSascha Wildner #include <string.h>
47*479ab7f0SSascha Wildner #include "stand.h"
48*479ab7f0SSascha Wildner 
49*479ab7f0SSascha Wildner /*
50*479ab7f0SSascha Wildner  * Note that stdarg.h and the ANSI style va_start macro is used for both
51*479ab7f0SSascha Wildner  * ANSI and traditional C compilers.
52*479ab7f0SSascha Wildner  */
53*479ab7f0SSascha Wildner #include <stdarg.h>
54*479ab7f0SSascha Wildner 
55*479ab7f0SSascha Wildner struct snprintf_arg {
56*479ab7f0SSascha Wildner 	char	*buf;
57*479ab7f0SSascha Wildner 	size_t	remain;
58*479ab7f0SSascha Wildner };
59*479ab7f0SSascha Wildner 
60*479ab7f0SSascha Wildner #define MAXNBUF (sizeof(intmax_t) * CHAR_BIT + 1)
61*479ab7f0SSascha Wildner 
62*479ab7f0SSascha Wildner static char	*ksprintn (char *buf, uintmax_t num, int base, int *len, int upper);
63*479ab7f0SSascha Wildner static int	kvprintf(const char *, void (*)(int, void *), void *, va_list);
64*479ab7f0SSascha Wildner static void	putchar_wrapper(int, void *);
65*479ab7f0SSascha Wildner static void	snprintf_func(int, void *);
66*479ab7f0SSascha Wildner 
67*479ab7f0SSascha Wildner static void
putchar_wrapper(int ch,void * arg __unused)68*479ab7f0SSascha Wildner putchar_wrapper(int ch, void *arg __unused)
69*479ab7f0SSascha Wildner {
70*479ab7f0SSascha Wildner 	putchar(ch);
71*479ab7f0SSascha Wildner }
72*479ab7f0SSascha Wildner 
73*479ab7f0SSascha Wildner int
printf(const char * fmt,...)74*479ab7f0SSascha Wildner printf(const char *fmt, ...)
75*479ab7f0SSascha Wildner {
76*479ab7f0SSascha Wildner 	va_list ap;
77*479ab7f0SSascha Wildner 	int retval;
78*479ab7f0SSascha Wildner 
79*479ab7f0SSascha Wildner 	va_start(ap, fmt);
80*479ab7f0SSascha Wildner 	retval = kvprintf(fmt, putchar_wrapper, NULL, ap);
81*479ab7f0SSascha Wildner 	va_end(ap);
82*479ab7f0SSascha Wildner 	return retval;
83*479ab7f0SSascha Wildner }
84*479ab7f0SSascha Wildner 
85*479ab7f0SSascha Wildner void
vprintf(const char * fmt,va_list ap)86*479ab7f0SSascha Wildner vprintf(const char *fmt, va_list ap)
87*479ab7f0SSascha Wildner {
88*479ab7f0SSascha Wildner 
89*479ab7f0SSascha Wildner 	kvprintf(fmt, putchar_wrapper, NULL, ap);
90*479ab7f0SSascha Wildner }
91*479ab7f0SSascha Wildner 
92*479ab7f0SSascha Wildner int
sprintf(char * buf,const char * cfmt,...)93*479ab7f0SSascha Wildner sprintf(char *buf, const char *cfmt, ...)
94*479ab7f0SSascha Wildner {
95*479ab7f0SSascha Wildner 	int retval;
96*479ab7f0SSascha Wildner 	va_list ap;
97*479ab7f0SSascha Wildner 
98*479ab7f0SSascha Wildner 	va_start(ap, cfmt);
99*479ab7f0SSascha Wildner 	retval = kvprintf(cfmt, NULL, buf, ap);
100*479ab7f0SSascha Wildner 	buf[retval] = '\0';
101*479ab7f0SSascha Wildner 	va_end(ap);
102*479ab7f0SSascha Wildner 	return retval;
103*479ab7f0SSascha Wildner }
104*479ab7f0SSascha Wildner 
105*479ab7f0SSascha Wildner void
vsprintf(char * buf,const char * cfmt,va_list ap)106*479ab7f0SSascha Wildner vsprintf(char *buf, const char *cfmt, va_list ap)
107*479ab7f0SSascha Wildner {
108*479ab7f0SSascha Wildner 	int	retval;
109*479ab7f0SSascha Wildner 
110*479ab7f0SSascha Wildner 	retval = kvprintf(cfmt, NULL, buf, ap);
111*479ab7f0SSascha Wildner 	buf[retval] = '\0';
112*479ab7f0SSascha Wildner }
113*479ab7f0SSascha Wildner 
114*479ab7f0SSascha Wildner int
snprintf(char * buf,size_t size,const char * cfmt,...)115*479ab7f0SSascha Wildner snprintf(char *buf, size_t size, const char *cfmt, ...)
116*479ab7f0SSascha Wildner {
117*479ab7f0SSascha Wildner 	int retval;
118*479ab7f0SSascha Wildner 	va_list ap;
119*479ab7f0SSascha Wildner 
120*479ab7f0SSascha Wildner 	va_start(ap, cfmt);
121*479ab7f0SSascha Wildner 	retval = vsnprintf(buf, size, cfmt, ap);
122*479ab7f0SSascha Wildner 	__va_end(ap);
123*479ab7f0SSascha Wildner 	return(retval);
124*479ab7f0SSascha Wildner }
125*479ab7f0SSascha Wildner 
126*479ab7f0SSascha Wildner int
vsnprintf(char * buf,size_t size,const char * cfmt,va_list ap)127*479ab7f0SSascha Wildner vsnprintf(char *buf, size_t size, const char *cfmt, va_list ap)
128*479ab7f0SSascha Wildner {
129*479ab7f0SSascha Wildner 	struct snprintf_arg info;
130*479ab7f0SSascha Wildner 	int retval;
131*479ab7f0SSascha Wildner 
132*479ab7f0SSascha Wildner 	info.buf = buf;
133*479ab7f0SSascha Wildner 	info.remain = size;
134*479ab7f0SSascha Wildner 	retval = kvprintf(cfmt, snprintf_func, &info, ap);
135*479ab7f0SSascha Wildner 	if (info.remain >= 1)
136*479ab7f0SSascha Wildner 		*info.buf++ = '\0';
137*479ab7f0SSascha Wildner 	return(retval);
138*479ab7f0SSascha Wildner }
139*479ab7f0SSascha Wildner 
140*479ab7f0SSascha Wildner static void
snprintf_func(int ch,void * arg)141*479ab7f0SSascha Wildner snprintf_func(int ch, void *arg)
142*479ab7f0SSascha Wildner {
143*479ab7f0SSascha Wildner 	struct snprintf_arg * const info = arg;
144*479ab7f0SSascha Wildner 
145*479ab7f0SSascha Wildner 	if (info->remain >= 2) {
146*479ab7f0SSascha Wildner 		*info->buf++ = ch;
147*479ab7f0SSascha Wildner 		info->remain--;
148*479ab7f0SSascha Wildner 	}
149*479ab7f0SSascha Wildner }
150*479ab7f0SSascha Wildner 
151*479ab7f0SSascha Wildner /*
152*479ab7f0SSascha Wildner  * Put a NUL-terminated ASCII number (base <= 36) in a buffer in reverse
153*479ab7f0SSascha Wildner  * order; return an optional length and a pointer to the last character
154*479ab7f0SSascha Wildner  * written in the buffer (i.e., the first character of the string).
155*479ab7f0SSascha Wildner  * The buffer pointed to by `nbuf' must have length >= MAXNBUF.
156*479ab7f0SSascha Wildner  */
157*479ab7f0SSascha Wildner static char *
ksprintn(char * nbuf,uintmax_t num,int base,int * lenp,int upper)158*479ab7f0SSascha Wildner ksprintn(char *nbuf, uintmax_t num, int base, int *lenp, int upper)
159*479ab7f0SSascha Wildner {
160*479ab7f0SSascha Wildner 	char *p, c;
161*479ab7f0SSascha Wildner 
162*479ab7f0SSascha Wildner 	p = nbuf;
163*479ab7f0SSascha Wildner 	*p = '\0';
164*479ab7f0SSascha Wildner 	do {
165*479ab7f0SSascha Wildner 		c = hex2ascii(num % base);
166*479ab7f0SSascha Wildner 		*++p = upper ? toupper(c) : c;
167*479ab7f0SSascha Wildner 	} while (num /= base);
168*479ab7f0SSascha Wildner 	if (lenp)
169*479ab7f0SSascha Wildner 		*lenp = p - nbuf;
170*479ab7f0SSascha Wildner 	return (p);
171*479ab7f0SSascha Wildner }
172*479ab7f0SSascha Wildner 
173*479ab7f0SSascha Wildner /*
174*479ab7f0SSascha Wildner  * Scaled down version of printf(3).
175*479ab7f0SSascha Wildner  */
176*479ab7f0SSascha Wildner static int
kvprintf(char const * fmt,void (* func)(int,void *),void * arg,va_list ap)177*479ab7f0SSascha Wildner kvprintf(char const *fmt, void (*func)(int, void *), void *arg, va_list ap)
178*479ab7f0SSascha Wildner {
179*479ab7f0SSascha Wildner #define PCHAR(c) {int cc=(c); if (func) (*func)(cc, arg); else *d++ = cc; retval++; }
180*479ab7f0SSascha Wildner 	char nbuf[MAXNBUF];
181*479ab7f0SSascha Wildner 	char *d;
182*479ab7f0SSascha Wildner 	const char *p, *percent;
183*479ab7f0SSascha Wildner 	int ch, n;
184*479ab7f0SSascha Wildner 	uintmax_t num;
185*479ab7f0SSascha Wildner 	int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot;
186*479ab7f0SSascha Wildner 	int cflag, hflag, jflag, tflag, zflag;
187*479ab7f0SSascha Wildner 	int dwidth, upper;
188*479ab7f0SSascha Wildner 	char padc;
189*479ab7f0SSascha Wildner 	int stop = 0, retval = 0;
190*479ab7f0SSascha Wildner 
191*479ab7f0SSascha Wildner 	num = 0;
192*479ab7f0SSascha Wildner 	if (!func)
193*479ab7f0SSascha Wildner 		d = (char *) arg;
194*479ab7f0SSascha Wildner 	else
195*479ab7f0SSascha Wildner 		d = NULL;
196*479ab7f0SSascha Wildner 
197*479ab7f0SSascha Wildner 	if (fmt == NULL)
198*479ab7f0SSascha Wildner 		fmt = "(fmt null)\n";
199*479ab7f0SSascha Wildner 
200*479ab7f0SSascha Wildner 	for (;;) {
201*479ab7f0SSascha Wildner 		padc = ' ';
202*479ab7f0SSascha Wildner 		width = 0;
203*479ab7f0SSascha Wildner 		while ((ch = (u_char)*fmt++) != '%' || stop) {
204*479ab7f0SSascha Wildner 			if (ch == '\0')
205*479ab7f0SSascha Wildner 				return (retval);
206*479ab7f0SSascha Wildner 			PCHAR(ch);
207*479ab7f0SSascha Wildner 		}
208*479ab7f0SSascha Wildner 		percent = fmt - 1;
209*479ab7f0SSascha Wildner 		qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0;
210*479ab7f0SSascha Wildner 		sign = 0; dot = 0; dwidth = 0; upper = 0;
211*479ab7f0SSascha Wildner 		cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0;
212*479ab7f0SSascha Wildner 
213*479ab7f0SSascha Wildner reswitch:	switch (ch = (u_char)*fmt++) {
214*479ab7f0SSascha Wildner 		case '.':
215*479ab7f0SSascha Wildner 			dot = 1;
216*479ab7f0SSascha Wildner 			goto reswitch;
217*479ab7f0SSascha Wildner 		case '#':
218*479ab7f0SSascha Wildner 			sharpflag = 1;
219*479ab7f0SSascha Wildner 			goto reswitch;
220*479ab7f0SSascha Wildner 		case '+':
221*479ab7f0SSascha Wildner 			sign = 1;
222*479ab7f0SSascha Wildner 			goto reswitch;
223*479ab7f0SSascha Wildner 		case '-':
224*479ab7f0SSascha Wildner 			ladjust = 1;
225*479ab7f0SSascha Wildner 			goto reswitch;
226*479ab7f0SSascha Wildner 		case '%':
227*479ab7f0SSascha Wildner 			PCHAR(ch);
228*479ab7f0SSascha Wildner 			break;
229*479ab7f0SSascha Wildner 		case '*':
230*479ab7f0SSascha Wildner 			if (!dot) {
231*479ab7f0SSascha Wildner 				width = va_arg(ap, int);
232*479ab7f0SSascha Wildner 				if (width < 0) {
233*479ab7f0SSascha Wildner 					ladjust = !ladjust;
234*479ab7f0SSascha Wildner 					width = -width;
235*479ab7f0SSascha Wildner 				}
236*479ab7f0SSascha Wildner 			} else {
237*479ab7f0SSascha Wildner 				dwidth = va_arg(ap, int);
238*479ab7f0SSascha Wildner 			}
239*479ab7f0SSascha Wildner 			goto reswitch;
240*479ab7f0SSascha Wildner 		case '0':
241*479ab7f0SSascha Wildner 			if (!dot) {
242*479ab7f0SSascha Wildner 				padc = '0';
243*479ab7f0SSascha Wildner 				goto reswitch;
244*479ab7f0SSascha Wildner 			}
245*479ab7f0SSascha Wildner 		case '1': case '2': case '3': case '4':
246*479ab7f0SSascha Wildner 		case '5': case '6': case '7': case '8': case '9':
247*479ab7f0SSascha Wildner 				for (n = 0;; ++fmt) {
248*479ab7f0SSascha Wildner 					n = n * 10 + ch - '0';
249*479ab7f0SSascha Wildner 					ch = *fmt;
250*479ab7f0SSascha Wildner 					if (ch < '0' || ch > '9')
251*479ab7f0SSascha Wildner 						break;
252*479ab7f0SSascha Wildner 				}
253*479ab7f0SSascha Wildner 			if (dot)
254*479ab7f0SSascha Wildner 				dwidth = n;
255*479ab7f0SSascha Wildner 			else
256*479ab7f0SSascha Wildner 				width = n;
257*479ab7f0SSascha Wildner 			goto reswitch;
258*479ab7f0SSascha Wildner 		case 'c':
259*479ab7f0SSascha Wildner 			PCHAR(va_arg(ap, int));
260*479ab7f0SSascha Wildner 			break;
261*479ab7f0SSascha Wildner 		case 'd':
262*479ab7f0SSascha Wildner 		case 'i':
263*479ab7f0SSascha Wildner 			base = 10;
264*479ab7f0SSascha Wildner 			sign = 1;
265*479ab7f0SSascha Wildner 			goto handle_sign;
266*479ab7f0SSascha Wildner 		case 'h':
267*479ab7f0SSascha Wildner 			if (hflag) {
268*479ab7f0SSascha Wildner 				hflag = 0;
269*479ab7f0SSascha Wildner 				cflag = 1;
270*479ab7f0SSascha Wildner 			} else
271*479ab7f0SSascha Wildner 				hflag = 1;
272*479ab7f0SSascha Wildner 			goto reswitch;
273*479ab7f0SSascha Wildner 		case 'j':
274*479ab7f0SSascha Wildner 			jflag = 1;
275*479ab7f0SSascha Wildner 			goto reswitch;
276*479ab7f0SSascha Wildner 		case 'l':
277*479ab7f0SSascha Wildner 			if (lflag) {
278*479ab7f0SSascha Wildner 				lflag = 0;
279*479ab7f0SSascha Wildner 				qflag = 1;
280*479ab7f0SSascha Wildner 			} else
281*479ab7f0SSascha Wildner 				lflag = 1;
282*479ab7f0SSascha Wildner 			goto reswitch;
283*479ab7f0SSascha Wildner 		case 'n':
284*479ab7f0SSascha Wildner 			if (jflag)
285*479ab7f0SSascha Wildner 				*(va_arg(ap, intmax_t *)) = retval;
286*479ab7f0SSascha Wildner 			else if (qflag)
287*479ab7f0SSascha Wildner 				*(va_arg(ap, quad_t *)) = retval;
288*479ab7f0SSascha Wildner 			else if (lflag)
289*479ab7f0SSascha Wildner 				*(va_arg(ap, long *)) = retval;
290*479ab7f0SSascha Wildner 			else if (zflag)
291*479ab7f0SSascha Wildner 				*(va_arg(ap, size_t *)) = retval;
292*479ab7f0SSascha Wildner 			else if (hflag)
293*479ab7f0SSascha Wildner 				*(va_arg(ap, short *)) = retval;
294*479ab7f0SSascha Wildner 			else if (cflag)
295*479ab7f0SSascha Wildner 				*(va_arg(ap, char *)) = retval;
296*479ab7f0SSascha Wildner 			else
297*479ab7f0SSascha Wildner 				*(va_arg(ap, int *)) = retval;
298*479ab7f0SSascha Wildner 			break;
299*479ab7f0SSascha Wildner 		case 'o':
300*479ab7f0SSascha Wildner 			base = 8;
301*479ab7f0SSascha Wildner 			goto handle_nosign;
302*479ab7f0SSascha Wildner 		case 'p':
303*479ab7f0SSascha Wildner 			base = 16;
304*479ab7f0SSascha Wildner 			sharpflag = (width == 0);
305*479ab7f0SSascha Wildner 			sign = 0;
306*479ab7f0SSascha Wildner 			num = (uintptr_t)va_arg(ap, void *);
307*479ab7f0SSascha Wildner 			goto number;
308*479ab7f0SSascha Wildner 		case 'q':
309*479ab7f0SSascha Wildner 			qflag = 1;
310*479ab7f0SSascha Wildner 			goto reswitch;
311*479ab7f0SSascha Wildner 		case 's':
312*479ab7f0SSascha Wildner 			p = va_arg(ap, char *);
313*479ab7f0SSascha Wildner 			if (p == NULL)
314*479ab7f0SSascha Wildner 				p = "(null)";
315*479ab7f0SSascha Wildner 			if (!dot)
316*479ab7f0SSascha Wildner 				n = strlen (p);
317*479ab7f0SSascha Wildner 			else
318*479ab7f0SSascha Wildner 				for (n = 0; n < dwidth && p[n]; n++)
319*479ab7f0SSascha Wildner 					continue;
320*479ab7f0SSascha Wildner 
321*479ab7f0SSascha Wildner 			width -= n;
322*479ab7f0SSascha Wildner 
323*479ab7f0SSascha Wildner 			if (!ladjust && width > 0)
324*479ab7f0SSascha Wildner 				while (width--)
325*479ab7f0SSascha Wildner 					PCHAR(padc);
326*479ab7f0SSascha Wildner 			while (n--)
327*479ab7f0SSascha Wildner 				PCHAR(*p++);
328*479ab7f0SSascha Wildner 			if (ladjust && width > 0)
329*479ab7f0SSascha Wildner 				while (width--)
330*479ab7f0SSascha Wildner 					PCHAR(padc);
331*479ab7f0SSascha Wildner 			break;
332*479ab7f0SSascha Wildner 		case 't':
333*479ab7f0SSascha Wildner 			tflag = 1;
334*479ab7f0SSascha Wildner 			goto reswitch;
335*479ab7f0SSascha Wildner 		case 'u':
336*479ab7f0SSascha Wildner 			base = 10;
337*479ab7f0SSascha Wildner 			goto handle_nosign;
338*479ab7f0SSascha Wildner 		case 'X':
339*479ab7f0SSascha Wildner 			upper = 1;
340*479ab7f0SSascha Wildner 		case 'x':
341*479ab7f0SSascha Wildner 			base = 16;
342*479ab7f0SSascha Wildner 			goto handle_nosign;
343*479ab7f0SSascha Wildner 		case 'z':
344*479ab7f0SSascha Wildner 			zflag = 1;
345*479ab7f0SSascha Wildner 			goto reswitch;
346*479ab7f0SSascha Wildner handle_nosign:
347*479ab7f0SSascha Wildner 			sign = 0;
348*479ab7f0SSascha Wildner 			if (jflag)
349*479ab7f0SSascha Wildner 				num = va_arg(ap, uintmax_t);
350*479ab7f0SSascha Wildner 			else if (qflag)
351*479ab7f0SSascha Wildner 				num = va_arg(ap, u_quad_t);
352*479ab7f0SSascha Wildner 			else if (tflag)
353*479ab7f0SSascha Wildner 				num = va_arg(ap, ptrdiff_t);
354*479ab7f0SSascha Wildner 			else if (lflag)
355*479ab7f0SSascha Wildner 				num = va_arg(ap, u_long);
356*479ab7f0SSascha Wildner 			else if (zflag)
357*479ab7f0SSascha Wildner 				num = va_arg(ap, size_t);
358*479ab7f0SSascha Wildner 			else if (hflag)
359*479ab7f0SSascha Wildner 				num = (u_short)va_arg(ap, int);
360*479ab7f0SSascha Wildner 			else if (cflag)
361*479ab7f0SSascha Wildner 				num = (u_char)va_arg(ap, int);
362*479ab7f0SSascha Wildner 			else
363*479ab7f0SSascha Wildner 				num = va_arg(ap, u_int);
364*479ab7f0SSascha Wildner 			goto number;
365*479ab7f0SSascha Wildner handle_sign:
366*479ab7f0SSascha Wildner 			if (jflag)
367*479ab7f0SSascha Wildner 				num = va_arg(ap, intmax_t);
368*479ab7f0SSascha Wildner 			else if (qflag)
369*479ab7f0SSascha Wildner 				num = va_arg(ap, quad_t);
370*479ab7f0SSascha Wildner 			else if (tflag)
371*479ab7f0SSascha Wildner 				num = va_arg(ap, ptrdiff_t);
372*479ab7f0SSascha Wildner 			else if (lflag)
373*479ab7f0SSascha Wildner 				num = va_arg(ap, long);
374*479ab7f0SSascha Wildner 			else if (zflag)
375*479ab7f0SSascha Wildner 				num = va_arg(ap, ssize_t);
376*479ab7f0SSascha Wildner 			else if (hflag)
377*479ab7f0SSascha Wildner 				num = (short)va_arg(ap, int);
378*479ab7f0SSascha Wildner 			else if (cflag)
379*479ab7f0SSascha Wildner 				num = (char)va_arg(ap, int);
380*479ab7f0SSascha Wildner 			else
381*479ab7f0SSascha Wildner 				num = va_arg(ap, int);
382*479ab7f0SSascha Wildner number:
383*479ab7f0SSascha Wildner 			if (sign && (intmax_t)num < 0) {
384*479ab7f0SSascha Wildner 				neg = 1;
385*479ab7f0SSascha Wildner 				num = -(intmax_t)num;
386*479ab7f0SSascha Wildner 			}
387*479ab7f0SSascha Wildner 			p = ksprintn(nbuf, num, base, &n, upper);
388*479ab7f0SSascha Wildner 			tmp = 0;
389*479ab7f0SSascha Wildner 			if (sharpflag && num != 0) {
390*479ab7f0SSascha Wildner 				if (base == 8)
391*479ab7f0SSascha Wildner 					tmp++;
392*479ab7f0SSascha Wildner 				else if (base == 16)
393*479ab7f0SSascha Wildner 					tmp += 2;
394*479ab7f0SSascha Wildner 			}
395*479ab7f0SSascha Wildner 			if (neg)
396*479ab7f0SSascha Wildner 				tmp++;
397*479ab7f0SSascha Wildner 
398*479ab7f0SSascha Wildner 			if (!ladjust && padc == '0')
399*479ab7f0SSascha Wildner 				dwidth = width - tmp;
400*479ab7f0SSascha Wildner 			width -= tmp + imax(dwidth, n);
401*479ab7f0SSascha Wildner 			dwidth -= n;
402*479ab7f0SSascha Wildner 			if (!ladjust)
403*479ab7f0SSascha Wildner 				while (width-- > 0)
404*479ab7f0SSascha Wildner 					PCHAR(' ');
405*479ab7f0SSascha Wildner 			if (neg)
406*479ab7f0SSascha Wildner 				PCHAR('-');
407*479ab7f0SSascha Wildner 			if (sharpflag && num != 0) {
408*479ab7f0SSascha Wildner 				if (base == 8) {
409*479ab7f0SSascha Wildner 					PCHAR('0');
410*479ab7f0SSascha Wildner 				} else if (base == 16) {
411*479ab7f0SSascha Wildner 					PCHAR('0');
412*479ab7f0SSascha Wildner 					PCHAR('x');
413*479ab7f0SSascha Wildner 				}
414*479ab7f0SSascha Wildner 			}
415*479ab7f0SSascha Wildner 			while (dwidth-- > 0)
416*479ab7f0SSascha Wildner 				PCHAR('0');
417*479ab7f0SSascha Wildner 
418*479ab7f0SSascha Wildner 			while (*p)
419*479ab7f0SSascha Wildner 				PCHAR(*p--);
420*479ab7f0SSascha Wildner 
421*479ab7f0SSascha Wildner 			if (ladjust)
422*479ab7f0SSascha Wildner 				while (width-- > 0)
423*479ab7f0SSascha Wildner 					PCHAR(' ');
424*479ab7f0SSascha Wildner 
425*479ab7f0SSascha Wildner 			break;
426*479ab7f0SSascha Wildner 		default:
427*479ab7f0SSascha Wildner 			while (percent < fmt)
428*479ab7f0SSascha Wildner 				PCHAR(*percent++);
429*479ab7f0SSascha Wildner 			/*
430*479ab7f0SSascha Wildner 			 * Since we ignore an formatting argument it is no
431*479ab7f0SSascha Wildner 			 * longer safe to obey the remaining formatting
432*479ab7f0SSascha Wildner 			 * arguments as the arguments will no longer match
433*479ab7f0SSascha Wildner 			 * the format specs.
434*479ab7f0SSascha Wildner 			 */
435*479ab7f0SSascha Wildner 			stop = 1;
436*479ab7f0SSascha Wildner 			break;
437*479ab7f0SSascha Wildner 		}
438*479ab7f0SSascha Wildner 	}
439*479ab7f0SSascha Wildner #undef PCHAR
440*479ab7f0SSascha Wildner }
441