use memrchr() to implement cx_strrchr() when it is available default tip

Thu, 02 Oct 2025 17:58:43 +0200

author
Mike Becker <universe@uap-core.de>
date
Thu, 02 Oct 2025 17:58:43 +0200
changeset 1412
a6f357c18ac6
parent 1411
838796848e12

use memrchr() to implement cx_strrchr() when it is available

src/string.c file | annotate | diff | comparison | revisions
tests/test_string.c file | annotate | diff | comparison | revisions
--- a/src/string.c	Wed Oct 01 22:45:48 2025 +0200
+++ b/src/string.c	Thu Oct 02 17:58:43 2025 +0200
@@ -25,9 +25,14 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  */
+#define _GNU_SOURCE
+#include <string.h>
+#if defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >=2
+#define FEATURE_MEMRCHR_AVAILABLE
+#endif
+
 #include "cx/string.h"
 
-#include <string.h>
 #include <stdarg.h>
 #include <assert.h>
 #include <errno.h>
@@ -231,9 +236,14 @@
 }
 
 cxstring cx_strrchr(
-        cxstring string,
-        int chr
+    cxstring string,
+    int chr
 ) {
+#ifdef FEATURE_MEMRCHR_AVAILABLE
+    char *ret = memrchr(string.ptr, 0xFF & chr, string.length);
+    if (ret == NULL) return (cxstring) {NULL, 0};
+    return (cxstring) {ret, string.length - (ret - string.ptr)};
+#else
     chr = 0xFF & chr;
     size_t i = string.length;
     while (i > 0) {
@@ -244,6 +254,7 @@
         }
     }
     return (cxstring) {NULL, 0};
+#endif
 }
 
 cxmutstr cx_strrchr_m(
--- a/tests/test_string.c	Wed Oct 01 22:45:48 2025 +0200
+++ b/tests/test_string.c	Thu Oct 02 17:58:43 2025 +0200
@@ -200,7 +200,7 @@
 }
 
 CX_TEST(test_strrchr) {
-    cxstring str = CX_STR("I will find you - and I will kill you");
+    cxstring str = CX_STR("X will find you - and I will kill you");
 
     CX_TEST_DO {
         cxstring notfound = cx_strrchr(str, 'x');
@@ -210,6 +210,13 @@
         CX_TEST_ASSERT(result.length == 13);
         CX_TEST_ASSERT(0 == strcmp(result.ptr, "will kill you"));
 
+        result = cx_strrchr(str, 'u');
+        CX_TEST_ASSERT(result.length == 1);
+        CX_TEST_ASSERT(0 == strcmp(result.ptr, "u"));
+
+        result = cx_strrchr(str, 'X');
+        CX_TEST_ASSERT(0 == cx_strcmp(result, str));
+
         // just for coverage, call the _m variant
         cxmutstr m = cx_strrchr_m(cx_mutstrn(NULL, 0), 'a');
         CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(m), cx_str("")));

mercurial