strv: add strv_equal_ignore_order() helper

This commit is contained in:
Lennart Poettering
2025-01-21 09:56:53 +01:00
parent e7e707f058
commit 5072f4268b
3 changed files with 44 additions and 0 deletions
+20
View 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);
+2
View 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)
+22
View 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);