Dual-linked list: clear list

This commit is contained in:
2026-08-04 19:08:30 +03:00
parent 43a1da856f
commit 769aab6d1f
3 changed files with 77 additions and 20 deletions
+35 -7
View File
@@ -24,7 +24,8 @@ dlist_t *_dlist_init(void *el_ptr, int el_siz, dblist_add_cb_t add_cb) {
return dlist; 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) { if (prev_node != NULL) {
new_el->next = prev_node->next; new_el->next = prev_node->next;
prev_node->next->previous = new_el; prev_node->next->previous = new_el;
@@ -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)); dlist_node_t *node = malloc(sizeof(dlist_node_t));
node->el_ptr = malloc(el_siz); node->el_ptr = malloc(el_siz);
add_cb(node->el_ptr, el_ptr); 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 *find_node_by_ptr(dlist_t *dlist, void *el_ptr) {
dlist_node_t *node = dlist->start; dlist_node_t *node = dlist->start;
do { do {
if (node->el_ptr == el_ptr) break; if (node->el_ptr == el_ptr)
break;
} while ((node = node->next) != NULL); } while ((node = node->next) != NULL);
if (node->el_ptr == el_ptr) return node; if (node->el_ptr == el_ptr)
return node;
return NULL; return NULL;
} }
int dlist_remove_by_ptr(dlist_t *dlist, void *el_ptr, dblist_rm_cb_t cb) { 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); 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->next->previous = node->previous;
node->previous->next = node->next; node->previous->next = node->next;
dlist->len--; dlist->len--;
if (node->next == NULL) dlist->current = node->previous; if (node->next == NULL)
if (node->previous == NULL) dlist->start = node->next; dlist->current = node->previous;
if (node->previous == NULL)
dlist->start = node->next;
cb(node->el_ptr); cb(node->el_ptr);
free(node); free(node);
return 1; 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) { void *dlist_it_prev(dlist_t *dlist) {
dlist_node_t *cur_ptr = dlist->pointer; dlist_node_t *cur_ptr = dlist->pointer;
if (dlist->pointer->previous != NULL) { if (dlist->pointer->previous != NULL) {
+1
View File
@@ -32,6 +32,7 @@ void *dlist_it_next(dlist_t *dlist);
void _dlist_add_sort(dlist_t *dlist, void *el_ptr, int el_siz, 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);
int dlist_remove_by_ptr(dlist_t *dlist, void *el_ptr, dblist_rm_cb_t 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) \ #define dlist_init(el_ptr, el_def, add_cb) \
_dlist_init(el_ptr, sizeof(el_def), add_cb) _dlist_init(el_ptr, sizeof(el_def), add_cb)
+39 -11
View File
@@ -42,7 +42,7 @@ void test__init(void **state) {
assert_ptr_equal(dt_ptr->text, LOREM_IPSUM); 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 t1 = {.buf = "TEST BUF", .num = 123, .text = LOREM_IPSUM};
test_t t2 = {.buf = "TEST 1 BUF", .num = 11, .text = "RAND 1 TEXT"}; 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"}; 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)); 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 t1 = {.buf = "TEST BUF", .num = 123, .text = LOREM_IPSUM};
test_t t2 = {.buf = "TEST 1 BUF", .num = 11, .text = "RAND 1 TEXT"}; 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"}; 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)); 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 t1 = {.buf = "TEST BUF", .num = 123, .text = LOREM_IPSUM};
test_t t2 = {.buf = "TEST 1 BUF", .num = 11, .text = "RAND 1 TEXT"}; 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"}; 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_TEXT "RAND TEXT "
#define T_IT_NUM 120 #define T_IT_NUM 120
void test__init__insert_sort(void **state) { void test__insert_sort(void **state) {
srand(time(NULL)); srand(time(NULL));
test_t t = {.text = T_TEXT}; test_t t = {.text = T_TEXT};
@@ -152,7 +152,7 @@ bool delete_cb(void *el_ptr) {
return 1; 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 ta = {.buf = "TEST A", .num = 123, .text = "TEXT A"};
test_t tb = {.buf = "TEST B", .num = 456, .text = "TEXT B"}; test_t tb = {.buf = "TEST B", .num = 456, .text = "TEXT B"};
test_t tc = {.buf = "TEST C", .num = 789, .text = "TEXT C"}; 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); 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 setup(void **state) { return 0; }
int tear_down(void **state) { return 0; } int tear_down(void **state) { return 0; }
int main(int argc, char **argv) { int main(int argc, char **argv) {
const struct CMUnitTest tests[] = { const struct CMUnitTest tests[] = {
cmocka_unit_test(test__init), cmocka_unit_test(test__init),
cmocka_unit_test(test__init__add_several_times), cmocka_unit_test(test__add_several_times),
cmocka_unit_test(test__init__add_several_times_prepend), cmocka_unit_test(test__add_several_times_prepend),
cmocka_unit_test(test__init__add_and_iterate), cmocka_unit_test(test__add_and_iterate),
cmocka_unit_test(test__init__insert_sort), cmocka_unit_test(test__insert_sort),
cmocka_unit_test(test__init__remove_by_ptr), cmocka_unit_test(test__remove_by_ptr),
cmocka_unit_test(test__clear_list),
}; };
return cmocka_run_group_tests(tests, setup, tear_down); return cmocka_run_group_tests(tests, setup, tear_down);