diff --git a/CMakeLists.txt b/CMakeLists.txt index e1973b0af7664e11dfb0f4a6bb4db4a38086453b..534d04550d83cbc86e758bc30ed82589fb5432c4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,21 +5,7 @@ project(common_function C) set(HOME ${CMAKE_CURRENT_SOURCE_DIR}) set(SDK_NAME common) -if(WIN32) - - message("WINDOWS PLATFORM") - add_definitions(-DWINDOWS_PLATFORM) - -elseif(APPLE) - - message(FATAL_ERROR "NOT SUPPORT") - -elseif(UNIX) - - message("UNIX PLATFORM") - add_definitions(-DUNIX_PLATFORM) - -endif() +set(COMPILE_LIST FALSE CACHE BOOL "是否编译list相关接口") add_subdirectory(src) diff --git a/build.sh b/build.sh index c0bf999b4548f26809a58183977d2a09dc88b0ad..327dcbc214abf27c0d849bc17a0518909071d783 100755 --- a/build.sh +++ b/build.sh @@ -12,7 +12,7 @@ echo -e "========================== info end ==========================\n\n" echo -e "=======================cmake build info=======================" cd $root_dir/build -cmake -DUNIT_TEST=1 .. +cmake -DUNIT_TEST=1 -DCOMPILE_LIST=true .. make echo -e "========================== info end ==========================\n\n" diff --git a/demos/CMakeLists.txt b/demos/CMakeLists.txt index 451be0a67d94d24fd91ace6ee40a02c2113788d7..ceb940bcd48ddbf969ec82a910c88d06a8b14945 100644 --- a/demos/CMakeLists.txt +++ b/demos/CMakeLists.txt @@ -10,6 +10,10 @@ set(dep_libs ${SDK_NAME} ) +## 是否编译list相关接口 +if(COMPILE_LIST) + add_definitions(-DCOMPILE_DEFINITIONS_LIST) +endif(COMPILE_LIST) include_directories(${include_dir}) link_directories(${libs_dir}) diff --git a/demos/list.c b/demos/list.c new file mode 100644 index 0000000000000000000000000000000000000000..4b46111c959dfac09574aa73f4774bfcb3765c86 --- /dev/null +++ b/demos/list.c @@ -0,0 +1,96 @@ +#include +#include + +#ifdef COMPILE_DEFINITIONS_LIST + +#include "list.h" + +int main() { + list *handler = NULL; + int ret = 0; + int i = 0; + int *temp = NULL; + int8_t size = 0; + int get = 0; + + ret = list_init(&handler); + if(ret != LIST_OK) { + printf("list initialization error, code: 0x%04x\n", ret); + goto exit; + } + + for(i = 0; i < 10; i++) { + temp = (int *)malloc(sizeof(int)); + *temp = i + 1; + ret = list_add(handler, temp); + if(ret != LIST_OK) { + printf("list add error, code: 0x%04x\n", ret); + goto exit; + } + } + + temp = NULL; + + ret = list_size(handler, &size); + if(ret != LIST_OK) { + printf("list get isze error, code: 0x%04x\n", ret); + goto exit; + } + printf("list size is %d\n", size); + + for(i = 0; i < 10; i++) { + ret = list_get_at(handler, i + 1, &temp); + if(ret != LIST_OK) { + printf("list get error, code: 0x%04x\n", ret); + goto exit; + } + printf("%d\n", *temp); + } + + printf("start list free at\n\n\n"); + + ret = list_free_at(handler, 10); + if(ret != LIST_OK) { + printf("list free at error, index is %d, error code is 0x%04x\n", 4, ret); + goto exit; + } + for(i = 0; i < 9; i++) { + ret = list_get_at(handler, i + 1, &temp); + if(ret != LIST_OK) { + printf("list get error, code: 0x%04x\n", ret); + goto exit; + } + printf("%d\n", *temp); + } + + temp = (int *)malloc(sizeof(int)); + *temp = 4; + + printf("start list add at\n\n\n"); + ret = list_add_at(handler, 4, temp); + if(ret != LIST_OK) { + printf("list add error, code: 0x%04x\n", ret); + goto exit; + } + for(i = 0; i < 10; i++) { + ret = list_get_at(handler, i + 1, &temp); + if(ret != LIST_OK) { + printf("list get error, code: 0x%04x\n", ret); + goto exit; + } + printf("%d\n", *temp); + } + +exit: + list_free_all(&handler); + + return 0; +} +#else + +int main() { + printf("please use defination:\'COMPILE_DEFINITIONS_LIST\' to rebuild this project\n"); + return 0; +} + +#endif \ No newline at end of file diff --git a/include/list.h b/include/list.h new file mode 100644 index 0000000000000000000000000000000000000000..9e2ab8e9a421e8fcdc52eca70cda72f2dce44031 --- /dev/null +++ b/include/list.h @@ -0,0 +1,113 @@ +/** + * @file list.h + * @author 1248825327@qq.com + * @brief list数据结构 + * @version 0.1 + * @date 2023-10-23 + * + * @copyright Copyright (c) 2023 + * + */ + +#ifndef LIST_H +#define LIST_H + +#include + +#define LIST_OK 0x0000 + +#define LIST_BAD_INPUT_DATA 0x0001 +#define LIST_MALLOC_FAILED 0x0002 +#define LIST_INDEX_BIGGER_THAN_MAX 0x0003 +#define LIST_BUFFER_TOO_SMALL 0x0004 + +typedef struct list list; + +/** + * @brief list句柄初始化 + * + * @param handler 初始化句柄,需要传入二级指针,内部自动申请内存 + * @return int + */ +int list_init(list **handler); + +/** + * @brief list添加一个元素,需要element需要外部malloc申请内存 + * + * @param handler list句柄 + * @param element 任意类型的指针,但是需要在接口外部malloc内存 + * @return int + */ +int list_add(list *handler, void *element); + +/** + * @brief 添加到指定位置,index从1开始计数 + * + * @param handler list句柄 + * @param index 具体位置,从1开始 + * @param element 任意类型的指针,但是需要在接口外部malloc + * @return int + */ +int list_add_at(list *handler, int64_t index, void *element); + +/** + * @brief 替换element + * + * @param handler list句柄 + * @param index 位置 + * @param element_in 替换进入的内容 + * @param element_out 替换输出的内容 + * @return int + */ +int list_replace_at(list *handler, int64_t index, void *element_in, void **element_out); + +/** + * @brief 获得list的大小并存放到size中 + * + * @param handler list句柄 + * @param size 大小 + * @return int + */ +int list_size(list *handler, int64_t *size); + +/** + * @brief 获得list中index处的一个元素,下标从1开始计算 + * + * @warning 获得的element是一个浅拷贝,仅仅只是把指针返回出来了,如果外部释放会导致程序崩溃;而且此处的element需要和add的时候是同样的类型 + * + * @param handler list句柄 + * @param index 位置 + * @param element 获得元素,返回的是指针,需要传入二级指针 + * @return int + */ +int list_get_at(list *handler, int64_t index, void **element); + +/** + * @brief list导出,将handler中的所有内容导出到export_arr中,需要确保前后元素类型一致 + * + * @param handler list句柄 + * @param export_arr 导出的buffer + * @param arr_size buffer大小 + * @param arr_length buffer输出长度 + * @return int + */ +int list_export(list *handler, void *export_arr[], int64_t arr_size, int64_t *arr_length); + +/** + * @brief 释放list中所有的内存,并将handler指向NULL + * + * @param handler list句柄 + * @return int + */ +int list_free_all(list **handler); + +/** + * @brief 释放index处的内容 + * + * @param handler list句柄 + * @param index 位置 + * @return int + */ +int list_free_at(list *handler, int index); + +#endif \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 60c27686ed7d7bc3b88d8ce44585fcd079bd2687..a2183347b87a8fc4d592019d0b81e9ce2cb6d844 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,6 +3,23 @@ include_directories(../include/) set(LIB_SHARED "${SDK_NAME}_shared") set(LIB_STATIC "${SDK_NAME}_static") +# 配置编译宏定义 + +## 平台相关接口 +if(WIN32) + message("WINDOWS PLATFORM") + add_definitions(-DWINDOWS_PLATFORM) +elseif(APPLE) + message(FATAL_ERROR "NOT SUPPORT") +elseif(UNIX) + message("UNIX PLATFORM") + add_definitions(-DUNIX_PLATFORM) +endif() +## 是否编译list相关接口 +if(COMPILE_LIST) + add_definitions(-DCOMPILE_DEFINITIONS_LIST) +endif(COMPILE_LIST) + file(GLOB C_SOURCE_FILE "*.c") add_library(${LIB_SHARED} SHARED ${C_SOURCE_FILE}) diff --git a/src/list.c b/src/list.c new file mode 100644 index 0000000000000000000000000000000000000000..518e8d62a6de332151b514bed39c781b132e01da --- /dev/null +++ b/src/list.c @@ -0,0 +1,315 @@ +/** + * @file list.c + * @author your name (you@domain.com) + * @brief 实现list数据结构 + * @version 0.1 + * @date 2023-10-23 + * + * @copyright Copyright (c) 2023 + * + */ + +#include +#include + +#include "list.h" + +#ifdef COMPILE_DEFINITIONS_LIST + +/** + * @brief list的单个节点 + * + */ +typedef struct node{ + void *data; + struct node *next; +}node; + +/** + * @brief list结构体 + * + */ +struct list { + node *start; + node *end; + int64_t total; +}; + +/** + * @brief list句柄初始化 + * + * @param handler 初始化句柄,需要传入二级指针,内部自动申请内存 + * @return int + */ +int list_init(list **handler) { + if(handler == NULL) { + return LIST_BAD_INPUT_DATA; + } + + *handler = (list*)malloc(sizeof(list)); + + if((*handler) == NULL) { + return LIST_MALLOC_FAILED; + } + + (*handler)->start = (node*)malloc(sizeof(node)); + (*handler)->end = (*handler)->start; + (*handler)->total = 0; + + return LIST_OK; +} + +/** + * @brief list添加一个元素,需要element需要外部malloc申请内存 + * + * @param handler list句柄 + * @param element 任意类型的指针,但是需要在接口外部malloc内存 + * @return int + */ +int list_add(list *handler, void *element) { + node *n = NULL; + + if(handler == NULL || element == NULL) { + return LIST_BAD_INPUT_DATA; + } + + n = (node *)malloc(sizeof(node)); + + if(n == NULL) { + return LIST_MALLOC_FAILED; + } + + n->data = element; + n->next = NULL; + handler->end->next = n; + handler->end = n; + + handler->total++; + + return LIST_OK; +} + +/** + * @brief 添加到指定位置,index从1开始计数 + * + * @param handler list句柄 + * @param index 具体位置,从1开始 + * @param element 任意类型的指针,但是需要在接口外部malloc + * @return int + */ +int list_add_at(list *handler, int64_t index, void *element) { + int i = 0; + node *head = NULL; + node *n = NULL; + + if(handler == NULL || index <= 0 || element == NULL) { + return LIST_BAD_INPUT_DATA; + } + + if(index > handler->total) { + return LIST_INDEX_BIGGER_THAN_MAX; + } + + head = handler->start; + + for(i = 1; i < index; i++) { + head = head->next; + } + + n = (node *)malloc(sizeof(node)); + n->next = head->next; + n->data = element; + head->next = n; + + handler->total++; + + return LIST_OK; +} + +/** + * @brief 替换element + * + * @param handler list句柄 + * @param index 位置 + * @param element_in 替换进入的内容 + * @param element_out 替换输出的内容 + * @return int + */ +int list_replace_at(list *handler, int64_t index, void *element_in, void **element_out) { + int i = 0; + node *head = NULL; + + if(handler == NULL || index <= 0 || element_in == NULL || element_out == NULL || (*element_out) == NULL) { + return LIST_BAD_INPUT_DATA; + } + + if(index > handler->total) { + return LIST_INDEX_BIGGER_THAN_MAX; + } + + head = handler->start; + for(i = 1; i < index; i++) { + head = head->next; + } + + (*element_out) = head->data; + head->data = element_in; + + return LIST_OK; +} + +/** + * @brief 获得list的大小并存放到size中 + * + * @param handler list句柄 + * @param size 大小 + * @return int + */ +int list_size(list *handler, int64_t *size) { + if(handler == NULL || size == NULL) { + return LIST_BAD_INPUT_DATA; + } + + *size = handler->total; + return LIST_OK; +} + +/** + * @brief 获得list中index处的一个元素,下标从1开始计算 + * + * @warning 获得的element是一个浅拷贝,仅仅只是把指针返回出来了,如果外部释放会导致程序崩溃;而且此处的element需要和add的时候是同样的类型 + * + * @param handler list句柄 + * @param index 位置 + * @param element 获得元素,返回的是指针 + * @return int + */ +int list_get_at(list *handler, int64_t index, void **element) { + int i = 0; + node *head = NULL; + + if(handler == NULL || index <= 0 || element == NULL) { + return LIST_BAD_INPUT_DATA; + } + + if(index > handler->total) { + return LIST_INDEX_BIGGER_THAN_MAX; + } + + head = handler->start->next; + + for(i = 1; i < index; i++) { + head = head->next; + } + + *element = head->data; + + return LIST_OK; +} + +/** + * @brief list导出,将handler中的所有内容导出到export_arr中,需要确保前后元素类型一致 + * + * @param handler list句柄 + * @param export_arr 导出的buffer + * @param arr_size buffer大小 + * @param arr_length buffer输出长度 + * @return int + */ +int list_export(list *handler, void *export_arr[], int64_t arr_size, int64_t *arr_length) { + node *head = handler->start->next; + int i = 0; + + if(handler == NULL || export_arr == NULL || handler->total <= 0) { + return LIST_BAD_INPUT_DATA; + } + + if(handler->total > arr_size) { + return LIST_BUFFER_TOO_SMALL; + } + + for(i = 0; i < handler->total && head != NULL; i++, head = head->next) { + export_arr[i] = head->data; + } + + *arr_length = handler->total; + + return LIST_OK; +} + +/** + * @brief 释放list中所有的内存,并将handler指向NULL + * + * @param handler list句柄 + * @return int + */ +int list_free_all(list **handler) { + node *head = NULL; + node *temp = NULL; + + if(handler == NULL || *handler == NULL) { + return LIST_BAD_INPUT_DATA; + } + + head = (*handler)->start; + + while(head != NULL) { + if(head->data != NULL) { + int *t = head->data; + free(head->data); + } + temp = head; + head = head->next; + free(temp); + } + + (*handler)->start = NULL; + (*handler)->end = NULL; + + free((*handler)); + + (*handler) = NULL; + + return LIST_OK; +} + +/** + * @brief 释放index处的内容 + * + * @param handler list句柄 + * @param index 位置 + * @return int + */ +int list_free_at(list *handler, int index) { + int i = 0; + node *head = NULL; + node *temp = NULL; + + if(handler == NULL || index <= 0) { + return LIST_BAD_INPUT_DATA; + } + + if(handler->total < index) { + return LIST_INDEX_BIGGER_THAN_MAX; + } + + head = handler->start; + + for(i = 1; i < index; i++) { + head = head->next; + } + + temp = head->next; + head->next = temp->next; + free(temp->data); + free(temp); + + handler->total--; + + if(head->next == NULL) { // 如果删除最后一个节点,则需要更新end指针 + handler->end = head; + } + + return LIST_OK; +} +#endif \ No newline at end of file