Sat, 07 Dec 2024 23:59:54 +0100
change cx_strcat variants to allow handling of ENOMEM
CHANGELOG | file | annotate | diff | comparison | revisions | |
src/cx/string.h | file | annotate | diff | comparison | revisions | |
src/string.c | file | annotate | diff | comparison | revisions |
--- a/CHANGELOG Thu Dec 05 01:54:12 2024 +0100 +++ b/CHANGELOG Sat Dec 07 23:59:54 2024 +0100 @@ -16,6 +16,7 @@ * changes all functions, for which there is no dedicated xyz_a variant, to accept NULL as allocator argument (in which case a default allocator will be used) * changes the name of destroy functions that actually free the memory to better indicate their behavior + * change cx_strcat variants to allow handling of ENOMEM * moves cx_compare_func typedef to compare.h * moves cx_szmul() to common.h * moves stream copy functions to new streams.h
--- a/src/cx/string.h Thu Dec 05 01:54:12 2024 +0100 +++ b/src/cx/string.h Sat Dec 07 23:59:54 2024 +0100 @@ -313,7 +313,11 @@ * If \p str already contains a string, the memory will be reallocated and * the other strings are appended. Otherwise, new memory is allocated. * - * \note It is guaranteed that there is only one allocation. + * If memory allocation fails, the pointer in the returned string will + * be \c NULL. Depending on the allocator, \c errno might be set. + * + * \note It is guaranteed that there is only one allocation for the + * resulting string. * It is also guaranteed that the returned string is zero-terminated. * * @param alloc the allocator to use @@ -337,7 +341,11 @@ * The resulting string will be allocated by the specified allocator. * So developers \em must pass the return value to cx_strfree_a() eventually. * - * \note It is guaranteed that there is only one allocation. +* If memory allocation fails, the pointer in the returned string will + * be \c NULL. Depending on the allocator, \c errno might be set. + * + * \note It is guaranteed that there is only one allocation for the + * resulting string. * It is also guaranteed that the returned string is zero-terminated. * * @param alloc the allocator to use @@ -354,7 +362,11 @@ * The resulting string will be allocated by standard \c malloc(). * So developers \em must pass the return value to cx_strfree() eventually. * - * \note It is guaranteed that there is only one allocation. +* If memory allocation fails, the pointer in the returned string will + * be \c NULL and \c errno might be set. + * + * \note It is guaranteed that there is only one allocation for the + * resulting string. * It is also guaranteed that the returned string is zero-terminated. * * @param count the number of the other following strings to concatenate @@ -373,7 +385,11 @@ * If \p str already contains a string, the memory will be reallocated and * the other strings are appended. Otherwise, new memory is allocated. * - * \note It is guaranteed that there is only one allocation. +* If memory allocation fails, the pointer in the returned string will + * be \c NULL and \c errno might be set. + * + * \note It is guaranteed that there is only one allocation for the + * resulting string. * It is also guaranteed that the returned string is zero-terminated. * * @param str the string the other strings shall be concatenated to
--- a/src/string.c Thu Dec 05 01:54:12 2024 +0100 +++ b/src/string.c Sat Dec 07 23:59:54 2024 +0100 @@ -107,8 +107,16 @@ ) { if (count == 0) return str; - cxstring *strings = calloc(count, sizeof(cxstring)); - if (!strings) abort(); + cxstring strings_stack[8]; + cxstring *strings; + if (count > 8) { + strings = calloc(count, sizeof(cxstring)); + if (strings == NULL) { + return (cxmutstr) {NULL, 0}; + } + } else { + strings = strings_stack; + } va_list ap; va_start(ap, count); @@ -123,12 +131,17 @@ va_end(ap); // reallocate or create new string + char *newstr; if (str.ptr == NULL) { - str.ptr = cxMalloc(alloc, slen + 1); + newstr = cxMalloc(alloc, slen + 1); } else { - str.ptr = cxRealloc(alloc, str.ptr, slen + 1); + newstr = cxRealloc(alloc, str.ptr, slen + 1); } - if (str.ptr == NULL) abort(); + if (newstr == NULL) { + free(strings); + return (cxmutstr) {NULL, 0}; + } + str.ptr = newstr; // concatenate strings size_t pos = str.length; @@ -143,7 +156,9 @@ str.ptr[str.length] = '\0'; // free temporary array - free(strings); + if (strings != strings_stack) { + free(strings); + } return str; }