Add: colorprintf, kernel panic coloring

This commit is contained in:
xamidev
2024-09-10 08:40:17 +02:00
parent a9a4b89c85
commit d90682c40e
3 changed files with 246 additions and 1 deletions

View File

@@ -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;
}