diff -r b7e2e1d7ed22 -r 85859399a0cc src/printf.c --- a/src/printf.c Tue Jan 16 23:12:43 2024 +0100 +++ b/src/printf.c Tue Jan 16 23:13:01 2024 +0100 @@ -127,3 +127,73 @@ return s; } +int cx_sprintf_a(CxAllocator *alloc, char **str, size_t len, const char *fmt, ... ) { + va_list ap; + va_start(ap, fmt); + int ret = cx_vsprintf_a(alloc, str, len, fmt, ap); + va_end(ap); + return ret; +} + +int cx_vsprintf_a(CxAllocator *alloc, char **str, size_t len, const char *fmt, va_list ap) { + va_list ap2; + va_copy(ap2, ap); + int ret = vsnprintf(*str, len, fmt, ap); + if (ret < 0 || ((unsigned)ret) < len) { + va_end(ap2); + return ret; + } else { + unsigned newlen = ret + 1; + char *ptr = cxRealloc(alloc, *str, newlen); + if (ptr) { + int newret = vsnprintf(ptr, newlen, fmt, ap2); + va_end(ap2); + if (newret < 0) { + cxFree(alloc, ptr); + return ret; + } else { + *str = ptr; + return newret; + } + } else { + va_end(ap2); + return ret; + } + } +} + +int cx_sprintf_sa(CxAllocator *alloc, char *buf, size_t len, char **str, const char *fmt, ... ) { + va_list ap; + va_start(ap, fmt); + int ret = cx_vsprintf_sa(alloc, buf, len, str, fmt, ap); + va_end(ap); + return ret; +} + +int cx_vsprintf_sa(CxAllocator *alloc, char *buf, size_t len, char **str, const char *fmt, va_list ap) { + va_list ap2; + va_copy(ap2, ap); + int ret = vsnprintf(buf, len, fmt, ap); + *str = buf; + if (ret < 0 || ((unsigned)ret) < len) { + va_end(ap2); + return ret; + } else { + unsigned newlen = ret + 1; + char *ptr = cxMalloc(alloc, newlen); + if (ptr) { + int newret = vsnprintf(ptr, newlen, fmt, ap2); + va_end(ap2); + if (newret < 0) { + cxFree(alloc, ptr); + return ret; + } else { + *str = ptr; + return newret; + } + } else { + va_end(ap2); + return ret; + } + } +}