// // Created by rick on 06-02-21. // #include "kprintf.h" #include "libc.h" #include #include #include #include #include /* * Integer to string */ void print_int(u32 value, u32 width, char *buf, u32 *ptr, u8 base) { // u32 in binary is 32 digits, so never longer than 33 digits char msg[33]; itoa(value, msg, base); u32 digits = strlen(msg); if (digits < width) { for (u32 i = 0; i < (width - digits); ++i) { buf[*ptr] = '0'; *ptr += 1; } } for (u32 i = 0; i < digits; ++i) { buf[*ptr] = msg[i]; *ptr += 1; } } u32 vasprintf(char *buf, const char *fmt, va_list args) { u32 ptr = 0; for (int i = 0; i < strlen(fmt); ++i) { if (fmt[i] != '%') { buf[ptr++] = fmt[i]; continue; } ++i; u32 arg_width = 0; while (fmt[i] >= '0' && fmt[i] <= '9') { arg_width *= 10; arg_width += fmt[i] - '0'; ++i; } switch (fmt[i]) { case 's': { // string char *s_fmt = (char *) va_arg(args, char*); while (*s_fmt) { buf[ptr++] = *s_fmt++; } break; } case 'c': buf[ptr++] = (char) va_arg(args, int); break; case 'x': print_int((u32) va_arg(args, u32), arg_width, buf, &ptr, 16); break; case 'd': print_int((u32) va_arg(args, u32), arg_width, buf, &ptr, 10); break; case '%': buf[ptr++] = '%'; break; default: printf("FMT '%c' is not supported\n", fmt[i]); k_panic(); break; } } buf[ptr] = 0; return ptr; } int printf(const char *fmt, ...) { int result; char buf[1024] = {-1}; va_list args; va_start(args, fmt); result = vasprintf(buf, fmt, args); va_end(args); kprint(buf); return result; } int sprintf(char *target, const char *fmt, ...) { int result; va_list args; va_start(args, fmt); result = vasprintf(target, fmt, args); va_end(args); return result; }