1.1 --- a/src/string.c Sat Apr 22 12:29:00 2023 +0200 1.2 +++ b/src/string.c Sat Apr 22 13:06:18 2023 +0200 1.3 @@ -98,11 +98,14 @@ 1.4 return size; 1.5 } 1.6 1.7 -cxmutstr cx_strcat_a( 1.8 +cxmutstr cx_strcat_ma( 1.9 CxAllocator const *alloc, 1.10 + cxmutstr str, 1.11 size_t count, 1.12 ... 1.13 ) { 1.14 + if (count == 0) return str; 1.15 + 1.16 cxstring *strings = calloc(count, sizeof(cxstring)); 1.17 if (!strings) abort(); 1.18 1.19 @@ -110,34 +113,38 @@ 1.20 va_start(ap, count); 1.21 1.22 // get all args and overall length 1.23 - size_t slen = 0; 1.24 + size_t slen = str.length; 1.25 cx_for_n(i, count) { 1.26 cxstring s = va_arg (ap, cxstring); 1.27 strings[i] = s; 1.28 slen += s.length; 1.29 } 1.30 + va_end(ap); 1.31 1.32 - // create new string 1.33 - cxmutstr result; 1.34 - result.ptr = cxMalloc(alloc, slen + 1); 1.35 - result.length = slen; 1.36 - if (result.ptr == NULL) abort(); 1.37 + // reallocate or create new string 1.38 + if (str.ptr == NULL) { 1.39 + str.ptr = cxMalloc(alloc, slen + 1); 1.40 + } else { 1.41 + str.ptr = cxRealloc(alloc, str.ptr, slen + 1); 1.42 + } 1.43 + if (str.ptr == NULL) abort(); 1.44 1.45 // concatenate strings 1.46 - size_t pos = 0; 1.47 + size_t pos = str.length; 1.48 + str.length = slen; 1.49 cx_for_n(i, count) { 1.50 cxstring s = strings[i]; 1.51 - memcpy(result.ptr + pos, s.ptr, s.length); 1.52 + memcpy(str.ptr + pos, s.ptr, s.length); 1.53 pos += s.length; 1.54 } 1.55 1.56 // terminate string 1.57 - result.ptr[result.length] = '\0'; 1.58 + str.ptr[str.length] = '\0'; 1.59 1.60 // free temporary array 1.61 free(strings); 1.62 1.63 - return result; 1.64 + return str; 1.65 } 1.66 1.67 cxstring cx_strsubs(