diff options
Diffstat (limited to 'src/init')
-rw-r--r-- | src/init/stdlib.c | 76 |
1 files changed, 3 insertions, 73 deletions
diff --git a/src/init/stdlib.c b/src/init/stdlib.c index 82410d6..e928d2c 100644 --- a/src/init/stdlib.c +++ b/src/init/stdlib.c @@ -1,6 +1,6 @@ #include <init/stdlib.h> +#include <shared/printf.h> #include <shared/syscalls.h> -#include <stdarg.h> int __stdin = -1; int __stdout = -1; @@ -9,82 +9,12 @@ static void backend_file(void *arg, const char *buf, size_t len) { _syscall_write(*(handle_t*)arg, buf, len, -1); } -static int __printf_internal(const char *fmt, va_list argp, - void (*back)(void*, const char*, size_t), void *back_arg) -{ - const char *seg = fmt; // beginning of the current segment - int total = 0; - - for (;;) { - char c = *fmt++; - switch (c) { - case '\0': - back(back_arg, seg, fmt - seg - 1); - return total + (fmt - seg - 1); - - case '%': - back(back_arg, seg, fmt - seg - 1); - total += fmt - seg - 1; - size_t pad_len = 0; - - c = *fmt++; - while (1) { - switch (c) { - case '0': - pad_len = *fmt++ - '0'; // can skip over the null byte, idc - break; - default: - goto modifier_break; - } - c = *fmt++; - } -modifier_break: - switch (c) { - case 'c': - char c = va_arg(argp, int); - back(back_arg, &c, 1); - total += 1; - break; - - case 's': - const char *s = va_arg(argp, char*); - if (s) { - back(back_arg, s, strlen(s)); - total += strlen(s); - } - break; - - case 'x': - unsigned int n = va_arg(argp, int); - size_t i = 4; // nibbles * 4 - while (n >> i && i < (sizeof(int) * 8)) - i += 4; - - if (i < pad_len * 4) - i = pad_len * 4; - - while (i > 0) { - i -= 4; - char h = '0' + ((n >> i) & 0xf); - if (h > '9') h += 'a' - '9' - 1; - back(back_arg, &h, 1); - total++; - } - break; - } - seg = fmt; - break; - } - } -} - int printf(const char *fmt, ...) { int ret = 0; va_list argp; va_start(argp, fmt); - if (__stdout < 0) goto end; - __printf_internal(fmt, argp, backend_file, (void*)&__stdout); -end: + if (__stdout >= 0) + ret = __printf_internal(fmt, argp, backend_file, (void*)&__stdout); va_end(argp); return ret; } |