support widths in printf

This commit is contained in:
Justin C. Miller
2018-04-25 19:52:27 -07:00
parent bed882f41c
commit 2404b22c1f
2 changed files with 60 additions and 26 deletions

View File

@@ -244,6 +244,7 @@ console::puts(const char *message)
while (message && *message) { while (message && *message) {
char c = *message++; char c = *message++;
if (m_screen) m_screen->putc(c); if (m_screen) m_screen->putc(c);
serial_write(c); serial_write(c);
if (c == '\n') serial_write('\r'); if (c == '\n') serial_write('\r');
} }
@@ -271,39 +272,62 @@ void console::printf(const char *fmt, ...)
continue; continue;
} }
r++; // chomp the %
flush(); flush();
r++; // chomp the % bool done = false;
switch (*r++) { bool right = true;
case '%': *w = '%'; break; int width = 0;
case 'x': put_hex<uint32_t>(va_arg(args, uint32_t)); break; while (!done) {
char c = *r++;
switch (c) {
case '%': *w = '%'; done = true; break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': width = width * 10 + (c - '0'); break;
case '-': right = !right; break;
case 'x': put_hex<uint32_t>(va_arg(args, uint32_t), right ? width : -width); done = true; break;
case 'd': case 'd':
case 'u': put_dec<uint32_t>(va_arg(args, uint32_t)); break; case 'u': put_dec<uint32_t>(va_arg(args, uint32_t), right ? width : -width); done = true; break;
case 's': { case 's': {
const char *s = va_arg(args, const char*); const char *s = va_arg(args, const char*);
if (s) puts(s); if (s) puts(s);
} }
done = true;
break; break;
case 'l': case 'l':
switch (*r++) { switch (*r++) {
case 'x': put_hex<uint64_t>(va_arg(args, uint64_t)); break; case 'x': put_hex<uint64_t>(va_arg(args, uint64_t), right ? width : -width); done = true; break;
case 'd': case 'd':
case 'u': put_dec<uint32_t>(va_arg(args, uint64_t)); break; case 'u': put_dec<uint32_t>(va_arg(args, uint64_t), right ? width : -width); done = true; break;
default: default:
done = true;
break; break;
} }
break; break;
default: default:
done = true;
break; break;
} }
} }
}
flush(); flush();
va_end(args); va_end(args);

View File

@@ -17,10 +17,12 @@ public:
void printf(const char *fmt, ...); void printf(const char *fmt, ...);
template <typename T> template <typename T>
void put_hex(T x); void put_hex(T x, int width = 0);
template <typename T> template <typename T>
void put_dec(T x); void put_dec(T x, int width = 0);
void set_screen(console_out_screen *out) { m_screen = out; }
static console * get(); static console * get();
@@ -39,7 +41,7 @@ console_out_screen * console_get_screen_out(
extern const char digits[]; extern const char digits[];
template <typename T> template <typename T>
void console::put_hex(T x) void console::put_hex(T x, int width)
{ {
static const int chars = sizeof(x) * 2; static const int chars = sizeof(x) * 2;
char message[chars + 1]; char message[chars + 1];
@@ -47,19 +49,27 @@ void console::put_hex(T x)
message[chars - i - 1] = digits[(x >> (i*4)) & 0xf]; message[chars - i - 1] = digits[(x >> (i*4)) & 0xf];
} }
message[chars] = 0; message[chars] = 0;
if (width > chars) for(int i=0; i<(width-chars); ++i) puts(" ");
puts(message); puts(message);
if (-width > chars) for(int i=0; i<(-width-chars); ++i) puts(" ");
} }
template <typename T> template <typename T>
void console::put_dec(T x) void console::put_dec(T x, int width)
{ {
static const int chars = sizeof(x) * 3; static const int chars = sizeof(x) * 3;
char message[chars + 1]; char message[chars + 1];
char *p = message + chars; char *p = message + chars;
int length = 0;
*p-- = 0; *p-- = 0;
do { do {
*p-- = digits[x % 10]; *p-- = digits[x % 10];
x /= 10; x /= 10;
length += 1;
} while (x != 0); } while (x != 0);
if (width > length) for(int i=0; i<(width-length); ++i) puts(" ");
puts(++p); puts(++p);
if (-width > length) for(int i=0; i<(-width-length); ++i) puts(" ");
} }