tests and fixes for dlist_remove_by_ptr
This commit is contained in:
+19
-13
@@ -6,16 +6,19 @@
|
|||||||
|
|
||||||
#include "dlist.h"
|
#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_t *dlist = malloc(sizeof(dlist_t));
|
||||||
dlist->len = 0;
|
dlist->len = 0;
|
||||||
dlist->current = NULL;
|
dlist->current = NULL;
|
||||||
dlist->start = NULL;
|
dlist->start = NULL;
|
||||||
|
|
||||||
if (el_ptr != 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;
|
return dlist;
|
||||||
@@ -49,11 +52,11 @@ void _dlist_insert_end(dlist_t *dlist, dlist_node_t *new_node) {
|
|||||||
dlist->len++;
|
dlist->len++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _dlist_insert_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_sort_cb_t cb, dblist_add_cb_t add_cb) {
|
||||||
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);
|
||||||
memcpy(node->el_ptr, el_ptr, el_siz);
|
add_cb(node->el_ptr, el_ptr);
|
||||||
|
|
||||||
dlist_node_t *dlist_item = dlist->start;
|
dlist_node_t *dlist_item = dlist->start;
|
||||||
bool res = true;
|
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));
|
dlist_node_t *node = malloc(sizeof(dlist_node_t));
|
||||||
node->el_ptr = malloc(el_siz);
|
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) {
|
if (dlist->start == NULL) {
|
||||||
node->previous = 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 *find_node_by_ptr(dlist_t *dlist, void *el_ptr) {
|
||||||
dlist_node_t *el = dlist->start;
|
dlist_node_t *node = dlist->start;
|
||||||
do {
|
do {
|
||||||
if (el->el_ptr == el_ptr) break;
|
if (node->el_ptr == el_ptr) break;
|
||||||
} while ((el = el->next) != NULL);
|
} while ((node = node->next) != NULL);
|
||||||
if (el->el_ptr == el_ptr) return el_ptr;
|
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;
|
||||||
cb(node->el_ptr);
|
|
||||||
node->next->previous = node->previous;
|
node->next->previous = node->previous;
|
||||||
node->previous->next = node->next;
|
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);
|
free(node);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-11
@@ -17,26 +17,28 @@ typedef struct dlist_t {
|
|||||||
size_t len;
|
size_t len;
|
||||||
} dlist_t;
|
} dlist_t;
|
||||||
|
|
||||||
dlist_t *_dlist_init(void *el_ptr, int el_siz);
|
|
||||||
|
|
||||||
/* Returns if a > b */
|
/* Returns if a > b */
|
||||||
typedef bool dblist_sort_cb_t(void *a, void *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);
|
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_get_current(dlist_t *dlist);
|
||||||
void *dlist_it_prev(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_prev(dlist_t *dlist);
|
||||||
void *dlist_it_next(dlist_t *dlist);
|
void *dlist_it_next(dlist_t *dlist);
|
||||||
void _dlist_insert_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_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_init(el_ptr, el_def, add_cb) \
|
||||||
#define dlist_add(dlist, el_ptr, el_def, prepend) \
|
_dlist_init(el_ptr, sizeof(el_def), add_cb)
|
||||||
_dlist_add(dlist, el_ptr, sizeof(el_def), prepend)
|
#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_get_current(dlist) dlist->current->el_ptr
|
||||||
#define dlist_insert_sort(dlist, el_ptr, el_typ, cb) \
|
#define dlist_add_sort(dlist, el_ptr, el_typ, sort_cb, add_cb) \
|
||||||
_dlist_insert_sort(dlist, el_ptr, sizeof(el_typ), cb)
|
_dlist_add_sort(dlist, el_ptr, sizeof(el_typ), sort_cb, add_cb)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
+62
-17
@@ -2,6 +2,7 @@
|
|||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <utils/dlist.h>
|
#include <utils/dlist.h>
|
||||||
|
|
||||||
@@ -11,6 +12,16 @@ typedef struct {
|
|||||||
char buf[128];
|
char buf[128];
|
||||||
} test_t;
|
} 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 \
|
#define LOREM_IPSUM \
|
||||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod " \
|
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod " \
|
||||||
"tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim " \
|
"tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim " \
|
||||||
@@ -23,7 +34,7 @@ typedef struct {
|
|||||||
void test__init(void **state) {
|
void test__init(void **state) {
|
||||||
test_t t = {.buf = "TEST BUF", .num = 123, .text = LOREM_IPSUM};
|
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);
|
assert_int_equal(dlist->len, 1);
|
||||||
test_t *dt_ptr = dlist->current->el_ptr;
|
test_t *dt_ptr = dlist->current->el_ptr;
|
||||||
assert_int_equal(dt_ptr->num, t.num);
|
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 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"};
|
||||||
|
|
||||||
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, &t1, test_t, dblist_add_cb, false);
|
||||||
dlist_add(dlist, &t2, test_t, false);
|
dlist_add(dlist, &t2, test_t, dblist_add_cb, false);
|
||||||
dlist_add(dlist, &t3, test_t, false);
|
dlist_add(dlist, &t3, test_t, dblist_add_cb, false);
|
||||||
|
|
||||||
assert_int_equal(dlist->len, 3);
|
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 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"};
|
||||||
|
|
||||||
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, &t1, test_t, dblist_add_cb, true);
|
||||||
dlist_add(dlist, &t2, test_t, true);
|
dlist_add(dlist, &t2, test_t, dblist_add_cb, true);
|
||||||
dlist_add(dlist, &t3, test_t, true);
|
dlist_add(dlist, &t3, test_t, dblist_add_cb, true);
|
||||||
|
|
||||||
assert_int_equal(dlist->len, 3);
|
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 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"};
|
||||||
|
|
||||||
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, &t1, test_t, dblist_add_cb, false);
|
||||||
dlist_add(dlist, &t2, test_t, false);
|
dlist_add(dlist, &t2, test_t, dblist_add_cb, false);
|
||||||
dlist_add(dlist, &t3, test_t, false);
|
dlist_add(dlist, &t3, test_t, dblist_add_cb, false);
|
||||||
|
|
||||||
test_t *dl_t3 = dlist_it_prev(dlist);
|
test_t *dl_t3 = dlist_it_prev(dlist);
|
||||||
test_t *dl_t2 = 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));
|
srand(time(NULL));
|
||||||
|
|
||||||
test_t t = {.text = T_TEXT};
|
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++) {
|
for (int i = 0; i < T_IT_NUM; i++) {
|
||||||
sprintf(t.buf, "%s %d", T_BUF, i);
|
sprintf(t.buf, "%s %d", T_BUF, i);
|
||||||
t.num = rand();
|
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;
|
test_t *t1, *t2;
|
||||||
@@ -123,8 +134,8 @@ void test__init__insert_sort(void **state) {
|
|||||||
t2 = dlist_it_prev(dlist);
|
t2 = dlist_it_prev(dlist);
|
||||||
t1 = 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--) {
|
for (int i = T_IT_NUM - 2; i > 0; i--) {
|
||||||
t2 = t1;
|
t2 = t1;
|
||||||
t1 = dlist_it_prev(dlist);
|
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 setup(void **state) { return 0; }
|
||||||
int tear_down(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_several_times_prepend),
|
||||||
cmocka_unit_test(test__init__add_and_iterate),
|
cmocka_unit_test(test__init__add_and_iterate),
|
||||||
cmocka_unit_test(test__init__insert_sort),
|
cmocka_unit_test(test__init__insert_sort),
|
||||||
|
cmocka_unit_test(test__init__remove_by_ptr),
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user