#include "base.h" #include "ctype.h" #include "terminal.h" #include #include 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; }