diff options
author | lantw44 <lantw44@gmail.com> | 2012-09-01 00:54:36 +0800 |
---|---|---|
committer | lantw44 <lantw44@gmail.com> | 2012-09-01 01:02:58 +0800 |
commit | 8cc2b5193043646da2da31c6cef2b61de0d3dbed (patch) | |
tree | c429bc680bfcbeffd424441d0c7e3ce525499641 | |
parent | a94fdfa83c012fab5e1dd69c247c6d6e57b98a16 (diff) | |
download | l4basic-8cc2b5193043646da2da31c6cef2b61de0d3dbed.tar.gz l4basic-8cc2b5193043646da2da31c6cef2b61de0d3dbed.tar.zst l4basic-8cc2b5193043646da2da31c6cef2b61de0d3dbed.zip |
加入 VERSION、README,和未經測試的 l4bds
-rw-r--r-- | README | 11 | ||||
-rw-r--r-- | VERSION | 1 | ||||
-rw-r--r-- | l4bds/Makefile | 2 | ||||
-rw-r--r-- | l4bds/l4bds.h | 79 | ||||
-rw-r--r-- | l4bds/list.c | 210 |
5 files changed, 262 insertions, 41 deletions
@@ -0,0 +1,11 @@ +l4arg: + (Argument) 解析命令列的常用函式 +l4bds: + (Basic Data Structure) 包含 list、stack、queue,其中 stack 和 queue 其實都 + 是用 list 實作 +l4darr: + (Dynamic Array) 包含可動態調整大小的一維陣列(類似 C++ 的 vector),還有透 + 或一維陣列模擬二維陣列的功能(但不可動態調整大小) + +基本上這些函式庫都很小,所以請直接靜態連結到你的程式,不要安裝到系統上! +同時預設的 Makefile 也不提供建立動態函式庫的功能,有需要請自行處理! @@ -0,0 +1 @@ +1.0.0 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 |