summaryrefslogtreecommitdiff
path: root/printf.c
diff options
context:
space:
mode:
Diffstat (limited to 'printf.c')
-rw-r--r--printf.c34
1 files changed, 22 insertions, 12 deletions
diff --git a/printf.c b/printf.c
index b3298aa..c820305 100644
--- a/printf.c
+++ b/printf.c
@@ -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 {