diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2020-12-06 20:10:48 +0900 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2020-12-08 12:28:54 +0900 |
commit | 4dbce717873000cff7b56f89266d1d2fe53f9284 (patch) | |
tree | 70054e296c38e7d8a433c2757c14388504a7a4ea | |
parent | 77613416e0c79050b46bd728608e2c9e05e216d9 (diff) | |
download | systemd-4dbce717873000cff7b56f89266d1d2fe53f9284.tar.gz |
set: introduce set_strjoin()
-rw-r--r-- | src/basic/hashmap.c | 35 | ||||
-rw-r--r-- | src/basic/set.h | 2 | ||||
-rw-r--r-- | src/test/test-set.c | 51 |
3 files changed, 88 insertions, 0 deletions
diff --git a/src/basic/hashmap.c b/src/basic/hashmap.c index dd1b18c878..e38e580530 100644 --- a/src/basic/hashmap.c +++ b/src/basic/hashmap.c @@ -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; +} diff --git a/src/basic/set.h b/src/basic/set.h index 20abc8f0dc..2b06c39cbe 100644 --- a/src/basic/set.h +++ b/src/basic/set.h @@ -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); diff --git a/src/test/test-set.c b/src/test/test-set.c index 16314d051b..8979408242 100644 --- a/src/test/test-set.c +++ b/src/test/test-set.c @@ -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; } |