src/string.c

changeset 1137
61939929030a
parent 1136
d9ff0f091f28
--- a/src/string.c	Mon Jan 20 22:43:46 2025 +0100
+++ b/src/string.c	Mon Jan 20 22:50:24 2025 +0100
@@ -620,6 +620,8 @@
 };
 
 static void cx_strrepl_free_ibuf(struct cx_strreplace_ibuf *buf) {
+    // remember, the first data is on the stack!
+    buf = buf->next;
     while (buf) {
         struct cx_strreplace_ibuf *next = buf->next;
         free(buf->buf);
@@ -646,15 +648,12 @@
         ibuflen = CX_STRREPLACE_INDEX_BUFFER_SIZE;
     }
 
-    // Allocate first index buffer
-    struct cx_strreplace_ibuf *firstbuf, *curbuf;
-    firstbuf = curbuf = calloc(1, sizeof(struct cx_strreplace_ibuf));
-    if (!firstbuf) return cx_mutstrn(NULL, 0);
-    firstbuf->buf = calloc(ibuflen, sizeof(size_t));
-    if (!firstbuf->buf) {
-        free(firstbuf);
-        return cx_mutstrn(NULL, 0);
-    }
+    // First index buffer can be on the stack
+    struct cx_strreplace_ibuf ibuf, *curbuf = &ibuf;
+    size_t ibuf_sbo[CX_STRREPLACE_INDEX_BUFFER_SIZE];
+    ibuf.buf = ibuf_sbo;
+    ibuf.next = NULL;
+    ibuf.len = 0;
 
     // Search occurrences
     cxstring searchstr = str;
@@ -667,13 +666,13 @@
                 struct cx_strreplace_ibuf *nextbuf =
                         calloc(1, sizeof(struct cx_strreplace_ibuf));
                 if (!nextbuf) {
-                    cx_strrepl_free_ibuf(firstbuf);
+                    cx_strrepl_free_ibuf(&ibuf);
                     return cx_mutstrn(NULL, 0);
                 }
                 nextbuf->buf = calloc(ibuflen, sizeof(size_t));
                 if (!nextbuf->buf) {
                     free(nextbuf);
-                    cx_strrepl_free_ibuf(firstbuf);
+                    cx_strrepl_free_ibuf(&ibuf);
                     return cx_mutstrn(NULL, 0);
                 }
                 curbuf->next = nextbuf;
@@ -696,7 +695,7 @@
     {
         ssize_t adjlen = (ssize_t) replacement.length - (ssize_t) pattern.length;
         size_t rcount = 0;
-        curbuf = firstbuf;
+        curbuf = &ibuf;
         do {
             rcount += curbuf->len;
             curbuf = curbuf->next;
@@ -704,13 +703,13 @@
         result.length = str.length + rcount * adjlen;
         result.ptr = cxMalloc(allocator, result.length + 1);
         if (!result.ptr) {
-            cx_strrepl_free_ibuf(firstbuf);
+            cx_strrepl_free_ibuf(&ibuf);
             return cx_mutstrn(NULL, 0);
         }
     }
 
     // Build result string
-    curbuf = firstbuf;
+    curbuf = &ibuf;
     size_t srcidx = 0;
     char *destptr = result.ptr;
     do {
@@ -737,7 +736,7 @@
     result.ptr[result.length] = '\0';
 
     // Free index buffer
-    cx_strrepl_free_ibuf(firstbuf);
+    cx_strrepl_free_ibuf(&ibuf);
 
     return result;
 }

mercurial