From 43a1da856f31bd9972848fc00e764eaea17b7c06 Mon Sep 17 00:00:00 2001 From: Alexander Zhylin Date: Mon, 3 Aug 2026 17:50:09 +0300 Subject: [PATCH] tests and fixes for dlist_remove_by_ptr --- src/utils/dlist.c | 32 +++++++++++-------- src/utils/dlist.h | 24 +++++++------- test/utils/dlist.c | 79 ++++++++++++++++++++++++++++++++++++---------- 3 files changed, 94 insertions(+), 41 deletions(-) diff --git a/src/utils/dlist.c b/src/utils/dlist.c index 3625484..b1cd06a 100644 --- a/src/utils/dlist.c +++ b/src/utils/dlist.c @@ -6,16 +6,19 @@ #include "dlist.h" -/* TODO: Test for dlist_remove_by_ptr */ +/* + Uses *add* when needs to make a full copy of the element. + Uses *insert* when operates with nodes. +*/ -dlist_t *_dlist_init(void *el_ptr, int el_siz) { +dlist_t *_dlist_init(void *el_ptr, int el_siz, dblist_add_cb_t add_cb) { dlist_t *dlist = malloc(sizeof(dlist_t)); dlist->len = 0; dlist->current = NULL; dlist->start = NULL; if (el_ptr != NULL) { - _dlist_add(dlist, el_ptr, el_siz, false); + _dlist_add(dlist, el_ptr, el_siz, add_cb, false); } return dlist; @@ -49,11 +52,11 @@ void _dlist_insert_end(dlist_t *dlist, dlist_node_t *new_node) { dlist->len++; } -void _dlist_insert_sort(dlist_t *dlist, void *el_ptr, int el_siz, - dblist_sort_cb_t *cb) { +void _dlist_add_sort(dlist_t *dlist, void *el_ptr, int el_siz, + 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); - memcpy(node->el_ptr, el_ptr, el_siz); + add_cb(node->el_ptr, el_ptr); dlist_node_t *dlist_item = dlist->start; bool res = true; @@ -82,10 +85,10 @@ void _dlist_insert_sort(dlist_t *dlist, void *el_ptr, int el_siz, } } -void _dlist_add(dlist_t *dlist, void *el_ptr, int el_siz, 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); - memcpy(node->el_ptr, el_ptr, el_siz); + add_cb(node->el_ptr, el_ptr); if (dlist->start == NULL) { node->previous = NULL; @@ -109,20 +112,23 @@ void _dlist_add(dlist_t *dlist, void *el_ptr, int el_siz, bool prepend) { } dlist_node_t *find_node_by_ptr(dlist_t *dlist, void *el_ptr) { - dlist_node_t *el = dlist->start; + dlist_node_t *node = dlist->start; do { - if (el->el_ptr == el_ptr) break; - } while ((el = el->next) != NULL); - if (el->el_ptr == el_ptr) return el_ptr; + if (node->el_ptr == el_ptr) break; + } while ((node = node->next) != NULL); + 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; - cb(node->el_ptr); 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; + cb(node->el_ptr); free(node); return 1; } diff --git a/src/utils/dlist.h b/src/utils/dlist.h index 13f5d3f..e57b3f9 100644 --- a/src/utils/dlist.h +++ b/src/utils/dlist.h @@ -17,26 +17,28 @@ typedef struct dlist_t { size_t len; } dlist_t; -dlist_t *_dlist_init(void *el_ptr, int el_siz); - /* Returns if a > b */ typedef bool dblist_sort_cb_t(void *a, void *b); - +typedef bool dblist_add_cb_t(void *dst, void *src); typedef bool dblist_rm_cb_t(void *el_ptr); +dlist_t *_dlist_init(void *el_ptr, int el_siz, dblist_add_cb_t); void *dlist_get_current(dlist_t *dlist); void *dlist_it_prev(dlist_t *dlist); -void _dlist_add(dlist_t *dlist, void *el_ptr, int el_siz, bool prepend); +void _dlist_add(dlist_t *dlist, void *el_ptr, int el_siz, + dblist_add_cb_t add_cb, bool prepend); void *dlist_it_prev(dlist_t *dlist); void *dlist_it_next(dlist_t *dlist); -void _dlist_insert_sort(dlist_t *dlist, void *el_ptr, int el_siz, - dblist_sort_cb_t *cb); +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); -#define dlist_init(el_ptr, el_def) _dlist_init(el_ptr, sizeof(el_def)) -#define dlist_add(dlist, el_ptr, el_def, prepend) \ - _dlist_add(dlist, el_ptr, sizeof(el_def), prepend) +#define dlist_init(el_ptr, el_def, add_cb) \ + _dlist_init(el_ptr, sizeof(el_def), add_cb) +#define dlist_add(dlist, el_ptr, el_def, add_cb, prepend) \ + _dlist_add(dlist, el_ptr, sizeof(el_def), add_cb, prepend) #define dlist_get_current(dlist) dlist->current->el_ptr -#define dlist_insert_sort(dlist, el_ptr, el_typ, cb) \ - _dlist_insert_sort(dlist, el_ptr, sizeof(el_typ), cb) +#define dlist_add_sort(dlist, el_ptr, el_typ, sort_cb, add_cb) \ + _dlist_add_sort(dlist, el_ptr, sizeof(el_typ), sort_cb, add_cb) #endif \ No newline at end of file diff --git a/test/utils/dlist.c b/test/utils/dlist.c index afa6f2b..6340488 100644 --- a/test/utils/dlist.c +++ b/test/utils/dlist.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -11,6 +12,16 @@ typedef struct { char buf[128]; } test_t; +bool dblist_add_cb(void *dst, void *src) { + // test_t *dst = _dst; + // test_t *src = _src; + memcpy(dst, src, sizeof(test_t)); + return true; +} + +#define tlist_add(dlist, item, prepend) \ + dlist_add(dlist, item, test_t, dblist_add_cb, prepend); + #define LOREM_IPSUM \ "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod " \ "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim " \ @@ -23,7 +34,7 @@ typedef struct { void test__init(void **state) { test_t t = {.buf = "TEST BUF", .num = 123, .text = LOREM_IPSUM}; - dlist_t *dlist = dlist_init(&t, test_t); + dlist_t *dlist = dlist_init(&t, test_t, dblist_add_cb); assert_int_equal(dlist->len, 1); test_t *dt_ptr = dlist->current->el_ptr; assert_int_equal(dt_ptr->num, t.num); @@ -36,11 +47,11 @@ void test__init__add_several_times(void **state) { 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"}; - dlist_t *dlist = dlist_init(NULL, test_t); + dlist_t *dlist = dlist_init(NULL, test_t, NULL); - dlist_add(dlist, &t1, test_t, false); - dlist_add(dlist, &t2, test_t, false); - dlist_add(dlist, &t3, test_t, false); + dlist_add(dlist, &t1, test_t, dblist_add_cb, false); + dlist_add(dlist, &t2, test_t, dblist_add_cb, false); + dlist_add(dlist, &t3, test_t, dblist_add_cb, false); assert_int_equal(dlist->len, 3); @@ -58,11 +69,11 @@ void test__init__add_several_times_prepend(void **state) { 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"}; - dlist_t *dlist = dlist_init(NULL, test_t); + dlist_t *dlist = dlist_init(NULL, test_t, NULL); - dlist_add(dlist, &t1, test_t, true); - dlist_add(dlist, &t2, test_t, true); - dlist_add(dlist, &t3, test_t, true); + dlist_add(dlist, &t1, test_t, dblist_add_cb, true); + dlist_add(dlist, &t2, test_t, dblist_add_cb, true); + dlist_add(dlist, &t3, test_t, dblist_add_cb, true); assert_int_equal(dlist->len, 3); @@ -80,11 +91,11 @@ void test__init__add_and_iterate(void **state) { 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"}; - dlist_t *dlist = dlist_init(NULL, test_t); + dlist_t *dlist = dlist_init(NULL, test_t, NULL); - dlist_add(dlist, &t1, test_t, false); - dlist_add(dlist, &t2, test_t, false); - dlist_add(dlist, &t3, test_t, false); + dlist_add(dlist, &t1, test_t, dblist_add_cb, false); + dlist_add(dlist, &t2, test_t, dblist_add_cb, false); + dlist_add(dlist, &t3, test_t, dblist_add_cb, false); test_t *dl_t3 = dlist_it_prev(dlist); test_t *dl_t2 = dlist_it_prev(dlist); @@ -110,12 +121,12 @@ void test__init__insert_sort(void **state) { srand(time(NULL)); test_t t = {.text = T_TEXT}; - dlist_t *dlist = dlist_init(NULL, test_t); + dlist_t *dlist = dlist_init(NULL, test_t, NULL); for (int i = 0; i < T_IT_NUM; i++) { sprintf(t.buf, "%s %d", T_BUF, i); t.num = rand(); - dlist_insert_sort(dlist, &t, test_t, _sort); + dlist_add_sort(dlist, &t, test_t, _sort, dblist_add_cb); } test_t *t1, *t2; @@ -123,8 +134,8 @@ void test__init__insert_sort(void **state) { t2 = dlist_it_prev(dlist); t1 = dlist_it_prev(dlist); - assert_int_in_range(t2->num, t1->num, INT_MAX);\ - + assert_int_in_range(t2->num, t1->num, INT_MAX); + for (int i = T_IT_NUM - 2; i > 0; i--) { t2 = t1; t1 = dlist_it_prev(dlist); @@ -132,6 +143,39 @@ void test__init__insert_sort(void **state) { } } +int delete_times = 0; +test_t *b_ptr = NULL; + +bool delete_cb(void *el_ptr) { + assert_int_equal(b_ptr, el_ptr); + delete_times++; + return 1; +} + +void test__init__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"}; + dlist_t *dlist = dlist_init(NULL, int, NULL); + + tlist_add(dlist, &ta, false); + tlist_add(dlist, &tb, false); + tlist_add(dlist, &tc, false); + + b_ptr = dlist->start->next->el_ptr; + assert_int_equal(tb.num, 456); + + dlist_remove_by_ptr(dlist, b_ptr, delete_cb); + assert_ptr_equal(dlist->start->next, dlist->current); + assert_ptr_equal(dlist->current->previous, dlist->start); + assert_int_equal(dlist->len, 2); + assert_int_equal(delete_times, 1); + test_t *a_ptr = dlist->start->el_ptr; + test_t *c_ptr = dlist->start->next->el_ptr; + assert_int_equal(a_ptr->num, 123); + assert_int_equal(c_ptr->num, 789); +} + int setup(void **state) { return 0; } int tear_down(void **state) { return 0; } @@ -142,6 +186,7 @@ int main(int argc, char **argv) { 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), };