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.
15 #define IsDigit(x) ( ((x) >= '0') && ((x) <= '9') )
16 #define Ctod(x) ( (x) - '0')
18 /* forward declaration */
19 extern int PrintChar(char *, char, int, int);
20 extern int PrintString(char *, char *, int, int);
21 extern int PrintNum(char *, unsigned long, int, int, int, int, char, int);
23 /* private variable */
24 static const char theFatalMsg[] = "fatal error in lp_Print!";
27 * A low level printf() function.
30 lp_Print(void (*output)(void *, char *, int),
36 #define OUTPUT(arg, s, l) \
37 { if (((l) < 0) || ((l) > LP_MAX_BUF)) { \
38 (*output)(arg, (char*)theFatalMsg, sizeof(theFatalMsg)-1); for(;;); \
40 (*output)(arg, s, l); \
61 /* scan for the next '%' */
63 while ( (*fmt != '\0') && (*fmt != '%')) {
67 /* flush the string found so far */
68 OUTPUT(arg, fmtStart, fmt-fmtStart);
70 /* are we hitting the end? */
71 if (*fmt == '\0') break;
85 /* check for other prefixes */
102 while (IsDigit(*fmt)) {
103 width = 10 * width + Ctod(*fmt++);
111 while (IsDigit(*fmt)) {
112 prec = prec*10 + Ctod(*fmt++);
118 /* check format flag */
123 num = va_arg(ap, long int);
125 num = va_arg(ap, int);
127 length = PrintNum(buf, num, 2, 0, width, ladjust, padc, 0);
128 OUTPUT(arg, buf, length);
134 num = va_arg(ap, long int);
136 num = va_arg(ap, int);
142 length = PrintNum(buf, num, 10, negFlag, width, ladjust, padc, 0);
143 OUTPUT(arg, buf, length);
149 num = va_arg(ap, long int);
151 num = va_arg(ap, int);
153 length = PrintNum(buf, num, 8, 0, width, ladjust, padc, 0);
154 OUTPUT(arg, buf, length);
160 num = va_arg(ap, long int);
162 num = va_arg(ap, int);
164 length = PrintNum(buf, num, 10, 0, width, ladjust, padc, 0);
165 OUTPUT(arg, buf, length);
170 num = va_arg(ap, long int);
172 num = va_arg(ap, int);
174 length = PrintNum(buf, num, 16, 0, width, ladjust, padc, 0);
175 OUTPUT(arg, buf, length);
180 num = va_arg(ap, long int);
182 num = va_arg(ap, int);
184 length = PrintNum(buf, num, 16, 0, width, ladjust, padc, 1);
185 OUTPUT(arg, buf, length);
189 c = (char)va_arg(ap, int);
190 length = PrintChar(buf, c, width, ladjust);
191 OUTPUT(arg, buf, length);
195 s = (char*)va_arg(ap, char *);
196 length = PrintString(buf, s, width, ladjust);
197 OUTPUT(arg, buf, length);
205 /* output this char as it is */
207 } /* switch (*fmt) */
212 /* special termination call */
213 OUTPUT(arg, "\0", 1);
217 /* --------------- local help functions --------------------- */
219 PrintChar(char * buf, char c, int length, int ladjust)
223 if (length < 1) length = 1;
226 for (i=1; i< length; i++) buf[i] = ' ';
228 for (i=0; i< length-1; i++) buf[i] = ' ';
235 PrintString(char * buf, char* s, int length, int ladjust)
241 if (length < len) length = len;
244 for (i=0; i< len; i++) buf[i] = s[i];
245 for (i=len; i< length; i++) buf[i] = ' ';
247 for (i=0; i< length-len; i++) buf[i] = ' ';
248 for (i=length-len; i < length; i++) buf[i] = s[i-length+len];
254 PrintNum(char * buf, unsigned long u, int base, int negFlag,
255 int length, int ladjust, char padc, int upcase)
258 * 1. prints the number from left to right in reverse form.
259 * 2. fill the remaining spaces with padc if length is longer than
261 * TRICKY : if left adjusted, no "0" padding.
262 * if negtive, insert "0" padding between "0" and number.
263 * 3. if (!ladjust) we reverse the whole string including paddings
264 * 4. otherwise we only reverse the actual string representing the num.
276 *p++ = 'A' + tmp - 10;
278 *p++ = 'a' + tmp - 10;
287 /* figure out actual length and adjust the maximum length */
288 actualLength = p - buf;
289 if (length < actualLength) length = actualLength;
295 if (negFlag && !ladjust && (padc == '0')) {
296 for (i = actualLength-1; i< length-1; i++) buf[i] = padc;
297 buf[length -1] = '-';
299 for (i = actualLength; i< length; i++) buf[i] = padc;
303 /* prepare to reverse the string */
308 end = actualLength - 1;
313 while (end > begin) {
314 char tmp = buf[begin];
315 buf[begin] = buf[end];
322 /* adjust the string pointer */