]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
string-util: add strrstr() helper
authorLennart Poettering <lennart@poettering.net>
Fri, 3 Mar 2023 13:01:02 +0000 (14:01 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 3 Jan 2024 17:38:46 +0000 (18:38 +0100)
src/basic/string-util.c
src/basic/string-util.h
src/test/test-string-util.c

index 7329bfacdf05b91ca4ad2c0f8b320644163fc6b2..f6453990bd9e9b73edd02b2e639dcef3c7be2b04 100644 (file)
@@ -1519,3 +1519,26 @@ ssize_t strlevenshtein(const char *x, const char *y) {
 
         return t1[yl];
 }
+
+char *strrstr(const char *haystack, const char *needle) {
+        const char *f = NULL;
+        size_t l;
+
+        /* Like strstr() but returns the last rather than the first occurence of "needle" in "haystack". */
+
+        if (!haystack || !needle)
+                return NULL;
+
+        l = strlen(needle);
+
+        /* Special case: for the empty string we return the very last possible occurence, i.e. *after* the
+         * last char, not before. */
+        if (l == 0)
+                return strchr(haystack, 0);
+
+        for (const char *p = haystack; *p; p++)
+                if (strncmp(p, needle, l) == 0)
+                        f = p;
+
+        return (char*) f;
+}
index b6d8be30834e5adbfa357e80d8734bfea698c71b..bf427cd7f7a67144c5272504e93739c3ddf8acb0 100644 (file)
@@ -322,3 +322,5 @@ static inline int strdup_or_null(const char *s, char **ret) {
         *ret = c;
         return 1;
 }
+
+char *strrstr(const char *haystack, const char *needle);
index a8fd45df733e77aed6d42e46a971e725c11fb53c..e78e299ed293c2d753589e49ac18b9278a6d1f7a 100644 (file)
@@ -1324,4 +1324,27 @@ TEST(strlevenshtein) {
         assert_se(strlevenshtein("sunday", "saturday") == 3);
 }
 
+TEST(strrstr) {
+        assert_se(!strrstr(NULL, NULL));
+        assert_se(!strrstr("foo", NULL));
+        assert_se(!strrstr(NULL, "foo"));
+
+        const char *p = "foo";
+        assert_se(strrstr(p, "foo") == p);
+        assert_se(strrstr(p, "fo") == p);
+        assert_se(strrstr(p, "f") == p);
+        assert_se(strrstr(p, "oo") == p + 1);
+        assert_se(strrstr(p, "o") == p + 2);
+        assert_se(strrstr(p, "") == p + strlen(p));
+        assert_se(!strrstr(p, "bar"));
+
+        p = "xoxoxox";
+        assert_se(strrstr(p, "") == p + strlen(p));
+        assert_se(strrstr(p, "x") == p + 6);
+        assert_se(strrstr(p, "ox") == p + 5);
+        assert_se(strrstr(p, "xo") == p + 4);
+        assert_se(strrstr(p, "xox") == p + 4);
+        assert_se(!strrstr(p, "xx"));
+}
+
 DEFINE_TEST_MAIN(LOG_DEBUG);