summaryrefslogtreecommitdiff
path: root/printf.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@twiddle.net>2011-05-06 15:50:07 -0700
committerRichard Henderson <rth@twiddle.net>2011-05-06 15:50:07 -0700
commit45a30cd864c313b353f47c8186b2b932069af4a1 (patch)
tree8eb31dfd2bf4c7fbc4f613dcf604eb636c167ff8 /printf.c
parent87fb8be28570645cd42f940ebdaed4ee1d7724cf (diff)
downloadqemu-palcode-45a30cd864c313b353f47c8186b2b932069af4a1.zip
qemu-palcode-45a30cd864c313b353f47c8186b2b932069af4a1.tar.gz
qemu-palcode-45a30cd864c313b353f47c8186b2b932069af4a1.tar.bz2
Handle padding in printf numerical output.
Diffstat (limited to 'printf.c')
-rw-r--r--printf.c85
1 files changed, 59 insertions, 26 deletions
diff --git a/printf.c b/printf.c
index f5c7545..469b82c 100644
--- a/printf.c
+++ b/printf.c
@@ -20,14 +20,38 @@
#include <stdarg.h>
#include <stdbool.h>
-#include "uart.h"
+#include <string.h>
+#include "console.h"
-static int print_decimal(unsigned long val)
+static int print_buf_pad(char *buf, int buflen, char *p, int width, int pad)
+{
+ int len = buf + buflen - p;
+ int r = 0;
+
+ if (width > len)
+ {
+ *--p = pad;
+ len++;
+
+ while (width > buflen)
+ {
+ crb_puts(0, p, 1);
+ width--;
+ r++;
+ }
+ while (width > len)
+ *--p = pad, len++;
+ }
+
+ crb_puts(0, p, len);
+ return r + len;
+}
+
+static int print_decimal(unsigned long val, int width, int pad)
{
char buf[32];
- char *p = buf+31;
+ char *p = buf + sizeof(buf);
- *p = 0;
if (val == 0)
*--p = '0';
else
@@ -48,16 +72,14 @@ static int print_decimal(unsigned long val)
while (val);
}
- uart_puts(COM1, p+1);
- return sizeof(buf) - (p - buf);
+ return print_buf_pad(buf, sizeof(buf), p, width, pad);
}
-static int print_hex(unsigned long val)
+static int print_hex(unsigned long val, int width, char pad)
{
char buf[32];
- char *p = buf+31;
+ char *p = buf + sizeof(buf);
- *p = 0;
if (val == 0)
*--p = '0';
else
@@ -71,8 +93,7 @@ static int print_hex(unsigned long val)
while (val);
}
- uart_puts(COM1, p+1);
- return sizeof(buf) - (p - buf);
+ return print_buf_pad(buf, sizeof(buf), p, width, pad);
}
int printf(const char *fmt, ...)
@@ -86,18 +107,21 @@ int printf(const char *fmt, ...)
for (; *fmt ; fmt++)
if (*fmt != '%')
{
- uart_putchar(COM1, *fmt);
+ crb_puts(0, fmt, 1);
r++;
}
else
{
+ const char *percent = fmt;
bool is_long = false;
+ char pad = ' ';
+ int width = 0;
restart:
switch (*++fmt)
{
case '%':
- uart_putchar(COM1, '%');
+ crb_puts(0, "%", 1);
r++;
break;
@@ -111,7 +135,7 @@ int printf(const char *fmt, ...)
long d = va_arg (args, long);
if (d < 0)
{
- uart_putchar(COM1, '-');
+ crb_puts(0, "-", 1);
d = -d;
}
val = d;
@@ -121,7 +145,7 @@ int printf(const char *fmt, ...)
int d = va_arg (args, int);
if (d < 0)
{
- uart_putchar(COM1, '-');
+ crb_puts(0, "-", 1);
d = -d;
r++;
}
@@ -136,7 +160,7 @@ int printf(const char *fmt, ...)
val = va_arg (args, unsigned int);
do_unsigned:
- r += print_decimal (val);
+ r += print_decimal (val, width, pad);
break;
case 'x':
@@ -144,23 +168,32 @@ int printf(const char *fmt, ...)
val = va_arg (args, unsigned long);
else
val = va_arg (args, unsigned int);
- r += print_hex (val);
+ r += print_hex (val, width, pad);
+ break;
case 's':
{
const char *s = va_arg (args, const char *);
- while (*s)
- {
- uart_putchar(COM1, *s++);
- r++;
- }
- break;
+ int len = strlen(s);
+ crb_puts(0, s, len);
+ r += len;
}
+ break;
+
+ case '0':
+ pad = '0';
+ case '1' ... '9':
+ width = *fmt - '0';
+ while (fmt[1] >= '0' && fmt[1] <= '9')
+ width = width * 10 + *++fmt - '0';
+ goto restart;
default:
- uart_putchar(COM1, '%');
- uart_putchar(COM1, *fmt);
- r += 2;
+ {
+ int len = fmt - percent;
+ crb_puts(0, percent, len);
+ r += len;
+ }
break;
}
}