Mon, 29 Dec 2025 11:21:16 +0100
add full generic support for cx_strtrim()
relates to #792
| src/cx/string.h | file | annotate | diff | comparison | revisions | |
| src/string.c | file | annotate | diff | comparison | revisions | |
| tests/test_string.c | file | annotate | diff | comparison | revisions |
--- a/src/cx/string.h Mon Dec 29 10:45:55 2025 +0100 +++ b/src/cx/string.h Mon Dec 29 11:21:16 2025 +0100 @@ -354,8 +354,8 @@ * @return (@c cxstring) or (@c cxmutstr) the string wrapped as UCX string */ #define cx_strcast_m(str) _Generic((str), \ + cxstring: cx_strcast_cxs, \ cxmutstr: cx_strcast_cxms, \ - cxstring: cx_strcast_cxs, \ const unsigned char*: cx_strcast_ucc, \ unsigned char *: cx_strcast_uc, \ const char*: cx_strcast_cc, \ @@ -696,20 +696,20 @@ cxstring cx_strrchr_(cxstring string, int chr); #ifdef __cplusplus -CX_CPPDECL cxstring cx_strchr_cpp(cxstring string, int chr) { +CX_CPPDECL cxstring cx_strchr_cpp_(cxstring string, int chr) { return cx_strchr_(string, chr); } -CX_CPPDECL cxmutstr cx_strchr_cpp(cxmutstr string, int chr) { +CX_CPPDECL cxmutstr cx_strchr_cpp_(cxmutstr string, int chr) { return cx_mutstrcast(cx_strchr_(cx_strcast(string), chr)); } -#define cx_strchr(s, chr) cx_strchr_cpp(cx_strcast_m(s), chr) -CX_CPPDECL cxstring cx_strrchr_cpp(cxstring string, int chr) { +#define cx_strchr(s, chr) cx_strchr_cpp_(cx_strcast_m(s), chr) +CX_CPPDECL cxstring cx_strrchr_cpp_(cxstring string, int chr) { return cx_strrchr_(string, chr); } -CX_CPPDECL cxmutstr cx_strrchr_cpp(cxmutstr string, int chr) { +CX_CPPDECL cxmutstr cx_strrchr_cpp_(cxmutstr string, int chr) { return cx_mutstrcast(cx_strrchr_(cx_strcast(string), chr)); } -#define cx_strrchr(s, chr) cx_strrchr_cpp(cx_strcast_m(s), chr) +#define cx_strrchr(s, chr) cx_strrchr_cpp_(cx_strcast_m(s), chr) #else /** * Internal conversion function - do not use. @@ -776,13 +776,13 @@ cxstring cx_strstr_(cxstring haystack, cxstring needle); #ifdef __cplusplus -CX_CPPDECL cxstring cx_strstr_cpp(cxstring haystack, cxstring needle) { +CX_CPPDECL cxstring cx_strstr_cpp_(cxstring haystack, cxstring needle) { return cx_strstr_(haystack, needle); } -CX_CPPDECL cxmutstr cx_strstr_cpp(cxmutstr haystack, cxstring needle) { +CX_CPPDECL cxmutstr cx_strstr_cpp_(cxmutstr haystack, cxstring needle) { return cx_mutstrcast(cx_strstr_(cx_strcast(haystack), needle)); } -#define cx_strstr(h,n) cx_strstr_cpp(cx_strcast_m(h), cx_strcast(n)) +#define cx_strstr(h,n) cx_strstr_cpp_(cx_strcast_m(h), cx_strcast(n)) #else /** * Internal conversion - do not use. @@ -1074,16 +1074,31 @@ #define cx_strdup(string) cx_strdup_a(cxDefaultAllocator, string) /** - * Omits leading and trailing spaces. - * - * @note the returned string references the same memory, thus you - * must @em not free the returned memory. - * - * @param string the string that shall be trimmed - * @return the trimmed string + * Trims a string. + * Internal function - do not use. + * @param string + * @return */ CX_EXTERN CX_NODISCARD -cxstring cx_strtrim(cxstring string); +cxstring cx_strtrim_(cxstring string); + +#ifdef __cplusplus +CX_CPPDECL cxstring cx_strtrim_cpp_(cxstring string) { + return cx_strtrim_(string); +} +CX_CPPDECL cxmutstr cx_strtrim_cpp_(cxmutstr string) { + return cx_mutstrcast(cx_strtrim_(cx_strcast(string))); +} +#define cx_strtrim(string) cx_strtrim_cpp_(cx_strcast_m(string)) +#else +/** + * Internal conversion function. + * @param string + * @return + */ +CX_INLINE cxmutstr cx_strtrim_m_(cxmutstr string) { + return cx_mutstrcast(cx_strtrim_(cx_strcast(string))); +} /** * Omits leading and trailing spaces. @@ -1092,10 +1107,12 @@ * must @em not free the returned memory. * * @param string the string that shall be trimmed - * @return the trimmed string + * @return (@c cxstring or @c cxmutstr) the trimmed string */ -CX_EXTERN CX_NODISCARD -cxmutstr cx_strtrim_m(cxmutstr string); +#define cx_strtrim(string) _Generic(cx_strcast_m(string), \ + cxstring: cx_strtrim_, \ + cxmutstr: cx_strtrim_m_)(cx_strcast_m(string)) +#endif /** * Checks if a string has a specific prefix.
--- a/src/string.c Mon Dec 29 10:45:55 2025 +0100 +++ b/src/string.c Mon Dec 29 11:21:16 2025 +0100 @@ -465,7 +465,7 @@ return result; } -cxstring cx_strtrim(cxstring string) { +cxstring cx_strtrim_(cxstring string) { cxstring result = string; while (isspace((unsigned char)cx_strat(result, 0))) { result.ptr++; @@ -477,11 +477,6 @@ 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
--- a/tests/test_string.c Mon Dec 29 10:45:55 2025 +0100 +++ b/tests/test_string.c Mon Dec 29 11:21:16 2025 +0100 @@ -835,24 +835,21 @@ } CX_TEST(test_strtrim) { - cxstring t1 = cx_strtrim(cx_str(" ein test \t ")); + const char *t = " ein test \t "; + cxstring t1 = cx_strtrim(t); cxstring t2 = cx_strtrim(cx_str("abc")); - cxstring t3 = cx_strtrim(cx_str(" 123")); - cxstring t4 = cx_strtrim(cx_str("xyz ")); + cxmutstr t3 = cx_strtrim(cx_mutstr((char*)" 123")); + cxmutstr t4 = cx_strtrim((char*)"xyz "); cxstring t5 = cx_strtrim(cx_str(" ")); cxstring empty = cx_strtrim(cx_str("")); CX_TEST_DO { - CX_TEST_ASSERT(0 == cx_strcmp(t1, cx_str("ein test"))); - CX_TEST_ASSERT(0 == cx_strcmp(t2, cx_str("abc"))); - CX_TEST_ASSERT(0 == cx_strcmp(t3, cx_str("123"))); - CX_TEST_ASSERT(0 == cx_strcmp(t4, cx_str("xyz"))); - CX_TEST_ASSERT(0 == cx_strcmp(t5, cx_str(""))); - CX_TEST_ASSERT(0 == cx_strcmp(empty, cx_str(""))); - - // call the _m variant just for coverage - cxmutstr m1 = cx_strtrim_m(cx_mutstr((char *) " ein test \t ")); - CX_TEST_ASSERT(0 == cx_strcmp(m1, "ein test")); + CX_TEST_ASSERT(0 == cx_strcmp(t1, "ein test")); + CX_TEST_ASSERT(0 == cx_strcmp(t2, "abc")); + CX_TEST_ASSERT(0 == cx_strcmp(t3, "123")); + CX_TEST_ASSERT(0 == cx_strcmp(t4, "xyz")); + CX_TEST_ASSERT(0 == cx_strcmp(t5, "")); + CX_TEST_ASSERT(0 == cx_strcmp(empty, "")); } }