diff --git a/src/basic/strv.c b/src/basic/strv.c index 4044a129c6..e4f9373f8a 100644 --- a/src/basic/strv.c +++ b/src/basic/strv.c @@ -812,16 +812,14 @@ bool strv_is_uniq(char * const *l) { } char** strv_remove(char **l, const char *s) { - char **f, **t; - if (!l) return NULL; assert(s); - /* Drops every occurrence of s in the string list, edits - * in-place. */ + /* Drops every occurrence of s in the string list, edits in-place. */ + char **f, **t; for (f = t = l; *f; f++) if (streq(*f, s)) free(*f); @@ -832,6 +830,17 @@ char** strv_remove(char **l, const char *s) { return l; } +char** strv_remove_strv(char **l, char *const*ll) { + + if (strv_isempty(l)) + return l; + + STRV_FOREACH(i, ll) + strv_remove(l, *i); + + return l; +} + bool strv_overlap(char * const *a, char * const *b) { POINTER_MAY_BE_NULL(a); POINTER_MAY_BE_NULL(b); diff --git a/src/basic/strv.h b/src/basic/strv.h index cf6fa158b6..7bac1b66fa 100644 --- a/src/basic/strv.h +++ b/src/basic/strv.h @@ -85,6 +85,7 @@ int strv_consume_pair(char ***l, char *a, char *b); int strv_consume_prepend(char ***l, char *value); char** strv_remove(char **l, const char *s); +char** strv_remove_strv(char **l, char *const*ll); char** strv_uniq(char **l); bool strv_is_uniq(char * const *l) _pure_; diff --git a/src/test/test-strv.c b/src/test/test-strv.c index 283ae5c865..386c54f787 100644 --- a/src/test/test-strv.c +++ b/src/test/test-strv.c @@ -510,6 +510,26 @@ TEST(strv_overlap) { assert_se(!strv_overlap((char **)input_table, (char**)input_table_unique)); } +TEST(strv_remove_strv) { + _cleanup_strv_free_ char **l = NULL; + + ASSERT_OK(strv_extend_strv(&l, STRV_MAKE("one", "two", "three", "four"), false)); + + ASSERT_PTR_EQ(strv_remove_strv(l, STRV_MAKE("two", "four")), l); + ASSERT_TRUE(strv_equal(l, STRV_MAKE("one", "three"))); + + /* Removing entries not present is a no-op. */ + ASSERT_PTR_EQ(strv_remove_strv(l, STRV_MAKE("nope")), l); + ASSERT_TRUE(strv_equal(l, STRV_MAKE("one", "three"))); + + /* Empty removal list leaves the list untouched. */ + ASSERT_PTR_EQ(strv_remove_strv(l, STRV_EMPTY), l); + ASSERT_TRUE(strv_equal(l, STRV_MAKE("one", "three"))); + + /* Removing from an empty/NULL list is fine. */ + ASSERT_NULL(strv_remove_strv(NULL, STRV_MAKE("one"))); +} + TEST(strv_sort) { const char* input_table[] = { "durian",