add support for any string to all cx_strreplace() variants

Mon, 22 Dec 2025 15:28:07 +0100

author
Mike Becker <universe@uap-core.de>
date
Mon, 22 Dec 2025 15:28:07 +0100
changeset 1651
38b051dea6b1
parent 1650
aa8621b58cd7
child 1652
db8299984bfe

add support for any string to all cx_strreplace() variants

relates to #789

docs/Writerside/topics/string.h.md file | annotate | diff | comparison | revisions
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/docs/Writerside/topics/string.h.md	Mon Dec 22 00:20:41 2025 +0100
+++ b/docs/Writerside/topics/string.h.md	Mon Dec 22 15:28:07 2025 +0100
@@ -196,17 +196,17 @@
 ```C
 #include <cx/string.h>
 
-cxmutstr cx_strreplace(cxstring str,
-        cxstring search, cxstring replacement);
+cxmutstr cx_strreplace(AnyStr str,
+        AnyStr search, AnyStr replacement);
 
-cxmutstr cx_strreplace_a(const CxAllocator *allocator, cxstring str,
-        cxstring search, cxstring replacement);
+cxmutstr cx_strreplace_a(const CxAllocator *allocator, AnyStr str,
+        AnyStr search, AnyStr replacement);
 
-cxmutstr cx_strreplacen(cxstring str,
-        cxstring search, cxstring replacement, size_t replmax);
+cxmutstr cx_strreplacen(AnyStr str,
+        AnyStr search, AnyStr replacement, size_t replmax);
 
-cxmutstr cx_strreplacen_a(const CxAllocator *allocator, cxstring str,
-        cxstring search, cxstring replacement, size_t replmax);
+cxmutstr cx_strreplacen_a(const CxAllocator *allocator, AnyStr str,
+        AnyStr search, AnyStr replacement, size_t replmax);
 ```
 
 The function `cx_strreplace()` allocates a new string which will contain a copy of `str`
--- a/src/cx/string.h	Mon Dec 22 00:20:41 2025 +0100
+++ b/src/cx/string.h	Mon Dec 22 15:28:07 2025 +0100
@@ -1006,6 +1006,27 @@
  */
 #define cx_strcasesuffix(string, suffix) cx_strcasesuffix_(cx_strcast(string), cx_strcast(suffix))
 
+
+/**
+ * Replaces a string with another string.
+ *
+ * Internal function - do not use.
+ *
+ * @param allocator
+ * @param str
+ * @param search
+ * @param replacement
+ * @param replmax
+ * @return
+ * @see cx_strreplace_a()
+ * @see cx_strreplace()
+ * @see cx_strreplacen_a()
+ * @see cx_strreplacen()
+ */
+cx_attr_nodiscard cx_attr_nonnull
+CX_EXPORT cxmutstr cx_strreplace_(const CxAllocator *allocator,
+        cxstring str, cxstring search, cxstring replacement, size_t replmax);
+
 /**
  * Replaces a string with another string.
  *
@@ -1017,16 +1038,15 @@
  * If allocation fails, or the input string is empty,
  * the returned string will be empty.
  *
- * @param allocator the allocator to use
+ * @param allocator (@c CxAllocator*) the allocator to use
  * @param str the string where replacements should be applied
  * @param search the string to search for
  * @param replacement the replacement string
- * @param replmax maximum number of replacements
- * @return the resulting string after applying the replacements
+ * @param replmax (@c size_t) maximum number of replacements
+ * @return (@c cxmutstr) the resulting string after applying the replacements
  */
-cx_attr_nodiscard cx_attr_nonnull
-CX_EXPORT cxmutstr cx_strreplacen_a(const CxAllocator *allocator,
-        cxstring str, cxstring search, cxstring replacement, size_t replmax);
+#define cx_strreplacen_a(allocator, str, search, replacement, replmax) \
+        cx_strreplace_(allocator, cx_strcast(str), cx_strcast(search), cx_strcast(replacement), replmax)
 
 /**
  * Replaces a string with another string.
@@ -1039,9 +1059,9 @@
  * If allocation fails, or the input string is empty,
  * the returned string will be empty.
  *
- * @param str (@c cxstring) the string where replacements should be applied
- * @param search (@c cxstring) the string to search for
- * @param replacement (@c cxstring) the replacement string
+ * @param str the string where replacements should be applied
+ * @param search the string to search for
+ * @param replacement the replacement string
  * @param replmax (@c size_t) maximum number of replacements
  * @return (@c cxmutstr) the resulting string after applying the replacements
  */
@@ -1058,9 +1078,9 @@
  * the returned string will be empty.
  *
  * @param allocator (@c CxAllocator*) the allocator to use
- * @param str (@c cxstring) the string where replacements should be applied
- * @param search (@c cxstring) the string to search for
- * @param replacement (@c cxstring) the replacement string
+ * @param str the string where replacements should be applied
+ * @param search the string to search for
+ * @param replacement the replacement string
  * @return (@c cxmutstr) the resulting string after applying the replacements
  */
 #define cx_strreplace_a(allocator, str, search, replacement) \
@@ -1075,9 +1095,9 @@
  * If allocation fails, or the input string is empty,
  * the returned string will be empty.
  *
