From 99da70deba62de235454ef1852745610a9c9f741 Mon Sep 17 00:00:00 2001 From: dzwdz Date: Fri, 29 Jul 2022 21:33:15 +0200 Subject: user/libc: properly implement snprintf; the v*printf family --- src/user/lib/printf.c | 59 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 18 deletions(-) (limited to 'src/user/lib/printf.c') diff --git a/src/user/lib/printf.c b/src/user/lib/printf.c index 443c424..53b1140 100644 --- a/src/user/lib/printf.c +++ b/src/user/lib/printf.c @@ -5,47 +5,70 @@ static void backend_file(void *arg, const char *buf, size_t len) { - fwrite(buf, 1, len, (FILE *)arg); + fwrite(buf, 1, len, arg); } -int printf(const char *fmt, ...) { - int ret = 0; - va_list argp; - va_start(argp, fmt); - ret = __printf_internal(fmt, argp, backend_file, (void*)stdout); - va_end(argp); - return ret; +int vfprintf(FILE *restrict f, const char *restrict fmt, va_list ap) { + return __printf_internal(fmt, ap, backend_file, f); } static void backend_buf(void *arg, const char *buf, size_t len) { char **ptrs = arg; size_t space = ptrs[1] - ptrs[0]; if (len > space) len = space; + memcpy(ptrs[0], buf, len); ptrs[0] += len; + /* ptrs[1] is the last byte of the buffer, it must be 0. + * on overflow: + * ptrs[0] + (ptrs[1] - ptrs[0]) = ptrs[1] */ + *ptrs[0] = '\0'; +} + +int vsnprintf(char *restrict str, size_t len, const char *restrict fmt, va_list ap) { + char *ptrs[2] = {str, str + len - 1}; + return __printf_internal(fmt, ap, backend_buf, &ptrs); +} + + +int printf(const char *restrict fmt, ...) { + int ret; + va_list argp; + va_start(argp, fmt); + ret = vprintf(fmt, argp); + va_end(argp); + return ret; } -int snprintf(char *str, size_t len, const char *fmt, ...) { - int ret = 0; - char *ptrs[2] = {str, str + len}; +int fprintf(FILE *restrict f, const char *restrict fmt, ...) { + int ret; va_list argp; va_start(argp, fmt); - ret = __printf_internal(fmt, argp, backend_buf, &ptrs); + ret = vfprintf(f, fmt, argp); va_end(argp); - if (ptrs[0] < ptrs[1]) *ptrs[0] = '\0'; return ret; } +int snprintf(char *restrict str, size_t len, const char *restrict fmt, ...) { + int ret; + va_list argp; + va_start(argp, fmt); + ret = vsnprintf(str, len, fmt, argp); + va_end(argp); + return ret; +} + +int vprintf(const char *restrict fmt, va_list ap) { + return vfprintf(stdout, fmt, ap); +} + int _klogf(const char *fmt, ...) { - // idiotic. however, this hack won't matter anyways char buf[256]; - int ret = 0; - char *ptrs[2] = {buf, buf + sizeof buf}; + int ret; va_list argp; va_start(argp, fmt); - ret = __printf_internal(fmt, argp, backend_buf, &ptrs); + ret = vsnprintf(buf, sizeof buf, fmt, argp); va_end(argp); - if (ptrs[0] < ptrs[1]) *ptrs[0] = '\0'; _syscall_debug_klog(buf, ret); return ret; } -- cgit v1.2.3