Initial Commit
This commit is contained in:
+139
@@ -0,0 +1,139 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include "stdio.h"
|
||||
#include "debug.h"
|
||||
#include "video/render.h"
|
||||
#include "arch/x86_64/e9.h"
|
||||
#include "mp/spinlock.h"
|
||||
|
||||
static const uint32_t g_LogSeverityColors[] =
|
||||
{
|
||||
[LVL_DEBUG] = 0xAAAAAA, // light gray
|
||||
[LVL_INFO] = 0xFFFFFF, // white
|
||||
[LVL_WARN] = 0xFFFF00, // yellow
|
||||
[LVL_ERROR] = 0xFF0000, // red
|
||||
[LVL_CRITICAL] = 0xFFFFFF, // white (can do red background separately if you want)
|
||||
};
|
||||
|
||||
static spinlock_t s_printf_lock = SPINLOCK_INIT;
|
||||
|
||||
|
||||
|
||||
void fputc(char c)
|
||||
{
|
||||
putchar(c);
|
||||
e9_putc(c);
|
||||
}
|
||||
|
||||
void fputs(const char* str)
|
||||
{
|
||||
const char* s = str;
|
||||
while (*s) fputc(*s++);
|
||||
}
|
||||
|
||||
void fputs_colored(const char* str, uint32_t color) {
|
||||
while (*str) putchar_colored(*str++, color);
|
||||
while (*str) fputc(*str++);
|
||||
}
|
||||
|
||||
const char g_HexChars[] = "0123456789abcdef";
|
||||
|
||||
void fprintf_unsigned(uint64_t number, int radix)
|
||||
{
|
||||
char buffer[32];
|
||||
int pos = 0;
|
||||
|
||||
do {
|
||||
buffer[pos++] = g_HexChars[number % radix];
|
||||
number /= radix;
|
||||
} while (number > 0);
|
||||
|
||||
while (--pos >= 0) fputc(buffer[pos]);
|
||||
}
|
||||
|
||||
void fprintf_signed(int64_t number, int radix)
|
||||
{
|
||||
if (number < 0) {
|
||||
fputc('-');
|
||||
fprintf_unsigned(-number, radix);
|
||||
} else {
|
||||
fprintf_unsigned(number, radix);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void vfprintf(const char* fmt, va_list args)
|
||||
{
|
||||
int state = 0; // normal
|
||||
int length = 0; // default
|
||||
int radix = 10;
|
||||
bool sign = false;
|
||||
bool number = false;
|
||||
|
||||
while (*fmt) {
|
||||
switch (state) {
|
||||
case 0: // normal
|
||||
if (*fmt == '%') state = 1;
|
||||
else fputc(*fmt);
|
||||
break;
|
||||
|
||||
case 1: // length
|
||||
if (*fmt == 'l') { length = 3; state = 4; }
|
||||
else if (*fmt == 'h') { length = 2; state = 4; }
|
||||
else goto spec;
|
||||
break;
|
||||
|
||||
case 4: // spec
|
||||
spec:
|
||||
switch (*fmt) {
|
||||
case 'c': fputc((char)va_arg(args,int)); break;
|
||||
case 's': fputs(va_arg(args,const char*)); break;
|
||||
case 'd':
|
||||
case 'i': sign = true; number = true; radix = 10; break;
|
||||
case 'u': sign = false; number = true; radix = 10; break;
|
||||
case 'x':
|
||||
case 'X': sign = false; number = true; radix = 16; break;
|
||||
case 'p': number = true; sign = false; radix = 16; break;
|
||||
case 'o': sign = false; number = true; radix = 8; break;
|
||||
case '%': fputc('%'); break;
|
||||
}
|
||||
|
||||
if (number) {
|
||||
if (sign) fprintf_signed(va_arg(args,long), radix);
|
||||
else fprintf_unsigned(va_arg(args,unsigned long), radix);
|
||||
}
|
||||
|
||||
state = 0;
|
||||
length = 0;
|
||||
number = false;
|
||||
sign = false;
|
||||
break;
|
||||
}
|
||||
|
||||
fmt++;
|
||||
}
|
||||
}
|
||||
|
||||
void printf(const char* fmt, ...)
|
||||
{
|
||||
uint64_t flags;
|
||||
spinlock_acquire_irqsave(&s_printf_lock, &flags);
|
||||
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
||||
vfprintf(fmt, args);
|
||||
|
||||
va_end(args);
|
||||
|
||||
spinlock_release_irqrestore(&s_printf_lock, flags);
|
||||
}
|
||||
|
||||
void fprintf(const char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vfprintf(fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
Reference in New Issue
Block a user