lib

morphux C utility library
Log | Files | Refs | Submodules | README | LICENSE | git clone https://git.ne02ptzero.me/git/lib

commit 8b814e46549166f719af9ffcf1757d2af4ec5224
parent 5de58a99812bfa89c2038c539be42631b818f7ca
Author: Ne02ptzero <louis@ne02ptzero.me>
Date:   Tue, 24 Jan 2017 18:44:25 +0100

Add(list_remove): Add list_remove function in m_list.c:

Add define list_del too
Add units tests

Diffstat:
Minc/m_list.h | 4++++
Msrc/m_list.c | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Mtests/test_list.c | 34++++++++++++++++++++++++++++++++++
3 files changed, 87 insertions(+), 0 deletions(-)

diff --git a/inc/m_list.h b/inc/m_list.h @@ -49,6 +49,8 @@ typedef struct s_list { # define list_add_before(org_list, p_tr1, p_tr2, sizeZ) org_list = list_insert_before(org_list, p_tr1, p_tr2, sizeZ); +# define list_del(org_list, p_tr1, sizeZ, fn) org_list = list_remove(org_list, p_tr1, sizeZ, fn); + /* Functions */ mlist_t *list_add_member(mlist_t *list, void *member, u32_t size); @@ -58,5 +60,7 @@ mlist_t *list_insert_before(mlist_t *org, mlist_t *ptr, void *member, u32_t siz u32_t list_size(mlist_t *list); mlist_t *list_free(mlist_t *list, int (*free_fn)(void *member)); void *list_get(mlist_t *list, void *member, size_t size); +mlist_t *list_remove(mlist_t *list, void *member, size_t size, + int (*free_fn)(void *member)); #endif diff --git a/src/m_list.c b/src/m_list.c @@ -252,3 +252,52 @@ void *list_get(mlist_t *list, void *member, size_t size) { } return NULL; } + +/*! + * \brief Remove a member from the list + * \param list List head + * \param member Member to remove + * \param size Size of the member (Used for memcmp) + * \param free_fn Function use to free the member + * + * Remove a member in a list. + */ +mlist_t *list_remove(mlist_t *list, void *member, size_t size, + int (*free_fn)(void *member)) { + mlist_t *tmp, *tmp2; + void *ptr; + + if (list == NULL) + return NULL; + + /* Search for the member */ + list_for_each(list, tmp2, ptr) { + if (memcmp(member, ptr, size) == 0) + break ; + } + + /* We can't find the member */ + if (tmp2 == NULL) { + return list; + } + + if (tmp2 == list) { + /* Replace the head */ + list = tmp2->next; + + /* Update the head in all other members */ + list_for_each(list, tmp, ptr) { + tmp->head = list; + } + } else { + tmp2->prev->next = tmp2->next; + } + + if (free_fn != NULL) { + free_fn(tmp2->member); + } else { + free(tmp2->member); + } + free(tmp2); + return list; +} diff --git a/tests/test_list.c b/tests/test_list.c @@ -217,6 +217,39 @@ TEST(list_free) { return TEST_SUCCESS; } +int callback_list_free_2(void *ptr) { + free(ptr); + printf("Sup ?!\n"); + return 1; +} + +TEST(list_remove) { + mlist_t *ptr = NULL; + char test[] = "Hello !\n"; + char test2[] = "Hello2 !\n"; + char test3[] = "Hello3 !\n"; + char test4[] = "Hello4 !\n"; + + list_add(ptr, test, sizeof(test)); + list_add(ptr, test2, sizeof(test2)); + list_add(ptr, test3, sizeof(test3)); + + list_del(ptr, test2, sizeof(test2), NULL); + TEST_ASSERT(strcmp(ptr->next->member, test3) == 0, "List order is wrong"); + list_add(ptr, test3, sizeof(test3)); + + list_del(ptr, test, sizeof(test), &callback_list_free_2); + TEST_ASSERT(strcmp(ptr->member, test3) == 0, "List order is wrong"); + + list_del(ptr, test4, sizeof(test4), NULL); + TEST_ASSERT(strcmp(ptr->member, test3) == 0, "List order is wrong"); + + list_free(ptr, NULL); + ptr = NULL; + list_del(ptr, test, sizeof(test), NULL); + return TEST_SUCCESS; +} + void register_list_tests(void) { reg_test("mlist", list_add_null); reg_test("mlist", list_add_member); @@ -229,4 +262,5 @@ void register_list_tests(void) { reg_test("mlist", list_for_each_rev); reg_test("mlist", list_size); reg_test("mlist", list_free); + reg_test("mlist", list_remove); }