From d90682c40e2fa04ca9ded3b132a642635be10358 Mon Sep 17 00:00:00 2001 From: xamidev <121681048+xamidev@users.noreply.github.com> Date: Tue, 10 Sep 2024 08:40:17 +0200 Subject: [PATCH] Add: colorprintf, kernel panic coloring --- src/kernel/isr.c | 2 +- src/libc/stdio.c | 243 +++++++++++++++++++++++++++++++++++++++++++++++ src/libc/stdio.h | 2 + 3 files changed, 246 insertions(+), 1 deletion(-) diff --git a/src/kernel/isr.c b/src/kernel/isr.c index a692d9b..1886ff7 100644 --- a/src/kernel/isr.c +++ b/src/kernel/isr.c @@ -116,7 +116,7 @@ void fault_handler(struct regs *r) { if (r->int_no < 32) { - printf("\n\n*** [Kernel panic - %s Exception] ***\nInterrupt error code %u\nedi: %x esi: %u ebp: %u esp: %u\nebx: %u edx: %u ecx: %u eax: %u\neip: %x cs:%x eflags: %x ss: %x\ngs: %x fs: %x es: %x ds: %x\nHalting!\n", exception_messages[r->int_no], r->err_code, r->edi, r->esi, r->ebp, r->esp, r->ebx, r->edx, r->ecx, r->eax, r->eip, r->cs, r->eflags, r->ss, r->gs, r->fs, r->es, r->ds); + colorprintf(white, red, "\n\n*** [Kernel panic - %s Exception] ***\nInterrupt error code %u\nedi: 0x%x\nesi: 0x%x\nebp: 0x%x\nesp: 0x%x\neip: 0x%x\neax: 0x%x\nebx: 0x%x\necx: 0x%x\nedx: 0x%x\ncs: 0x%x\neflags: 0x%x\nss: 0x%x\ngs: 0x%x\nfs: 0x%x\nes: 0x%x\nds: 0x%x\nHalting!\n", exception_messages[r->int_no], r->err_code, r->edi, r->esi, r->ebp, r->esp, r->eip, r->eax, r->ebx, r->ecx, r->edx, r->cs, r->eflags, r->ss, r->gs, r->fs, r->es, r->ds); for (;;); } } diff --git a/src/libc/stdio.c b/src/libc/stdio.c index d583d24..220b8ea 100644 --- a/src/libc/stdio.c +++ b/src/libc/stdio.c @@ -492,3 +492,246 @@ void get_input(char *buffer, int size) { } buffer[index] = '\0'; } + +void colorprintf(uint32_t fg, uint32_t bg, const char* fmt, ...) +{ + int* argp = (int*)&fmt; + int state = PRINTF_STATE_START; + int length = PRINTF_LENGTH_START; + int radix = 10; + bool sign = false; + int width = 0; + char pad_char = ' '; + + argp++; + while (*fmt) + { + switch (state) + { + case PRINTF_STATE_START: + if (*fmt == '%') + { + state = PRINTF_STATE_LENGTH; + width = 0; + pad_char = ' '; + } + else + { + colorputc(*fmt, fg, bg); + } + break; + + case PRINTF_STATE_LENGTH: + if (*fmt == '0') + { + pad_char = '0'; + state = PRINTF_STATE_WIDTH; + } + else if (*fmt >= '1' && *fmt <= '9') + { + width = *fmt - '0'; + state = PRINTF_STATE_WIDTH; + } + else if (*fmt == 'h') + { + length = PRINTF_LENGTH_SHORT; + state = PRINTF_STATE_SHORT; + } + else if (*fmt == 'l') + { + length = PRINTF_LENGTH_LONG; + state = PRINTF_STATE_LONG; + } + else + { + goto PRINTF_STATE_SPEC_; + } + break; + + case PRINTF_STATE_WIDTH: + if (*fmt >= '0' && *fmt <= '9') + { + width = width * 10 + (*fmt - '0'); + } + else + { + goto PRINTF_STATE_SPEC_; + } + break; + + case PRINTF_STATE_SHORT: + if (*fmt == 'h') + { + length = PRINTF_LENGTH_SHORT_SHORT; + state = PRINTF_STATE_SPEC; + } + else + { + goto PRINTF_STATE_SPEC_; + } + break; + + case PRINTF_STATE_LONG: + if (*fmt == 'l') + { + length = PRINTF_LENGTH_LONG_LONG; + state = PRINTF_STATE_SPEC; + } + else + { + goto PRINTF_STATE_SPEC_; + } + break; + + case PRINTF_STATE_SPEC: + PRINTF_STATE_SPEC_: + switch (*fmt) + { + case 'c': + colorputc((char)*argp, fg, bg); + argp++; + break; + case 's': + colorputs(*(const char**)argp, fg, bg); + argp++; + break; + case '%': + putc('%'); + break; + case 'd': + case 'i': + radix = 10; + sign = true; + argp = colorprintf_number(argp, length, sign, radix, width, pad_char, fg, bg); + break; + case 'u': + radix = 10; + sign = false; + argp = colorprintf_number(argp, length, sign, radix, width, pad_char, fg, bg); + break; + case 'X': + case 'x': + case 'p': + radix = 16; + sign = false; + argp = colorprintf_number(argp, length, sign, radix, width, pad_char, fg, bg); + break; + case 'o': + radix = 8; + sign = false; + argp = colorprintf_number(argp, length, sign, radix, width, pad_char, fg, bg); + break; + case 'f': { + double* dargp = (double*)argp; + double d = *(double*)dargp; + char buffer[64]; + dtostrf(d, buffer, 6); + colorputs(buffer, fg, bg); + argp += 2; + break; + } + default: + break; + } + state = PRINTF_STATE_START; + length = PRINTF_LENGTH_START; + radix = 10; + sign = false; + width = 0; + pad_char = ' '; + break; + } + fmt++; + } +} + +int* colorprintf_number(int* argp, int length, bool sign, int radix, int width, char pad_char, uint32_t fg, uint32_t bg) +{ + char buffer[32]; + unsigned long long number; + int number_sign = 1; + int pos = 0; + + switch (length) + { + case PRINTF_LENGTH_SHORT_SHORT: + case PRINTF_LENGTH_SHORT: + case PRINTF_LENGTH_START: + if (sign) + { + int n = *argp; + if (n < 0) + { + n = -n; + number_sign = -1; + } + number = (unsigned long long)n; + } + else + { + number = *(unsigned int*)argp; + } + argp++; + break; + case PRINTF_LENGTH_LONG: + if (sign) + { + long int n = *(long int*)argp; + if (n < 0) + { + n = -n; + number_sign = -1; + } + number = (unsigned long long)n; + } + else + { + number = *(unsigned long int*)argp; + } + argp += 2; + break; + case PRINTF_LENGTH_LONG_LONG: + if (sign) + { + long long int n = *(long long int*)argp; + if (n < 0) + { + n = -n; + number_sign = -1; + } + number = (unsigned long long)n; + } + else + { + number = *(unsigned long long int*)argp; + } + argp += 4; + break; + } + + do + { + uint32_t rem; + x86_div64_32(number, radix, &number, &rem); + buffer[pos++] = charset[rem]; + } while (number > 0); + + if (sign && number_sign < 0) + { + buffer[pos++] = '-'; + } + + int padding = width - pos; + + while (padding-- > 0) + { + colorputc(pad_char, fg, bg); + } + + while (--pos >= 0) + { + colorputc(buffer[pos], fg, bg); + } + + return argp; +} diff --git a/src/libc/stdio.h b/src/libc/stdio.h index fcc849c..0da0a59 100644 --- a/src/libc/stdio.h +++ b/src/libc/stdio.h @@ -33,6 +33,8 @@ char getchar(int x, int y); unsigned int getcolor(int x, int y); void putc(char c); void colorputc(char c, uint32_t fg, uint32_t bg); +void colorprintf(uint32_t fg, uint32_t bg, const char* fmt, ...); +int* colorprintf_number(int* argp, int length, bool sign, int radix, int width, char pad_char, uint32_t fg, uint32_t bg); #define PRINTF_STATE_START 0 #define PRINTF_STATE_LENGTH 1