From 12e890bb8a128d54d8396445e79f5f2dc9afe4dd Mon Sep 17 00:00:00 2001 From: Aaron Lindsay Date: Fri, 7 Sep 2012 23:53:27 -0400 Subject: [PATCH] Add basic printing/formatting infrastructure for debugging --- include/print.h | 7 ++++ include/vargs.h | 14 +++++++ kernel/print.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 127 insertions(+) create mode 100644 include/print.h create mode 100644 include/vargs.h create mode 100644 kernel/print.c diff --git a/include/print.h b/include/print.h new file mode 100644 index 0000000..652be6f --- /dev/null +++ b/include/print.h @@ -0,0 +1,7 @@ +#ifndef PRINT_H +#define PRINT_H + +int print(char *fmt, ...); +void print_init(void (*putc)(char)); + +#endif /* PRINT_H */ diff --git a/include/vargs.h b/include/vargs.h new file mode 100644 index 0000000..00642c7 --- /dev/null +++ b/include/vargs.h @@ -0,0 +1,14 @@ +#ifndef VARGS_H +#define VARGS_H + +#ifdef __GNUC__ + typedef __builtin_va_list va_list; + #define va_start(v,l) __builtin_va_start(v,l) + #define va_end(v) __builtin_va_end(v) + #define va_arg(v,l) __builtin_va_arg(v,l) + #define va_copy(d,s) __builtin_va_copy(d,s) +#else + #error "Variadic functions aren't supported with any compiler other than GCC." +#endif + +#endif /* VARGS_H */ diff --git a/kernel/print.c b/kernel/print.c new file mode 100644 index 0000000..2f2b5cd --- /dev/null +++ b/kernel/print.c @@ -0,0 +1,106 @@ +#include +#include + +/* This function exists solely so crashes don't happen if putc() gets + * called before it is initialized. */ +void putc_initial(char c) { + (void)c; +} +void (*putc)(char) = &putc_initial; + +void print_init(void (*putcfn)(char)) { + if (putcfn) + putc = putcfn; +} + +void puts(const char *s) +{ + while (*s) putc (*s++); +} + +void puti(int i) +{ + unsigned int left; + char buf[1 << (sizeof(int)*8) / 10]; + char *p = buf; + unsigned char negative = i < 0; + + if (!i) + putc('0'); + + left = negative ? -1*i : i; + + while (left) { + unsigned int remainder = left % 10; + left /= 10; + *p = ('0'-0) + remainder; + p++; + } + + if (negative) + putc('-'); + + while (p-- != buf) + putc(*p); +} + +void putx(unsigned int i) { + unsigned int left = i; + char buf[1 << (sizeof(int)*8) / 16]; + char *p = buf; + + puts("0x"); + if (!i) + putc('0'); + + while (left) { + unsigned int remainder = left % 16; + left /= 16; + if (remainder < 10) + *p = ('0'-0) + remainder; + else + *p = ('a'-10) + remainder; + p++; + } + + while (p-- != buf) + putc(*p); +} + +int print(char *fmt, ...) { + char *c; + va_list arg; + + va_start(arg, fmt); + for (c = fmt; *c; c++) { + if (*c == '%') { + switch (*++c) { + case '%': + putc('%'); + break; + case 's': + puts(va_arg(arg, char *)); + break; + case 'c': + putc(va_arg(arg, unsigned int)); + break; + case 'd': + puti(va_arg(arg, int)); + break; + case 'x': + putx(va_arg(arg, unsigned int)); + break; + default: + puts("\nError: print(): Invalid formatting character: '"); + putc(*c); + puts("'\n"); + return -1; + } + } else { + putc(*c); + } + } + va_end(arg); + + return 0; +}