]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
strv: add strv_equal_ignore_order() helper
authorLennart Poettering <lennart@poettering.net>
Mon, 20 Jan 2025 09:31:09 +0000 (10:31 +0100)
committerLennart Poettering <lennart@poettering.net>
Tue, 21 Jan 2025 08:56:53 +0000 (09:56 +0100)
src/basic/strv.c
src/basic/strv.h
src/test/test-strv.c

index a92b1234a3a4e30abc615e4a541fa5236a81664e..c9c4551cdca904bbf5a0630118ef4711126c6aa8 100644 (file)
@@ -861,6 +861,26 @@ int strv_compare(char * const *a, char * const *b) {
         return 0;
 }
 
+bool strv_equal_ignore_order(char **a, char **b) {
+
+        /* Just like strv_equal(), but doesn't care about the order of elements or about redundant entries
+         * (i.e. it's even ok if the number of entries in the array differ, as long as the difference just
+         * consists of repititions) */
+
+        if (a == b)
+                return true;
+
+        STRV_FOREACH(i, a)
+                if (!strv_contains(b, *i))
+                        return false;
+
+        STRV_FOREACH(i, b)
+                if (!strv_contains(a, *i))
+                        return false;
+
+        return true;
+}
+
 void strv_print_full(char * const *l, const char *prefix) {
         STRV_FOREACH(s, l)
                 printf("%s%s\n", strempty(prefix), *s);
index 49ef19dcb5a0358d9159f0788a5c10154be48f02..86ba06f835a81c96af6b1ab0afcb956444b12d6e 100644 (file)
@@ -96,6 +96,8 @@ static inline bool strv_equal(char * const *a, char * const *b) {
         return strv_compare(a, b) == 0;
 }
 
+bool strv_equal_ignore_order(char **a, char **b);
+
 char** strv_new_internal(const char *x, ...) _sentinel_;
 char** strv_new_ap(const char *x, va_list ap);
 #define strv_new(...) strv_new_internal(__VA_ARGS__, NULL)
index d641043c509075708914ed7a9e9e38b753488781..b1d30d73a546fca6ee4914e58978a907866a201e 100644 (file)
@@ -1255,4 +1255,26 @@ TEST(strv_find_closest) {
         ASSERT_NULL(strv_find_closest(l, "sfajosajfosdjaofjdsaf"));
 }
 
+TEST(strv_equal_ignore_order) {
+
+        ASSERT_TRUE(strv_equal_ignore_order(NULL, NULL));
+        ASSERT_TRUE(strv_equal_ignore_order(NULL, STRV_MAKE(NULL)));
+        ASSERT_TRUE(strv_equal_ignore_order(STRV_MAKE(NULL), NULL));
+        ASSERT_TRUE(strv_equal_ignore_order(STRV_MAKE(NULL), STRV_MAKE(NULL)));
+
+        ASSERT_FALSE(strv_equal_ignore_order(STRV_MAKE("foo"), NULL));
+        ASSERT_FALSE(strv_equal_ignore_order(STRV_MAKE("foo"), STRV_MAKE(NULL)));
+        ASSERT_FALSE(strv_equal_ignore_order(NULL, STRV_MAKE("foo")));
+        ASSERT_FALSE(strv_equal_ignore_order(STRV_MAKE(NULL), STRV_MAKE("foo")));
+        ASSERT_TRUE(strv_equal_ignore_order(STRV_MAKE("foo"), STRV_MAKE("foo")));
+        ASSERT_FALSE(strv_equal_ignore_order(STRV_MAKE("foo"), STRV_MAKE("foo", "bar")));
+        ASSERT_FALSE(strv_equal_ignore_order(STRV_MAKE("foo", "bar"), STRV_MAKE("foo")));
+        ASSERT_TRUE(strv_equal_ignore_order(STRV_MAKE("foo", "bar"), STRV_MAKE("foo", "bar")));
+        ASSERT_TRUE(strv_equal_ignore_order(STRV_MAKE("bar", "foo"), STRV_MAKE("foo", "bar")));
+        ASSERT_FALSE(strv_equal_ignore_order(STRV_MAKE("bar", "foo"), STRV_MAKE("foo", "bar", "quux")));
+        ASSERT_FALSE(strv_equal_ignore_order(STRV_MAKE("bar", "foo", "quux"), STRV_MAKE("foo", "bar")));
+        ASSERT_TRUE(strv_equal_ignore_order(STRV_MAKE("bar", "foo", "quux"), STRV_MAKE("quux", "foo", "bar")));
+        ASSERT_TRUE(strv_equal_ignore_order(STRV_MAKE("bar", "foo"), STRV_MAKE("bar", "foo", "bar", "foo", "foo")));
+}
+
 DEFINE_TEST_MAIN(LOG_INFO);