summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2023-02-16 15:41:55 +0100
committerLennart Poettering <lennart@poettering.net>2023-02-17 09:55:35 +0100
commit4ea517a6e07f47117348c68c6fe087bf6d401558 (patch)
tree1fa110ee7ee35a2c987c6e19f37d3c0606a91931
parentf4ff3e71493dbc6ace5d942aa544b1c829763710 (diff)
downloadsystemd-4ea517a6e07f47117348c68c6fe087bf6d401558.tar.gz
strv: add strv_copy_n() helper for copying part of a n strv
-rw-r--r--src/basic/strv.c10
-rw-r--r--src/basic/strv.h5
-rw-r--r--src/test/test-strv.c40
3 files changed, 52 insertions, 3 deletions
diff --git a/src/basic/strv.c b/src/basic/strv.c
index 2b7a61d442..9b4a7663a9 100644
--- a/src/basic/strv.c
+++ b/src/basic/strv.c
@@ -77,20 +77,26 @@ char** strv_free_erase(char **l) {
return mfree(l);
}
-char** strv_copy(char * const *l) {
+char** strv_copy_n(char * const *l, size_t m) {
_cleanup_strv_free_ char **result = NULL;
char **k;
- result = new(char*, strv_length(l) + 1);
+ result = new(char*, MIN(strv_length(l), m) + 1);
if (!result)
return NULL;
k = result;
STRV_FOREACH(i, l) {
+ if (m == 0)
+ break;
+
*k = strdup(*i);
if (!*k)
return NULL;
k++;
+
+ if (m != SIZE_MAX)
+ m--;
}
*k = NULL;
diff --git a/src/basic/strv.h b/src/basic/strv.h
index 1f8da85fcc..71ff3a4edf 100644
--- a/src/basic/strv.h
+++ b/src/basic/strv.h
@@ -29,7 +29,10 @@ char** strv_free_erase(char **l);
DEFINE_TRIVIAL_CLEANUP_FUNC(char**, strv_free_erase);
#define _cleanup_strv_free_erase_ _cleanup_(strv_free_erasep)
-char** strv_copy(char * const *l);
+char** strv_copy_n(char * const *l, size_t n);
+static inline char** strv_copy(char * const *l) {
+ return strv_copy_n(l, SIZE_MAX);
+}
size_t strv_length(char * const *l) _pure_;
int strv_extend_strv(char ***a, char * const *b, bool filter_duplicates);
diff --git a/src/test/test-strv.c b/src/test/test-strv.c
index 5c03eaa960..0f08dd4615 100644
--- a/src/test/test-strv.c
+++ b/src/test/test-strv.c
@@ -954,4 +954,44 @@ TEST(strv_extend_join) {
assert_se(streq(v[1], "ABC=QER"));
}
+TEST(strv_copy_n) {
+ char **x = STRV_MAKE("a", "b", "c", "d", "e");
+ _cleanup_strv_free_ char **l = NULL;
+
+ l = strv_copy_n(x, 0);
+ assert_se(strv_equal(l, NULL));
+ strv_free(l);
+
+ l = strv_copy_n(x, 0);
+ assert_se(strv_equal(l, (char**) { NULL }));
+ strv_free(l);
+
+ l = strv_copy_n(x, 1);
+ assert_se(strv_equal(l, STRV_MAKE("a")));
+ strv_free(l);
+
+ l = strv_copy_n(x, 2);
+ assert_se(strv_equal(l, STRV_MAKE("a", "b")));
+ strv_free(l);
+
+ l = strv_copy_n(x, 3);
+ assert_se(strv_equal(l, STRV_MAKE("a", "b", "c")));
+ strv_free(l);
+
+ l = strv_copy_n(x, 4);
+ assert_se(strv_equal(l, STRV_MAKE("a", "b", "c", "d")));
+ strv_free(l);
+
+ l = strv_copy_n(x, 5);
+ assert_se(strv_equal(l, STRV_MAKE("a", "b", "c", "d", "e")));
+ strv_free(l);
+
+ l = strv_copy_n(x, 6);
+ assert_se(strv_equal(l, STRV_MAKE("a", "b", "c", "d", "e")));
+ strv_free(l);
+
+ l = strv_copy_n(x, SIZE_MAX);
+ assert_se(strv_equal(l, STRV_MAKE("a", "b", "c", "d", "e")));
+}
+
DEFINE_TEST_MAIN(LOG_INFO);