From 49ae127b16596523592fc88bb6d50138fdd67712 Mon Sep 17 00:00:00 2001 From: lifegpc Date: Mon, 3 Jan 2022 09:01:21 +0800 Subject: [PATCH] Update --- CMakeLists.txt | 2 + c_linked_list.cpp | 44 +++++++++++++++++++ c_linked_list.h | 25 +++++++++++ fileop.cpp | 5 +++ fileop.h | 6 +++ linked_list.h | 110 ++++++++++++++++++++++++++++++++++++++++++++++ str_util.cpp | 16 +++++++ str_util.h | 10 +++++ 8 files changed, 218 insertions(+) create mode 100644 c_linked_list.cpp create mode 100644 c_linked_list.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 76e4a93..dcf9a10 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,6 +51,7 @@ set(SOURCE_FILE time_util.cpp encoding.cpp str_util.cpp + c_linked_list.cpp ) set(SOURCE_FILE_HEADERS cfileop.h @@ -66,6 +67,7 @@ set(SOURCE_FILE_HEADERS encoding.h str_util.h linked_list.h + c_linked_list.h ) add_library(utils STATIC ${SOURCE_FILE} ${SOURCE_FILE_HEADERS}) diff --git a/c_linked_list.cpp b/c_linked_list.cpp new file mode 100644 index 0000000..1e5e03a --- /dev/null +++ b/c_linked_list.cpp @@ -0,0 +1,44 @@ +#include "c_linked_list.h" +#include "linked_list.h" + +int c_linked_list_append(c_linked_list** list, void* data) { + struct LinkedList* li = (struct LinkedList*)(*list); + auto re = linked_list_append(li, &data); + *list = (c_linked_list*)li; + return re; +} + +int c_linked_list_append_head(c_linked_list** list, void* data) { + struct LinkedList* li = (struct LinkedList*)(*list); + auto re = linked_list_append_head(li, &data); + *list = (c_linked_list*)li; + return re; +} + +void c_linked_list_clear(c_linked_list** list, void(*free_func)(void*)) { + struct LinkedList* li = (struct LinkedList*)(*list); + linked_list_clear(li, free_func); + *list = (c_linked_list*)li; +} + +size_t c_linked_list_count(c_linked_list* list) { + struct LinkedList* li = (struct LinkedList*)list; + return linked_list_count(li); +} + +void c_linked_list_free_tail(c_linked_list** list, void(*free_func)(void*)) { + struct LinkedList* li = (struct LinkedList*)(*list); + linked_list_free_tail(li, free_func); + *list = (c_linked_list*)li; +} + +void c_linked_list_remove(c_linked_list** node, void(*free_func)(void*)) { + struct LinkedList* li = (struct LinkedList*)(*node); + linked_list_remove(li); + *node = (c_linked_list*)li; +} + +c_linked_list* c_linked_list_tail(c_linked_list* list) { + struct LinkedList* li = (struct LinkedList*)list; + return (c_linked_list*)linked_list_tail(li); +} diff --git a/c_linked_list.h b/c_linked_list.h new file mode 100644 index 0000000..988386d --- /dev/null +++ b/c_linked_list.h @@ -0,0 +1,25 @@ +#ifndef _UTIL_C_LINKED_LIST_H +#define _UTIL_C_LINKED_LIST_H +#ifdef __cplusplus +extern "C" { +#endif +#include +/** + * @brief Struct are same with struct LinkedList +*/ +typedef struct c_linked_list { + void* d; + struct c_linked_list* prev; + struct c_linked_list* next; +} c_linked_list; +int c_linked_list_append(c_linked_list** list, void* data); +int c_linked_list_append_head(c_linked_list** list, void* data); +void c_linked_list_clear(c_linked_list** list, void(*free_func)(void*)); +size_t c_linked_list_count(c_linked_list* list); +void c_linked_list_free_tail(c_linked_list** list, void(*free_func)(void*)); +void c_linked_list_remove(c_linked_list** node, void(*free_func)(void*)); +c_linked_list* c_linked_list_tail(c_linked_list* list); +#ifdef __cplusplus +} +#endif +#endif diff --git a/fileop.cpp b/fileop.cpp index 7935f53..5ebf5c5 100644 --- a/fileop.cpp +++ b/fileop.cpp @@ -530,3 +530,8 @@ bool fileop::listdir(std::string path, std::list& filelist, bool ig return true; #endif } + +std::string fileop::filename(std::string path) { + auto loc = path.find_last_of('.'); + return loc == -1 ? path : path.substr(0, loc); +} diff --git a/fileop.h b/fileop.h index 5fc7c44..17c41b9 100644 --- a/fileop.h +++ b/fileop.h @@ -163,5 +163,11 @@ namespace fileop { * @return true if successed. */ bool listdir(std::string path, std::list& filelist, bool ignore_hidden_file = true); + /** + * @brief Return a path without file extension + * @param path Path + * @return Result + */ + std::string filename(std::string path); } #endif diff --git a/linked_list.h b/linked_list.h index c89ee10..b2723e1 100644 --- a/linked_list.h +++ b/linked_list.h @@ -2,6 +2,7 @@ #define _UTIL_LINKED_LIST_H #include #include +#include template struct LinkedList { T d; @@ -33,6 +34,45 @@ bool linked_list_append(struct LinkedList*& list, struct LinkedList** tail return linked_list_append(list, (T*)nullptr, tail); } +template +bool linked_list_append_head(struct LinkedList*& list, T* data = nullptr) { + bool have_list = list; + struct LinkedList* tmp = (struct LinkedList*)malloc(sizeof(LinkedList)); + if (!tmp) return false; + memset(tmp, 0, sizeof(LinkedList)); + if (data) tmp->d = T(*data); else tmp->d = T(); + if (have_list) { + tmp->next = list; + list->prev = tmp; + } + list = tmp; + return true; +} + +template +bool linked_list_append_list(struct LinkedList*& list, struct LinkedList* list2, bool(*compare_func)(T, T, Args...) = nullptr, Args... args) { + if (!list2) return true; + struct LinkedList* t = list2; + struct LinkedList* tail = linked_list_tail(list); + if (!compare_func || !linked_list_have(list, t->d, compare_func, args...)) { + if (!linked_list_append(list, &t->d)) return false; + } + while (t->next) { + t = t->next; + if (!compare_func || !linked_list_have(list, t->d, compare_func, args...)) { + if (!linked_list_append(list, &t->d)) { + if (tail == nullptr) { + linked_list_clear(list); + } else { + if (tail->next) linked_list_clear(tail->next); + } + return false; + } + } + } + return true; +} + template void linked_list_clear(struct LinkedList*& list, void(*free_func)(T) = nullptr) { if (!list) return; @@ -48,4 +88,74 @@ void linked_list_clear(struct LinkedList*& list, void(*free_func)(T) = nullpt free(t); list = nullptr; } + +template +size_t linked_list_count(struct LinkedList* list) { + if (!list) return 0; + struct LinkedList* t = list; + size_t c = 1; + while (t->next) { + t = t->next; + c += 1; + } + if (list->prev) { + t = t->prev; + c += 1; + while (t->prev) { + t = t->prev; + c += 1; + } + } + return c; +} + +template +void linked_list_free_tail(struct LinkedList*& list, void(*free_func)(T) = nullptr) { + if (!list) return; + struct LinkedList* t = linked_list_tail(list); + if (t == list) { + linked_list_clear(list, free_func); + } else { + if (free_func) free_func(t->d); + if (t->prev) { + t->prev->next = nullptr; + } + free(t); + } +} + +template +bool linked_list_have(struct LinkedList* list, T data, bool(*compare_func)(T, T, Args...), Args... args) { + if (!list || !compare_func) return false; + struct LinkedList* t = list; + if (compare_func(t->d, data, args...)) return true; + while (t->next) { + t = t->next; + if (compare_func(t->d, data, args...)) return true; + } + return false; +} + +template +void linked_list_remove(struct LinkedList*& node, void(*free_func)(T) = nullptr) { + if (!node) return; + if (node->prev) { + node->prev->next = node->next; + } + if (node->next) { + node->next->prev = node->prev; + } + if (free_func) free_func(node->d); + free(node); +} + +template +struct LinkedList* linked_list_tail(struct LinkedList* list) { + if (!list) return nullptr; + struct LinkedList* t = list; + while (t->next) { + t = t->next; + } + return t; +} #endif diff --git a/str_util.cpp b/str_util.cpp index eebea22..26fb974 100644 --- a/str_util.cpp +++ b/str_util.cpp @@ -28,4 +28,20 @@ std::string str_util::str_replace(std::string input, std::string pattern, std::s else break; } return input; +} + +std::list str_util::str_split(std::string input, std::string pattern, size_t max) { + if (max == 0) return {}; + std::list li; + auto loc = input.find(pattern, 0); + auto last_loc = 0; + auto len = pattern.length(); + while (loc != -1 && li.size() < max) { + li.push_back(input.substr(last_loc, loc - last_loc)); + last_loc = loc + len; + if (last_loc < input.length()) loc = input.find(pattern, max(0, last_loc)); + else break; + } + if (last_loc <= input.length()) li.push_back(input.substr(last_loc, input.length() - last_loc)); + return li; } \ No newline at end of file diff --git a/str_util.h b/str_util.h index b831a2c..e70cb42 100644 --- a/str_util.h +++ b/str_util.h @@ -1,5 +1,7 @@ #ifndef _UTILS_STR_UTIL_H #define _UTILS_STR_UTIL_H +#include +#include #include namespace str_util { /** @@ -17,5 +19,13 @@ namespace str_util { * @return Result string */ std::string str_replace(std::string input, std::string pattern, std::string new_content); + /** + * @brief Split string with pattern. + * @param input Input string + * @param pattern Partten + * @param max Maximum count of result. + * @return Result. + */ + std::list str_split(std::string input, std::string pattern, size_t max = -1); } #endif