]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
set: introduce set_to_strv()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 11 Apr 2025 00:54:21 +0000 (09:54 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sat, 12 Apr 2025 19:59:26 +0000 (04:59 +0900)
It is similar to set_get_strv(), but invalidates the set on success.

src/basic/hashmap.c
src/basic/set.h
src/test/test-set.c

index 951f63ae6da9f3fb1f31a62a53101bffd4fc8310..a547b8c31cbc50753d6db8f17a74e622bc9b7f72 100644 (file)
@@ -1805,6 +1805,23 @@ char** _hashmap_get_strv(HashmapBase *h) {
         return sv;
 }
 
+char** set_to_strv(Set **s) {
+        assert(s);
+
+        /* This is similar to set_get_strv(), but invalidates the set on success. */
+
+        char **v = new(char*, set_size(*s) + 1);
+        if (!v)
+                return NULL;
+
+        for (char **p = v; (*p = set_steal_first(*s)); p++)
+                ;
+
+        assert(set_isempty(*s));
+        *s = set_free(*s);
+        return v;
+}
+
 void* ordered_hashmap_next(OrderedHashmap *h, const void *key) {
         struct ordered_hashmap_entry *e;
         unsigned hash, idx;
index 618e729744662b29938db978573cd49da8b6cfc0..05d7d88875e744a5a62c99eb1a29c421fd086e24 100644 (file)
@@ -114,6 +114,8 @@ static inline char **set_get_strv(Set *s) {
         return _hashmap_get_strv(HASHMAP_BASE(s));
 }
 
+char** set_to_strv(Set **s);
+
 int _set_ensure_put(Set **s, const struct hash_ops *hash_ops, const void *key  HASHMAP_DEBUG_PARAMS);
 #define set_ensure_put(s, hash_ops, key) _set_ensure_put(s, hash_ops, key  HASHMAP_DEBUG_SRC_ARGS)
 
index f1e6e9314b534f1b113b388ab77683c14c7c7e22..19b46a529fa9aa94cc1914f57e86b7e4fb2e1b39 100644 (file)
@@ -400,4 +400,28 @@ TEST(set_fnmatch) {
         assert_se(!set_fnmatch(match, nomatch, "cccXX"));
 }
 
+TEST(set_to_strv) {
+        _cleanup_set_free_ Set *set = NULL;
+        _cleanup_strv_free_ char **a = NULL;
+        _cleanup_free_ char **b = NULL;
+        char **v = STRV_MAKE("aaa", "bbb", "ccc");
+
+        ASSERT_NOT_NULL(a = set_to_strv(&set));
+        ASSERT_TRUE(strv_isempty(a));
+        ASSERT_NULL(set);
+        a = strv_free(a);
+
+        ASSERT_OK(set_put_strdupv(&set, v));
+        ASSERT_EQ(set_size(set), strv_length(v));
+
+        ASSERT_NOT_NULL(b = set_get_strv(set));
+        ASSERT_EQ(strv_length(b), strv_length(v));
+        ASSERT_TRUE(strv_equal_ignore_order(b, v));
+
+        ASSERT_NOT_NULL(a = set_to_strv(&set));
+        ASSERT_EQ(strv_length(a), strv_length(v));
+        ASSERT_TRUE(strv_equal_ignore_order(a, v));
+        ASSERT_NULL(set);
+}
+
 DEFINE_TEST_MAIN(LOG_INFO);