diff --git a/include/ucore/strvec.h b/include/ucore/strvec.h index 3789d78..79fd641 100644 --- a/include/ucore/strvec.h +++ b/include/ucore/strvec.h @@ -83,6 +83,18 @@ void uc_strv_clear(struct UCStrv *strv); */ void uc_strv_destroy(struct UCStrv *strv); +/** + * Append all the elments from b to a + * If copy is 1, the appended elements will be copied when appended + * + * @param a destination UCStrv + * @param b source UCStrv + * @param copy 1 for making a copy of the string when appending it + * 0 to just append the same pointer in b to a + * @return 0 on success, != 0 if appending/allocation fails + */ +int uc_strv_append_all(struct UCStrv *a, struct UCStrv *b, int copy); + #ifdef __cplusplus } #endif diff --git a/src/strvec.c b/src/strvec.c index 079cbdd..9131b3f 100644 --- a/src/strvec.c +++ b/src/strvec.c @@ -105,3 +105,28 @@ void uc_strv_destroy(struct UCStrv *strv) strv->strings = NULL; } +int uc_strv_append_all(struct UCStrv *a, struct UCStrv *b, int copy) +{ + size_t i; + int rc; + + rc = uc_strv_grow(a, a->allocated + b->cnt); + if (rc != 0) { + return rc; + } + + for (i = 0; i < b->cnt; i++) { + if (copy) { + rc = uc_strv_append(a, b->strings[i]); + } else { + rc = uc_strv_append_nocopy(a, b->strings[i]); + } + + if (rc != 0) { + return rc; + } + } + + return 0; +} + diff --git a/test/test_strv.c b/test/test_strv.c index d9745b2..e8bf8ec 100644 --- a/test/test_strv.c +++ b/test/test_strv.c @@ -1,5 +1,6 @@ #include #include +#include #include @@ -73,6 +74,54 @@ START_TEST (test_strv_null_terminate) END_TEST +START_TEST (test_strv_append_all_copy) + struct UCStrv src; + struct UCStrv dst; + int rc; + + uc_strv_init(&src); + uc_strv_init(&dst); + + uc_strv_append(&dst, "string1"); + uc_strv_append(&src, "string2"); + uc_strv_append(&src, "string3"); + + rc = uc_strv_append_all(&dst, &src, 1); + fail_if(rc != 0); + fail_if(dst.cnt != 3); + ck_assert_str_eq("string1", dst.strings[0]); + ck_assert_str_eq("string2", dst.strings[1]); + ck_assert_str_eq("string3", dst.strings[2]); + + uc_strv_destroy(&src); + uc_strv_destroy(&dst); + +END_TEST + +START_TEST (test_strv_append_all_nocopy) + struct UCStrv src; + struct UCStrv dst; + int rc; + + uc_strv_init(&src); + uc_strv_init(&dst); + + uc_strv_append(&dst, "string1"); + uc_strv_append(&src, "string2"); + uc_strv_append(&src, "string3"); + + rc = uc_strv_append_all(&dst, &src, 0); + fail_if(rc != 0); + fail_if(dst.cnt != 3); + ck_assert_str_eq("string1", dst.strings[0]); + ck_assert_str_eq("string2", dst.strings[1]); + ck_assert_str_eq("string3", dst.strings[2]); + + uc_strv_destroy(&dst); + free(src.strings); + +END_TEST + Suite *strv_suite(void) { @@ -83,6 +132,8 @@ Suite *strv_suite(void) tcase_add_test(tc, test_strv_clear); tcase_add_test(tc, test_strv_nocopy); tcase_add_test(tc, test_strv_null_terminate); + tcase_add_test(tc, test_strv_append_all_copy); + tcase_add_test(tc, test_strv_append_all_nocopy); suite_add_tcase(s, tc);