]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
string-util: add new strrstr_no_case() call
authorLennart Poettering <lennart@amutable.com>
Wed, 15 Apr 2026 14:05:37 +0000 (16:05 +0200)
committerLennart Poettering <lennart@amutable.com>
Fri, 17 Apr 2026 16:32:20 +0000 (18:32 +0200)
src/basic/string-util.c
src/basic/string-util.h
src/test/test-string-util.c

index 9b63516ce0908f4dec958ce73541eeb84955a153..c3298bc8eeebd8c9f8f0f57e8f8ac3a3a0975c53 100644 (file)
@@ -1530,6 +1530,17 @@ char* strrstr_internal(const char *haystack, const char *needle) {
         return NULL;
 }
 
+char* strrstr_no_case_internal(const char *haystack, const char *needle) {
+        if (!haystack || !needle)
+                return NULL;
+
+        for (const char *p = strchr(haystack, 0); p > haystack; p--)
+                if (startswith_no_case(p, needle))
+                        return (char*) p;
+
+        return startswith_no_case(haystack, needle) ? (char*) haystack : NULL;
+}
+
 size_t str_common_prefix(const char *a, const char *b) {
         assert(a);
         assert(b);
index 5ab4dd9016dd2c43e54ecd9e9a9e7d7ecc731466..65fe5072b30922593d6900869299b0d896ee8c3d 100644 (file)
@@ -312,4 +312,8 @@ char* strrstr_internal(const char *haystack, const char *needle) _pure_;
 #define strrstr(haystack, needle) \
         const_generic(haystack, strrstr_internal(haystack, needle))
 
+char* strrstr_no_case_internal(const char *haystack, const char *needle) _pure_;
+#define strrstr_no_case(haystack, needle) \
+        const_generic(haystack, strrstr_no_case_internal(haystack, needle))
+
 size_t str_common_prefix(const char *a, const char *b) _pure_;
index 8490f34f696ebdc924d31c1509a700d42129c14d..5707569e7e17d7e925eafd07175022fe8f3d7223 100644 (file)
@@ -535,6 +535,29 @@ TEST(endswith_no_case) {
         assert_se(!endswith_no_case("foobar", "FOOBARFOOFOO"));
 }
 
+TEST(strrstr_no_case) {
+        ASSERT_STREQ(strrstr_no_case("fooBARfoobar", "bar"), "bar");
+        ASSERT_STREQ(strrstr_no_case("fooBARfoobar", "BAR"), "bar");
+        ASSERT_STREQ(strrstr_no_case("fooBARfoobar", "bAR"), "bar");
+        ASSERT_STREQ(strrstr_no_case("fooBARfoobar", "FOO"), "foobar");
+        ASSERT_STREQ(strrstr_no_case("fooBARfoobar", "foo"), "foobar");
+        ASSERT_STREQ(strrstr_no_case("fooBARfoobar", "FoO"), "foobar");
+        ASSERT_STREQ(strrstr_no_case("aXaXa", "x"), "Xa");
+        ASSERT_STREQ(strrstr_no_case("aXaXa", "X"), "Xa");
+        ASSERT_STREQ(strrstr_no_case("xHello", "hello"), "Hello");
+        ASSERT_STREQ(strrstr_no_case("Hello", "l"), "lo");
+        ASSERT_STREQ(strrstr_no_case("Hello", ""), "");
+        ASSERT_STREQ(strrstr_no_case("", ""), "");
+        ASSERT_STREQ(strrstr_no_case("FOO", "foo"), "FOO");
+        ASSERT_STREQ(strrstr_no_case("hello", "hello"), "hello");
+        ASSERT_STREQ(strrstr_no_case("X", "x"), "X");
+
+        ASSERT_NULL(strrstr_no_case("hello", "xyz"));
+        ASSERT_NULL(strrstr_no_case("", "x"));
+        ASSERT_NULL(strrstr_no_case(NULL, "x"));
+        ASSERT_NULL(strrstr_no_case("x", NULL));
+}
+
 TEST(delete_chars) {
         char *s, input[] = "   hello, waldo.   abc";