]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Add string_contains_word_strv()
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 30 Jul 2020 08:34:44 +0000 (10:34 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 4 Sep 2020 10:59:26 +0000 (12:59 +0200)
I had to move STRV_MAKE to macro.h. There is a circular dependency between
extract-word.h, strv.h, and string-util.h that makes it hard to define the
inline function otherwise.

src/basic/extract-word.c
src/basic/macro.h
src/basic/string-util.c
src/basic/string-util.h
src/basic/strv.h
src/test/test-string-util.c

index 1a53da334a23588bdb65ae8a9a51d5de3ce97872..d64dddd641d121fc4be994727b0596e202e47d45 100644 (file)
@@ -14,6 +14,7 @@
 #include "log.h"
 #include "macro.h"
 #include "string-util.h"
+#include "strv.h"
 #include "utf8.h"
 
 int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags) {
index ceea8176f5b85321e7966b4e747c386f8ed79980..41c2c3289e8f2094f8648dd4767fb19c8d16b701 100644 (file)
@@ -538,6 +538,9 @@ static inline int __coverity_check_and_return__(int condition) {
                 (y) = (_t);                        \
         } while (false)
 
+#define STRV_MAKE(...) ((char**) ((const char*[]) { __VA_ARGS__, NULL }))
+#define STRV_MAKE_EMPTY ((char*[1]) { NULL })
+
 /* Iterates through a specified list of pointers. Accepts NULL pointers, but uses (void*) -1 as internal marker for EOL. */
 #define FOREACH_POINTER(p, x, ...)                                                      \
         for (typeof(p) *_l = (typeof(p)[]) { ({ p = x; }), ##__VA_ARGS__, (void*) -1 }; \
index 6d366a3510f09c0acf77c654ab871fa4291941d0..c4f86b4ee2f8183dc39c156b03c5469208bbdd7a 100644 (file)
@@ -15,6 +15,7 @@
 #include "macro.h"
 #include "memory-util.h"
 #include "string-util.h"
+#include "strv.h"
 #include "terminal-util.h"
 #include "utf8.h"
 #include "util.h"
@@ -1209,11 +1210,13 @@ 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) {
+int string_contains_word_strv(const char *string, const char *separators, char **words, const char **ret_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;
 
+        const char *found = NULL;
+
         for (const char *p = string;;) {
                 _cleanup_free_ char *w = NULL;
                 int r;
@@ -1222,8 +1225,14 @@ int string_contains_word(const char *string, const char *separators, const char
                 if (r < 0)
                         return r;
                 if (r == 0)
-                        return false;
-                if (streq(w, word))
-                        return true;
+                        break;
+
+                found = strv_find(words, w);
+                if (found)
+                        break;
         }
+
+        if (ret_word)
+                *ret_word = found;
+        return !!found;
 }
index e0ed5cee8c194a428fd4b4f1db1c5ecbd38a47dc..087fb7c90716c802a1b4790370e52a0067c03a09 100644 (file)
@@ -280,4 +280,8 @@ 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);
+
+int string_contains_word_strv(const char *string, const char *separators, char **words, const char **ret_word);
+static inline int string_contains_word(const char *string, const char *separators, const char *word) {
+        return string_contains_word_strv(string, separators, STRV_MAKE(word), NULL);
+}
index e57dfff69bee78fad10d4740e682212378e28bf8..bc0b04b56b3262a580a68b7647132d86c65ac8b7 100644 (file)
@@ -123,10 +123,6 @@ bool strv_overlap(char * const *a, char * const *b) _pure_;
 char **strv_sort(char **l);
 void strv_print(char * const *l);
 
-#define STRV_MAKE(...) ((char**) ((const char*[]) { __VA_ARGS__, NULL }))
-
-#define STRV_MAKE_EMPTY ((char*[1]) { NULL })
-
 #define strv_from_stdarg_alloca(first)                          \
         ({                                                      \
                 char **_l;                                      \
index 0834e0b96975503b5729cfddd2bee2c576160d7d..b39fda0313baa4158f14a17b32049edad007a215 100644 (file)
@@ -796,6 +796,35 @@ 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_strv(void) {
+        log_info("/* %s */", __func__);
+
+        const char *w;
+
+        assert_se(string_contains_word_strv("a b cc", NULL, STRV_MAKE("a", "b"), NULL));
+
+        assert_se(string_contains_word_strv("a b cc", NULL, STRV_MAKE("a", "b"), &w));
+        assert_se(streq(w, "a"));
+
+        assert_se(!string_contains_word_strv("a b cc", NULL, STRV_MAKE("d"), &w));
+        assert_se(w == NULL);
+
+        assert_se(string_contains_word_strv("a b cc", NULL, STRV_MAKE("b", "a"), &w));
+        assert_se(streq(w, "a"));
+
+        assert_se(string_contains_word_strv("b a b cc", NULL, STRV_MAKE("b", "a", "b"), &w));
+        assert_se(streq(w, "b"));
+
+        assert_se(string_contains_word_strv("a b cc", NULL, STRV_MAKE("b", ""), &w));
+        assert_se(streq(w, "b"));
+
+        assert_se(!string_contains_word_strv("a b cc", NULL, STRV_MAKE(""), &w));
+        assert_se(w == NULL);
+
+        assert_se(string_contains_word_strv("a b  cc", " ", STRV_MAKE(""), &w));
+        assert_se(streq(w, ""));
+}
+
 static void test_string_contains_word(void) {
         log_info("/* %s */", __func__);
 
@@ -884,6 +913,7 @@ int main(int argc, char *argv[]) {
         test_memory_startswith_no_case();
         test_string_truncate_lines();
         test_string_extract_line();
+        test_string_contains_word_strv();
         test_string_contains_word();
 
         return 0;