summaryrefslogtreecommitdiff
path: root/src/kernel/log.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/log.c')
-rw-r--r--src/kernel/log.c103
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);
+}