2 * Copyright (C) 2001 MontaVista Software Inc.
3 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
14 extern void board_putc(int ch
);
16 /* this is the maximum width for a variable */
17 #define LP_MAX_BUF 256
20 #define IsDigit(x) ( ((x) >= '0') && ((x) <= '9') )
21 #define Ctod(x) ( (x) - '0')
23 /* forward declaration */
24 static int PrintChar(char *, char, int, int);
25 static int PrintString(char *, char *, int, int);
26 static int PrintNum(char *, unsigned long, int, int, int, int, char, int);
28 /* private variable */
29 static const char theFatalMsg
[] = "fatal error in lp_Print!";
32 * A low level printf() function.
35 lp_Print(void (*output
)(void *, char *, int),
41 #define OUTPUT(arg, s, l) \
42 { if (((l) < 0) || ((l) > LP_MAX_BUF)) { \
43 (*output)(arg, (char*)theFatalMsg, sizeof(theFatalMsg)-1); for(;;); \
45 (*output)(arg, s, l); \
66 /* scan for the next '%' */
68 while ( (*fmt
!= '\0') && (*fmt
!= '%')) {
72 /* flush the string found so far */
73 OUTPUT(arg
, fmtStart
, fmt
-fmtStart
);
75 /* are we hitting the end? */
76 if (*fmt
== '\0') break;
90 /* check for other prefixes */
107 while (IsDigit(*fmt
)) {
108 width
= 10 * width
+ Ctod(*fmt
++);
116 while (IsDigit(*fmt
)) {
117 prec
= prec
*10 + Ctod(*fmt
++);
123 /* check format flag */
128 num
= va_arg(ap
, long int);
130 num
= va_arg(ap
, int);
132 length
= PrintNum(buf
, num
, 2, 0, width
, ladjust
, padc
, 0);
133 OUTPUT(arg
, buf
, length
);
139 num
= va_arg(ap
, long int);
141 num
= va_arg(ap
, int);
147 length
= PrintNum(buf
, num
, 10, negFlag
, width
, ladjust
, padc
, 0);
148 OUTPUT(arg
, buf
, length
);
154 num
= va_arg(ap
, long int);
156 num
= va_arg(ap
, int);
158 length
= PrintNum(buf
, num
, 8, 0, width
, ladjust
, padc
, 0);
159 OUTPUT(arg
, buf
, length
);
165 num
= va_arg(ap
, long int);
167 num
= va_arg(ap
, int);
169 length
= PrintNum(buf
, num
, 10, 0, width
, ladjust
, padc
, 0);
170 OUTPUT(arg
, buf
, length
);
175 num
= va_arg(ap
, long int);
177 num
= va_arg(ap
, int);
179 length
= PrintNum(buf
, num
, 16, 0, width
, ladjust
, padc
, 0);
180 OUTPUT(arg
, buf
, length
);
185 num
= va_arg(ap
, long int);
187 num
= va_arg(ap
, int);
189 length
= PrintNum(buf
, num
, 16, 0, width
, ladjust
, padc
, 1);
190 OUTPUT(arg
, buf
, length
);
194 c
= (char)va_arg(ap
, int);
195 length
= PrintChar(buf
, c
, width
, ladjust
);
196 OUTPUT(arg
, buf
, length
);
200 s
= (char*)va_arg(ap
, char *);
201 length
= PrintString(buf
, s
, width
, ladjust
);
202 OUTPUT(arg
, buf
, length
);
210 /* output this char as it is */
212 } /* switch (*fmt) */
217 /* special termination call */
218 OUTPUT(arg
, "\0", 1);
222 /* --------------- local help functions --------------------- */
224 PrintChar(char * buf
, char c
, int length
, int ladjust
)
228 if (length
< 1) length
= 1;
231 for (i
=1; i
< length
; i
++) buf
[i
] = ' ';
233 for (i
=0; i
< length
-1; i
++) buf
[i
] = ' ';
240 PrintString(char * buf
, char* s
, int length
, int ladjust
)
246 if (length
< len
) length
= len
;
249 for (i
=0; i
< len
; i
++) buf
[i
] = s
[i
];
250 for (i
=len
; i
< length
; i
++) buf
[i
] = ' ';
252 for (i
=0; i
< length
-len
; i
++) buf
[i
] = ' ';
253 for (i
=length
-len
; i
< length
; i
++) buf
[i
] = s
[i
-length
+len
];
259 PrintNum(char * buf
, unsigned long u
, int base
, int negFlag
,
260 int length
, int ladjust
, char padc
, int upcase
)
263 * 1. prints the number from left to right in reverse form.
264 * 2. fill the remaining spaces with padc if length is longer than
266 * TRICKY : if left adjusted, no "0" padding.
267 * if negtive, insert "0" padding between "0" and number.
268 * 3. if (!ladjust) we reverse the whole string including paddings
269 * 4. otherwise we only reverse the actual string representing the num.
281 *p
++ = 'A' + tmp
- 10;
283 *p
++ = 'a' + tmp
- 10;
292 /* figure out actual length and adjust the maximum length */
293 actualLength
= p
- buf
;
294 if (length
< actualLength
) length
= actualLength
;
300 if (negFlag
&& !ladjust
&& (padc
== '0')) {
301 for (i
= actualLength
-1; i
< length
-1; i
++) buf
[i
] = padc
;
302 buf
[length
-1] = '-';
304 for (i
= actualLength
; i
< length
; i
++) buf
[i
] = padc
;
308 /* prepare to reverse the string */
313 end
= actualLength
- 1;
318 while (end
> begin
) {
319 char tmp
= buf
[begin
];
320 buf
[begin
] = buf
[end
];
327 /* adjust the string pointer */
331 static void printf_output(void *arg
, char *s
, int l
)
335 // special termination call
336 if ((l
==1) && (s
[0] == '\0')) return;
338 for (i
=0; i
< l
; i
++) {
340 if (s
[i
] == '\n') board_putc('\r');
344 void printf(char *fmt
, ...)
348 lp_Print(printf_output
, 0, fmt
, ap
);
This page took 0.071249 seconds and 5 git commands to generate.