62 lines
1.3 KiB
C
62 lines
1.3 KiB
C
#include "base.h"
|
|
#include "ctype.h"
|
|
#include "terminal.h"
|
|
|
|
#include <stdarg.h>
|
|
#include <stdint.h>
|
|
|
|
int print_int_base(int64_t number, const char *prefix, const char *base);
|
|
|
|
static int get_level(const char *str)
|
|
{
|
|
if (!str || !isdigit(str[0]))
|
|
return 0;
|
|
return str[0] - '0';
|
|
}
|
|
|
|
static int print_flag(char flag, va_list *ap)
|
|
{
|
|
switch (flag) {
|
|
case '%':
|
|
return terminal_putchar('%');
|
|
case 'i':
|
|
return print_int_base(va_arg(*ap, int32_t), NULL, BASE_DECA);
|
|
case 'd':
|
|
return print_int_base(va_arg(*ap, int32_t), NULL, BASE_DECA);
|
|
case 'c':
|
|
return terminal_putchar(va_arg(*ap, int));
|
|
case 's':
|
|
return terminal_writestring(va_arg(*ap, char *));
|
|
case 'p':
|
|
return print_int_base(va_arg(*ap, uint32_t), "0x", BASE_HEXA);
|
|
case 'x':
|
|
return print_int_base(va_arg(*ap, int32_t), "0x", BASE_HEXA);
|
|
case 'u':
|
|
return print_int_base(va_arg(*ap, uint32_t), NULL, BASE_DECA);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int kvprintf(const char *restrict format, va_list *ap)
|
|
{
|
|
const char *start = format;
|
|
int ret = 0;
|
|
|
|
const int level = get_level(format);
|
|
set_color_level(level);
|
|
if (level)
|
|
start++;
|
|
while (*start != '\0') {
|
|
if (*start == '%' && *(start + 1) != '\0') {
|
|
ret += print_flag(*(start + 1), ap);
|
|
start++;
|
|
} else {
|
|
ret += terminal_putchar(*start);
|
|
}
|
|
start++;
|
|
}
|
|
set_color_level(0);
|
|
update_cursor();
|
|
return ret;
|
|
}
|