diff options
author | dzwdz | 2022-07-29 21:33:15 +0200 |
---|---|---|
committer | dzwdz | 2022-07-29 21:33:15 +0200 |
commit | 99da70deba62de235454ef1852745610a9c9f741 (patch) | |
tree | d4d1297bd3f1df579362603d40a0f7c57ff15c3b /src/user/lib/printf.c | |
parent | df7e4aeeed27c35994bc12614d5ffcb82ec6497b (diff) |
user/libc: properly implement snprintf; the v*printf family
Diffstat (limited to 'src/user/lib/printf.c')
-rw-r--r-- | src/user/lib/printf.c | 59 |
1 files changed, 41 insertions, 18 deletions
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; } |