diff options
Diffstat (limited to 'src/kernel/log.c')
-rw-r--r-- | src/kernel/log.c | 103 |
1 files changed, 81 insertions, 22 deletions
diff --git a/src/kernel/log.c b/src/kernel/log.c index b5a96cb..8ef2baf 100644 --- a/src/kernel/log.c +++ b/src/kernel/log.c @@ -1,33 +1,92 @@ -#include "vga.h" +#include <stdarg.h> +#include <stdbool.h> + #include "serial.h" #include "log.h" #define LOG_COM COM1 -static const uint8_t log_mode_colors[] = { - 0x30, - 0x07, - 0x4f +void init_log() { + //TODO: move old "sys/current.log" + //TODO: open new "sys/current.log" +} + +static const char *const log_prefixes[] = { + " [USER] ", + " [INFO] ", + " [WARN] ", + "[ERROR] ", + "[PANIC] ", }; -void set_log_mode(enum log_mode mode) { - vga_set_color(log_mode_colors[mode]); - vga_printch('\n'); - vga_printch('\n'); +static inline void logch(char ch) { + sout(LOG_COM, ch); + //TODO: write to log file as well } -void logch(char ch) { - if (ch == '\n') { - sout(LOG_COM, (uint8_t)'\r'); - sout(LOG_COM, (uint8_t)'\n'); - } - else - sout(LOG_COM, (uint8_t)ch); +static const char hex_table[] = "0123456789abcdef"; - vga_printch(ch); -} +void logf(enum log_level level, const char *format, ...) { + va_list args; + va_start(args, format); -void logsz(const char *sz) { - while (*sz) - logch(*sz++); -}
\ No newline at end of file + const char *log_prefix = log_prefixes[level]; + while (*log_prefix) + logch(*(log_prefix++)); + + for (const char *fi = format; *fi;) + if (*fi != '%') + logch(*(fi++)); + else { + switch (*(fi + 1)) { + case '%': + logch('%'); + break; + case 's':; + const char *s = va_arg(args, const char *); + while (*s) + logch(*(s++)); + break; + case 'd':; + const uint32_t d = va_arg(args, uint32_t); + if (d == 0) { + logch('0'); + break; + } + bool zeros = false; + for (uint32_t place = 1000000000; place; place /= 10) { + uint8_t digit = (d / place) % 10; + if (digit) + zeros = true; + if (zeros) + logch(digit | '0'); + } + break; + case 'h':; + const uint32_t h = va_arg(args, uint32_t); + uint32_t shift = 32; + if (*(fi + 2) == 'b') { + shift = 8; + ++fi; + } + else if (*(fi + 2) == 'w') { + shift = 16; + ++fi; + } + else if (*(fi + 2) == 'd') { + ++fi; + } + while (shift) + logch(hex_table[(h >> (shift -= 4)) & 0xf]); + break; + default: + logch('%'); + logch(*(fi + 1)); + } + fi += 2; + } + + logch('\n'); + + va_end(args); +} |