]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
string-util: add strstrafter()
authorLennart Poettering <lennart@poettering.net>
Fri, 14 Apr 2023 10:48:14 +0000 (12:48 +0200)
committerLennart Poettering <lennart@poettering.net>
Fri, 14 Apr 2023 14:56:15 +0000 (16:56 +0200)
strstrafter() is like strstr() but returns a pointer to the first
character *after* the found substring, not on the substring itself.
Quite often this is what we actually want.

Inspired by #27267 I think it makes sense to add a helper for this,
to avoid the potentially fragile manual pointer increment afterwards.

src/basic/mountpoint-util.c
src/basic/string-util.h
src/libsystemd/sd-device/device-enumerator.c
src/shared/bus-get-properties.c
src/shared/edit-util.c
src/shared/xml.c
src/test/test-string-util.c

index 751d5a35ce0ff8a13a55d17e91d9c664994f9e73..027e64c498c3011938e31ec19049c3ea4d8ab5cc 100644 (file)
@@ -559,12 +559,12 @@ int dev_is_devtmpfs(void) {
                 if (mid != mount_id)
                         continue;
 
-                e = strstr(line, " - ");
+                e = strstrafter(line, " - ");
                 if (!e)
                         continue;
 
                 /* accept any name that starts with the currently expected type */
-                if (startswith(e + 3, "devtmpfs"))
+                if (startswith(e, "devtmpfs"))
                         return true;
         }
 
index 1755b3275ad989f546966cec4c084c9a7193333f..75483924af0bca6d83899fdf4ddb0e0ed2358dd2 100644 (file)
@@ -29,6 +29,18 @@ static inline char* strstr_ptr(const char *haystack, const char *needle) {
         return strstr(haystack, needle);
 }
 
+static inline char *strstrafter(const char *haystack, const char *needle) {
+        char *p;
+
+        /* Returns NULL if not found, or pointer to first character after needle if found */
+
+        p = strstr_ptr(haystack, needle);
+        if (!p)
+                return NULL;
+
+        return p + strlen(needle);
+}
+
 static inline const char* strnull(const char *s) {
         return s ?: "(null)";
 }
index 0bd2c89eb6e4e247d4e518427509a0f20f299ec2..f3f59e2ac3f3a8c7b927f49eca2e20b3f26ed041 100644 (file)
@@ -281,11 +281,10 @@ static int sound_device_compare(const char *devpath_a, const char *devpath_b) {
          * kernel makes this guarantee when creating those devices, and hence we should too when
          * enumerating them. */
 
-        sound_a = strstr(devpath_a, "/sound/card");
+        sound_a = strstrafter(devpath_a, "/sound/card");
         if (!sound_a)
                 return 0;
 
-        sound_a += STRLEN("/sound/card");
         sound_a = strchr(devpath_a, '/');
         if (!sound_a)
                 return 0;
index 3d0887e6df72ea4b61bc8967c6f00d274676bc59..53e5d6b99f18715ad61f99e53260997bbad76937 100644 (file)
@@ -149,9 +149,9 @@ int bus_property_get_rlimit(
                 s = is_soft ? strndupa_safe(property, is_soft - property) : property;
 
                 /* Skip over any prefix, such as "Default" */
-                assert_se(p = strstr(s, "Limit"));
+                assert_se(p = strstrafter(s, "Limit"));
 
-                z = rlimit_from_string(p + 5);
+                z = rlimit_from_string(p);
                 assert(z >= 0);
 
                 (void) getrlimit(z, &buf);
index 9fd74973aa2d62b95e015e861dd3bec27882c38f..96ad72134332b5050fca2371642b24c516d72451 100644 (file)
@@ -300,10 +300,8 @@ static int strip_edit_temp_file(EditFile *e) {
 
                 assert(e->context->marker_end);
 
-                contents_start = strstr(old_contents, e->context->marker_start);
-                if (contents_start)
-                        contents_start += strlen(e->context->marker_start);
-                else
+                contents_start = strstrafter(old_contents, e->context->marker_start);
+                if (!contents_start)
                         contents_start = old_contents;
 
                 contents_end = strstr(contents_start, e->context->marker_end);
index df381d85b8b9f7eaef6b496d197cf3fea7385424..3b1fb41fef74b04721be82cd5206bfbe71af0e61 100644 (file)
@@ -87,26 +87,26 @@ int xml_tokenize(const char **p, char **name, void **state, unsigned *line) {
 
                         if (startswith(b, "!--")) {
                                 /* A comment */
-                                e = strstr(b + 3, "-->");
+                                e = strstrafter(b + 3, "-->");
                                 if (!e)
                                         return -EINVAL;
 
-                                inc_lines(line, b, e + 3 - b);
+                                inc_lines(line, b, e - b);
 
-                                c = e + 3;
+                                c = e;
                                 continue;
                         }
 
                         if (*b == '?') {
                                 /* Processing instruction */
 
-                                e = strstr(b + 1, "?>");
+                                e = strstrafter(b + 1, "?>");
                                 if (!e)
                                         return -EINVAL;
 
-                                inc_lines(line, b, e + 2 - b);
+                                inc_lines(line, b, e - b);
 
-                                c = e + 2;
+                                c = e;
                                 continue;
                         }
 
index 9eb048adfa09d00e72b9d8a35592bdea4203c6de..65052c627d7c397fdbe4c3b4f65931ba76661f14 100644 (file)
@@ -1247,4 +1247,21 @@ TEST(find_line_startswith) {
         assert_se(!find_line_startswith(emptystring, "x"));
 }
 
+TEST(strstrafter) {
+        static const char buffer[] = "abcdefghijklmnopqrstuvwxyz";
+
+        assert_se(!strstrafter(NULL, NULL));
+        assert_se(!strstrafter("", NULL));
+        assert_se(!strstrafter(NULL, ""));
+        assert_se(streq_ptr(strstrafter("", ""), ""));
+
+        assert_se(strstrafter(buffer, "a") == buffer + 1);
+        assert_se(strstrafter(buffer, "") == buffer);
+        assert_se(strstrafter(buffer, "ab") == buffer + 2);
+        assert_se(strstrafter(buffer, "cde") == buffer + 5);
+        assert_se(strstrafter(buffer, "xyz") == strchr(buffer, 0));
+        assert_se(strstrafter(buffer, buffer) == strchr(buffer, 0));
+        assert_se(!strstrafter(buffer, "-"));
+}
+
 DEFINE_TEST_MAIN(LOG_DEBUG);