]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
strv: add strv_copy_n() helper for copying part of a n strv
authorLennart Poettering <lennart@poettering.net>
Thu, 16 Feb 2023 14:41:55 +0000 (15:41 +0100)
committerLennart Poettering <lennart@poettering.net>
Fri, 17 Feb 2023 08:55:35 +0000 (09:55 +0100)
src/basic/strv.c
src/basic/strv.h
src/test/test-strv.c

index 2b7a61d442b7a8e8e23768b6a3580b5329a0650a..9b4a7663a90562340e957f5f631d6e6f60cf3731 100644 (file)
@@ -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;
index 1f8da85fccd94dcc81fa86ba45164848658c9e1e..71ff3a4edf279418168a19c351dde5448cc2f07d 100644 (file)
@@ -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);
index 5c03eaa960b54c8df9330544a898d03ae474134c..0f08dd4615b3c0a497a84e38c95457afc87c7a8c 100644 (file)
@@ -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);