]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
set: introduce set_strjoin()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 6 Dec 2020 11:10:48 +0000 (20:10 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 8 Dec 2020 03:28:54 +0000 (12:28 +0900)
src/basic/hashmap.c
src/basic/set.h
src/test/test-set.c

index dd1b18c87824d5755c23fee6a9022d639aac96f4..e38e5805300e0a8adaca00fa30bad94974d032ba 100644 (file)
@@ -1976,3 +1976,38 @@ IteratedCache* iterated_cache_free(IteratedCache *cache) {
 
         return mfree(cache);
 }
+
+int set_strjoin(Set *s, const char *separator, char **ret) {
+        size_t separator_len, allocated = 0, len = 0;
+        _cleanup_free_ char *str = NULL;
+        const char *value;
+        bool first = true;
+
+        assert(ret);
+
+        separator_len = strlen_ptr(separator);
+
+        SET_FOREACH(value, s) {
+                size_t l = strlen_ptr(value);
+
+                if (l == 0)
+                        continue;
+
+                if (!GREEDY_REALLOC(str, allocated, len + l + (first ? 0 : separator_len) + 1))
+                        return -ENOMEM;
+
+                if (separator_len > 0 && !first) {
+                        memcpy(str + len, separator, separator_len);
+                        len += separator_len;
+                }
+
+                memcpy(str + len, value, l);
+                len += l;
+                first = false;
+        }
+        if (str)
+                str[len] = '\0';
+
+        *ret = TAKE_PTR(str);
+        return 0;
+}
index 20abc8f0dcf1866f9345a552134af664bcd723ce..2b06c39cbe5647c4d8b2441443f6d8f1bfe145f1 100644 (file)
@@ -150,3 +150,5 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(Set*, set_free_free);
 
 #define _cleanup_set_free_ _cleanup_(set_freep)
 #define _cleanup_set_free_free_ _cleanup_(set_free_freep)
+
+int set_strjoin(Set *s, const char *separator, char **ret);
index 16314d051b6d1f529137ab01b0e5fe9fe8830247..897940824255d70f31ca4d36a2b68c453d2436f9 100644 (file)
@@ -150,6 +150,56 @@ static void test_set_ensure_consume(void) {
         assert_se(set_size(m) == 2);
 }
 
+static void test_set_strjoin(void) {
+        _cleanup_set_free_ Set *m = NULL;
+        _cleanup_free_ char *joined = NULL;
+
+        assert_se(set_strjoin(m, NULL, &joined) >= 0);
+        assert_se(!joined);
+        assert_se(set_strjoin(m, "", &joined) >= 0);
+        assert_se(!joined);
+        assert_se(set_strjoin(m, " ", &joined) >= 0);
+        assert_se(!joined);
+        assert_se(set_strjoin(m, "xxx", &joined) >= 0);
+        assert_se(!joined);
+
+        assert_se(set_put_strdup(&m, "aaa") == 1);
+
+        assert_se(set_strjoin(m, NULL, &joined) >= 0);
+        assert_se(streq(joined, "aaa"));
+
+        joined = mfree(joined);
+        assert_se(set_strjoin(m, "", &joined) >= 0);
+        assert_se(streq(joined, "aaa"));
+
+        joined = mfree(joined);
+        assert_se(set_strjoin(m, " ", &joined) >= 0);
+        assert_se(streq(joined, "aaa"));
+
+        joined = mfree(joined);
+        assert_se(set_strjoin(m, "xxx", &joined) >= 0);
+        assert_se(streq(joined, "aaa"));
+
+        assert_se(set_put_strdup(&m, "bbb") == 1);
+        assert_se(set_put_strdup(&m, "aaa") == 0);
+
+        joined = mfree(joined);
+        assert_se(set_strjoin(m, NULL, &joined) >= 0);
+        assert_se(STR_IN_SET(joined, "aaabbb", "bbbaaa"));
+
+        joined = mfree(joined);
+        assert_se(set_strjoin(m, "", &joined) >= 0);
+        assert_se(STR_IN_SET(joined, "aaabbb", "bbbaaa"));
+
+        joined = mfree(joined);
+        assert_se(set_strjoin(m, " ", &joined) >= 0);
+        assert_se(STR_IN_SET(joined, "aaa bbb", "bbb aaa"));
+
+        joined = mfree(joined);
+        assert_se(set_strjoin(m, "xxx", &joined) >= 0);
+        assert_se(STR_IN_SET(joined, "aaaxxxbbb", "bbbxxxaaa"));
+}
+
 int main(int argc, const char *argv[]) {
         test_set_steal_first();
         test_set_free_with_destructor();
@@ -160,6 +210,7 @@ int main(int argc, const char *argv[]) {
         test_set_ensure_allocated();
         test_set_ensure_put();
         test_set_ensure_consume();
+        test_set_strjoin();
 
         return 0;
 }