- * @param str (@c cxstring) the string where replacements should be applied
- * @param search (@c cxstring) the string to search for
- * @param replacement (@c cxstring) the replacement string
+ * @param str the string where replacements should be applied
+ * @param search the string to search for
+ * @param replacement the replacement string
  * @return (@c cxmutstr) the resulting string after applying the replacements
  */
 #define cx_strreplace(str, search, replacement) \
--- a/src/string.c	Mon Dec 22 00:20:41 2025 +0100
+++ b/src/string.c	Mon Dec 22 15:28:07 2025 +0100
@@ -568,7 +568,7 @@
 #endif
 }
 
-cxmutstr cx_strreplacen_a(
+cxmutstr cx_strreplace_(
         const CxAllocator *allocator,
         cxstring str,
         cxstring search,
--- a/tests/test_string.c	Mon Dec 22 00:20:41 2025 +0100
+++ b/tests/test_string.c	Mon Dec 22 15:28:07 2025 +0100
@@ -740,57 +740,53 @@
     CxAllocator *alloc = &talloc.base;
 
     cxstring str = cx_str("test ababab string aba");
-    cxstring longstr = cx_str(
-            "xyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacd");
-    cxstring notrail = cx_str("test abab");
-    cxstring empty = cx_str("");
     cxstring astr = cx_str("aaaaaaaaaa");
     cxstring csstr = cx_str("test AB ab TEST xyz");
 
-    cxmutstr repl = cx_strreplace(str, cx_str("abab"), cx_str("muchlonger"));
+    cxmutstr repl = cx_strreplace(str, "abab", "muchlonger");
     const char *expected = "test muchlongerab string aba";
 
-    cxmutstr repln = cx_strreplacen(str, cx_str("ab"), cx_str("c"), 2);
+    cxmutstr repln = cx_strreplacen(str, "ab", "c", 2);
     const char *expectedn = "test ccab string aba";
 
-    cxmutstr longrepl = cx_strreplace(longstr, cx_str("a"), cx_str("z"));
+    cxmutstr longrepl = cx_strreplace("xyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacd", "a", "z");
     const char *longexpect = "xyzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzcd";
 
-    cxmutstr replnotrail = cx_strreplace(notrail, cx_str("ab"), cx_str("z"));
+    cxmutstr replnotrail = cx_strreplace("test abab", "ab", "z");
     const char *notrailexpect = "test zz";
 
-    cxmutstr repleq = cx_strreplace(str, str, cx_str("hello"));
+    cxmutstr repleq = cx_strreplace(str, str, "hello");
     const char *eqexpect = "hello";
 
-    cxmutstr replempty1 = cx_strreplace(empty, cx_str("ab"), cx_str("c")); // expect: empty
-    cxmutstr replempty2 = cx_strreplace(str, cx_str("abab"), empty);
+    cxmutstr replempty1 = cx_strreplace("", "ab", "c"); // expect: empty
+    cxmutstr replempty2 = cx_strreplace(str, "abab", "");
     const char *emptyexpect2 = "test ab string aba";
 
-    cxmutstr replpre = cx_strreplace(str, cx_str("test "), cx_str("TEST "));
+    cxmutstr replpre = cx_strreplace(str, "test ", "TEST ");
     const char *preexpected = "TEST ababab string aba";
 
-    cxmutstr replan1 = cx_strreplacen(astr, cx_str("a"), cx_str("x"), 1);
+    cxmutstr replan1 = cx_strreplacen(astr, "a", "x", 1);
     const char *an1expected = "xaaaaaaaaa";
 
-    cxmutstr replan4 = cx_strreplacen(astr, cx_str("a"), cx_str("x"), 4);
+    cxmutstr replan4 = cx_strreplacen(astr, "a", "x", 4);
     const char *an4expected = "xxxxaaaaaa";
 
-    cxmutstr replan9 = cx_strreplacen(astr, cx_str("a"), cx_str("x"), 9);
+    cxmutstr replan9 = cx_strreplacen(astr, "a", "x", 9);
     const char *an9expected = "xxxxxxxxxa";
 
-    cxmutstr replan10 = cx_strreplacen(astr, cx_str("a"), cx_str("x"), 10);
+    cxmutstr replan10 = cx_strreplacen(astr, "a", "x", 10);
     const char *an10expected = "xxxxxxxxxx";
 
-    cxmutstr norepl = cx_strreplace(cx_strn("hello world", 11), cx_str("worlds"), cx_str("test"));
+    cxmutstr norepl = cx_strreplace(cx_strn("hello worlds", 11), "worlds", "test");
     const char *noreplexpect = "hello world";
 
+    cxmutstr repl1_a = cx_strreplace_a(alloc, csstr, "AB", "*");
+    const char *expeced1_a = "test * ab TEST xyz";
+
+    cxmutstr repl2_a = cx_strreplace_a(alloc, csstr, "test", "TEST");
+    const char *expected2_a = "TEST AB ab TEST xyz";
+
     CX_TEST_DO {
-        cxmutstr repl1_a = cx_strreplace_a(alloc, csstr, cx_str("AB"), cx_str("*"));
-        const char *expeced1_a = "test * ab TEST xyz";
-
-        cxmutstr repl2_a = cx_strreplace_a(alloc, csstr, cx_str("test"), cx_str("TEST"));
-        const char *expected2_a = "TEST AB ab TEST xyz";
-
         CX_TEST_ASSERT(repl.ptr != str.ptr);
         ASSERT_ZERO_TERMINATED(repl);
         CX_TEST_ASSERT(0 == strcmp(repl.ptr, expected));

mercurial