# HG changeset patch # User Mike Becker # Date 1767099055 -3600 # Node ID 1aa21afb87636369053a8503c0eeebcf364815bb # Parent 4a08dabe5e8fdd3797c9b3e52c77611e0991963a add full generic support for cx_strsplit() resolves #792 diff -r 4a08dabe5e8f -r 1aa21afb8763 docs/Writerside/topics/string.h.md --- a/docs/Writerside/topics/string.h.md Mon Dec 29 11:21:16 2025 +0100 +++ b/docs/Writerside/topics/string.h.md Tue Dec 30 13:50:55 2025 +0100 @@ -225,19 +225,12 @@ ```C #include -size_t cx_strsplit(cxstring string, AnyStr delim, - size_t limit, cxstring *output); +size_t cx_strsplit(UcxStr string, AnyStr delim, + size_t limit, UcxStr *output); size_t cx_strsplit_a(const CxAllocator *allocator, - cxstring string, AnyStr delim, - size_t limit, cxstring **output); - -size_t cx_strsplit_m(cxmutstr string, AnyStr delim, - size_t limit, cxmutstr *output); - -size_t cx_strsplit_ma(const CxAllocator *allocator, - cxmutstr string, AnyStr delim, - size_t limit, cxmutstr **output); + UcxStr string, AnyStr delim, + size_t limit, UcxStr **output); ``` The `cx_strsplit()` function splits the input `string` using the specified delimiter `delim` @@ -249,10 +242,10 @@ On the other hand, `cx_strsplit_a()` uses the specified `allocator` to allocate the output array, and writes the pointer to the allocated memory to `output`. -The functions `cx_strsplit_m()` and `cx_strsplit_ma()` are equivalent to `cx_strsplit()` and `cx_strsplit_a()`, -except that they work on `cxmustr` instead of `cxstring`. +> The type of the `UcxStr` must the same for `string` and `output` (i.e., either both `cxstring` or both `cxmutstr`). +> {style="note"} -> The `allocator` in `cx_strsplit_a()` and `cx_strsplit_ma()` is _only_ used to allocate the output array. +> The `allocator` in `cx_strsplit_a()` is _only_ used to allocate the output array. > The strings will always point into the original `string` > and you need to use `cx_strdup()` or `cx_strdup_a()` if you want copies or zero-terminated strings after performing the split. {style="note"} diff -r 4a08dabe5e8f -r 1aa21afb8763 src/cx/string.h --- a/src/cx/string.h Mon Dec 29 11:21:16 2025 +0100 +++ b/src/cx/string.h Tue Dec 30 13:50:55 2025 +0100 @@ -882,20 +882,46 @@ cxmutstr string, cxstring delim, size_t limit, cxmutstr **output); +#ifdef __cplusplus +CX_CPPDECL size_t cx_strsplit_cpp_(cxstring string, cxstring delim, + size_t limit, cxstring *output) { + return cx_strsplit_(string, delim, limit, output); +} +CX_CPPDECL size_t cx_strsplit_cpp_(cxmutstr string, cxstring delim, + size_t limit, cxmutstr *output) { + return cx_strsplit_m_(string, delim, limit, output); +} +CX_CPPDECL size_t cx_strsplit_a_cpp_(const CxAllocator *allocator, + cxstring string, cxstring delim, size_t limit, cxstring **output) { + return cx_strsplit_a_(allocator, string, delim, limit, output); +} +CX_CPPDECL size_t cx_strsplit_a_cpp_(const CxAllocator *allocator, + cxmutstr string, cxstring delim, size_t limit, cxmutstr **output) { + return cx_strsplit_ma_(allocator, string, delim, limit, output); +} +#define cx_strsplit(string, delim, limit, output) \ + cx_strsplit_cpp_(cx_strcast_m(string), cx_strcast(delim), limit, output) +#define cx_strsplit_a(allocator, string, delim, limit, output) \ + cx_strsplit_a_cpp_(allocator, cx_strcast_m(string), cx_strcast(delim), limit, output) +#else /** * Splits a given string using a delimiter string. * * @note The resulting array contains strings that point to the source * @p string. Use cx_strdup() to get copies. * - * @param string (@c cxstring) the string to split + * @param string the string to split * @param delim the delimiter * @param limit (@c size_t) the maximum number of split items - * @param output (@c cxstring*) a preallocated array of at least @p limit length + * @param output (@c cxstring* or @c cxmutstr*) a preallocated array of at + * least @p limit length * @return the actual number of split items */ #define cx_strsplit(string, delim, limit, output) \ - cx_strsplit_(string, cx_strcast(delim), limit, output) + _Generic(cx_strcast_m(string), \ + cxstring: cx_strsplit_, \ + cxmutstr: cx_strsplit_m_)\ + (cx_strcast_m(string), cx_strcast(delim), limit, output) /** * Splits a given string using a delimiter string. @@ -909,53 +935,19 @@ * @p output and the number returned will be zero. * * @param allocator (@c CxAllocator*) the allocator to use for allocating the resulting array - * @param string (@c cxstring) the string to split + * @param string the string to split * @param delim the delimiter * @param limit (@c size_t) the maximum number of split items - * @param output (@c cxstring**) a pointer where the address of the allocated - * array shall be written to + * @param output (@c cxstring** or @c cxmutstr**) a pointer where the address + * of the allocated array shall be written to * @return the actual number of split items */ #define cx_strsplit_a(allocator, string, delim, limit, output) \ - cx_strsplit_a_(allocator, string, cx_strcast(delim), limit, output) - - -/** - * Splits a given string using a delimiter string. - * - * @note The resulting array contains strings that point to the source - * @p string. Use cx_strdup() to get copies. - * - * @param string (@c cxmutstr) the string to split - * @param delim the delimiter - * @param limit (@c size_t) the maximum number of split items - * @param output (@c cxmutstr*) a preallocated array of at least @p limit length - * @return the actual number of split items - */ -#define cx_strsplit_m(string, delim, limit, output) \ - cx_strsplit_m_(string, cx_strcast(delim), limit, output) - -/** - * Splits a given string using a delimiter string. - * - * The array pointed to by @p output will be allocated by @p allocator. - * - * @note The resulting array contains strings that point to the source - * @p string. Use cx_strdup() to get copies. - * - * @attention If allocation fails, the @c NULL pointer will be written to - * @p output and the number returned will be zero. - * - * @param allocator (@c CxAllocator*) the allocator to use for allocating the resulting array - * @param string (@c cxmutstr) the string to split - * @param delim the delimiter - * @param limit (@c size_t) the maximum number of split items - * @param output (@c cxmutstr**) a pointer where the address of the allocated - * array shall be written to - * @return the actual number of split items - */ -#define cx_strsplit_ma(allocator, string, delim, limit, output) \ - cx_strsplit_ma_(allocator, string, cx_strcast(delim), limit, output) + _Generic(cx_strcast_m(string), \ + cxstring: cx_strsplit_a_, \ + cxmutstr: cx_strsplit_ma_)\ + (allocator, cx_strcast_m(string), cx_strcast(delim), limit, output) +#endif /** * Compares two strings. diff -r 4a08dabe5e8f -r 1aa21afb8763 tests/test_string.c --- a/tests/test_string.c Mon Dec 29 11:21:16 2025 +0100 +++ b/tests/test_string.c Tue Dec 30 13:50:55 2025 +0100 @@ -702,10 +702,10 @@ CX_TEST_ASSERT(0 == cx_strcmp(list[1], "")); CX_TEST_ASSERT(0 == cx_strcmp(list[2], "a,csv,string")); - // call the _m variant just for coverage + // test with a cxmutstr cxmutstr mtest = cx_strdup(test); cxmutstr mlist[4]; - n = cx_strsplit_m(mtest, "is,", 4, mlist); + n = cx_strsplit(mtest, "is,", 4, mlist); CX_TEST_ASSERT(n == 3); CX_TEST_ASSERT(0 == cx_strcmp(mlist[0], "th")); CX_TEST_ASSERT(0 == cx_strcmp(mlist[1], "")); @@ -818,10 +818,10 @@ CX_TEST_ASSERT(0 == cx_strcmp(list[2], "a,csv,string")); cxFree(alloc, list); - // call the _m variant just for coverage + // test with a cxmutstr cxmutstr mtest = cx_strdup(test); cxmutstr *mlist; - n = cx_strsplit_ma(alloc, mtest, "is,", 4, &mlist); + n = cx_strsplit_a(alloc, mtest, "is,", 4, &mlist); CX_TEST_ASSERT(n == 3); CX_TEST_ASSERT(0 == cx_strcmp(mlist[0], "th")); CX_TEST_ASSERT(0 == cx_strcmp(mlist[1], ""));