diff --git a/kernel/printf.c b/kernel/printf.c new file mode 100644 index 0000000..8557139 --- /dev/null +++ b/kernel/printf.c @@ -0,0 +1,132 @@ +/* +Copyright (C) 2016-2019 The University of Notre Dame +This software is distributed under the GNU General Public License. +See the file LICENSE for details. +*/ + +#include "printf.h" +#include "string.h" +#include "console.h" +#include + +static void printf_putchar( char c ) +{ + console_putchar(&console_root,c); +} + +char getchar() +{ + return console_getchar(&console_root); +} + +void putchar( char c) +{ + return printf_putchar(c); +} + +static void printf_putstring(char *s) +{ + console_putstring(&console_root,s); +} + +static void printf_puthexdigit(uint8_t i) +{ + if(i < 10) { + printf_putchar('0' + i); + } else { + printf_putchar('a' + i - 10); + } +} + +static void printf_puthex(uint32_t i) +{ + int j; + for(j = 28; j >= 0; j = j - 4) { + printf_puthexdigit((i >> j) & 0x0f); + } +} + +static void printf_putint(int32_t i) +{ + int f, d; + if(i < 0 && i != 0) { + printf_putchar('-'); + i = -i; + } + + f = 1; + while((i / f) >= 10) { + f *= 10; + } + while(f > 0) { + d = i / f; + printf_putchar('0' + d); + i = i - d * f; + f = f / 10; + } +} + +static void printf_putuint(uint32_t u) +{ + int f, d; + f = 1; + while((u / f) >= 10) { + f *= 10; + } + while(f > 0) { + d = u / f; + printf_putchar('0' + d); + u = u - d * f; + f = f / 10; + } +} + +void printf(const char *s, ...) +{ + va_list args; + + uint32_t u; + int32_t i; + char *str; + + va_start(args, s); + + while(*s) { + if(*s != '%') { + printf_putchar(*s); + } else { + s++; + switch (*s) { + case 'd': + i = va_arg(args, int32_t); + printf_putint(i); + break; + case 'u': + u = va_arg(args, uint32_t); + printf_putuint(u); + break; + case 'x': + u = va_arg(args, uint32_t); + printf_puthex(u); + break; + case 's': + str = va_arg(args, char *); + printf_putstring(str); + break; + case 'c': + u = va_arg(args, int32_t); + printf_putchar(u); + break; + case 0: + return; + break; + default: + printf_putchar(*s); + break; + } + } + s++; + } + va_end(args); +} +