diff --git a/src/utils/dlist.c b/src/utils/dlist.c index b1cd06a..bfd64db 100644 --- a/src/utils/dlist.c +++ b/src/utils/dlist.c @@ -6,7 +6,7 @@ #include "dlist.h" -/* +/* Uses *add* when needs to make a full copy of the element. Uses *insert* when operates with nodes. */ @@ -24,7 +24,8 @@ dlist_t *_dlist_init(void *el_ptr, int el_siz, dblist_add_cb_t add_cb) { return dlist; } -void _dlist_insert(dlist_t *dlist, dlist_node_t *new_el, dlist_node_t *prev_node) { +void _dlist_insert(dlist_t *dlist, dlist_node_t *new_el, + dlist_node_t *prev_node) { if (prev_node != NULL) { new_el->next = prev_node->next; prev_node->next->previous = new_el; @@ -53,7 +54,7 @@ void _dlist_insert_end(dlist_t *dlist, dlist_node_t *new_node) { } void _dlist_add_sort(dlist_t *dlist, void *el_ptr, int el_siz, - dblist_sort_cb_t cb, dblist_add_cb_t add_cb) { + dblist_sort_cb_t cb, dblist_add_cb_t add_cb) { dlist_node_t *node = malloc(sizeof(dlist_node_t)); node->el_ptr = malloc(el_siz); add_cb(node->el_ptr, el_ptr); @@ -85,7 +86,8 @@ void _dlist_add_sort(dlist_t *dlist, void *el_ptr, int el_siz, } } -void _dlist_add(dlist_t *dlist, void *el_ptr, int el_siz, dblist_add_cb_t *add_cb, bool prepend) { +void _dlist_add(dlist_t *dlist, void *el_ptr, int el_siz, + dblist_add_cb_t *add_cb, bool prepend) { dlist_node_t *node = malloc(sizeof(dlist_node_t)); node->el_ptr = malloc(el_siz); add_cb(node->el_ptr, el_ptr); @@ -114,25 +116,51 @@ void _dlist_add(dlist_t *dlist, void *el_ptr, int el_siz, dblist_add_cb_t *add_c dlist_node_t *find_node_by_ptr(dlist_t *dlist, void *el_ptr) { dlist_node_t *node = dlist->start; do { - if (node->el_ptr == el_ptr) break; + if (node->el_ptr == el_ptr) + break; } while ((node = node->next) != NULL); - if (node->el_ptr == el_ptr) return node; + if (node->el_ptr == el_ptr) + return node; return NULL; } int dlist_remove_by_ptr(dlist_t *dlist, void *el_ptr, dblist_rm_cb_t cb) { dlist_node_t *node = find_node_by_ptr(dlist, el_ptr); - if (node == NULL) return -1; + if (node == NULL) + return -1; node->next->previous = node->previous; node->previous->next = node->next; dlist->len--; - if (node->next == NULL) dlist->current = node->previous; - if (node->previous == NULL) dlist->start = node->next; + if (node->next == NULL) + dlist->current = node->previous; + if (node->previous == NULL) + dlist->start = node->next; cb(node->el_ptr); free(node); return 1; } +int dlist_clear_list(dlist_t *dlist, dblist_rm_cb_t cb) { + dlist_node_t *current = dlist->start; + dlist_node_t *next = NULL; + + do { + cb(current->el_ptr); + next = current->next; + free(current); + current = next; + } while (current != NULL); + + dlist->len = 0; + dlist->current = NULL; + dlist->start = NULL; + dlist->pointer = NULL; + + return 1; +} + +/* Iterators */ + void *dlist_it_prev(dlist_t *dlist) { dlist_node_t *cur_ptr = dlist->pointer; if (dlist->pointer->previous != NULL) { diff --git a/src/utils/dlist.h b/src/utils/dlist.h index e57b3f9..a515464 100644 --- a/src/utils/dlist.h +++ b/src/utils/dlist.h @@ -32,6 +32,7 @@ void *dlist_it_next(dlist_t *dlist); void _dlist_add_sort(dlist_t *dlist, void *el_ptr, int el_siz, dblist_sort_cb_t cb, dblist_add_cb_t add_cb); int dlist_remove_by_ptr(dlist_t *dlist, void *el_ptr, dblist_rm_cb_t cb); +int dlist_clear_list(dlist_t *dlist, dblist_rm_cb_t cb); #define dlist_init(el_ptr, el_def, add_cb) \ _dlist_init(el_ptr, sizeof(el_def), add_cb) diff --git a/test/utils/dlist.c b/test/utils/dlist.c index 6340488..984c89f 100644 --- a/test/utils/dlist.c +++ b/test/utils/dlist.c @@ -42,7 +42,7 @@ void test__init(void **state) { assert_ptr_equal(dt_ptr->text, LOREM_IPSUM); } -void test__init__add_several_times(void **state) { +void test__add_several_times(void **state) { test_t t1 = {.buf = "TEST BUF", .num = 123, .text = LOREM_IPSUM}; test_t t2 = {.buf = "TEST 1 BUF", .num = 11, .text = "RAND 1 TEXT"}; test_t t3 = {.buf = "TEST 2 BUF", .num = 22, .text = "RAND 2 TEXT"}; @@ -64,7 +64,7 @@ void test__init__add_several_times(void **state) { assert_memory_equal(dl_t3, &t3, sizeof(test_t)); } -void test__init__add_several_times_prepend(void **state) { +void test__add_several_times_prepend(void **state) { test_t t1 = {.buf = "TEST BUF", .num = 123, .text = LOREM_IPSUM}; test_t t2 = {.buf = "TEST 1 BUF", .num = 11, .text = "RAND 1 TEXT"}; test_t t3 = {.buf = "TEST 2 BUF", .num = 22, .text = "RAND 2 TEXT"}; @@ -86,7 +86,7 @@ void test__init__add_several_times_prepend(void **state) { assert_memory_equal(dl_t3, &t3, sizeof(test_t)); } -void test__init__add_and_iterate(void **state) { +void test__add_and_iterate(void **state) { test_t t1 = {.buf = "TEST BUF", .num = 123, .text = LOREM_IPSUM}; test_t t2 = {.buf = "TEST 1 BUF", .num = 11, .text = "RAND 1 TEXT"}; test_t t3 = {.buf = "TEST 2 BUF", .num = 22, .text = "RAND 2 TEXT"}; @@ -117,7 +117,7 @@ bool _sort(void *_a, void *_b) { #define T_TEXT "RAND TEXT " #define T_IT_NUM 120 -void test__init__insert_sort(void **state) { +void test__insert_sort(void **state) { srand(time(NULL)); test_t t = {.text = T_TEXT}; @@ -152,7 +152,7 @@ bool delete_cb(void *el_ptr) { return 1; } -void test__init__remove_by_ptr(void **state) { +void test__remove_by_ptr(void **state) { test_t ta = {.buf = "TEST A", .num = 123, .text = "TEXT A"}; test_t tb = {.buf = "TEST B", .num = 456, .text = "TEXT B"}; test_t tc = {.buf = "TEST C", .num = 789, .text = "TEXT C"}; @@ -176,18 +176,46 @@ void test__init__remove_by_ptr(void **state) { assert_int_equal(c_ptr->num, 789); } +int clean_db_call_times = 0; + +bool clean_db(void *ptr) { + free(ptr); + clean_db_call_times++; + return 1; +} + +void test__clear_list(void **state) { + test_t ta = {.buf = "TEST A", .num = 123, .text = "TEXT A"}; + test_t tb = {.buf = "TEST B", .num = 456, .text = "TEXT B"}; + test_t tc = {.buf = "TEST C", .num = 789, .text = "TEXT C"}; + + dlist_t *dlist = dlist_init(NULL, int, NULL); + + tlist_add(dlist, &ta, false); + tlist_add(dlist, &tb, false); + tlist_add(dlist, &tc, false); + + assert_int_equal(dlist->len, 3); + dlist_clear_list(dlist, clean_db); + assert_int_equal(dlist->len, 0); + assert_ptr_equal(dlist->current, NULL); + assert_ptr_equal(dlist->start, NULL); + assert_int_equal(clean_db_call_times, 3); + clean_db_call_times = 0; +} + int setup(void **state) { return 0; } int tear_down(void **state) { return 0; } int main(int argc, char **argv) { const struct CMUnitTest tests[] = { cmocka_unit_test(test__init), - cmocka_unit_test(test__init__add_several_times), - cmocka_unit_test(test__init__add_several_times_prepend), - cmocka_unit_test(test__init__add_and_iterate), - cmocka_unit_test(test__init__insert_sort), - cmocka_unit_test(test__init__remove_by_ptr), - + cmocka_unit_test(test__add_several_times), + cmocka_unit_test(test__add_several_times_prepend), + cmocka_unit_test(test__add_and_iterate), + cmocka_unit_test(test__insert_sort), + cmocka_unit_test(test__remove_by_ptr), + cmocka_unit_test(test__clear_list), }; return cmocka_run_group_tests(tests, setup, tear_down);