ucx/printf.c

branch
newapi
changeset 253
087cc9216f28
parent 174
0358f1d9c506
--- a/ucx/printf.c	Sun Feb 11 15:44:33 2024 +0100
+++ b/ucx/printf.c	Sun Feb 11 22:06:23 2024 +0100
@@ -34,6 +34,7 @@
 #ifndef CX_PRINTF_SBO_SIZE
 #define CX_PRINTF_SBO_SIZE 512
 #endif
+unsigned const cx_printf_sbo_size = CX_PRINTF_SBO_SIZE;
 
 int cx_fprintf(
         void *stream,
@@ -60,17 +61,21 @@
     va_copy(ap2, ap);
     int ret = vsnprintf(buf, CX_PRINTF_SBO_SIZE, fmt, ap);
     if (ret < 0) {
+        va_end(ap2);
         return ret;
     } else if (ret < CX_PRINTF_SBO_SIZE) {
+        va_end(ap2);
         return (int) wfc(buf, 1, ret, stream);
     } else {
         int len = ret + 1;
         char *newbuf = malloc(len);
         if (!newbuf) {
+            va_end(ap2);
             return -1;
         }
 
         ret = vsnprintf(newbuf, len, fmt, ap2);
+        va_end(ap2);
         if (ret > 0) {
             ret = (int) wfc(newbuf, 1, ret, stream);
         }
@@ -85,9 +90,8 @@
         ...
 ) {
     va_list ap;
-    cxmutstr ret;
     va_start(ap, fmt);
-    ret = cx_vasprintf_a(allocator, fmt, ap);
+    cxmutstr ret = cx_vasprintf_a(allocator, fmt, ap);
     va_end(ap);
     return ret;
 }
@@ -104,7 +108,7 @@
     va_list ap2;
     va_copy(ap2, ap);
     int ret = vsnprintf(buf, CX_PRINTF_SBO_SIZE, fmt, ap);
-    if (ret > 0 && ret < CX_PRINTF_SBO_SIZE) {
+    if (ret >= 0 && ret < CX_PRINTF_SBO_SIZE) {
         s.ptr = cxMalloc(a, ret + 1);
         if (s.ptr) {
             s.length = (size_t) ret;
@@ -124,6 +128,65 @@
             }
         }
     }
+    va_end(ap2);
     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 ((unsigned) ret >= len) {
+        unsigned newlen = ret + 1;
+        char *ptr = cxRealloc(alloc, *str, newlen);
+        if (ptr) {
+            int newret = vsnprintf(ptr, newlen, fmt, ap2);
+            if (newret < 0) {
+                cxFree(alloc, ptr);
+            } else {
+                *str = ptr;
+                ret = newret;
+            }
+        }
+    }
+    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 ((unsigned) ret >= len) {
+        unsigned newlen = ret + 1;
+        char *ptr = cxMalloc(alloc, newlen);
+        if (ptr) {
+            int newret = vsnprintf(ptr, newlen, fmt, ap2);
+            if (newret < 0) {
+                cxFree(alloc, ptr);
+            } else {
+                *str = ptr;
+                ret = newret;
+            }
+        }
+    }
+    va_end(ap2);
+    return ret;
+}

mercurial