diff options
Diffstat (limited to 'printf.c')
-rw-r--r-- | printf.c | 34 |
1 files changed, 22 insertions, 12 deletions
@@ -2,6 +2,10 @@ #include "stat.h" #include "user.h" +#include <stdarg.h> + +static char digits[] = "0123456789ABCDEF"; + static void putc(int fd, char c) { @@ -11,7 +15,6 @@ putc(int fd, char c) static void printint(int fd, int xx, int base, int sgn) { - static char digits[] = "0123456789ABCDEF"; char buf[16]; int i, neg; uint x; @@ -35,16 +38,25 @@ printint(int fd, int xx, int base, int sgn) putc(fd, buf[i]); } +static void +printptr(int fd, uint64 x) { + int i; + putc(fd, '0'); + putc(fd, 'x'); + for (i = 0; i < (sizeof(uint64) * 2); i++, x <<= 4) + putc(fd, digits[x >> (sizeof(uint64) * 8 - 4)]); +} + // Print to the given fd. Only understands %d, %x, %p, %s. void printf(int fd, const char *fmt, ...) { + va_list ap; char *s; int c, i, state; - uint *ap; + va_start(ap, fmt); state = 0; - ap = (uint*)(void*)&fmt + 1; for(i = 0; fmt[i]; i++){ c = fmt[i] & 0xff; if(state == 0){ @@ -55,14 +67,13 @@ printf(int fd, const char *fmt, ...) } } else if(state == '%'){ if(c == 'd'){ - printint(fd, *ap, 10, 1); - ap++; - } else if(c == 'x' || c == 'p'){ - printint(fd, *ap, 16, 0); - ap++; + printint(fd, va_arg(ap, int), 10, 1); + } else if(c == 'x') { + printint(fd, va_arg(ap, int), 16, 0); + } else if(c == 'p') { + printptr(fd, va_arg(ap, uint64)); } else if(c == 's'){ - s = (char*)*ap; - ap++; + s = va_arg(ap, char*); if(s == 0) s = "(null)"; while(*s != 0){ @@ -70,8 +81,7 @@ printf(int fd, const char *fmt, ...) s++; } } else if(c == 'c'){ - putc(fd, *ap); - ap++; + putc(fd, va_arg(ap, uint)); } else if(c == '%'){ putc(fd, c); } else { |