diff options
author | Robert Morris <[email protected]> | 2019-06-11 09:57:14 -0400 |
---|---|---|
committer | Robert Morris <[email protected]> | 2019-06-11 09:57:14 -0400 |
commit | 5753553213df8f9de851adb68377db43faecb91f (patch) | |
tree | 3b629ff54897fca414146677532cb459a2ed11ba /user/printf.c | |
parent | 91ba81110acd3163f7de3580b677eece0c57f5e7 (diff) | |
download | xv6-labs-5753553213df8f9de851adb68377db43faecb91f.tar.gz xv6-labs-5753553213df8f9de851adb68377db43faecb91f.tar.bz2 xv6-labs-5753553213df8f9de851adb68377db43faecb91f.zip |
separate source into kernel/ user/ mkfs/
Diffstat (limited to 'user/printf.c')
-rw-r--r-- | user/printf.c | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/user/printf.c b/user/printf.c new file mode 100644 index 0000000..0c6b34b --- /dev/null +++ b/user/printf.c @@ -0,0 +1,95 @@ +#include "kernel/types.h" +#include "kernel/stat.h" +#include "user/user.h" + +#include <stdarg.h> + +static char digits[] = "0123456789ABCDEF"; + +static void +putc(int fd, char c) +{ + write(fd, &c, 1); +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + char buf[16]; + int i, neg; + uint x; + + neg = 0; + if(sgn && xx < 0){ + neg = 1; + x = -xx; + } else { + x = xx; + } + + i = 0; + do{ + buf[i++] = digits[x % base]; + }while((x /= base) != 0); + if(neg) + buf[i++] = '-'; + + while(--i >= 0) + 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; + + va_start(ap, fmt); + state = 0; + for(i = 0; fmt[i]; i++){ + c = fmt[i] & 0xff; + if(state == 0){ + if(c == '%'){ + state = '%'; + } else { + putc(fd, c); + } + } else if(state == '%'){ + if(c == 'd'){ + 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 = va_arg(ap, char*); + if(s == 0) + s = "(null)"; + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + putc(fd, va_arg(ap, uint)); + } else if(c == '%'){ + putc(fd, c); + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + } + } +} |