From 03c6f3cf458c89df17b02557cd232f9cde73ed54 Mon Sep 17 00:00:00 2001 From: dzwdz Date: Sat, 6 Aug 2022 00:12:51 +0200 Subject: make snprintf shared; dynamic resolution support --- src/shared/printf.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) (limited to 'src/shared/printf.c') diff --git a/src/shared/printf.c b/src/shared/printf.c index c1206f3..2dc3048 100644 --- a/src/shared/printf.c +++ b/src/shared/printf.c @@ -1,6 +1,7 @@ -#include #include #include +#include +#include struct out_state { void (*back)(void *, const char *, size_t); @@ -165,3 +166,31 @@ int __printf_internal(const char *fmt, va_list argp, seg = fmt; } } + + +static void vsnprintf_backend(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, vsnprintf_backend, &ptrs); +} + +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; +} -- cgit v1.2.3