]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
string-util: add delete_trailing_chars() and skip_leading_chars() helpers
authorLennart Poettering <lennart@poettering.net>
Thu, 9 Nov 2017 10:12:47 +0000 (11:12 +0100)
committerLennart Poettering <lennart@poettering.net>
Mon, 13 Nov 2017 09:47:15 +0000 (10:47 +0100)
And let's port over a couple of users to the new APIs.

src/basic/string-util.c
src/basic/string-util.h
src/basic/unit-name.c
src/core/cgroup.c
src/libudev/libudev-private.h
src/libudev/libudev-util.c
src/test/test-string-util.c
src/udev/udev-rules.c
src/udev/udevadm-test-builtin.c
src/udev/udevadm-test.c

index 6fb4134ae9305b7ce35d0672000ea415ee477e78..be2613ca9eb28cfbeac0e79baaf83f5c0cba4763 100644 (file)
@@ -278,6 +278,9 @@ char *strjoin_real(const char *x, ...) {
 char *strstrip(char *s) {
         char *e;
 
+        if (!s)
+                return NULL;
+
         /* Drops trailing whitespace. Modifies the string in
          * place. Returns pointer to first non-space character */
 
@@ -295,7 +298,13 @@ char *strstrip(char *s) {
 char *delete_chars(char *s, const char *bad) {
         char *f, *t;
 
-        /* Drops all whitespace, regardless where in the string */
+        /* Drops all specified bad characters, regardless where in the string */
+
+        if (!s)
+                return NULL;
+
+        if (!bad)
+                bad = WHITESPACE;
 
         for (f = s, t = s; *f; f++) {
                 if (strchr(bad, *f))
@@ -309,6 +318,26 @@ char *delete_chars(char *s, const char *bad) {
         return s;
 }
 
+char *delete_trailing_chars(char *s, const char *bad) {
+        char *p, *c = s;
+
+        /* Drops all specified bad characters, at the end of the string */
+
+        if (!s)
+                return NULL;
+
+        if (!bad)
+                bad = WHITESPACE;
+
+        for (p = s; *p; p++)
+                if (!strchr(bad, *p))
+                        c = p + 1;
+
+        *c = 0;
+
+        return s;
+}
+
 char *truncate_nl(char *s) {
         assert(s);
 
index 4c94b182c1b53c6780c34372fba1218d3c2c443f..d2040ebd12c0188654dc6cc75fb08bbf8c47cb17 100644 (file)
@@ -133,8 +133,20 @@ char *strjoin_real(const char *x, ...) _sentinel_;
 
 char *strstrip(char *s);
 char *delete_chars(char *s, const char *bad);
+char *delete_trailing_chars(char *s, const char *bad);
 char *truncate_nl(char *s);
 
+static inline char *skip_leading_chars(const char *s, const char *bad) {
+
+        if (!s)
+                return NULL;
+
+        if (!bad)
+                bad = WHITESPACE;
+
+        return (char*) s + strspn(s, bad);
+}
+
 char ascii_tolower(char x);
 char *ascii_strlower(char *s);
 char *ascii_strlower_n(char *s, size_t n);
index ba9928375ee457a7b10da60ee52e011c5249f09d..27ce432197b0e81d3513fee6e18394e1234841be 100644 (file)
@@ -382,19 +382,14 @@ int unit_name_path_escape(const char *f, char **ret) {
         if (STR_IN_SET(p, "/", ""))
                 s = strdup("-");
         else {
-                char *e;
-
                 if (!path_is_safe(p))
                         return -EINVAL;
 
                 /* Truncate trailing slashes */
-                e = endswith(p, "/");
-                if (e)
-                        *e = 0;
+                delete_trailing_chars(p, "/");
 
                 /* Truncate leading slashes */
-                if (p[0] == '/')
-                        p++;
+                p = skip_leading_chars(p, "/");
 
                 s = unit_name_escape(p);
         }
index b717837c721e061286a1e1d4309611d7f69ed813..d81d10a2df9ac3817d8203ddd8d24d5dffb01bb5 100644 (file)
@@ -1944,11 +1944,9 @@ int manager_setup_cgroup(Manager *m) {
         if (e)
                 *e = 0;
 
-        /* And make sure to store away the root value without trailing
-         * slash, even for the root dir, so that we can easily prepend
-         * it everywhere. */
-        while ((e = endswith(m->cgroup_root, "/")))
-                *e = 0;
+        /* And make sure to store away the root value without trailing slash, even for the root dir, so that we can
+         * easily prepend it everywhere. */
+        delete_trailing_chars(m->cgroup_root, "/");
 
         /* 2. Show data */
         r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_root, NULL, &path);
index 52c50751107f32f17969e94f4eb485fd5637ed2d..818da8465e94426f9f469ebdf6f3b14d2a380da0 100644 (file)
@@ -138,7 +138,6 @@ int udev_queue_export_device_finished(struct udev_queue_export *udev_queue_expor
 #define UDEV_ALLOWED_CHARS_INPUT        "/ $%?,"
 int util_log_priority(const char *priority);
 size_t util_path_encode(const char *src, char *dest, size_t size);
-void util_remove_trailing_chars(char *path, char c);
 int util_replace_whitespace(const char *str, char *to, size_t len);
 int util_replace_chars(char *str, const char *white);
 unsigned int util_string_hash32(const char *key);
index 1d73d8f09061ad852fc66cb4011b25f5fc9d3984..ae809d85e177292625575a8b4f4e437bccc27450 100644 (file)
@@ -150,17 +150,6 @@ size_t util_path_encode(const char *src, char *dest, size_t size)
         return j;
 }
 
-void util_remove_trailing_chars(char *path, char c)
-{
-        size_t len;
-
-        if (path == NULL)
-                return;
-        len = strlen(path);
-        while (len > 0 && path[len-1] == c)
-                path[--len] = '\0';
-}
-
 /*
  * Copy from 'str' to 'to', while removing all leading and trailing whitespace,
  * and replacing each run of consecutive whitespace with a single underscore.
index 604701ff7ad5953c88ec18d4d85824ee2bed7960..5d97080d2cdee41775020a92a04830fab763c9ee 100644 (file)
@@ -288,11 +288,47 @@ static void test_endswith_no_case(void) {
 }
 
 static void test_delete_chars(void) {
-        char *r;
-        char input[] = "   hello, waldo.   abc";
+        char *s, input[] = "   hello, waldo.   abc";
+
+        s = delete_chars(input, WHITESPACE);
+        assert_se(streq(s, "hello,waldo.abc"));
+        assert_se(s == input);
+}
+
+static void test_delete_trailing_chars(void) {
+
+        char *s,
+                input1[] = " \n \r k \n \r ",
+                input2[] = "kkkkthiskkkiskkkaktestkkk",
+                input3[] = "abcdef";
+
+        s = delete_trailing_chars(input1, WHITESPACE);
+        assert_se(streq(s, " \n \r k"));
+        assert_se(s == input1);
+
+        s = delete_trailing_chars(input2, "kt");
+        assert_se(streq(s, "kkkkthiskkkiskkkaktes"));
+        assert_se(s == input2);
+
+        s = delete_trailing_chars(input3, WHITESPACE);
+        assert_se(streq(s, "abcdef"));
+        assert_se(s == input3);
+
+        s = delete_trailing_chars(input3, "fe");
+        assert_se(streq(s, "abcd"));
+        assert_se(s == input3);
+}
+
+static void test_skip_leading_chars(void) {
+        char input1[] = " \n \r k \n \r ",
+                input2[] = "kkkkthiskkkiskkkaktestkkk",
+                input3[] = "abcdef";
 
-        r = delete_chars(input, WHITESPACE);
-        assert_se(streq(r, "hello,waldo.abc"));
+        assert_se(streq(skip_leading_chars(input1, WHITESPACE), "k \n \r "));
+        assert_se(streq(skip_leading_chars(input2, "k"), "thiskkkiskkkaktestkkk"));
+        assert_se(streq(skip_leading_chars(input2, "tk"), "hiskkkiskkkaktestkkk"));
+        assert_se(streq(skip_leading_chars(input3, WHITESPACE), "abcdef"));
+        assert_se(streq(skip_leading_chars(input3, "bcaef"), "def"));
 }
 
 static void test_in_charset(void) {
@@ -361,6 +397,8 @@ int main(int argc, char *argv[]) {
         test_endswith();
         test_endswith_no_case();
         test_delete_chars();
+        test_delete_trailing_chars();
+        test_skip_leading_chars();
         test_in_charset();
         test_split_pair();
         test_first_word();
index 9aaec72baf5888c45e42b8f14867469ab2530d99..b061210c7ca15a3bfd23331d821556206ec1d763 100644 (file)
@@ -1967,7 +1967,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
                         } else {
                                 int count;
 
-                                util_remove_trailing_chars(result, '\n');
+                                delete_trailing_chars(result, "\n");
                                 if (IN_SET(esc, ESCAPE_UNSET, ESCAPE_REPLACE)) {
                                         count = util_replace_chars(result, UDEV_ALLOWED_CHARS_INPUT);
                                         if (count > 0)
index b5662be5c2980b688f76019060da413d071012bb..3bcd09061acd6b75042f724e17a02d622e4800ac 100644 (file)
@@ -85,7 +85,7 @@ static int adm_builtin(struct udev *udev, int argc, char *argv[]) {
                 strscpyl(filename, sizeof(filename), "/sys", syspath, NULL);
         else
                 strscpy(filename, sizeof(filename), syspath);
-        util_remove_trailing_chars(filename, '/');
+        delete_trailing_chars(filename, "/");
 
         dev = udev_device_new_from_syspath(udev, filename);
         if (dev == NULL) {
index e8ffe2f309d9161d226cda2298e6ec7ba8590f55..b180e24369c4cbf0c3857143fd4b7ecafd096af1 100644 (file)
@@ -116,7 +116,7 @@ static int adm_test(struct udev *udev, int argc, char *argv[]) {
                 strscpyl(filename, sizeof(filename), "/sys", syspath, NULL);
         else
                 strscpy(filename, sizeof(filename), syspath);
-        util_remove_trailing_chars(filename, '/');
+        delete_trailing_chars(filename, "/");
 
         dev = udev_device_new_from_synthetic_event(udev, filename, action);
         if (dev == NULL) {