diff options
author | LAN-TW <lantw44@gmail.com> | 2013-12-07 17:22:33 +0800 |
---|---|---|
committer | LAN-TW <lantw44@gmail.com> | 2013-12-07 17:24:32 +0800 |
commit | 6df97cb16c8c1bc2a584630b772941dacc124243 (patch) | |
tree | 4524845d607bdc1e09ec94a7d91cdbba7ba92afc | |
parent | 271dae160214fa04039fb0f4226b60551c00b375 (diff) | |
download | l4basic-6df97cb16c8c1bc2a584630b772941dacc124243.tar.gz l4basic-6df97cb16c8c1bc2a584630b772941dacc124243.tar.zst l4basic-6df97cb16c8c1bc2a584630b772941dacc124243.zip |
Rewrite dynamic array (LbsArray) and add test suitel4basic-unstable-1.91
-rw-r--r-- | Makefile | 44 | ||||
-rw-r--r-- | VERSION | 2 | ||||
-rw-r--r-- | l4array.c | 304 | ||||
-rw-r--r-- | l4array.h | 129 | ||||
-rw-r--r-- | l4common.h | 23 | ||||
-rw-r--r-- | test-array.c | 186 |
6 files changed, 510 insertions, 178 deletions
@@ -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: @@ -1 +1 @@ -1.90.0 +1.91.0 @@ -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; } @@ -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; +} |