4 * Open Hack'Ware BIOS: formated output functions
6 * Copyright (c) 2004-2005 Jocelyn Mayer
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License V2
10 * as published by the Free Software Foundation
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 /* functions prototypes are here */
24 /* va_list is defined here */
26 /* size_t is defined here */
28 /* NULL is defined here */
30 /* write is defined here */
32 /* memcpy is defined here */
33 /* memset is defined here */
34 /* strlen is defined here */
37 #define unused __attribute__ (( unused ))
38 int console_write (const void *buffer, int len);
39 /* XXX: this is a hack to be fixed */
40 int serial_write (const void *buffer, int len);
41 #define debug_write serial_write
43 /* Low level output fonctions */
44 typedef size_t (*outf_t)(void *private, const unsigned char *buf, size_t len);
47 #if defined (__USE__vprintf__)
48 size_t outfd (void *private, const unsigned char *buf, size_t len)
52 if (*fd == 1 || *fd == 2)
53 return console_write(buf, len);
55 return write(*fd, buf, len);
58 size_t outf_dbg (void *private, const unsigned char *buf, size_t len)
62 if (*fd == 1 || *fd == 2)
63 return debug_write(buf, len);
65 return write(*fd, buf, len);
68 /* output to buffer */
69 size_t outbuf (void *private, const unsigned char *buf, size_t len)
71 unsigned char **dst = private;
73 memcpy(*dst, buf, len);
80 /* misc formatted output functions */
81 /* out one character */
82 static size_t outc (outf_t outf, void *private,
83 unsigned int value, size_t maxlen)
90 if ((*outf)(private, &buffer, 1) == (size_t)-1)
96 /* out one int in decimal */
97 static size_t outdecs (outf_t outf, void *private,
98 int value, size_t fill, size_t maxlen)
100 unsigned char buffer[12];
116 for (; value != 0; pos--) {
117 buffer[pos] = (value % 10) + '0';
123 for (; fill != 0 && pos != 0; fill--) {
131 if ((*outf)(private, buffer + pos + 1, len) == (size_t)-1)
137 /* out one unsigned int as decimal */
138 static size_t outdecu (outf_t outf, void *private,
139 unsigned int value, size_t fill, size_t maxlen)
141 unsigned char buffer[11];
149 for (; value != 0; pos--) {
150 buffer[pos] = (value % 10) + '0';
156 for (; fill != 0 && pos != (size_t)-1; fill--) {
162 if ((*outf)(private, buffer + pos + 1, len) == (size_t)-1)
168 /* out one unsigned int as hexadecimal */
169 static size_t outhex (outf_t outf, void *private,
170 unsigned int value, size_t fill, size_t maxlen)
172 unsigned char buffer[9];
181 for (; value != 0; pos--) {
185 buffer[pos] = d + '0';
191 for (; fill != 0 && pos != (size_t)-1; fill--) {
197 if ((*outf)(private, buffer + pos + 1, len) == (size_t)-1)
203 static size_t outstr (outf_t outf, void *private,
204 const unsigned char *str, unused size_t fill,
207 #define TMPBUF_LEN 256
209 unsigned char tmpbuf[TMPBUF_LEN];
210 size_t len, totlen, tmp;
216 /* Avoid crash if given a NULL string */
223 memset(tmpbuf, ' ', TMPBUF_LEN);
225 for (; fill > 0; fill -= tmp) {
227 if (tmp > TMPBUF_LEN)
230 if (totlen > maxlen) {
231 tmp = maxlen - totlen;
234 (*outf)(private, tmpbuf, tmp);
239 if (totlen > maxlen) {
240 len = maxlen - totlen;
243 if ((*outf)(private, str, len) == (size_t)-1)
249 int _vprintf(outf_t outf, void *private, size_t maxlen,
250 const unsigned char *format, va_list ap)
252 const unsigned char *p, *str;
253 size_t maxfill, totlen, len, tmp;
258 for (totlen = 0; totlen != maxlen;) {
259 for (p = str; (*p != '%' || cur > 6) && *p != '\0'; p++)
262 if (len + totlen > maxlen)
263 len = maxlen - totlen;
264 tmp = (*outf)(private, str, p - str);
265 if (tmp == (size_t)-1)
279 if (maxfill >= (size_t)-2) {
293 maxfill = (maxfill * 10) + *p - '0';
304 if (maxfill == (size_t)-2 || maxfill == (size_t)(-1))
306 tmp = outdecs(outf, private,
307 va_arg(ap, int), maxfill, maxlen - totlen);
310 if (maxfill == (size_t)-2 || maxfill == (size_t)(-1))
312 tmp = outdecu(outf, private,
313 va_arg(ap, unsigned int), maxfill, maxlen - totlen);
316 if (maxfill == (size_t)-2 || maxfill == (size_t)(-1))
318 tmp = outhex(outf, private,
319 va_arg(ap, unsigned int), maxfill, maxlen - totlen);
326 if (maxfill == (size_t)-2 || maxfill == (size_t)(-1))
328 tmp = outhex(outf, private, va_arg(ap, unsigned int),
329 maxfill, maxlen - totlen);
337 tmp = outc(outf, private,
338 va_arg(ap, int), maxlen - totlen);
342 if (maxfill == (size_t)-2 || maxfill == (size_t)(-1))
344 str = va_arg(ap, const unsigned char *);
345 tmp = outstr(outf, private, str, maxfill, maxlen - totlen);
352 tmp = outc(outf, private, '%', maxlen - totlen);
356 /* Invalid format : display the raw string */
358 if (len + totlen > maxlen)
359 len = maxlen - totlen;
360 tmp = (*outf)(private, str, len);
363 if (tmp == (size_t)-1)
371 #else /* defined (__USE__vprintf__) */
372 size_t outfd (void *private, const unsigned char *buf, size_t len);
373 size_t outf_dbg (void *private, const unsigned char *buf, size_t len);
374 size_t outbuf (void *private, const unsigned char *buf, size_t len);
375 int _vprintf(outf_t outf, void *private, size_t maxlen,
376 const unsigned char *format, va_list ap);
377 #endif /* defined (__USE__vprintf__) */
379 #if defined (__USE_printf__)
380 int printf (const char *format, ...)
386 va_start(ap, format);
387 ret = _vprintf(&outfd, &fd, -1, format, ap);
392 #endif /* defined (__USE_printf__) */
394 #if defined (__USE_dprintf__)
395 int dprintf (const char *format, ...)
401 va_start(ap, format);
402 ret = _vprintf(&outf_dbg, &fd, -1, format, ap);
407 #endif /* defined (__USE_dprintf__) */
409 #if defined (__USE_sprintf__)
410 int sprintf (char *str, const char *format, ...)
415 va_start(ap, format);
416 ret = _vprintf(&outbuf, &str, -1, format, ap);
421 #endif /* defined (__USE_sprintf__) */
423 #if defined (__USE_snprintf__)
424 int snprintf (char *str, size_t size, const char *format, ...)
429 va_start(ap, format);
430 ret = _vprintf(&outbuf, &str, size, format, ap);
435 #endif /* defined (__USE_snprintf__) */
437 #if defined (__USE_vprintf__)
438 int vprintf (const char *format, va_list ap)
442 return _vprintf(&outfd, &fd, -1, format, ap);
444 #endif /* defined (__USE_vprintf__) */
446 #if defined (__USE_vdprintf__)
447 int vdprintf (const char *format, va_list ap)
451 return _vprintf(&outf_dbg, &fd, -1, format, ap);
453 #endif /* defined (__USE_vdprintf__) */
455 #if defined (__USE_vsprintf__)
456 int vsprintf (char *str, const char *format, va_list ap)
458 return _vprintf(&outbuf, &str, -1, format, ap);
460 #endif /* defined (__USE_vsprintf__) */
462 #if defined (__USE_vsnprintf__)
463 int vsnprintf (char *str, size_t size, const char *format, va_list ap)
465 return _vprintf(&outbuf, &str, size, format, ap);
467 #endif /* defined (__USE_vsnprintf__) */