#include #include #include "serial.h" #include "log.h" #define LOG_COM COM1 void init_log() { //TODO: move old "sys/current.log" //TODO: open new "sys/current.log" } static const char *const log_prefixes[] = { " [USER] ", " [INFO] ", " [DUMP] ", " [WARN] ", "[ERROR] ", "[PANIC] ", }; static inline void logch(char ch) { sout(LOG_COM, ch); //TODO: write to log file as well } static const char hex_table[] = "0123456789abcdef"; void logf(enum log_level level, const char *format, ...) { va_list args; va_start(args, format); 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 'c':; const char c = (char)va_arg(args, uint32_t); logch(c); 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); }