aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLAN-TW <lantw44@gmail.com>2013-12-14 15:30:44 +0800
committerLAN-TW <lantw44@gmail.com>2013-12-14 15:30:44 +0800
commitaada971bb36304c9eb3bdd2a88993a84139402ca (patch)
treedc4c0949f584e3361f7d997975a7a3249176eb2c
parent6bb04f938c70f65d96cf596dd1fbf570dfd07c59 (diff)
downloadl4basic-aada971bb36304c9eb3bdd2a88993a84139402ca.tar.gz
l4basic-aada971bb36304c9eb3bdd2a88993a84139402ca.tar.zst
l4basic-aada971bb36304c9eb3bdd2a88993a84139402ca.zip
Add string vector manager (LbsStrv) and add test suite
-rw-r--r--Makefile21
-rw-r--r--l4strv.c285
-rw-r--r--l4strv.h75
-rw-r--r--test-strv.c188
4 files changed, 562 insertions, 7 deletions
diff --git a/Makefile b/Makefile
index d666836..92a1ae3 100644
--- a/Makefile
+++ b/Makefile
@@ -27,24 +27,28 @@ INCLUDEDIR= $(DESTDIR)$(PREFIX)/include
# Tasks definition
lib_LIBRARIES= libl4basic.a
-libl4basic_a_OBJECTS= l4array.o l4array2.o l4file.o l4list.o l4arg.o
+libl4basic_a_OBJECTS= l4array.o l4array2.o l4file.o l4strv.o l4arg.o \
+ l4list.o
libl4basic_a_HEADERS= $(libl4basic_a_OBJECTS:.o=.h) l4common.h
-check_PROGRAMS= test-array test-array2 test-file test-list test-arg
+check_PROGRAMS= test-array test-array2 test-file test-strv test-arg \
+ test-list
check_OBJECTS= $(check_PROGRAMS:=.o)
# Build dependencies
l4array_o_DEPENDS= l4common.h
l4array2_o_DEPENDS= l4common.h
l4file_o_DEPENDS= l4common.h l4array.o
-l4list_o_DEPENDS= l4common.h
+l4strv_o_DEPENDS= l4common.h l4array.o
l4arg_o_DEPENDS= l4common.h l4array.o
+l4list_o_DEPENDS= l4common.h
test_array_o_DEPENDS= l4array.o
test_array2_o_DEPENDS= l4array2.o
test_file_o_DEPENDS= l4file.o l4array.o
-test_list_o_DEPENDS= l4list.o
+test_strv_o_DEPENDS= l4strv.o l4array.o
test_arg_o_DEPENDS= l4arg.o l4array.o
+test_list_o_DEPENDS= l4list.o
.POSIX:
.PHONY: all clean install install-HEADERS install-LIB \
@@ -62,8 +66,9 @@ libl4basic.a: $(libl4basic_a_OBJECTS)
l4array.o: l4array.c l4array.h $(l4array_o_DEPENDS)
l4array2.o: l4array2.c l4array2.h $(l4array2_o_DEPENDS)
l4file.o: l4file.c l4file.h $(l4file_o_DEPENDS)
-l4list.o: l4list.c l4list.h $(l4list_o_DEPENDS)
+l4strv.o: l4strv.c l4strv.h $(l4strv_o_DEPENDS)
l4arg.o: l4arg.c l4arg.h $(l4arg_o_DEPENDS)
+l4list.o: l4list.c l4list.h $(l4list_o_DEPENDS)
test-array: test-array.o $(test_array_o_DEPENDS)
$(CC) $(M_CFLAGS) test-array.o $(test_array_o_DEPENDS) -o $@ $(M_LDFLAGS)
@@ -71,10 +76,12 @@ test-array2: test-array2.o $(test_array2_o_DEPENDS)
$(CC) $(M_CFLAGS) test-array2.o $(test_array2_o_DEPENDS) -o $@ $(M_LDFLAGS)
test-file: test-file.o $(test_file_o_DEPENDS)
$(CC) $(M_CFLAGS) test-file.o $(test_file_o_DEPENDS) -o $@ $(M_LDFLAGS)
-test-list: test-list.o $(test_list_o_DEPENDS)
- $(CC) $(M_CFLAGS) test-list.o $(test_list_o_DEPENDS) -o $@ $(M_LDFLAGS)
+test-strv: test-strv.o $(test_strv_o_DEPENDS)
+ $(CC) $(M_CFLAGS) test-strv.o $(test_strv_o_DEPENDS) -o $@ $(M_LDFLAGS)
test-arg: test-arg.o $(test_arg_o_DEPENDS)
$(CC) $(M_CFLAGS) test-arg.o $(test_arg_o_DEPENDS) -o $@ $(M_LDFLAGS)
+test-list: test-list.o $(test_list_o_DEPENDS)
+ $(CC) $(M_CFLAGS) test-list.o $(test_list_o_DEPENDS) -o $@ $(M_LDFLAGS)
clean:
-$(RM) \
diff --git a/l4strv.c b/l4strv.c
new file mode 100644
index 0000000..26e9969
--- /dev/null
+++ b/l4strv.c
@@ -0,0 +1,285 @@
+/* vim: set sw=4 ts=4 sts=4 et: */
+
+#include "l4strv.h"
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+LbsStrv* lbs_strv_new_with_max (size_t max) {
+ LbsStrv* strv = malloc (sizeof (LbsStrv));
+ if (strv == NULL) {
+ return NULL;
+ }
+
+ if (lbs_array_init (&strv->array, sizeof (LbsArray)) < 0) {
+ free (strv);
+ return NULL;
+ }
+
+ strv->ref_count = 1;
+ strv->is_alloc = true;
+ return strv;
+}
+
+int lbs_strv_init_with_max (LbsStrv* strv, size_t max) {
+ if (lbs_array_init (&strv->array, sizeof (LbsArray)) < 0) {
+ return -1;
+ }
+
+ strv->ref_count = 1;
+ strv->is_alloc = false;
+ return 0;
+}
+
+void* lbs_strv_ref_generic (void* strv_generic) {
+ LbsStrv* strv = LBS_STRV (strv_generic);
+ strv->ref_count++;
+ return strv;
+}
+
+void lbs_strv_unref_generic (void* strv_generic) {
+ if (strv_generic == NULL) {
+ return;
+ }
+ LbsStrv* strv = LBS_STRV (strv_generic);
+ strv->ref_count--;
+ if (strv->ref_count <= 0) {
+ lbs_strv_free (strv);
+ }
+}
+
+void lbs_strv_free_generic (void* strv_generic) {
+ if (strv_generic == NULL) {
+ return;
+ }
+ LbsStrv* strv = LBS_STRV (strv_generic);
+ int i = 0;
+ for (; i < lbs_strv_get_len (strv); i++) {
+ LbsArray* str_wrapper = lbs_strv_get_str_wrapper (strv, i);
+ lbs_array_unref (str_wrapper);
+ }
+ lbs_array_unref (&strv->array);
+ if (strv->is_alloc) {
+ free (strv);
+ }
+}
+
+char* lbs_strv_dup_str (LbsStrv* strv, size_t stri) {
+ LbsArray* str_wrapper = lbs_strv_get_str_wrapper (strv, stri);
+ size_t len = lbs_array_get_len (str_wrapper);
+ char* str = lbs_array_get_data (str_wrapper);
+
+ char* str_new = malloc (len + sizeof (char));
+ strncpy (str_new, str, len);
+ str_new[len] = '\0';
+
+ return str_new;
+}
+
+int lbs_strv_append_char (LbsStrv* strv, size_t stri, char chr) {
+ if (chr == '\0') {
+ return -1;
+ }
+
+ if (stri >= lbs_strv_get_len (strv)) {
+ stri = lbs_strv_get_len (strv);
+ LbsArray str_struct;
+ LbsArray* str = &str_struct;
+ if (lbs_array_init (str, sizeof (char)) < 0) {
+ return -1;
+ }
+ if (lbs_array_append_data (&strv->array, str) < 0) {
+ lbs_array_unref (str);
+ return -1;
+ }
+ }
+ LbsArray* str = lbs_strv_get_str_wrapper (strv, stri);
+ return lbs_array_append_data (str, &chr);
+}
+
+int lbs_strv_append_str (LbsStrv* strv, const char* bstr) {
+ if (bstr == NULL) {
+ return -1;
+ }
+
+ size_t len = strlen (bstr);
+ char* str_copy = malloc (sizeof (char) * len);
+ if (str_copy == NULL) {
+ return -1;
+ }
+ strncpy (str_copy, bstr, len);
+
+ LbsArray str_struct, *str = &str_struct;
+ if (lbs_array_make_struct (str, sizeof (char), len, len, str_copy) == NULL)
+ {
+ free (str_copy);
+ return -1;
+ }
+
+ if (lbs_array_append_data (&strv->array, &str_struct) < 0) {
+ lbs_array_unref (str);
+ free (str_copy);
+ return -1;
+ }
+
+ return 0;
+}
+
+int lbs_strv_append_strv (LbsStrv* strv, const char* const* bstrv) {
+ if (bstrv == NULL) {
+ return -1;
+ }
+
+ int i;
+ for (i = 0; bstrv[i] != NULL; i++) {
+ if (lbs_strv_append_str (strv, bstrv[i]) < 0) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+int lbs_strv_remove_str (LbsStrv* strv) {
+ size_t len = lbs_strv_get_len (strv);
+ if (len <= 0) {
+ return -1;
+ }
+
+ lbs_array_unref (lbs_strv_get_str_wrapper (strv, len - 1));
+ return lbs_array_remove (&strv->array);
+}
+
+int lbs_strv_minimize (LbsStrv* strv) {
+ if (lbs_array_minimize (&strv->array) < 0) {
+ return -1;
+ }
+
+ int i;
+ size_t len = lbs_strv_get_len (strv);
+ for (i = 0; i < len; i++) {
+ LbsArray* str = lbs_strv_get_str_wrapper (strv, i);
+ if (lbs_array_minimize (str) < 0) {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+char** lbs_strv_copy_strv (LbsStrv* strv) {
+ size_t len = lbs_strv_get_len (strv);
+ char** bstrv = malloc (sizeof (char*) * (len + 1));
+ if (bstrv == NULL) {
+ return NULL;
+ }
+
+ int i;
+ for (i = 0; i < len; i++) {
+ LbsArray* str = lbs_strv_get_str_wrapper (strv, i);
+ size_t str_len = lbs_array_get_len (str);
+ char* bstr = malloc (sizeof (char) * (str_len + 1));
+
+ strncpy (bstr, lbs_array_get_data (str), str_len);
+ bstr[str_len] = '\0';
+ bstrv[i] = bstr;
+ }
+ bstrv[len] = NULL;
+ return bstrv;
+}
+
+char** lbs_strv_drop_struct (LbsStrv* strv) {
+ char** bstrv = lbs_strv_copy_strv (strv);
+ if (bstrv == NULL) {
+ return NULL;
+ }
+
+ lbs_strv_free (strv);
+ return bstrv;
+}
+
+char** lbs_strv_generic_build (const char* str_first, ...) {
+ LbsArray bstrv_w_struct, *bstrv_w = &bstrv_w_struct;
+ va_list ap;
+ char* str;
+ char* str_copy;
+ size_t str_len;
+
+ if (lbs_array_init (bstrv_w, sizeof (void*)) < 0) {
+ return NULL;
+ }
+
+ va_start (ap, str_first);
+
+ str_len = strlen (str_first);
+ str_copy = malloc (sizeof (char) * (str_len + 1));
+ if (str_copy == NULL) {
+ lbs_array_unref (bstrv_w);
+ va_end (ap);
+ return NULL;
+ }
+ strcpy (str_copy, str_first);
+
+ if (lbs_array_append_ptr (bstrv_w, str_copy) < 0) {
+ free (str_copy);
+ lbs_array_unref (bstrv_w);
+ va_end (ap);
+ return NULL;
+ }
+
+
+ while ((str = va_arg (ap, char*)) != NULL) {
+ str_len = strlen (str);
+ str_copy = malloc (sizeof (char) * (str_len + 1));
+ if (str_copy == NULL) {
+ lbs_array_unref (bstrv_w);
+ va_end (ap);
+ return NULL;
+ }
+ strcpy (str_copy, str);
+
+ if (lbs_array_append_ptr (bstrv_w, str_copy) < 0) {
+ free (str_copy);
+ lbs_array_unref (bstrv_w);
+ va_end (ap);
+ return NULL;
+ }
+ }
+ if (lbs_array_append_ptr (bstrv_w, NULL) < 0) {
+ lbs_array_unref (bstrv_w);
+ va_end (ap);
+ return NULL;
+ }
+
+ va_end (ap);
+
+ return lbs_array_drop_struct (bstrv_w);
+}
+
+int lbs_strv_generic_cmp (
+ const char* const* bstrv1, const char* const* bstrv2) {
+ int i;
+ for (i = 0; bstrv1[i] != NULL && bstrv2[i] != NULL; i++) {
+ int r = strcmp (bstrv1[i], bstrv2[i]);
+ if (r != 0) {
+ return r;
+ }
+ }
+
+ if (bstrv1[i] != NULL) {
+ return 1;
+ }
+ if (bstrv2[i] != NULL) {
+ return -1;
+ }
+
+ return 0;
+}
+
+void lbs_strv_generic_free (char** bstrv) {
+ int i;
+ for (i = 0; bstrv[i] != NULL; i++) {
+ free (bstrv[i]);
+ }
+ free (bstrv);
+}
diff --git a/l4strv.h b/l4strv.h
new file mode 100644
index 0000000..1ce5cfc
--- /dev/null
+++ b/l4strv.h
@@ -0,0 +1,75 @@
+/* vim: set sw=4 ts=4 sts=4 et: */
+#ifndef LBS_STRV_H
+#define LBS_STRV_H
+
+#include <l4common.h>
+#include <l4array.h>
+
+typedef struct LbsStrvStruct {
+ /*< private >*/
+ LbsArray array; /* data */
+ unsigned ref_count; /* reference count */
+ bool is_alloc; /* is allocated using malloc */
+} LbsStrv;
+
+#define LBS_STRV(x) ((LbsStrv*)(x))
+#define LBS_STRV_GENERIC(x) ((char**)(x))
+#define LBS_STRV_GENERIC_CONST(x) ((const char* const*)(x))
+
+#define lbs_strv_new() (lbs_strv_new_with_max (0))
+LbsStrv* lbs_strv_new_with_max (size_t max);
+
+#define lbs_strv_init(strv) (lbs_strv_init_with_max (strv, 0))
+int lbs_strv_init_with_max (LbsStrv* strv, size_t max);
+
+#define lbs_strv_ref(strv) \
+ (lbs_strv_ref_generic (LBS_COMMON_CHECK_TYPE ((strv), LbsStrv*)))
+#define lbs_strv_unref(strv) \
+ (lbs_strv_unref_generic (LBS_COMMON_CHECK_TYPE ((strv), LbsStrv*)))
+void* lbs_strv_ref_generic (void* strv);
+void lbs_strv_unref_generic (void* strv);
+
+#define lbs_strv_free(array) \
+ (lbs_strv_free_generic (LBS_COMMON_CHECK_TYPE ((strv), LbsStrv*)))
+void lbs_strv_free_generic (void* strv);
+
+#define lbs_strv_get_len(strv) \
+ (lbs_array_get_len (&(LBS_COMMON_CHECK_TYPE ((strv), LbsStrv*)->array)))
+#define lbs_strv_get_max(strv) \
+ (lbs_array_get_max (&(LBS_COMMON_CHECK_TYPE ((strv), LbsStrv*)->array)))
+#define lbs_strv_get_ref_count(strv) \
+ (LBS_COMMON_CHECK_TYPE ((strv), LbsStrv*)->ref_count)
+#define lbs_strv_get_is_alloc(strv) \
+ (LBS_COMMON_CHECK_TYPE ((strv), LbsStrv*)->is_alloc)
+#define lbs_strv_set_len(strv,len) \
+ (lbs_array_set_len (LBS_COMMON_CHECK_TYPE ((strv), LbsStrv*)->array, (len)))
+#define lbs_strv_set_max(strv,max) \
+ (lbs_array_set_max (LBS_COMMON_CHECK_TYPE ((strv), LbsStrv*)->array, (max)))
+
+char* lbs_strv_dup_str (LbsStrv* strv, size_t stri);
+#define lbs_strv_get_str_wrapper(strv,stri) \
+ (&(lbs_array_v (&((strv)->array), LbsArray, (stri))))
+#define lbs_strv_get_str_len(strv,stri) \
+ (lbs_array_get_len (lbs_strv_get_str_wrapper ((strv), (stri))))
+#define lbs_strv_get_str_not_null_terminated(strv, stri) \
+ ((char*)(lbs_array_get_data (lbs_strv_get_str_wrapper ((strv), (stri)))))
+#define lbs_strv_char(strv,stri,chri) \
+ (lbs_array_v (lbs_strv_get_str_wrapper (strv, stri), char, (chri)))
+
+int lbs_strv_append_char (LbsStrv* strv, size_t stri, char chr);
+int lbs_strv_append_str (LbsStrv* strv, const char* bstr);
+int lbs_strv_append_strv (LbsStrv* strv, const char* const* bstrv);
+int lbs_strv_remove_str (LbsStrv* strv);
+#define lbs_strv_remove_char(strv,stri) \
+ (lbs_array_remove (lbs_strv_get_str_wrapper ((strv), (stri))))
+
+int lbs_strv_minimize (LbsStrv* strv);
+char** lbs_strv_copy_strv (LbsStrv* strv);
+char** lbs_strv_drop_struct (LbsStrv* strv);
+
+char** lbs_strv_generic_build (const char* str, ...);
+int lbs_strv_generic_cmp (const char* const* bstrv1,
+ const char* const* bstrv2);
+void lbs_strv_generic_free (char** bstrv);
+
+#endif /* LBS_STRV_H */
diff --git a/test-strv.c b/test-strv.c
new file mode 100644
index 0000000..63fede2
--- /dev/null
+++ b/test-strv.c
@@ -0,0 +1,188 @@
+/* vim: set sw=4 ts=4 sts=4 et: */
+#undef NDEBUG
+#define _POSIX_C_SOURCE 200809L
+#include <l4strv.h>
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+void test_strv_new (void) {
+ const char* tc[] = {
+ "ABC", "DEF", "GHIJKL", "MNOP", "QRST", "UVWXYZ", NULL
+ };
+ const size_t tc_len = sizeof (tc) / sizeof (char*);
+
+ LbsStrv* strv = lbs_strv_new ();
+ for (int i = 0; i < tc_len; i++) {
+ lbs_strv_append_str (strv, tc[i]);
+ }
+
+ assert (lbs_strv_get_len (strv) == tc_len - 1);
+ for (int i = 0; i < lbs_strv_get_len (strv); i++) {
+ char* str = lbs_strv_dup_str (strv, i);
+ assert (strcmp (str, tc[i]) == 0);
+ free (str);
+ }
+
+ assert (lbs_strv_get_ref_count (strv) == 1);
+ assert (lbs_strv_get_is_alloc (strv) == true);
+ lbs_strv_unref (strv);
+
+ printf ("%s => PASS!\n", __func__);
+}
+
+void test_strv_init (void) {
+ const char* tc[] = {
+ "ABC", "DEF", "GHIJKL", "MNOP", "QRST", "UVWXYZ", NULL
+ };
+ const size_t tc_len = sizeof (tc) / sizeof (char*);
+
+ LbsStrv strv_struct;
+ LbsStrv* strv = &strv_struct;
+ lbs_strv_init (strv);
+ for (int i = 0; i < tc_len; i++) {
+ lbs_strv_append_str (strv, tc[i]);
+ }
+
+ assert (lbs_strv_get_len (strv) == tc_len - 1);
+ for (int i = 0; i < lbs_strv_get_len (strv); i++) {
+ char* str = lbs_strv_dup_str (strv, i);
+ assert (strcmp (str, tc[i]) == 0);
+ free (str);
+ }
+
+ assert (lbs_strv_get_ref_count (strv) == 1);
+ assert (lbs_strv_get_is_alloc (strv) == false);
+ lbs_strv_unref (strv);
+
+ printf ("%s => PASS!\n", __func__);
+}
+
+void test_strv_copy (void) {
+ const char* tc1[] = {
+ "ABC", "DEF", "GHIJKL", "MNOP", "QRST", "UVWXYZ", NULL
+ };
+ const size_t tc1_len = sizeof (tc1) / sizeof (char*);
+
+ const char* tc2[] = {
+ "01234", "5678", "9+_()", "<>?{}[]!@#$%^&*", NULL
+ };
+ const size_t tc2_len = sizeof (tc2) / sizeof (char*);
+
+ LbsStrv* strv = lbs_strv_new ();
+ lbs_strv_minimize (strv);
+ lbs_strv_append_strv (strv, tc1);
+ lbs_strv_append_strv (strv, tc2);
+ lbs_strv_minimize (strv);
+
+ assert (lbs_strv_get_len (strv) == lbs_strv_get_max (strv));
+ assert (lbs_strv_get_len (strv) == tc1_len + tc2_len - 2);
+
+ char** copy1 = lbs_strv_copy_strv (strv);
+ char** copy2 = lbs_strv_drop_struct (strv);
+
+ int vi = 0;
+ for (int i = 0; i < tc1_len - 1; i++, vi++) {
+ assert (strcmp (copy1[vi], tc1[i]) == 0);
+ assert (strcmp (copy2[vi], tc1[i]) == 0);
+ }
+ for (int i = 0; i < tc2_len - 1; i++, vi++) {
+ assert (strcmp (copy1[vi], tc2[i]) == 0);
+ assert (strcmp (copy2[vi], tc2[i]) == 0);
+ }
+
+ lbs_strv_generic_free (copy1);
+ lbs_strv_generic_free (copy2);
+
+ printf ("%s => PASS!\n", __func__);
+}
+
+void test_strv_ref (void) {
+ LbsStrv* strv = lbs_strv_new ();
+ assert (lbs_strv_get_ref_count (strv) == 1);
+ assert (lbs_strv_ref (strv) == strv);
+ assert (lbs_strv_get_ref_count (strv) == 2);
+ lbs_strv_unref (strv);
+ assert (lbs_strv_get_ref_count (strv) == 1);
+ lbs_strv_unref (strv);
+
+ printf ("%s => PASS!\n", __func__);
+}
+
+void test_strv_op (void) {
+ const char* tc[] = { "ABC", "UVWXYZ", NULL };
+ LbsStrv* strv = lbs_strv_new ();
+ lbs_strv_append_char (strv, 0, 'a');
+ lbs_strv_append_char (strv, 0, 't');
+ lbs_strv_append_char (strv, 0, 's');
+ lbs_strv_append_str (strv, "strv");
+ lbs_strv_append_strv (strv, tc);
+ lbs_strv_remove_char (strv, 3);
+ lbs_strv_remove_char (strv, 3);
+ lbs_strv_remove_char (strv, 3);
+ lbs_strv_append_str (strv, "Good");
+ lbs_strv_append_str (strv, "AC_AC_AC_AC_AC_AC_AC_AC_AC_AC_AC_AC_AC_AC");
+ lbs_strv_remove_str (strv);
+
+ assert (lbs_strv_get_len (strv) == 5);
+
+ assert (lbs_strv_get_str_len (strv, 0) == 3);
+ assert (memcmp (
+ lbs_strv_get_str_not_null_terminated (strv, 0), "ats", 3) == 0);
+
+ assert (lbs_strv_get_str_len (strv, 1) == 4);
+ assert (memcmp (
+ lbs_strv_get_str_not_null_terminated (strv, 1), "strv", 4) == 0);
+
+ assert (lbs_strv_get_str_len (strv, 2) == 3);
+ assert (memcmp (
+ lbs_strv_get_str_not_null_terminated (strv, 2), "ABC", 3) == 0);
+
+ assert (lbs_strv_get_str_len (strv, 3) == 3);
+ assert (memcmp (
+ lbs_strv_get_str_not_null_terminated (strv, 3), "UVW", 3) == 0);
+
+ assert (lbs_strv_get_str_len (strv, 4) == 4);
+ assert (memcmp (
+ lbs_strv_get_str_not_null_terminated (strv, 4), "Good", 4) == 0);
+
+ lbs_strv_unref (strv);
+
+ printf ("%s => PASS!\n", __func__);
+}
+
+void test_strv_generic (void) {
+ const char* tc[] = { "ABC", "DEF", "GHIJKL", "UVWXYZ", NULL };
+ LbsStrv* strv = lbs_strv_new ();
+ lbs_strv_append_strv (strv, tc);
+
+ char** copy1 = lbs_strv_copy_strv (strv);
+ char** copy2 = lbs_strv_generic_build (tc[0], tc[1], tc[2], tc[3], tc[4]);
+
+ for (int i = 0; i < 4; i++) {
+ assert (strcmp (copy1[i], tc[i]) == 0);
+ assert (strcmp (copy2[i], tc[i]) == 0);
+ }
+
+ assert (lbs_strv_generic_cmp (
+ LBS_STRV_GENERIC_CONST (copy1),
+ LBS_STRV_GENERIC_CONST (copy2)) == 0);
+
+ lbs_strv_unref (strv);
+ lbs_strv_generic_free (copy1);
+ lbs_strv_generic_free (copy2);
+
+ printf ("%s => PASS!\n", __func__);
+}
+
+int main () {
+ test_strv_new ();
+ test_strv_init ();
+ test_strv_copy ();
+ test_strv_ref ();
+ test_strv_op ();
+ test_strv_generic ();
+ return 0;
+}