aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile44
-rw-r--r--VERSION2
-rw-r--r--l4array.c304
-rw-r--r--l4array.h129
-rw-r--r--l4common.h23
-rw-r--r--test-array.c186
6 files changed, 510 insertions, 178 deletions
diff --git a/Makefile b/Makefile
index 1a790fc..23564d2 100644
--- a/Makefile
+++ b/Makefile
@@ -16,8 +16,8 @@ CFLAGS= -g -O2 -pipe
LDFLAGS=
# Internal flags
-L4B_CFLAGS= -Wall -I. $(CFLAGS)
-L4B_LDFLAGS= $(LDFLAGS)
+M_CFLAGS= -Wall -I. $(CFLAGS)
+M_LDFLAGS= $(LDFLAGS)
# Installation
DESTDIR=
@@ -27,33 +27,59 @@ INCLUDEDIR= $(DESTDIR)$(PREFIX)/include
# Tasks definition
lib_LIBRARIES= libl4basic.a
-libl4basic_a_OBJECTS= l4array.o l4array2.o l4list.o l4arg.o
+libl4basic_a_OBJECTS= l4array.o l4array2.o l4file.o l4list.o l4arg.o
libl4basic_a_HEADERS= $(libl4basic_a_OBJECTS:.o=.h)
+check_PROGRAMS= test-array test-array2 test-file test-list test-arg
+check_OBJECTS= $(check_PROGRAMS:=.o)
+
# Build dependencies
-l4array_o_DEPENDS=
-l4array2_o_DEPENDS=
-l4list_o_DEPENDS=
-l4arg_o_DEPENDS= l4array.o
+l4array_o_DEPENDS= l4common.h
+l4array2_o_DEPENDS= l4common.h
+l4file_o_DEPENDS= l4common.h l4array.o
+l4list_o_DEPENDS= l4common.h
+l4arg_o_DEPENDS= l4common.h l4array.o
+
+test_array_o_DEPENDS= l4array.o
+test_array2_o_DEPENDS= l4array2.o
+test_file_o_DEPENDS= l4file.o
+test_list_o_DEPENDS= l4list.o
+test_arg_o_DEPENDS= l4arg.o
.POSIX:
.PHONY: all clean install install-HEADERS install-LIB \
uninstall deinstall remove
.SUFFIXES: .c.o
.c.o:
- $(CC) $(L4B_CFLAGS) -c $< -o $@
+ $(CC) $(M_CFLAGS) -c $< -o $@
all: $(lib_LIBRARIES)
+check: $(check_PROGRAMS)
+ for i in $(check_PROGRAMS); do ./$$i || exit 1; done
libl4basic.a: $(libl4basic_a_OBJECTS)
$(AR) rcs $@ $(libl4basic_a_OBJECTS)
$(RANLIB) $@
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)
l4arg.o: l4arg.c l4arg.h $(l4arg_o_DEPENDS)
+test-array: test-array.o $(test_array_o_DEPENDS)
+ $(CC) $(M_CFLAGS) test-array.o $(test_array_o_DEPENDS) -o $@ $(M_LDFLAGS)
+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-arg: test-arg.o $(test_arg_o_DEPENDS)
+ $(CC) $(M_CFLAGS) test-arg.o $(test_arg_o_DEPENDS) -o $@ $(M_LDFLAGS)
+
clean:
- $(RM) $(lib_LIBRARIES) $(libl4basic_a_OBJECTS)
+ -$(RM) \
+ $(lib_LIBRARIES) $(libl4basic_a_OBJECTS) \
+ $(check_PROGRAMS) $(check_OBJECTS)
install: all install-HEADERS install-LIB
install-LIB:
diff --git a/VERSION b/VERSION
index 82e24bf..6979a6c 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.90.0
+1.91.0
diff --git a/l4array.c b/l4array.c
index b57c021..fed2876 100644
--- a/l4array.c
+++ b/l4array.c
@@ -3,176 +3,230 @@
#include <stdlib.h>
#include <string.h>
-L4DA* l4da_create_setmax(int itemsize, int len, int maxlen){
- if(itemsize <= 0 || len < 0 || maxlen < len){
+LbsArray* lbs_array_new_with_max (size_t size, size_t max) {
+ if (size <= 0) {
return NULL;
}
- L4DA* arr = (L4DA*)malloc(sizeof(L4DA));
- if(arr == NULL){
+
+ LbsArray* array = malloc (sizeof (LbsArray));
+ if (array == NULL) {
return NULL;
}
- arr->arr_itemsize = itemsize;
- arr->arr_curlen = len;
- arr->arr_maxlen = maxlen;
- if(maxlen != 0){
- arr->arr_data = malloc(itemsize * maxlen);
- if(arr->arr_data == NULL){
- free(arr);
+
+ if (max > 0) {
+ void* data = malloc (size * max);
+ if (data == NULL) {
+ free (array);
return NULL;
}
- }else{
- arr->arr_data = NULL;
+ array->data = data;
+ } else {
+ array->data = NULL;
}
- return arr;
-}
-L4DA* l4da_create(int itemsize, int len){
- return l4da_create_setmax(itemsize, len, len);
+ array->free_func = NULL;
+ array->size = size;
+ array->len = max;
+ array->max = max;
+ array->ref_count = 1;
+ array->is_alloc = true;
+
+ return array;
}
-void l4da_free(L4DA* arr){
- if(arr->arr_data != NULL){
- free(arr->arr_data);
+int lbs_array_init_with_max (LbsArray* array, size_t size, size_t max) {
+ if (size <= 0) {
+ return -1;
}
- free(arr);
-}
-int l4da_pushback(L4DA* arr, const void* data){
- if((arr->arr_maxlen) < (arr->arr_curlen + 1)){
- if(arr->arr_maxlen != 0){
- if(l4da_setmax(arr, arr->arr_maxlen*2) < 0){
- return -1;
- }
- }else{
- if(l4da_setmax(arr, 1) < 0){
- return -1;
- }
+ if (max > 0) {
+ void* data = malloc (size * max);
+ if (data == NULL) {
+ return -1;
}
+ array->data = data;
+ } else {
+ array->data = NULL;
}
- memcpy(l4da_vp(arr, arr->arr_curlen), data, arr->arr_itemsize);
- arr->arr_curlen++;
+
+ array->free_func = NULL;
+ array->size = size;
+ array->len = max;
+ array->max = max;
+ array->ref_count = 1;
+ array->is_alloc = false;
+
return 0;
}
-int l4da_setlen(L4DA* arr, int len){
- if(len > (arr->arr_maxlen)){
- if(l4da_setmax(arr, len) < 0){
- return -1;
- }else{
- arr->arr_curlen = len;
+LbsArray* lbs_array_copy (LbsArray* dest, const LbsArray* src) {
+ if (dest == NULL) {
+ dest = lbs_array_new_with_max (src->size, src->max);
+ if (dest == NULL) {
+ return NULL;
+ }
+ } else {
+ if (lbs_array_init_with_max (dest, src->size, src->max) < 0) {
+ return NULL;
}
- }else{
- arr->arr_curlen = len;
- return 0;
}
- return 0;
+
+ dest->len = src->len;
+ dest->free_func = src->free_func;
+ memcpy (dest->data, src->data, src->size * src->len);
+ return dest;
}
-int l4da_setmax(L4DA* arr, int max){
- void* newptr;
- if(arr->arr_data == NULL){
- newptr = malloc((arr->arr_itemsize)*max);
- if(newptr == NULL){
- return -1;
- }else{
- arr->arr_maxlen = max;
- arr->arr_data = newptr;
- return 0;
- }
+LbsArray* lbs_array_cat (LbsArray* dest, const LbsArray* more) {
+ if (dest == NULL) {
+ return lbs_array_copy (dest, more);
}
- newptr = realloc(arr->arr_data, (arr->arr_itemsize)*max);
- if(newptr == NULL){
- return -1;
- }else{
- arr->arr_maxlen = max;
- arr->arr_data = newptr;
+
+ if (dest->size != more->size) {
+ return NULL;
}
- return 0;
+
+ int oldlen = dest->len;
+ if (lbs_array_set_len (dest, dest->len + more->len) < 0) {
+ return NULL;
+ }
+
+ memcpy (lbs_array_vp (dest, oldlen), more->data, more->size * more->len);
+ return dest;
}
-int l4da_strip(L4DA* arr){
- if(arr->arr_data == NULL){
- return 0;
+void* lbs_array_ref_generic (void* array_generic) {
+ LbsArray* array = LBS_ARRAY (array_generic);
+ int oldref = array->ref_count;
+ int newref = oldref + 1;
+ if (newref <= oldref) {
+ return NULL;
}
- L4DA* newptr;
- /* 其實縮小空間營該一定會成功才對......
- * 不過還是保險一點,加個判斷式,別說 memory leak 是我害的
- * 當然也是避免編譯器一直跳 warning
- */
- if((arr->arr_maxlen) > (arr->arr_curlen)){
- arr->arr_maxlen = arr->arr_curlen;
- newptr = realloc(arr->arr_data, (arr->arr_curlen)*(arr->arr_itemsize));
- if(newptr == NULL){
- return -1;
+
+ array->ref_count = newref;
+ return array;
+}
+
+void lbs_array_unref_generic (void* array_generic) {
+ LbsArray* array = LBS_ARRAY (array_generic);
+ array->ref_count--;
+ if (array->ref_count <= 0) {
+ lbs_array_free (array);
+ }
+}
+
+void lbs_array_free_generic (void* array_generic) {
+ LbsArray* array = LBS_ARRAY (array_generic);
+ if (array->free_func != NULL) {
+ int i = 0;
+ char* d = array->data;
+ for (; i < array->len; i++, d += array->size) {
+ (*(array->free_func)) (*((void**)d));
}
- arr->arr_data = newptr;
}
- return 0;
+ free (array->data);
+ if (array->is_alloc) {
+ free (array);
+ }
}
-/* 基本上直接玩 struct 的函式還是少用吧 */
-void* l4da_drop_struct(L4DA* arr){
- void* toreturn = arr->arr_data;
- free(arr);
- return toreturn;
+void* lbs_array_drop_struct (LbsArray* array) {
+ if (!array->is_alloc) {
+ return array->data;
+ }
+
+ void* data = array->data;
+ free (array);
+ return data;
}
-L4DA* l4da_make_struct(void* data, int itemsize, int len, int maxlen){
- if(itemsize <= 0 || len < 0 || maxlen < len){
- return NULL;
+LbsArray* lbs_array_make_struct (LbsArray* array,
+ size_t size, size_t len, size_t max, void* data) {
+
+ if (array == NULL) {
+ array = lbs_array_new (size);
+ if (array == NULL) {
+ return NULL;
+ }
+ } else {
+ if (lbs_array_init (array, size) < 0) {
+ return NULL;
+ }
}
- L4DA* arr = (L4DA*)malloc(sizeof(L4DA));
- if(arr == NULL){
- return NULL;
+
+ array->len = len;
+ array->max = max;
+ array->data = data;
+ return array;
+}
+
+int lbs_array_set_len (LbsArray* array, size_t len) {
+ if (len > (array->max)){
+ if (lbs_array_set_max (array, len) < 0) {
+ return -1;
+ } else {
+ array->len = len;
+ }
+ } else {
+ array->len = len;
+ return 0;
}
- arr->arr_itemsize = itemsize;
- arr->arr_curlen = len;
- arr->arr_maxlen = maxlen;
- arr->arr_data = data;
- return arr;
+ return 0;
}
-L4DA* l4da_dup(const L4DA* arr){
- L4DA* newarr = l4da_create_setmax(
- l4da_itemsize(arr), l4da_getlen(arr), l4da_getmax(arr));
- if(newarr == NULL){
- return NULL;
+int lbs_array_set_max (LbsArray* array, size_t max) {
+ void* ptr = realloc (array->data, array->size * max);
+ if (ptr == NULL) {
+ return -1;
}
- memcpy(newarr->arr_data, arr->arr_data,
- l4da_getlen(arr) * l4da_itemsize(arr));
- return newarr;
+
+ array->max = max;
+ array->data = ptr;
+ return 0;
}
-int l4da_combine(L4DA* arr, const L4DA* att){
- if(l4da_itemsize(arr) != l4da_itemsize(att)){
- return -2;
+int lbs_array_append_ptr (LbsArray* array, const void* ptr) {
+ return lbs_array_append_data (array, &ptr);
+}
+
+int lbs_array_append_data (LbsArray* array, const void* data) {
+ if (array->max < array->len + 1) {
+ if (array->max > 0){
+ if (lbs_array_set_max (array, array->max * 2) < 0) {
+ return -1;
+ }
+ } else {
+ if (lbs_array_set_max (array, 1) < 0){
+ return -1;
+ }
+ }
}
- if(l4da_setlen(arr, l4da_getlen(arr) + l4da_getlen(att)) < 0){
+
+ memcpy (lbs_array_vp (array, array->len), data, array->size);
+ array->len++;
+ return 0;
+}
+
+int lbs_array_remove (LbsArray* array) {
+ if (array->len <= 0) {
return -1;
}
- memcpy(l4da_vp(arr, l4da_getlen(arr)), att->arr_data,
- l4da_getlen(att) * l4da_itemsize(att));
+
+ array->len--;
+ if (array->len < array->max * 2) {
+ lbs_array_minimize (array);
+ }
return 0;
}
-L4DA* l4da_filereadline_delim(FILE* infile, int chr){
- L4DA* newarr = l4da_create(1, 0);
- if(newarr == NULL){
- return NULL;
- }
- int c;
- char towrite;
- while((c = getc(infile)) != chr && !feof(infile)){
- towrite = c;
- if(l4da_pushback(newarr, (void*)&towrite) < 0){
- l4da_free(newarr);
- return NULL;
+int lbs_array_minimize (LbsArray* array) {
+ if (array->max > array->len) {
+ void* ptr = realloc (array->data, array->size * array->len);
+ if (ptr == NULL) {
+ return -1;
}
+ array->max = array->len;
+ array->data = ptr;
}
- towrite = '\0';
- if(l4da_pushback(newarr, (void*)&towrite) < 0){
- l4da_free(newarr);
- return NULL;
- }
- return newarr;
+ return 0;
}
diff --git a/l4array.h b/l4array.h
index 192f49d..145f6c9 100644
--- a/l4array.h
+++ b/l4array.h
@@ -1,43 +1,86 @@
-#ifndef L4LIB_DYNAMIC_ARRAY
-#define L4LIB_DYNAMIC_ARRAY
-
-#include <stdio.h> /* 取得 FILE */
-
-/*********** 一維陣列 ***********/
-
-typedef struct l4lib_dyn_arr{
- int arr_itemsize; /* 每個項目的大小 */
- int arr_curlen; /* 陣列總長度 */
- int arr_maxlen; /* 陣列最大長度 */
- void* arr_data; /* 資料區 */
-} L4DA ;
-
-L4DA* l4da_create_setmax(int, int, int);
-L4DA* l4da_create(int, int);
-void l4da_free(L4DA*);
-int l4da_pushback(L4DA*, const void*);
-#define l4da_popback(arr) (((arr)->arr_curlen)--)
-#define l4da_getlen(arr) ((arr)->arr_curlen)
-int l4da_setlen(L4DA*, int);
-#define l4da_getmax(arr) ((arr)->arr_maxlen)
-int l4da_setmax(L4DA*, int);
-int l4da_strip(L4DA*);
-#define l4da_itemsize(arr) ((arr)->arr_itemsize)
-#define l4da_data(arr) ((arr)->arr_data)
-#define l4da_v(arr, type, num) \
- (*(((type*)((arr)->arr_data))+(num)))
-#define l4da_vp(arr, num) \
- ((void*)(((char*)((arr)->arr_data))+(((arr)->arr_itemsize)*(num))))
-
-#define l4da_readline() (l4da_filereadline_delim(stdin, '\n'))
-#define l4da_readline_delim(delim) (l4da_filereadline_delim(stdin, (delim)))
-#define l4da_filereadline(infile) (l4da_filereadline_delim((infile), '\n'))
-L4DA* l4da_filereadline_delim(FILE*, int);
-
-L4DA* l4da_dup(const L4DA*);
-int l4da_combine(L4DA*, const L4DA*);
-
-void* l4da_drop_struct(L4DA*);
-L4DA* l4da_make_struct(void*, int, int, int);
-
-#endif
+/* vim: set sw=4 ts=4 sts=4 et: */
+#ifndef LBS_ARRAY_H
+#define LBS_ARRAY_H
+
+#include <l4common.h>
+
+typedef struct LbsArrayStruct {
+ /*< public >*/
+ void* data; /* data */
+ size_t len; /* current length */
+ void (*free_func) (void* data);
+ /* function to free the element */
+
+ /*< private >*/
+ size_t size; /* element size */
+ size_t max; /* maximal length */
+ unsigned ref_count; /* reference count */
+ bool is_alloc; /* is allocated using malloc */
+} LbsArray;
+
+#define LBS_ARRAY(x) ((LbsArray*)(x))
+
+#define lbs_array_new(size) \
+ (lbs_array_new_with_max (size, 0))
+LbsArray* lbs_array_new_with_max (size_t size, size_t max);
+
+#define lbs_array_init(array, size) \
+ (lbs_array_init_with_max (array, size, 0))
+int lbs_array_init_with_max (LbsArray* array, size_t size, size_t max);
+
+LbsArray* lbs_array_copy (LbsArray* dest, const LbsArray* src);
+LbsArray* lbs_array_cat (LbsArray* dest, const LbsArray* more);
+
+#define lbs_array_ref(array) \
+ (lbs_array_ref_generic (LBS_COMMON_CHECK_TYPE ((array), LbsArray*)))
+#define lbs_array_unref(array) \
+ (lbs_array_unref_generic (LBS_COMMON_CHECK_TYPE ((array), LbsArray*)))
+void* lbs_array_ref_generic (void* array);
+void lbs_array_unref_generic (void* array);
+
+#define lbs_array_free(array) \
+ (lbs_array_free_generic (LBS_COMMON_CHECK_TYPE ((array), LbsArray*)))
+void lbs_array_free_generic (void* array);
+void* lbs_array_drop_struct (LbsArray* array);
+LbsArray* lbs_array_make_struct (LbsArray* array, size_t size, size_t len,
+ size_t max, void* data);
+
+#define lbs_array_get_data(array) \
+ (LBS_COMMON_CHECK_TYPE ((array), LbsArray*)->data)
+#define lbs_array_get_size(array) \
+ (LBS_COMMON_CHECK_TYPE ((array), LbsArray*)->size)
+#define lbs_array_get_len(array) \
+ (LBS_COMMON_CHECK_TYPE ((array), LbsArray*)->len)
+#define lbs_array_get_max(array) \
+ (LBS_COMMON_CHECK_TYPE ((array), LbsArray*)->max)
+#define lbs_array_get_ref_count(array) \
+ (LBS_COMMON_CHECK_TYPE ((array), LbsArray*)->ref_count)
+#define lbs_array_get_is_alloc(array) \
+ (LBS_COMMON_CHECK_TYPE ((array), LbsArray*)->is_alloc)
+#define lbs_array_get_free_func(array) \
+ (LBS_COMMON_CHECK_TYPE ((array), LbsArray*)->free_func)
+
+int lbs_array_set_len (LbsArray* array, size_t len);
+int lbs_array_set_max (LbsArray* array, size_t max);
+#define lbs_array_set_free_func(array,value) \
+ ((LBS_COMMON_CHECK_TYPE ((array), LbsArray*)->free_func) = (value))
+
+#define lbs_array_append_var(array,var) \
+ lbs_array_append_data ((array), (&(var)))
+int lbs_array_append_ptr (LbsArray* array, const void* ptr);
+int lbs_array_append_data (LbsArray* array, const void* data);
+int lbs_array_remove (LbsArray* array);
+int lbs_array_minimize (LbsArray* array);
+#define lbs_array_push_back lbs_array_append_data
+#define lbs_array_push lbs_array_append_data
+#define lbs_array_pop_back lbs_array_remove
+#define lbs_array_pop lbs_array_remove
+
+#define lbs_array_vp(array, index) \
+ ((void*)(((char*)((array)->data))+(((array)->size)*(index))))
+#define lbs_array_v(array, type, index) \
+ (*(((type*)((array)->data))+(index)))
+#define lbs_array_index lbs_array_v
+#define lbs_array_index_ptr lbs_array_vp
+
+#endif /* LBS_ARRAY_H */
diff --git a/l4common.h b/l4common.h
new file mode 100644
index 0000000..34eef26
--- /dev/null
+++ b/l4common.h
@@ -0,0 +1,23 @@
+#ifndef LBS_COMMON_H
+#define LBS_COMMON_H
+
+#include <stddef.h>
+
+#ifdef __STDC_VERSION__
+# include <stdbool.h>
+# if __STDC_VERSION__ >= 201112L
+# define LBS_COMMON_ISO_C11
+# define LBS_COMMON_CHECK_TYPE(x,type) (_Generic ((x), type: (x)))
+# else
+# define LBS_COMMON_ISO_C99
+# define LBS_COMMON_CHECK_TYPE(x,type) (x)
+# endif
+#else
+# define bool char
+# define true 1
+# define false 0
+# define LBS_COMMON_ISO_C89
+# define LBS_COMMON_CHECK_TYPE(x,type) (x)
+#endif /* __STDC_VERSION__ */
+
+#endif /* LBS_COMMON_H */
diff --git a/test-array.c b/test-array.c
new file mode 100644
index 0000000..d2a4d20
--- /dev/null
+++ b/test-array.c
@@ -0,0 +1,186 @@
+#undef NDEBUG
+#define _POSIX_C_SOURCE 200809L
+#include <l4array.h>
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+void test_array_new (void) {
+ const char tc[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+ const size_t tc_len = sizeof (tc) / sizeof (char);
+
+ LbsArray* array = lbs_array_new (sizeof (char));
+ for (int i = 0; i < tc_len; i++) {
+ lbs_array_append_data (array, &tc[i]);
+ }
+
+ assert (lbs_array_get_len (array) == tc_len);
+ assert (lbs_array_get_size (array) == sizeof (char));
+ assert (lbs_array_get_is_alloc (array) == true);
+ assert (memcmp (tc, lbs_array_get_data (array), sizeof (tc)) == 0);
+ lbs_array_unref (array);
+
+ printf ("%s => PASS!\n", __func__);
+}
+
+void test_array_init (void) {
+ const char tc[] = "0123456789abcdefghijklmnopqrstuvwxyz";
+ const size_t tc_len = sizeof (tc) / sizeof (char);
+
+ LbsArray array_struct;
+ LbsArray* array = &array_struct;
+ lbs_array_init (array, sizeof (char));
+ for (int i = 0; i < tc_len; i++) {
+ lbs_array_append_data (array, &tc[i]);
+ }
+
+ assert (lbs_array_get_len (array) == tc_len);
+ assert (lbs_array_get_size (array) == sizeof (char));
+ assert (lbs_array_get_is_alloc (array) == false);
+ assert (memcmp (tc, lbs_array_get_data (array), sizeof (tc)) == 0);
+ lbs_array_unref (array);
+
+ printf ("%s => PASS!\n", __func__);
+}
+
+void test_array_copy (void) {
+ const char tc[] = "b1dc8070-3847-4ec6-8486-65d4e32d16b5";
+ const size_t tc_len = sizeof (tc) / sizeof (char);
+
+ LbsArray* array = lbs_array_new_with_max (sizeof (char), tc_len);
+ for (int i = 0; i < tc_len; i++) {
+ lbs_array_append_data (array, &tc[i]);
+ }
+
+ LbsArray* array_copy = lbs_array_copy (NULL, array);
+ assert (lbs_array_get_len (array) == lbs_array_get_len (array_copy));
+ assert (lbs_array_get_size (array) == lbs_array_get_size (array_copy));
+ assert (memcmp (lbs_array_get_data (array),
+ lbs_array_get_data (array_copy), sizeof (tc)) == 0);
+
+ lbs_array_unref (array);
+ lbs_array_unref (array_copy);
+
+ printf ("%s => PASS!\n", __func__);
+}
+
+void test_array_cat (void) {
+ char* tc1 = malloc (15);
+ char* tc2 = malloc (15);
+ strcpy (tc1, "!@#$%^&*()TGQ");
+ strcpy (tc2, ":;<>?/[]{}");
+ size_t tc1_len = strlen (tc1);
+ size_t tc2_len = strlen (tc2);
+
+ LbsArray *cat, *a1, *a2, a2_struct;
+ a1 = lbs_array_make_struct (NULL, sizeof (char), tc1_len, 15, tc1);
+ a2 = &a2_struct;
+ a2 = lbs_array_make_struct (a2, sizeof (char), tc2_len, 15, tc2);
+ cat = lbs_array_cat (a1, a2);
+
+ assert (a1 == cat);
+ assert (lbs_array_get_len (cat) == tc1_len + tc2_len);
+ assert (lbs_array_get_size (cat) == lbs_array_get_size (a2));
+ assert (memcmp (lbs_array_get_data (cat),
+ lbs_array_get_data (a1), sizeof (char) * tc1_len) == 0);
+ assert (memcmp (lbs_array_vp (cat, tc1_len),
+ lbs_array_get_data (a2), sizeof (char) * tc2_len) == 0);
+
+ lbs_array_unref (a1);
+ free (lbs_array_drop_struct (a2));
+
+ printf ("%s => PASS!\n", __func__);
+}
+
+void test_array_ref (void) {
+ LbsArray* array = lbs_array_new (16);
+ assert (lbs_array_get_ref_count (array) == 1);
+ assert (lbs_array_ref (array) == array);
+ assert (lbs_array_ref (array) == array);
+ assert (lbs_array_ref (array) == array);
+ assert (lbs_array_get_ref_count (array) == 4);
+ lbs_array_unref (array);
+ lbs_array_unref (array);
+ lbs_array_unref (array);
+ assert (lbs_array_get_ref_count (array) == 1);
+ lbs_array_unref (array);
+
+ printf ("%s => PASS!\n", __func__);
+}
+
+void test_array_ptr (void) {
+ const char* tc[] = {
+ "260740d8-6d94-41fc-9235-ee6b11209547",
+ "8613ff0b-4429-4432-8870-a79477665a89",
+ "b05adbb1-b628-4b49-8661-5576c477ea6e",
+ "641992b6-c5a5-4855-9448-11343a60ad67",
+ "74380d26-376a-4754-be5e-41cb62e52d86",
+ NULL
+ };
+ const size_t tc_len = sizeof (tc) / sizeof (char*);
+
+ /* This is a pointer array, so we use generic pointer (void*) */
+ LbsArray* ptr_array = lbs_array_new (sizeof (void*));
+ lbs_array_set_free_func (ptr_array, free);
+ for (int i = 0; i < tc_len; i++) {
+ if (tc[i] != NULL) {
+ lbs_array_append_ptr (ptr_array, strdup (tc[i]));
+ } else {
+ lbs_array_append_ptr (ptr_array, NULL);
+ }
+ }
+
+ assert (lbs_array_v (ptr_array, char*, tc_len - 1) == NULL);
+ assert (lbs_array_get_len (ptr_array) == tc_len);
+ for (int i = 0; i < tc_len - 1; i++) {
+ if (tc[i] != NULL) {
+ assert (strcmp (lbs_array_v (ptr_array, char*, i), tc[i]) == 0);
+ }
+ }
+ lbs_array_unref (ptr_array);
+
+ printf ("%s => PASS!\n", __func__);
+}
+
+void test_array_op (void) {
+ LbsArray* array = lbs_array_new (sizeof (int));
+ for (int i = 0; i < 80; i++) {
+#ifdef LBS_COMMON_ISO_C11
+ lbs_array_append (array, i);
+#else
+ lbs_array_append_data (array, &i);
+#endif
+ }
+
+ lbs_array_remove (array);
+ lbs_array_remove (array);
+ lbs_array_remove (array);
+ assert (lbs_array_get_len (array) == 77);
+
+ array->len = 20;
+ lbs_array_minimize (array);
+ assert (lbs_array_get_len (array) == 20);
+
+ array->len = 10;
+ lbs_array_v (array, int, 15) = 82;
+ for (int i = 0; i < 10; i++) {
+ assert (lbs_array_v (array, int, i) == i);
+ }
+
+ lbs_array_unref (array);
+ printf ("%s => PASS!\n", __func__);
+}
+
+int main () {
+ test_array_new ();
+ test_array_init ();
+ test_array_copy ();
+ test_array_cat ();
+ test_array_ref ();
+ test_array_ptr ();
+ test_array_op ();
+ return 0;
+}