2 * Oh, it's a waste of space, but oh-so-yummy for debugging. It's just
3 * initialization code anyway, so it doesn't take up space when we're
4 * actually running. This version of printf() does not include 64-bit
5 * support. "Live with it."
7 * Most of this code was shamelessly snarfed from the Linux kernel, then
8 * modified. It's therefore GPL.
10 * printf() isn't actually needed to build syslinux.com, but during
11 * debugging it's handy.
18 static int strnlen(const char *s
, int maxlen
)
21 while ( *es
&& maxlen
) {
28 #define ZEROPAD 1 /* pad with zero */
29 #define SIGN 2 /* unsigned/signed long */
30 #define PLUS 4 /* show plus */
31 #define SPACE 8 /* space if plus */
32 #define LEFT 16 /* left justified */
33 #define SPECIAL 32 /* 0x */
34 #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
36 #define do_div(n,base) ({ \
38 __res = ((unsigned long) n) % (unsigned) base; \
39 n = ((unsigned long) n) / (unsigned) base; \
42 static char * number(char * str
, long num
, int base
, int size
, int precision
46 const char *digits
="0123456789abcdefghijklmnopqrstuvwxyz";
50 digits
= "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
53 if (base
< 2 || base
> 36)
55 c
= (type
& ZEROPAD
) ? '0' : ' ';
62 } else if (type
& PLUS
) {
65 } else if (type
& SPACE
) {
80 tmp
[i
++] = digits
[do_div(num
,base
)];
84 if (!(type
&(ZEROPAD
+LEFT
)))
100 while (i
< precision
--)
109 /* Forward decl. needed for IP address printing stuff... */
110 int sprintf(char * buf
, const char *fmt
, ...);
112 int vsprintf(char *buf
, const char *fmt
, va_list args
)
120 int flags
; /* flags to number() */
122 int field_width
; /* width of output field */
123 int precision
; /* min. # of digits for integers; max
124 number of chars for from string */
125 int qualifier
; /* 'h', 'l', or 'L' for integer fields */
127 for (str
=buf
; *fmt
; ++fmt
) {
136 ++fmt
; /* this also skips first '%' */
138 case '-': flags
|= LEFT
; goto repeat
;
139 case '+': flags
|= PLUS
; goto repeat
;
140 case ' ': flags
|= SPACE
; goto repeat
;
141 case '#': flags
|= SPECIAL
; goto repeat
;
142 case '0': flags
|= ZEROPAD
; goto repeat
;
145 /* get field width */
148 field_width
= skip_atou(&fmt
);
149 else if (*fmt
== '*') {
151 /* it's the next argument */
152 field_width
= va_arg(args
, int);
153 if (field_width
< 0) {
154 field_width
= -field_width
;
159 /* get the precision */
164 precision
= skip_atou(&fmt
);
165 else if (*fmt
== '*') {
167 /* it's the next argument */
168 precision
= va_arg(args
, int);
174 /* get the conversion qualifier */
176 if (*fmt
== 'h' || *fmt
== 'l' || *fmt
== 'L') {
187 while (--field_width
> 0)
189 *str
++ = (unsigned char) va_arg(args
, int);
190 while (--field_width
> 0)
195 s
= va_arg(args
, char *);
196 len
= strnlen(s
, precision
);
199 while (len
< field_width
--)
201 for (i
= 0; i
< len
; ++i
)
203 while (len
< field_width
--)
208 if (field_width
== -1) {
209 field_width
= 2*sizeof(void *);
213 (unsigned long) va_arg(args
, void *), 16,
214 field_width
, precision
, flags
);
219 if (qualifier
== 'l') {
220 long * ip
= va_arg(args
, long *);
223 int * ip
= va_arg(args
, int *);
232 /* integer number formats - set up the flags and "break" */
257 if (qualifier
== 'l')
258 num
= va_arg(args
, unsigned long);
259 else if (qualifier
== 'h') {
260 num
= (unsigned short) va_arg(args
, int);
263 } else if (flags
& SIGN
)
264 num
= va_arg(args
, int);
266 num
= va_arg(args
, unsigned int);
267 str
= number(str
, num
, base
, field_width
, precision
, flags
);
273 int sprintf(char * buf
, const char *fmt
, ...)
279 i
=vsprintf(buf
,fmt
,args
);
284 int printf(const char *fmt
, ...)
286 char printf_buf
[1024];
291 printed
= vsprintf(printf_buf
, fmt
, args
);