aboutsummaryrefslogtreecommitdiffstats
path: root/l4bds
diff options
context:
space:
mode:
authorlantw44 <lantw44@gmail.com>2012-09-01 00:54:36 +0800
committerlantw44 <lantw44@gmail.com>2012-09-01 01:02:58 +0800
commit8cc2b5193043646da2da31c6cef2b61de0d3dbed (patch)
treec429bc680bfcbeffd424441d0c7e3ce525499641 /l4bds
parenta94fdfa83c012fab5e1dd69c247c6d6e57b98a16 (diff)
downloadl4basic-8cc2b5193043646da2da31c6cef2b61de0d3dbed.tar
l4basic-8cc2b5193043646da2da31c6cef2b61de0d3dbed.tar.gz
l4basic-8cc2b5193043646da2da31c6cef2b61de0d3dbed.tar.bz2
l4basic-8cc2b5193043646da2da31c6cef2b61de0d3dbed.tar.lz
l4basic-8cc2b5193043646da2da31c6cef2b61de0d3dbed.tar.xz
l4basic-8cc2b5193043646da2da31c6cef2b61de0d3dbed.tar.zst
l4basic-8cc2b5193043646da2da31c6cef2b61de0d3dbed.zip
加入 VERSION、README,和未經測試的 l4bds
Diffstat (limited to 'l4bds')
-rw-r--r--l4bds/Makefile2
-rw-r--r--l4bds/l4bds.h79
-rw-r--r--l4bds/list.c210
3 files changed, 250 insertions, 41 deletions
diff --git a/l4bds/Makefile b/l4bds/Makefile
index 817c11d..1691cee 100644
--- a/l4bds/Makefile
+++ b/l4bds/Makefile
@@ -2,7 +2,7 @@ CC=cc
AR=ar
RM=rm
CFLAGS=-Wall -g -I.
-OBJ=
+OBJ=list.o
LIBFILE=libl4bds.a
.PHONY: all clean
diff --git a/l4bds/l4bds.h b/l4bds/l4bds.h
index 31cd747..b0602da 100644
--- a/l4bds/l4bds.h
+++ b/l4bds/l4bds.h
@@ -3,63 +3,62 @@
/*********** list ***********/
-struct l4lib_list_node{ /* 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;
- struct l4lib_list_node* list_current;
- int list_prevcount;
- int list_nextcount;
int list_len;
} L4LL;
-/* 這兩個常數僅供 l4ll_remove 使用 */
-#define L4LL_PREV 1 /* 刪除後移至上一項 */
-#define L4LL_NEXT 2 /* 刪除後移至下一項 */
-
-/* 這兩個常數僅供 l4ll_goto 使用 */
-#define L4LL_FRONT 3
-#define L4LL_BACK 4
-
L4LL* l4ll_create(void);
void l4ll_free(L4LL*);
-void* l4ll_getcur(L4LL*);
-void* l4ll_getback(L4LL*);
-void* l4ll_getfront(L4LL*);
-int l4ll_pushback(L4LL*, void*);
-int l4ll_pushfront(L4LL*, void*);
-int l4ll_popback(L4LL*);
-int l4ll_popfront(L4LL*);
-int l4ll_remove(L4LL*, int);
-int l4ll_insprev(L4LL*);
-int l4ll_insnext(L4LL*);
-int l4ll_goto(L4LL*, int, int);
-#define l4ll_getlen(list)
-#define l4ll_getc(list)
-#define l4ll_getpc(list)
-#define l4ll_getnc(list)
+#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*, void*, int);
+L4LLNODE* l4ll_insert_next(L4LL*, L4LLNODE*, 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)))))
/*********** stack ***********/
-#define l4stack_create()
-#define l4stack_push(list, value)
-#define l4stack_pop(list)
-#define l4stack_getlen(list)
-#define l4stack_value(list)
-#define l4stack_free(list)
+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 ***********/
-#define l4queue_create()
-#define l4queue_push(list, value)
-#define l4queue_pop(list)
-#define l4queue_getlen(list)
-#define l4queue_value(list)
-#define l4queue_free(list)
+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)))
#endif
diff --git a/l4bds/list.c b/l4bds/list.c
new file mode 100644
index 0000000..8dc9279
--- /dev/null
+++ b/l4bds/list.c
@@ -0,0 +1,210 @@
+#include <stdlib.h>
+#include <string.h>
+#include <l4bds.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;
+}
+
+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);
+}
+
+static L4LLNODE*
+l4ll_initfirst(L4LL* list, 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;
+}
+
+L4LLNODE* l4ll_insert_prev(L4LL* list, L4LLNODE* node, 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(newnode, 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;
+}
+
+L4LLNODE* l4ll_insert_next(L4LL* list, L4LLNODE* node, 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(newnode, 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;
+}
+
+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;
+ }
+}
+
+#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;
+}
+
+
+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;
+}
+
+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;
+}
+
+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;
+}
+#endif