add full generic support for cx_strtrim() default tip

Mon, 29 Dec 2025 11:21:16 +0100

author
Mike Becker <universe@uap-core.de>
date
Mon, 29 Dec 2025 11:21:16 +0100
changeset 1679
4a08dabe5e8f
parent 1678
6cf10bb137c5

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, ""));
     }
 }
 

mercurial