]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
basic: add string_contains_word()
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 29 Jul 2020 12:06:26 +0000 (14:06 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 4 Sep 2020 10:59:25 +0000 (12:59 +0200)
This wraps the common pattern of using extract_first_word() in a loop
to look for a matching word.

src/basic/string-util.c
src/basic/string-util.h
src/test/test-string-util.c

index 755a37f6675aaf4abe6cc0f1e3356437ea3125d8..6d366a3510f09c0acf77c654ab871fa4291941d0 100644 (file)
@@ -8,6 +8,7 @@
 
 #include "alloc-util.h"
 #include "escape.h"
+#include "extract-word.h"
 #include "fileio.h"
 #include "gunicode.h"
 #include "locale-util.h"
@@ -1207,3 +1208,22 @@ int string_extract_line(const char *s, size_t i, char **ret) {
                 c++;
         }
 }
+
+int string_contains_word(const char *string, const char *separators, const char *word) {
+        /* In the default mode with no separators specified, we split on whitespace and
+         * don't coalesce separators. */
+        const ExtractFlags flags = separators ? EXTRACT_DONT_COALESCE_SEPARATORS : 0;
+
+        for (const char *p = string;;) {
+                _cleanup_free_ char *w = NULL;
+                int r;
+
+                r = extract_first_word(&p, &w, separators, flags);
+                if (r < 0)
+                        return r;
+                if (r == 0)
+                        return false;
+                if (streq(w, word))
+                        return true;
+        }
+}
index cf8c74b822931554cd0617408380489e1308f3e1..e0ed5cee8c194a428fd4b4f1db1c5ecbd38a47dc 100644 (file)
@@ -280,3 +280,4 @@ char* string_erase(char *x);
 
 int string_truncate_lines(const char *s, size_t n_lines, char **ret);
 int string_extract_line(const char *s, size_t i, char **ret);
+int string_contains_word(const char *string, const char *separators, const char *word);
index 33c5f835753b0a20034fa471c54554f88ecda31e..0834e0b96975503b5729cfddd2bee2c576160d7d 100644 (file)
@@ -796,6 +796,59 @@ static void test_string_extract_line(void) {
         test_string_extract_lines_one("\n\n\nx\n", 3, "x", false);
 }
 
+static void test_string_contains_word(void) {
+        log_info("/* %s */", __func__);
+
+        assert_se( string_contains_word("a b cc", NULL, "a"));
+        assert_se( string_contains_word("a b cc", NULL, "b"));
+        assert_se(!string_contains_word("a b cc", NULL, "c"));
+        assert_se( string_contains_word("a b cc", NULL, "cc"));
+        assert_se(!string_contains_word("a b cc", NULL, "d"));
+        assert_se(!string_contains_word("a b cc", NULL, "a b"));
+        assert_se(!string_contains_word("a b cc", NULL, "a b c"));
+        assert_se(!string_contains_word("a b cc", NULL, "b c"));
+        assert_se(!string_contains_word("a b cc", NULL, "b cc"));
+        assert_se(!string_contains_word("a b cc", NULL, "a "));
+        assert_se(!string_contains_word("a b cc", NULL, " b "));
+        assert_se(!string_contains_word("a b cc", NULL, " cc"));
+
+        assert_se( string_contains_word("  a  b\t\tcc", NULL, "a"));
+        assert_se( string_contains_word("  a  b\t\tcc", NULL, "b"));
+        assert_se(!string_contains_word("  a  b\t\tcc", NULL, "c"));
+        assert_se( string_contains_word("  a  b\t\tcc", NULL, "cc"));
+        assert_se(!string_contains_word("  a  b\t\tcc", NULL, "d"));
+        assert_se(!string_contains_word("  a  b\t\tcc", NULL, "a b"));
+        assert_se(!string_contains_word("  a  b\t\tcc", NULL, "a b\t\tc"));
+        assert_se(!string_contains_word("  a  b\t\tcc", NULL, "b\t\tc"));
+        assert_se(!string_contains_word("  a  b\t\tcc", NULL, "b\t\tcc"));
+        assert_se(!string_contains_word("  a  b\t\tcc", NULL, "a "));
+        assert_se(!string_contains_word("  a  b\t\tcc", NULL, " b "));
+        assert_se(!string_contains_word("  a  b\t\tcc", NULL, " cc"));
+
+        assert_se(!string_contains_word("  a  b\t\tcc", NULL, ""));
+        assert_se(!string_contains_word("  a  b\t\tcc", NULL, " "));
+        assert_se(!string_contains_word("  a  b\t\tcc", NULL, "  "));
+        assert_se( string_contains_word("  a  b\t\tcc", " ", ""));
+        assert_se( string_contains_word("  a  b\t\tcc", "\t", ""));
+        assert_se( string_contains_word("  a  b\t\tcc", WHITESPACE, ""));
+
+        assert_se( string_contains_word("a:b:cc", ":#", "a"));
+        assert_se( string_contains_word("a:b:cc", ":#", "b"));
+        assert_se(!string_contains_word("a:b:cc", ":#", "c"));
+        assert_se( string_contains_word("a:b:cc", ":#", "cc"));
+        assert_se(!string_contains_word("a:b:cc", ":#", "d"));
+        assert_se(!string_contains_word("a:b:cc", ":#", "a:b"));
+        assert_se(!string_contains_word("a:b:cc", ":#", "a:b:c"));
+        assert_se(!string_contains_word("a:b:cc", ":#", "b:c"));
+        assert_se(!string_contains_word("a#b#cc", ":#", "b:cc"));
+        assert_se( string_contains_word("a#b#cc", ":#", "b"));
+        assert_se( string_contains_word("a#b#cc", ":#", "cc"));
+        assert_se(!string_contains_word("a:b:cc", ":#", "a:"));
+        assert_se(!string_contains_word("a:b cc", ":#", "b"));
+        assert_se( string_contains_word("a:b cc", ":#", "b cc"));
+        assert_se(!string_contains_word("a:b:cc", ":#", ":cc"));
+}
+
 int main(int argc, char *argv[]) {
         test_setup_logging(LOG_DEBUG);
 
@@ -831,6 +884,7 @@ int main(int argc, char *argv[]) {
         test_memory_startswith_no_case();
         test_string_truncate_lines();
         test_string_extract_line();
+        test_string_contains_word();
 
         return 0;
 }