diff -r 38800d479cd4 -r e86049631677 ucx/string.c --- a/ucx/string.c Tue Dec 30 21:39:38 2025 +0100 +++ b/ucx/string.c Wed Dec 31 16:41:16 2025 +0100 @@ -41,7 +41,12 @@ #include #ifdef _WIN32 -#define cx_strcasecmp_impl _strnicmp +static int cx_fixed_strnicmp(const char* s1, const char* s2, size_t count) { + // Microsoft's implementation crashes when count == 0 and either string is NULL + if (count == 0) return 0; + return _strnicmp(s1, s2, count); +} +#define cx_strcasecmp_impl cx_fixed_strnicmp #else #include #define cx_strcasecmp_impl strncasecmp @@ -64,7 +69,7 @@ str->length = 0; } -int cx_strcpy_a( +int cx_strcpy_a_( const CxAllocator *alloc, cxmutstr *dest, cxstring src @@ -99,13 +104,19 @@ return size; } -cxmutstr cx_strcat_ma( +cxmutstr cx_strcat_a( const CxAllocator *alloc, cxmutstr str, size_t count, ... ) { - if (count == 0) return str; + if (count == 0) { + if (cxReallocate(alloc, &str.ptr, str.length + 1)) { + return CX_NULLSTR; // LCOV_EXCL_LINE + } + str.ptr[str.length] = '\0'; + return str; + } va_list ap; va_start(ap, count); va_list ap2; @@ -125,21 +136,16 @@ if (overflow) { va_end(ap2); errno = EOVERFLOW; - return (cxmutstr) { NULL, 0 }; + return CX_NULLSTR; } - // reallocate or create new string - char *newstr; - if (str.ptr == NULL) { - newstr = cxMalloc(alloc, slen + 1); - } else { - newstr = cxRealloc(alloc, str.ptr, slen + 1); + // reallocate or create a new string + if (cxReallocate(alloc, &str.ptr, slen + 1)) { + // LCOV_EXCL_START + va_end(ap2); + return CX_NULLSTR; + // LCOV_EXCL_STOP } - if (newstr == NULL) { // LCOV_EXCL_START - va_end(ap2); - return (cxmutstr) {NULL, 0}; - } // LCOV_EXCL_STOP - str.ptr = newstr; // concatenate strings size_t pos = str.length; @@ -157,21 +163,14 @@ return str; } -cxstring cx_strsubs( +cxstring cx_strsubs_( cxstring string, size_t start ) { - return cx_strsubsl(string, start, string.length - start); + return cx_strsubsl_(string, start, string.length); } -cxmutstr cx_strsubs_m( - cxmutstr string, - size_t start -) { - return cx_strsubsl_m(string, start, string.length - start); -} - -cxstring cx_strsubsl( +cxstring cx_strsubsl_( cxstring string, size_t start, size_t length @@ -188,16 +187,7 @@ return (cxstring) {string.ptr + start, length}; } -cxmutstr cx_strsubsl_m( - cxmutstr string, - size_t start, - size_t length -) { - cxstring result = cx_strsubsl(cx_strcast(string), start, length); - return (cxmutstr) {(char *) result.ptr, result.length}; -} - -cxstring cx_strchr( +cxstring cx_strchr_( cxstring string, int chr ) { @@ -206,15 +196,7 @@ return (cxstring) {ret, string.length - (ret - string.ptr)}; } -cxmutstr cx_strchr_m( - cxmutstr string, - int chr -) { - cxstring result = cx_strchr(cx_strcast(string), chr); - return (cxmutstr) {(char *) result.ptr, result.length}; -} - -cxstring cx_strrchr( +cxstring cx_strrchr_( cxstring string, int chr ) { @@ -235,23 +217,12 @@ #endif } -cxmutstr cx_strrchr_m( - cxmutstr string, - int chr -) { - cxstring result = cx_strrchr(cx_strcast(string), chr); - return (cxmutstr) {(char *) result.ptr, result.length}; -} - #ifndef CX_STRSTR_SBO_SIZE #define CX_STRSTR_SBO_SIZE 128 #endif const unsigned cx_strstr_sbo_size = CX_STRSTR_SBO_SIZE; -cxstring cx_strstr( - cxstring haystack, - cxstring needle -) { +cxstring cx_strstr_(cxstring haystack, cxstring needle) { if (needle.length == 0) { return haystack; } @@ -321,15 +292,7 @@ return result; } -cxmutstr cx_strstr_m( - cxmutstr haystack, - cxstring needle -) { - cxstring result = cx_strstr(cx_strcast(haystack), needle); - return (cxmutstr) {(char *) result.ptr, result.length}; -} - -size_t cx_strsplit( +size_t cx_strsplit_( cxstring string, cxstring delim, size_t limit, @@ -387,7 +350,7 @@ return n; } -size_t cx_strsplit_a( +size_t cx_strsplit_a_( const CxAllocator *allocator, cxstring string, cxstring delim, @@ -416,27 +379,27 @@ } } *output = cxCalloc(allocator, n, sizeof(cxstring)); - return cx_strsplit(string, delim, n, *output); + return cx_strsplit_(string, delim, n, *output); } -size_t cx_strsplit_m( +size_t cx_strsplit_m_( cxmutstr string, cxstring delim, size_t limit, cxmutstr *output ) { - return cx_strsplit(cx_strcast(string), + return cx_strsplit_(cx_strcast(string), delim, limit, (cxstring *) output); } -size_t cx_strsplit_ma( +size_t cx_strsplit_ma_( const CxAllocator *allocator, cxmutstr string, cxstring delim, size_t limit, cxmutstr **output ) { - return cx_strsplit_a(allocator, cx_strcast(string), + return cx_strsplit_a_(allocator, cx_strcast(string), delim, limit, (cxstring **) output); } @@ -511,23 +474,18 @@ return result; } -cxstring cx_strtrim(cxstring string) { +cxstring cx_strtrim_(cxstring string) { cxstring result = string; - while (result.length > 0 && isspace((unsigned char)(result.ptr[0]))) { + while (isspace((unsigned char)cx_strat(result, 0))) { result.ptr++; result.length--; } - while (result.length > 0 && isspace((unsigned char)result.ptr[result.length - 1])) { + while (isspace((unsigned char)cx_strat(result, -1))) { result.length--; } return result; } -cxmutstr cx_strtrim_m(cxmutstr string) { - cxstring result = cx_strtrim(cx_strcast(string)); - return (cxmutstr) {(char *) result.ptr, result.length}; -} - bool cx_strprefix_( cxstring string, cxstring prefix @@ -571,7 +529,7 @@ #endif } -cxmutstr cx_strreplacen_a( +cxmutstr cx_strreplace_( const CxAllocator *allocator, cxstring str, cxstring search, @@ -652,7 +610,7 @@ return ctx; } -bool cx_strtok_next( +bool cx_strtok_next_( CxStrtokCtx *ctx, cxstring *token ) { @@ -695,13 +653,6 @@ return true; } -bool cx_strtok_next_m( - CxStrtokCtx *ctx, - cxmutstr *token -) { - return cx_strtok_next(ctx, (cxstring *) token); -} - void cx_strtok_delim( CxStrtokCtx *ctx, const cxstring *delim,