diff options
author | LAN-TW <lantw44@gmail.com> | 2014-01-11 21:27:51 +0800 |
---|---|---|
committer | LAN-TW <lantw44@gmail.com> | 2014-01-11 21:30:49 +0800 |
commit | 600e2e611f426308bfb25601c62417f38198c1a6 (patch) | |
tree | 43edb14151ad72939bc11d978fb77f13a87c6111 | |
parent | e6333b32e01bc3e7541e2359bf3854a72837b6c3 (diff) | |
download | l4basic-unstable-1.93.tar.gz l4basic-unstable-1.93.tar.zst l4basic-unstable-1.93.zip |
Rewrite linked-list (LbsList) and add test suitel4basic-unstable-1.93
-rw-r--r-- | VERSION | 2 | ||||
-rw-r--r-- | l4list.c | 389 | ||||
-rw-r--r-- | l4list.h | 180 | ||||
-rw-r--r-- | test-list.c | 206 |
4 files changed, 497 insertions, 280 deletions
@@ -1 +1 @@ -1.92.0 +1.93.0 @@ -1,236 +1,199 @@ +/* vim: set sw=4 ts=4 sts=4 et: */ #include "l4list.h" #include <stdlib.h> #include <string.h> -L4LL* l4ll_create(void){ - L4LL* newlist = (L4LL*)malloc(sizeof(L4LL)); - if(newlist == NULL){ - return NULL; - } - newlist->list_first = NULL; - newlist->list_last = NULL; - newlist->list_len = 0; - return newlist; -} +LbsListMeta* lbs_list_meta_new (void (*free_func) (void*)) { + LbsListMeta* list = malloc (sizeof (LbsListMeta)); + if (list == NULL) { + return NULL; + } -void l4ll_free(L4LL* oldlist){ - if(oldlist->list_len <= 0){ - free(oldlist); - return; - } - L4LLNODE* i; - L4LLNODE* next; - for(i=oldlist->list_first; i!=NULL; i=next){ - next = i->node_next; - if(i->node_data_size){ /* 只要資料大小不為零,就還要釋放資料區 */ - free(i->node_data); - } - free(i); - } - free(oldlist); -} + list->first = NULL; + list->last = NULL; + list->len = 0; + list->free_func = free_func; -static L4LLNODE* -l4ll_initfirst(L4LL* list, const void* data, int size){ - /* 插入第一個資料,如果 list 不是空的就別用! - * 否則會造成資料結構混亂和 memory leak */ - L4LLNODE* node = (L4LLNODE*)malloc(sizeof(L4LLNODE)); - if(node == NULL){ - return NULL; - } - void* newdata; - if(size != 0){ - newdata = malloc(size); - if(newdata == NULL){ - free(node); - return NULL; - } - memcpy(newdata, data, size); - } - list->list_first = node; - list->list_last = node; - list->list_len = 1; - node->node_prev = NULL; - node->node_next = NULL; - node->node_data = (size != 0) ? newdata : NULL; - node->node_data_size = size; - return node; + return list; } -L4LLNODE* l4ll_insert_prev(L4LL* list, L4LLNODE* node, - const void* data, int size){ - /* list 送 NULL 來的我不理它,就自己去 segfault 吧 - * node 送 NULL 來只能在 list 是空的時候用 */ - if(list->list_len == 0){ - return l4ll_initfirst(list, data, size); - } - L4LLNODE* newnode = (L4LLNODE*)malloc(sizeof(L4LLNODE)); - if(newnode == NULL){ - return NULL; - } - void* newdata; - if(size != 0){ - newdata = malloc(size); - if(newdata == NULL){ - free(newnode); - return NULL; - } - memcpy(newdata, data, size); - } - list->list_len++; - if(list->list_first == node){ /* 如果是第一個,那要修改 list_first */ - list->list_first = newnode; - } - L4LLNODE* oldprev = node->node_prev; - node->node_prev = newnode; - newnode->node_next = node; - newnode->node_prev = oldprev; - if(oldprev != NULL){ - oldprev->node_next = newnode; - } - newnode->node_data = (size != 0) ? newdata : NULL; - newnode->node_data_size = size; - return newnode; -} +void lbs_list_meta_free (LbsListMeta* list) { + if (list == NULL) { + return; + } + if (list->len <= 0) { + free (list); + return; + } -L4LLNODE* l4ll_insert_next(L4LL* list, L4LLNODE* node, - const void* data, int size){ - /* 基本上同 l4ll_insert_prev */ - if(list->list_len == 0){ - return l4ll_initfirst(list, data, size); - } - L4LLNODE* newnode = (L4LLNODE*)malloc(sizeof(L4LLNODE)); - if(newnode == NULL){ - return NULL; - } - void* newdata; - if(size != 0){ - newdata = malloc(size); - if(newdata == NULL){ - free(newnode); - return NULL; - } - memcpy(newdata, data, size); - } - list->list_len++; - if(list->list_last == node){ - list->list_last = newnode; - } - L4LLNODE* oldnext = node->node_next; - node->node_next = newnode; - newnode->node_prev = node; - newnode->node_next = oldnext; - if(oldnext != NULL){ - oldnext->node_prev = newnode; - } - newnode->node_data = (size != 0) ? newdata : NULL; - newnode->node_data_size = size; - return newnode; + LbsList *iter, *next; + for (iter = list->first; iter != NULL; iter = next) { + next = iter->next; + if (iter->free_func != NULL) { + (*(iter->free_func)) (iter->data); + } else if (list->free_func != NULL) { + (*(list->free_func)) (iter->data); + } + free (iter); + } + free (list); } -void l4ll_remove(L4LL* list, L4LLNODE* node){ - /* 不要在 node 傳 NULL,這一點意義也沒有且我不知道會發生什麼事 */ - if(list->list_first == node){ - list->list_first = node->node_next; - } - if(list->list_last == node){ - list->list_last = node->node_prev; - } - list->list_len--; /* 不考慮長度為零的情況,空白是想要刪什麼? */ - L4LLNODE* oldnext = node->node_next; - L4LLNODE* oldprev = node->node_prev; - if(node->node_data_size != 0){ - free(node->node_data); - } - free(node); - if(oldnext != NULL){ - oldnext->node_prev = oldprev; - } - if(oldprev != NULL){ - oldprev->node_next = oldnext; - } -} +static LbsList* init_first_node (LbsListMeta* list, + void* data, void (*free_func) (void*)) { + + /* Warning: This function assumes the list is empty! */ + LbsList* node = malloc (sizeof (LbsList)); + if (node == NULL) { + return NULL; + } + + if (list != NULL) { + list->first = node; + list->last = node; + list->len = 1; + } -L4LLNODE* l4ll_goto(L4LLNODE* node, int count){ - int i; - if(count == 0){ - return node; - }else if(count > 0){ - for(i=1; i<=count; i++){ - node = node->node_next; - if(node == NULL){ - return NULL; - } - } - }else{ - count = -count; - for(i=1; i<=count; i++){ - node = node->node_prev; - if(node == NULL){ - return NULL; - } - } - } - return node; + node->prev = NULL; + node->next = NULL; + node->data = data; + node->free_func = free_func; + + return node; } -#if 0 -int l4ll_pushback(L4LL* list, void* data, int size){ - L4LLNODE* cur_save = list->list_current; /* 等一下要把現在位置搬回去 */ - list->list_current = list->list_last; - int result = l4ll_insnext(list, data, size); - if(result == 0){ /* 成功 */ - if(cur_save != NULL){ /* 原先的現在位置若為空就無意義了 */ - list->list_current = cur_save; - } - }else{ /* 失敗 */ - list->list_current = cur_save; - } - return result; +LbsList* lbs_list_insert_prev (LbsListMeta* list, LbsList* node, + void* data, void (*free_func) (void*)) { + + if (list != NULL && list->len <= 0) { + return init_first_node (list, data, free_func); + } + + LbsList* new_node = malloc (sizeof (LbsList)); + if (new_node == NULL) { + return NULL; + } + + if (node == NULL) { + new_node->prev = NULL; + new_node->next = NULL; + new_node->data = data; + new_node->free_func = free_func; + return new_node; + } + + if (list != NULL) { + list->len++; + if (list->first == node) { + list->first = new_node; + } + } + + LbsList* old_prev = node->prev; + node->prev = new_node; + new_node->next = node; + new_node->prev = old_prev; + if (old_prev != NULL) { + old_prev->next = new_node; + } + + new_node->data = data; + new_node->free_func = free_func; + return new_node; } +LbsList* lbs_list_insert_next (LbsListMeta* list, LbsList* node, + void* data, void (*free_func) (void*)) { + + if (list != NULL && list->len <= 0) { + return init_first_node (list, data, free_func); + } + + LbsList* new_node = malloc (sizeof (LbsList)); + if (new_node == NULL) { + return NULL; + } + + if (node == NULL) { + new_node->prev = NULL; + new_node->next = NULL; + new_node->data = data; + new_node->free_func = free_func; + return new_node; + } + + if (list != NULL) { + list->len++; + if(list->last == node){ + list->last = new_node; + } + } + + LbsList* old_next = node->next; + node->next = new_node; + new_node->prev = node; + new_node->next = old_next; + if (old_next != NULL) { + old_next->prev = new_node; + } -int l4ll_pushfront(L4LL*, void*){ /* 取自 l4ll_pushback */ - L4LLNODE* cur_save = list->list_current; - list->list_current = list->list_front; - int result = l4ll_insprev(list, data, size); - if(result == 0){ - if(cur_save != NULL){ - list->list_current = cur_save; - } - }else{ - list->list_current = cur_save; - } - return result; + new_node->data = data; + new_node->free_func = free_func; + return new_node; } -int l4ll_popback(L4LL*){ - L4LLNODE* cur_save = list->list_current; - L4LLNODE* last_save = list->list_last - list->list_current = last_save; - int result = l4ll_remove(list, L4LL_PREV); - if(result == 0){ - if(cur_save != NULL && ){ - list->list_current = cur_save; - } - }else{ - list->list_current = cur_save; - } - return result; +void lbs_list_remove (LbsListMeta* list, LbsList* node) { + /* node must not be NULL! */ + if (list != NULL) { + if (list->first == node) { + list->first = node->next; + } + if (list->last == node) { + list->last = node->prev; + } + if (list->len > 0) { + list->len--; + } + } + + LbsList* old_next = node->next; + LbsList* old_prev = node->prev; + + if (node->free_func != NULL) { + (*(node->free_func)) (node->data); + } else if (list != NULL && list->free_func != NULL) { + (*(list->free_func)) (node->data); + } + free (node); + + if (old_next != NULL) { + old_next->prev = old_prev; + } + if (old_prev != NULL) { + old_prev->next = old_next; + } } -int l4ll_popfront(L4LL*){ - L4LLNODE* cur_save = list->list_current; - list->list_current = list->list_first; - int result = l4ll_remove(list, L4LL_NEXT); - if(result == 0){ - if(cur_save != NULL){ - list->list_current = cur_save; - } - }else{ - list->list_current = cur_save; - } - return result; +LbsList* lbs_list_goto (LbsList* node, int count) { + int i; + + if (count > 0) { /* positive */ + for (i = 0; i < count; i++) { + node = node->next; + if (node == NULL) { + return NULL; + } + } + } else if (count < 0) { /* negative */ + count = -count; + for (i = 0; i < count; i++) { + node = node->prev; + if (node == NULL) { + return NULL; + } + } + } + + return node; } -#endif @@ -1,66 +1,114 @@ -#ifndef L4LIB_BASIC_DATA_STRUCTURE -#define L4LIB_BASIC_DATA_STRUCTURE - -/*********** list ***********/ - -typedef struct l4lib_list_node{ /* list 中每一個項目用的資料結構,會有很多個 */ - struct l4lib_list_node* node_prev; - struct l4lib_list_node* node_next; - void* node_data; - int node_data_size; -} L4LLNODE; - -typedef struct l4lib_list{ /* 管理 list 用的,每個 list 只有一個 */ - struct l4lib_list_node* list_first; - struct l4lib_list_node* list_last; - int list_len; -} L4LL; - -L4LL* l4ll_create(void); -void l4ll_free(L4LL*); -#define l4ll_prev(node) ((node)->node_prev) -#define l4ll_next(node) ((node)->node_next) -#define l4ll_len(list) ((list)->list_len) -#define l4ll_node_back(list) ((list)->list_last) -#define l4ll_node_front(list) ((list)->list_first) -#define l4ll_data(node) ((node)->node_data) -#define l4ll_datasize(node) ((node)->node_data_size) -L4LLNODE* l4ll_insert_prev(L4LL*, L4LLNODE*, const void*, int); -L4LLNODE* l4ll_insert_next(L4LL*, L4LLNODE*, const void*, int); -void l4ll_remove(L4LL*, L4LLNODE*); -#define l4ll_pushback(list,data,size) \ - (l4ll_insert_next((list),(l4ll_node_back(list)),(data),(size))) -#define l4ll_pushfront(list,data,size) \ - (l4ll_insert_prev((list),(l4ll_node_front(list)),(data),(size))) -#define l4ll_popback(list) \ - (l4ll_remove((list),(l4ll_node_back((list))))) -#define l4ll_popfront(list) \ - (l4ll_remove((list),(l4ll_node_front((list))))) -L4LLNODE* l4ll_goto(L4LLNODE*, int); - -/*********** stack ***********/ - -typedef L4LL L4STACK; -#define l4stack_create() (l4ll_create()) -#define l4stack_free(list) (l4ll_free(list)) -#define l4stack_push(list,data,size) (l4ll_pushback((list),(data),(size))) -#define l4stack_pop(list) (l4ll_popback(list)) -#define l4stack_len(list) (l4ll_len(list)) -#define l4stack_data(list) (l4ll_data(l4ll_node_back(list))) -#define l4stack_datasize(list) (l4ll_datasize(l4ll_node_back(list))) - -/*********** queue ***********/ - -typedef L4LL L4QUEUE; -#define l4queue_create() (l4ll_create()) -#define l4queue_free(list) (l4ll_free(list)) -#define l4queue_push(list,data,size) (l4ll_pushback((list),(data),(size))) -#define l4queue_pop(list) (l4ll_popfront(list)) -#define l4queue_len(list) (l4ll_len(list)) -#define l4queue_frontdata(list) (l4ll_data(l4ll_node_front(list))) -#define l4queue_frontdatasize(list) (l4ll_datasize(l4ll_node_front(list))) -#define l4queue_backdata(list) (l4ll_data(l4ll_node_back(list))) -#define l4queue_backdatasize(list) (l4ll_datasize(l4ll_node_back(list))) -#define l4queue_data(list) (l4queue_frontdata(list)) -#define l4queue_datasize(list) (l4queue_frontdatasize(list)) -#endif +/* vim: set sw=4 ts=4 sts=4 et: */ +#ifndef LBS_LIST_H +#define LBS_LIST_H + +#include <l4common.h> + +typedef struct LbsListStruct { /* list node */ + /*< private >*/ + struct LbsListStruct* prev; /* pointer to the previous node */ + struct LbsListStruct* next; /* pointer to the next node */ + + /*< public >*/ + void (*free_func) (void* data); /* function to free the data pointer */ + void* data; /* data pointer */ +} LbsList; + +typedef struct LbsListMetaStruct { /* list wrapper */ + /*< private >*/ + struct LbsListStruct* first; /* pointer to the first node in the list */ + struct LbsListStruct* last; /* pointer to the last node in the list */ + size_t len; /* current length of the list */ + + /*< public >*/ + void (*free_func) (void* data); + /* Function to free the data pointer. This function is used only if + * the free_func field in the node is set to NULL */ +} LbsListMeta; + +#define LBS_LIST(x) ((LbsList*)(x)) +#define LBS_LIST_META(x) ((LbsListMeta*)(x)) + +LbsListMeta* lbs_list_meta_new (void (*free_func) (void*)); +void lbs_list_meta_free (LbsListMeta* list); + +#define lbs_list_meta_get_first(list) \ + (LBS_COMMON_CHECK_TYPE ((list), LbsListMeta*)->first) +#define lbs_list_meta_get_last(list) \ + (LBS_COMMON_CHECK_TYPE ((list), LbsListMeta*)->last) +#define lbs_list_meta_get_len(list) \ + (LBS_COMMON_CHECK_TYPE ((list), LbsListMeta*)->len) +#define lbs_list_meta_get_free_func(list) \ + (LBS_COMMON_CHECK_TYPE ((list), LbsListMeta*)->free_func) + +#define lbs_list_meta_set_free_func(list,value) \ + ((LBS_COMMON_CHECK_TYPE ((list), LbsListMeta*)->free_func) = (value)) + +#define lbs_list_get_prev(node) \ + (LBS_COMMON_CHECK_TYPE ((node), LbsList*)->prev) +#define lbs_list_get_next(node) \ + (LBS_COMMON_CHECK_TYPE ((node), LbsList*)->next) +#define lbs_list_get_data(node) \ + (LBS_COMMON_CHECK_TYPE ((node), LbsList*)->data) +#define lbs_list_get_free_func(node) \ + (LBS_COMMON_CHECK_TYPE ((node), LbsList*)->free_func) + +#define lbs_list_set_data(node,value) \ + ((LBS_COMMON_CHECK_TYPE ((node), LbsList*)->data) = (value)) +#define lbs_list_set_free_func(node,value) \ + ((LBS_COMMON_CHECK_TYPE ((node), LbsList*)->free_func) = (value)) + +LbsList* lbs_list_insert_prev (LbsListMeta* list, LbsList* node, + void* data, void (*free_func) (void*)); +LbsList* lbs_list_insert_next (LbsListMeta* list, LbsList* node, + void* data, void (*free_func) (void*)); +void lbs_list_remove (LbsListMeta* list, LbsList* node); + +#define lbs_list_push_back(list,data,f) \ + (lbs_list_insert_next ((list), (lbs_list_meta_get_last (list)), (data), (f))) +#define lbs_list_push_front(list,data,f) \ + (lbs_list_insert_prev ((list), (lbs_list_meta_get_first (list)), (data), (f))) +#define lbs_list_pop_back(list) \ + (lbs_list_remove ((list), (lbs_list_meta_get_last ((list))))) +#define lbs_list_pop_front(list) \ + (lbs_list_remove ((list), (lbs_list_meta_get_first ((list))))) + +LbsList* lbs_list_goto (LbsList* node, int count); +#define lbs_list_meta_goto(list,count) \ + (lbs_list_goto ((lbs_list_meta_get_first (list)), (count))) + + +#ifndef LBS_LIST_DISABLE_STACK + +typedef LbsListMeta LbsStack; +#define lbs_stack_new(f) (lbs_list_meta_new (f)) +#define lbs_stack_free(stack) (lbs_list_meta_free (stack)) +#define lbs_stack_push(stack,data,f) \ + (lbs_list_push_back ((stack), (data), (f))) +#define lbs_stack_pop(stack) (lbs_list_pop_back (stack)) +#define lbs_stack_get_len(stack) (lbs_list_meta_get_len (stack)) +#define lbs_stack_get_data(stack) \ + (lbs_list_get_data (lbs_list_meta_get_last (stack))) + +#endif /* LBS_LIST_DISABLE_STACK */ + + +#ifndef LBS_LIST_DISABLE_QUEUE + +typedef LbsListMeta LbsQueue; +#define lbs_queue_new(f) (lbs_list_meta_new (f)) +#define lbs_queue_free(queue) (lbs_list_meta_free (queue)) +#define lbs_queue_enqueue(queue,data,f) \ + (lbs_list_push_back ((queue), (data), (f))) +#define lbs_queue_dequeue(queue) (lbs_list_pop_front (queue)) +#define lbs_queue_get_len(queue) (lbs_list_meta_get_len (queue)) +#define lbs_queue_get_front(queue) \ + (lbs_list_get_data (lbs_list_meta_get_first (queue))) +#define lbs_queue_get_back(queue) \ + (lbs_list_get_data (lbs_list_meta_get_last (queue))) +#define lbs_queue_get_data(queue) (lbs_queue_get_front (queue)) + +#endif /* LBS_LIST_DISABLE_QUEUE */ + + +#endif /* LBS_LIST_H */ diff --git a/test-list.c b/test-list.c new file mode 100644 index 0000000..71c26d3 --- /dev/null +++ b/test-list.c @@ -0,0 +1,206 @@ +/* vim: set sw=4 ts=4 sts=4 et: */ +#undef NDEBUG +#define _POSIX_C_SOURCE 200809L +#define _NETBSD_SOURCE + +#include <l4list.h> + +#include <assert.h> +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#define INT_TO_PTR(x) ((void*)((intptr_t)(x))) +#define PTR_TO_INT(x) ((int)((intptr_t)((void*)(x)))) + +void test_list_empty (void) { + LbsListMeta* list = lbs_list_meta_new (NULL); + LbsList* node = NULL; + + for (int i = 1; i <= 10; i++) { + node = lbs_list_insert_next (list, node, INT_TO_PTR (i), NULL); + } + + assert (lbs_list_meta_get_len (list) == 10); + + node = lbs_list_meta_goto (list, 5); + lbs_list_remove (list, node); + assert (lbs_list_meta_get_len (list) == 9); + + node = lbs_list_meta_get_first (list); + for (int i = 1; i <= 10; i++) { + if (i == 6) { + continue; + } + assert (PTR_TO_INT (lbs_list_get_data (node)) == i); + node = node->next; + } + + lbs_list_meta_free (list); + + printf ("%s => PASS!\n", __func__); +} + +void test_list_free_func (void) { + LbsListMeta* list = lbs_list_meta_new (free); + LbsList* node = NULL; + LbsList* node_next; + const char* a[] = { + "1 Good", + "2 Test", + "3 Free", + "4 Tree", + "5 Book", + "6 GGGGOOOOOOOODDDD", + "7 OOOOOOOOKKKKKKKKKKKK", + "8 QQQQQQQQAAAAAAAAAAAAAAAAAA", + "9 SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSHHHHHHHHHHHHHH", + "10 !!" + }; + + for (int i = 0; i < 10; i++) { + node = lbs_list_insert_next (list, node, strdup (a[i]), NULL); + } + + assert (lbs_list_meta_get_len (list) == 10); + + node = lbs_list_meta_goto (list, 5); + node_next = node->next; + lbs_list_remove (list, node); + assert (lbs_list_meta_get_len (list) == 9); + + lbs_list_insert_prev (list, node_next, INT_TO_PTR (0), NULL); + assert (lbs_list_meta_get_len (list) == 10); + + node = lbs_list_meta_get_first (list); + for (int i = 0; i < 10; i++) { + if (i == 5) { + assert (PTR_TO_INT (lbs_list_get_data (node)) == 0); + node = node->next; + continue; + } + assert (strcmp (lbs_list_get_data (node), a[i]) == 0); + node = node->next; + } + + lbs_list_meta_free (list); + printf ("%s => PASS!\n", __func__); +} + +void test_list_op (void) { + LbsListMeta* list = lbs_list_meta_new (NULL); + LbsList* node; + + node = lbs_list_insert_next (list, NULL, INT_TO_PTR (2), NULL); + node = lbs_list_insert_prev (list, node, INT_TO_PTR (1), NULL); + lbs_list_push_back (list, INT_TO_PTR (2), NULL); + lbs_list_push_front (list, INT_TO_PTR (0), NULL); + + lbs_list_insert_prev (list, lbs_list_meta_get_last (list), + INT_TO_PTR (3), NULL); + lbs_list_pop_back (list); + lbs_list_pop_front (list); + + lbs_list_push_front (list, INT_TO_PTR (-1), NULL); + node = lbs_list_meta_goto (list, 0); + lbs_list_remove (list, node); + lbs_list_meta_set_free_func (list, NULL); + + node = NULL; + for (int i = 1; node != NULL; i++, node = node->next) { + assert (PTR_TO_INT (lbs_list_get_data (node)) == i); + } + + lbs_list_meta_free (list); + printf ("%s => PASS!\n", __func__); +} + +void test_list_op_no_meta (void) { + LbsList* node_first; + LbsList* node_last; + LbsList* node; + LbsList* tmp; + + node_last = lbs_list_insert_next (NULL, NULL, INT_TO_PTR (2), NULL); + node_first = lbs_list_insert_prev (NULL, node_last, INT_TO_PTR (1), NULL); + node_last = lbs_list_insert_next (NULL, node_last, INT_TO_PTR (2), NULL); + node_first = lbs_list_insert_prev (NULL, node_first, INT_TO_PTR (0), NULL); + + lbs_list_insert_prev (NULL, node_last, INT_TO_PTR (3), NULL); + tmp = node_last->prev; + lbs_list_remove (NULL, node_last); + node_last = tmp; + tmp = node_first->next; + lbs_list_remove (NULL, node_first); + node_first = tmp; + + lbs_list_insert_prev (NULL, node_first, INT_TO_PTR (-1), NULL); + node = lbs_list_goto (node_first, -1); + lbs_list_remove (NULL, node); + + node = NULL; + for (int i = 1; node != NULL; i++, node = node->next) { + assert (PTR_TO_INT (lbs_list_get_data (node)) == i); + } + + free (lbs_list_goto (node_first, 1)); + free (node_first); + free (node_last); + + printf ("%s => PASS!\n", __func__); +} + +void test_stack (void) { + LbsStack* stk = lbs_stack_new (NULL); + + lbs_stack_push (stk, INT_TO_PTR (1), NULL); + lbs_stack_push (stk, INT_TO_PTR (2), NULL); + lbs_stack_push (stk, INT_TO_PTR (3), NULL); + + assert (lbs_stack_get_len (stk) == 3); + assert (lbs_stack_get_data (stk) == INT_TO_PTR (3)); + + lbs_stack_pop (stk); + assert (lbs_stack_get_len (stk) == 2); + assert (lbs_stack_get_data (stk) == INT_TO_PTR (2)); + + lbs_stack_pop (stk); + assert (lbs_stack_get_len (stk) == 1); + assert (lbs_stack_get_data (stk) == INT_TO_PTR (1)); + + lbs_stack_free (stk); + printf ("%s => PASS!\n", __func__); +} + +void test_queue (void) { + LbsQueue* q = lbs_queue_new (NULL); + + lbs_queue_enqueue (q, INT_TO_PTR (1), NULL); + lbs_queue_enqueue (q, INT_TO_PTR (2), NULL); + lbs_queue_enqueue (q, INT_TO_PTR (3), NULL); + + assert (lbs_queue_get_len (q) == 3); + assert (lbs_queue_get_front (q) == INT_TO_PTR (1)); + assert (lbs_queue_get_back (q) == INT_TO_PTR (3)); + assert (lbs_queue_get_data (q) == INT_TO_PTR (1)); + + lbs_queue_dequeue (q); + assert (lbs_queue_get_len (q) == 2); + assert (lbs_queue_get_front (q) == INT_TO_PTR (2)); + assert (lbs_queue_get_back (q) == INT_TO_PTR (3)); + assert (lbs_queue_get_data (q) == INT_TO_PTR (2)); + + lbs_queue_free (q); + printf ("%s => PASS!\n", __func__); +} + +int main () { + test_list_empty (); + test_list_free_func (); + test_list_op (); + test_list_op_no_meta (); + test_stack (); + test_queue (); + return 0; +} |