Tue, 28 Dec 2021 14:16:04 +0100
add cx_linked_list_compare() and simplifies some tests
src/cx/linked_list.h | file | annotate | diff | comparison | revisions | |
src/linked_list.c | file | annotate | diff | comparison | revisions | |
test/test_list.c | file | annotate | diff | comparison | revisions |
1.1 --- a/src/cx/linked_list.h Mon Dec 27 17:16:32 2021 +0100 1.2 +++ b/src/cx/linked_list.h Tue Dec 28 14:16:04 2021 +0100 1.3 @@ -382,6 +382,28 @@ 1.4 CxListComparator cmp_func 1.5 ) __attribute__((__nonnull__(1, 7))); 1.6 1.7 + 1.8 +/** 1.9 + * Compares two lists element wise. 1.10 + * 1.11 + * @param begin_left the begin of the left list (\c NULL denotes an empty list) 1.12 + * @param begin_right the begin of the right list (\c NULL denotes an empty list) 1.13 + * @param loc_advance the location of the pointer to advance 1.14 + * @param loc_data the location of the \c data pointer within your node struct 1.15 + * @param follow_ptr \c false if the pointer denoted by \p loc_data shall be passed to the \p cmp_func. 1.16 + * If \c true, the data at \p loc_data is assumed to be a pointer, dereferenced, and then passed to \p cmp_func. 1.17 + * @param cmp_func the function to compare the elements 1.18 + * @return 1.19 + */ 1.20 +int cx_linked_list_compare( 1.21 + void *begin_left, 1.22 + void *begin_right, 1.23 + ptrdiff_t loc_advance, 1.24 + ptrdiff_t loc_data, 1.25 + int follow_ptr, 1.26 + CxListComparator cmp_func 1.27 +) __attribute__((__nonnull__(6))); 1.28 + 1.29 /** 1.30 * Reverses the order of the nodes in a linked list. 1.31 *
2.1 --- a/src/linked_list.c Mon Dec 27 17:16:32 2021 +0100 2.2 +++ b/src/linked_list.c Tue Dec 28 14:16:04 2021 +0100 2.3 @@ -396,6 +396,28 @@ 2.4 } 2.5 } 2.6 2.7 +int cx_linked_list_compare( 2.8 + void *begin_left, 2.9 + void *begin_right, 2.10 + ptrdiff_t loc_advance, 2.11 + ptrdiff_t loc_data, 2.12 + int follow_ptr, 2.13 + CxListComparator cmp_func 2.14 +) { 2.15 + void *left = begin_left, *right = begin_right; 2.16 + 2.17 + while (left != NULL && right != NULL) { 2.18 + int result = cmp_func(ll_data(left), ll_data(right)); 2.19 + if (result != 0) return result; 2.20 + left = ll_advance(left); 2.21 + right = ll_advance(right); 2.22 + } 2.23 + 2.24 + if (left != NULL) { return 1; } 2.25 + else if (right != NULL) { return -1; } 2.26 + else { return 0; } 2.27 +} 2.28 + 2.29 void cx_linked_list_reverse( 2.30 void **begin, 2.31 void **end,
3.1 --- a/test/test_list.c Mon Dec 27 17:16:32 2021 +0100 3.2 +++ b/test/test_list.c Tue Dec 28 14:16:04 2021 +0100 3.3 @@ -30,20 +30,55 @@ 3.4 #include "test_config.h" 3.5 #include "util_allocator.h" 3.6 3.7 -int cmp_int(int const *l, int const *r) { 3.8 +int cmp_int( 3.9 + int const *l, 3.10 + int const *r 3.11 +) { 3.12 int left = *l, right = *r; 3.13 return left == right ? 0 : (left < right ? -1 : 1); 3.14 } 3.15 3.16 +struct node { 3.17 + struct node *next; 3.18 + struct node *prev; 3.19 + int data; 3.20 +}; 3.21 + 3.22 +#define nd(name) name = {0} 3.23 + 3.24 +const ptrdiff_t loc_prev = offsetof(struct node, prev); 3.25 +const ptrdiff_t loc_next = offsetof(struct node, next); 3.26 +const ptrdiff_t loc_data = offsetof(struct node, data); 3.27 + 3.28 +struct node *create_test_data( 3.29 + size_t n, 3.30 + const int data[] 3.31 +) { 3.32 + if (n == 0) return NULL; 3.33 + struct node *begin = calloc(1, sizeof(struct node)); 3.34 + struct node *prev = begin; 3.35 + if (data) begin->data = data[0]; 3.36 + for (size_t i = 1; i < n; i++) { 3.37 + struct node *node = calloc(1, sizeof(struct node)); 3.38 + if (data) node->data = data[i]; 3.39 + cx_linked_list_link(prev, node, loc_prev, loc_next); 3.40 + prev = node; 3.41 + } 3.42 + return begin; 3.43 +} 3.44 + 3.45 +void destroy_test_data(struct node *begin) { 3.46 + struct node *node = begin; 3.47 + while (node) { 3.48 + struct node *next = node->next; 3.49 + free(node); 3.50 + node = next; 3.51 + } 3.52 +} 3.53 + 3.54 void test_linked_list_link_unlink(void) { 3.55 - struct node { 3.56 - void *next; 3.57 - void *prev; 3.58 - }; 3.59 - const ptrdiff_t loc_prev = offsetof(struct node, prev); 3.60 - const ptrdiff_t loc_next = offsetof(struct node, next); 3.61 3.62 - struct node a = {NULL, NULL}, b = {NULL, NULL}; 3.63 + struct node nd(a), nd(b), nd(c); 3.64 3.65 cx_linked_list_link(&a, &b, loc_prev, loc_next); 3.66 CU_ASSERT_PTR_NULL(a.prev) 3.67 @@ -57,7 +92,6 @@ 3.68 CU_ASSERT_PTR_NULL(b.prev) 3.69 CU_ASSERT_PTR_NULL(b.next) 3.70 3.71 - struct node c = {NULL, NULL}; 3.72 cx_linked_list_link(&b, &c, loc_prev, loc_next); 3.73 cx_linked_list_link(&a, &b, loc_prev, loc_next); 3.74 cx_linked_list_unlink(&b, &c, loc_prev, loc_next); 3.75 @@ -70,22 +104,10 @@ 3.76 } 3.77 3.78 void test_linked_list_at(void) { 3.79 - struct node { 3.80 - void *next; 3.81 - void *prev; 3.82 - }; 3.83 - const ptrdiff_t loc_prev = offsetof(struct node, prev); 3.84 - const ptrdiff_t loc_next = offsetof(struct node, next); 3.85 - 3.86 - struct node a, b, c, d; 3.87 - a.prev = NULL; 3.88 - a.next = &b; 3.89 - b.prev = &a; 3.90 - b.next = &c; 3.91 - c.prev = &b; 3.92 - c.next = &d; 3.93 - d.prev = &c; 3.94 - d.next = NULL; 3.95 + struct node nd(a), nd(b), nd(c), nd(d); 3.96 + cx_linked_list_link(&a, &b, loc_prev, loc_next); 3.97 + cx_linked_list_link(&b, &c, loc_prev, loc_next); 3.98 + cx_linked_list_link(&c, &d, loc_prev, loc_next); 3.99 3.100 CU_ASSERT_PTR_EQUAL(cx_linked_list_at(&a, 0, loc_next, 0), &a) 3.101 CU_ASSERT_PTR_EQUAL(cx_linked_list_at(&a, 0, loc_next, 1), &b) 3.102 @@ -103,21 +125,43 @@ 3.103 CU_ASSERT_PTR_EQUAL(cx_linked_list_at(&d, 3, loc_prev, 1), &b) 3.104 } 3.105 3.106 +void test_linked_list_compare(void) { 3.107 + int a[] = {2, 4, 6, 8}; 3.108 + int b[] = {2, 4, 6}; 3.109 + int c[] = {2, 4, 6, 9}; 3.110 + 3.111 + void *la = create_test_data(4, a); 3.112 + void *lb = create_test_data(3, b); 3.113 + void *lc = create_test_data(4, c); 3.114 + 3.115 + CU_ASSERT_TRUE(0 < cx_linked_list_compare(la, lb, loc_next, loc_data, 3.116 + 0, (CxListComparator) cmp_int) 3.117 + ) 3.118 + CU_ASSERT_TRUE(0 > cx_linked_list_compare(lb, la, loc_next, loc_data, 3.119 + 0, (CxListComparator) cmp_int) 3.120 + ) 3.121 + CU_ASSERT_TRUE(0 < cx_linked_list_compare(lc, la, loc_next, loc_data, 3.122 + 0, (CxListComparator) cmp_int) 3.123 + ) 3.124 + CU_ASSERT_TRUE(0 > cx_linked_list_compare(la, lc, loc_next, loc_data, 3.125 + 0, (CxListComparator) cmp_int) 3.126 + ) 3.127 + CU_ASSERT_TRUE(0 == cx_linked_list_compare(la, la, loc_next, loc_data, 3.128 + 0, (CxListComparator) cmp_int) 3.129 + ) 3.130 + 3.131 + destroy_test_data(la); 3.132 + destroy_test_data(lb); 3.133 + destroy_test_data(lc); 3.134 +} 3.135 + 3.136 void test_linked_list_add(void) { 3.137 - struct node { 3.138 - void *prev; 3.139 - void *next; 3.140 - }; 3.141 - 3.142 struct node nodes[4]; 3.143 + void *begin, *end; 3.144 3.145 // test with begin, end / prev, next 3.146 memset(nodes, 0, 4 * sizeof(struct node)); 3.147 - void *begin = NULL; 3.148 - void *end = NULL; 3.149 - 3.150 - ptrdiff_t loc_prev = offsetof(struct node, prev); 3.151 - ptrdiff_t loc_next = offsetof(struct node, next); 3.152 + begin = end = NULL; 3.153 3.154 cx_linked_list_add(&begin, &end, loc_prev, loc_next, &nodes[0]); 3.155 CU_ASSERT_PTR_EQUAL(begin, &nodes[0]) 3.156 @@ -133,8 +177,7 @@ 3.157 3.158 // test with begin only / prev, next 3.159 memset(nodes, 0, 4 * sizeof(struct node)); 3.160 - begin = NULL; 3.161 - end = NULL; 3.162 + begin = end = NULL; 3.163 3.164 cx_linked_list_add(&begin, NULL, loc_prev, loc_next, &nodes[0]); 3.165 CU_ASSERT_PTR_EQUAL(begin, &nodes[0]) 3.166 @@ -149,8 +192,7 @@ 3.167 3.168 // test with end only / prev, next 3.169 memset(nodes, 0, 4 * sizeof(struct node)); 3.170 - begin = NULL; 3.171 - end = NULL; 3.172 + begin = end = NULL; 3.173 3.174 cx_linked_list_add(NULL, &end, loc_prev, loc_next, &nodes[0]); 3.175 CU_ASSERT_PTR_EQUAL(end, &nodes[0]) 3.176 @@ -166,8 +208,7 @@ 3.177 3.178 // test with begin, end / next 3.179 memset(nodes, 0, 4 * sizeof(struct node)); 3.180 - begin = NULL; 3.181 - end = NULL; 3.182 + begin = end = NULL; 3.183 3.184 cx_linked_list_add(&begin, &end, -1, loc_next, &nodes[0]); 3.185 CU_ASSERT_PTR_EQUAL(begin, &nodes[0]) 3.186 @@ -179,20 +220,12 @@ 3.187 } 3.188 3.189 void test_linked_list_prepend(void) { 3.190 - struct node { 3.191 - void *prev; 3.192 - void *next; 3.193 - }; 3.194 - 3.195 struct node nodes[4]; 3.196 + void *begin, *end; 3.197 3.198 // test with begin, end / prev, next 3.199 memset(nodes, 0, 4 * sizeof(struct node)); 3.200 - void *begin = NULL; 3.201 - void *end = NULL; 3.202 - 3.203 - ptrdiff_t loc_prev = offsetof(struct node, prev); 3.204 - ptrdiff_t loc_next = offsetof(struct node, next); 3.205 + begin = end = NULL; 3.206 3.207 cx_linked_list_prepend(&begin, &end, loc_prev, loc_next, &nodes[0]); 3.208 CU_ASSERT_PTR_EQUAL(begin, &nodes[0]) 3.209 @@ -208,8 +241,7 @@ 3.210 3.211 // test with begin only / prev, next 3.212 memset(nodes, 0, 4 * sizeof(struct node)); 3.213 - begin = NULL; 3.214 - end = NULL; 3.215 + begin = end = NULL; 3.216 3.217 cx_linked_list_prepend(&begin, NULL, loc_prev, loc_next, &nodes[0]); 3.218 CU_ASSERT_PTR_EQUAL(begin, &nodes[0]) 3.219 @@ -225,8 +257,7 @@ 3.220 3.221 // test with end only / prev, next 3.222 memset(nodes, 0, 4 * sizeof(struct node)); 3.223 - begin = NULL; 3.224 - end = NULL; 3.225 + begin = end = NULL; 3.226 3.227 cx_linked_list_prepend(NULL, &end, loc_prev, loc_next, &nodes[0]); 3.228 CU_ASSERT_PTR_EQUAL(end, &nodes[0]) 3.229 @@ -242,8 +273,7 @@ 3.230 3.231 // test with begin, end / next 3.232 memset(nodes, 0, 4 * sizeof(struct node)); 3.233 - begin = NULL; 3.234 - end = NULL; 3.235 + begin = end = NULL; 3.236 3.237 cx_linked_list_prepend(&begin, &end, -1, loc_next, &nodes[0]); 3.238 CU_ASSERT_PTR_EQUAL(begin, &nodes[0]) 3.239 @@ -259,13 +289,6 @@ 3.240 } 3.241 3.242 void test_linked_list_insert(void) { 3.243 - struct node { 3.244 - void *prev; 3.245 - void *next; 3.246 - }; 3.247 - ptrdiff_t loc_prev = offsetof(struct node, prev); 3.248 - ptrdiff_t loc_next = offsetof(struct node, next); 3.249 - 3.250 struct node nodes[4]; 3.251 void *begin, *end; 3.252 3.253 @@ -317,13 +340,6 @@ 3.254 } 3.255 3.256 void test_linked_list_insert_chain(void) { 3.257 - struct node { 3.258 - void *prev; 3.259 - void *next; 3.260 - }; 3.261 - ptrdiff_t loc_prev = offsetof(struct node, prev); 3.262 - ptrdiff_t loc_next = offsetof(struct node, next); 3.263 - 3.264 struct node nodes[5]; 3.265 void *begin, *end; 3.266 3.267 @@ -378,138 +394,78 @@ 3.268 } 3.269 3.270 void test_linked_list_first(void) { 3.271 - struct node { 3.272 - int data; 3.273 - void *prev; 3.274 - }; 3.275 - ptrdiff_t loc = offsetof(struct node, prev); 3.276 - 3.277 - struct node first = {1, NULL}; 3.278 - struct node second = {2, &first}; 3.279 - struct node third = {3, &second}; 3.280 - 3.281 - CU_ASSERT_PTR_EQUAL(cx_linked_list_first(&first, loc), &first) 3.282 - CU_ASSERT_PTR_EQUAL(cx_linked_list_first(&second, loc), &first) 3.283 - CU_ASSERT_PTR_EQUAL(cx_linked_list_first(&third, loc), &first) 3.284 + struct node *begin = create_test_data(3, NULL); 3.285 + CU_ASSERT_PTR_EQUAL(cx_linked_list_first(begin, loc_prev), begin) 3.286 + CU_ASSERT_PTR_EQUAL(cx_linked_list_first(begin->next, loc_prev), begin) 3.287 + CU_ASSERT_PTR_EQUAL(cx_linked_list_first(begin->next->next, loc_prev), begin) 3.288 + destroy_test_data(begin); 3.289 } 3.290 3.291 void test_linked_list_last(void) { 3.292 - struct node { 3.293 - int data; 3.294 - void *next; 3.295 - }; 3.296 - ptrdiff_t loc = offsetof(struct node, next); 3.297 - 3.298 - struct node third = {3, NULL}; 3.299 - struct node second = {2, &third}; 3.300 - struct node first = {1, &second}; 3.301 - 3.302 - CU_ASSERT_PTR_EQUAL(cx_linked_list_last(&first, loc), &third) 3.303 - CU_ASSERT_PTR_EQUAL(cx_linked_list_last(&second, loc), &third) 3.304 - CU_ASSERT_PTR_EQUAL(cx_linked_list_last(&third, loc), &third) 3.305 + struct node *begin = create_test_data(3, NULL); 3.306 + struct node *end = begin->next->next; 3.307 + CU_ASSERT_PTR_EQUAL(cx_linked_list_last(begin, loc_next), end) 3.308 + CU_ASSERT_PTR_EQUAL(cx_linked_list_last(begin->next, loc_next), end) 3.309 + CU_ASSERT_PTR_EQUAL(cx_linked_list_last(begin->next->next, loc_next), end) 3.310 + destroy_test_data(begin); 3.311 } 3.312 3.313 void test_linked_list_prev(void) { 3.314 - struct node { 3.315 - void *next; 3.316 - }; 3.317 - ptrdiff_t loc = offsetof(struct node, next); 3.318 - 3.319 - struct node third = {NULL}; 3.320 - struct node second = {&third}; 3.321 - struct node first = {&second}; 3.322 - 3.323 - CU_ASSERT_PTR_NULL(cx_linked_list_prev(&first, loc, &first)) 3.324 - CU_ASSERT_PTR_EQUAL(cx_linked_list_prev(&first, loc, &second), &first) 3.325 - CU_ASSERT_PTR_EQUAL(cx_linked_list_prev(&first, loc, &third), &second) 3.326 + struct node *begin = create_test_data(3, NULL); 3.327 + CU_ASSERT_PTR_NULL(cx_linked_list_prev(begin, loc_next, begin)) 3.328 + CU_ASSERT_PTR_EQUAL(cx_linked_list_prev(begin, loc_next, begin->next), begin) 3.329 + CU_ASSERT_PTR_EQUAL(cx_linked_list_prev(begin, loc_next, begin->next->next), begin->next) 3.330 + destroy_test_data(begin); 3.331 } 3.332 3.333 void test_linked_list_remove(void) { 3.334 - struct node { 3.335 - void *next; 3.336 - }; 3.337 - struct dnode { 3.338 - void *next; 3.339 - void *prev; 3.340 - }; 3.341 - ptrdiff_t loc = offsetof(struct node, next); 3.342 - ptrdiff_t ploc = offsetof(struct dnode, prev); 3.343 + void *begin, *end; 3.344 3.345 - void *begin; 3.346 - void *end; 3.347 + int data[] = {2, 4, 6}; 3.348 + begin = create_test_data(3, data); 3.349 + struct node *first = begin; 3.350 + struct node *second = first->next; 3.351 + struct node *third = second->next; 3.352 + end = third; 3.353 3.354 - // single linked list 3.355 - struct node third = {NULL}; 3.356 - struct node second = {&third}; 3.357 - struct node first = {&second}; 3.358 - begin = &first; 3.359 + cx_linked_list_remove(&begin, &end, loc_prev, loc_next, second); 3.360 + CU_ASSERT_PTR_EQUAL(begin, first) 3.361 + CU_ASSERT_PTR_EQUAL(end, third) 3.362 + CU_ASSERT_PTR_NULL(first->prev) 3.363 + CU_ASSERT_PTR_EQUAL(first->next, third) 3.364 + CU_ASSERT_PTR_EQUAL(third->prev, first) 3.365 + CU_ASSERT_PTR_NULL(third->next) 3.366 3.367 - cx_linked_list_remove(&begin, NULL, -1, loc, &second); 3.368 - CU_ASSERT_PTR_EQUAL(begin, &first) 3.369 - CU_ASSERT_PTR_EQUAL(first.next, &third) 3.370 - CU_ASSERT_PTR_NULL(third.next) 3.371 + cx_linked_list_remove(&begin, &end, loc_prev, loc_next, third); 3.372 + CU_ASSERT_PTR_EQUAL(begin, first) 3.373 + CU_ASSERT_PTR_EQUAL(end, first) 3.374 + CU_ASSERT_PTR_NULL(first->prev) 3.375 + CU_ASSERT_PTR_NULL(first->next) 3.376 3.377 - cx_linked_list_remove(&begin, NULL, -1, loc, &first); 3.378 - CU_ASSERT_PTR_EQUAL(begin, &third) 3.379 - CU_ASSERT_PTR_NULL(third.next) 3.380 - 3.381 - cx_linked_list_remove(&begin, NULL, -1, loc, &third); 3.382 - CU_ASSERT_PTR_NULL(begin) 3.383 - 3.384 - // doubly linked list 3.385 - struct dnode dthird = {NULL , NULL}; 3.386 - struct dnode dsecond = {&dthird, NULL}; 3.387 - struct dnode dfirst = {&dsecond, NULL}; 3.388 - dthird.prev = &dsecond; 3.389 - dsecond.prev = &dfirst; 3.390 - begin = &dfirst; 3.391 - end = &dthird; 3.392 - 3.393 - cx_linked_list_remove(&begin, &end, ploc, loc, &dsecond); 3.394 - CU_ASSERT_PTR_EQUAL(begin, &dfirst) 3.395 - CU_ASSERT_PTR_EQUAL(end, &dthird) 3.396 - CU_ASSERT_PTR_NULL(dfirst.prev) 3.397 - CU_ASSERT_PTR_EQUAL(dfirst.next, &dthird) 3.398 - CU_ASSERT_PTR_EQUAL(dthird.prev, &dfirst) 3.399 - CU_ASSERT_PTR_NULL(dthird.next) 3.400 - 3.401 - cx_linked_list_remove(&begin, &end, ploc, loc, &dthird); 3.402 - CU_ASSERT_PTR_EQUAL(begin, &dfirst) 3.403 - CU_ASSERT_PTR_EQUAL(end, &dfirst) 3.404 - CU_ASSERT_PTR_NULL(dfirst.prev) 3.405 - CU_ASSERT_PTR_NULL(dfirst.next) 3.406 - 3.407 - cx_linked_list_remove(&begin, &end, ploc, loc, &dfirst); 3.408 + cx_linked_list_remove(&begin, &end, loc_prev, loc_next, first); 3.409 CU_ASSERT_PTR_NULL(begin) 3.410 CU_ASSERT_PTR_NULL(end) 3.411 + 3.412 + free(first); 3.413 + free(second); 3.414 + free(third); 3.415 } 3.416 3.417 void test_linked_list_size(void) { 3.418 - struct node { 3.419 - void *next; 3.420 - }; 3.421 - ptrdiff_t loc = offsetof(struct node, next); 3.422 + struct node *list; 3.423 3.424 - struct node first = {NULL}; 3.425 - struct node second = {NULL}; 3.426 - struct node third = {NULL}; 3.427 + CU_ASSERT_PTR_EQUAL(cx_linked_list_size(NULL, loc_next), 0) 3.428 3.429 - CU_ASSERT_PTR_EQUAL(cx_linked_list_size(NULL, loc), 0) 3.430 - CU_ASSERT_PTR_EQUAL(cx_linked_list_size(&first, loc), 1) 3.431 - first.next = &second; 3.432 - CU_ASSERT_PTR_EQUAL(cx_linked_list_size(&first, loc), 2) 3.433 - second.next = &third; 3.434 - CU_ASSERT_PTR_EQUAL(cx_linked_list_size(&first, loc), 3) 3.435 - CU_ASSERT_PTR_EQUAL(cx_linked_list_size(&second, loc), 2) 3.436 + list = create_test_data(5, NULL); 3.437 + CU_ASSERT_EQUAL(cx_linked_list_size(list, loc_next), 5) 3.438 + destroy_test_data(list); 3.439 + 3.440 + list = create_test_data(13, NULL); 3.441 + CU_ASSERT_EQUAL(cx_linked_list_size(list, loc_next), 13) 3.442 + destroy_test_data(list); 3.443 } 3.444 3.445 void test_linked_list_sort(void) { 3.446 - struct node { 3.447 - void *prev; 3.448 - void *next; 3.449 - int data; 3.450 - }; 3.451 - 3.452 int expected[] = { 3.453 14, 30, 151, 163, 227, 300, 315, 317, 363, 398, 417, 424, 438, 446, 508, 555, 605, 713, 716, 759, 761, 880, 3.454 894, 1034, 1077, 1191, 1231, 1264, 1297, 1409, 1423, 1511, 1544, 1659, 1686, 1707, 1734, 1771, 1874, 1894, 3.455 @@ -527,26 +483,16 @@ 3.456 4016, 4085, 4121, 4254, 4319, 4366, 4459, 4514, 4681 3.457 }; 3.458 3.459 - struct node *nodes = calloc(100, sizeof(struct node)); 3.460 - for (int i = 0; i < 100; i++) { 3.461 - nodes[i].prev = i == 0 ? NULL : &nodes[i - 1]; 3.462 - nodes[i].next = i == 99 ? NULL : &nodes[i + 1]; 3.463 - nodes[i].data = scrambled[i]; 3.464 - } 3.465 + void *begin = create_test_data(100, scrambled); 3.466 + void *end = cx_linked_list_last(begin, loc_next); 3.467 3.468 - struct node *begin = &nodes[0]; 3.469 - struct node *end = &nodes[99]; 3.470 - 3.471 - cx_linked_list_sort((void **) &begin, (void **) &end, 3.472 - offsetof(struct node, prev), 3.473 - offsetof(struct node, next), 3.474 - offsetof(struct node, data), 3.475 + cx_linked_list_sort(&begin, &end, loc_prev, loc_next, loc_data, 3.476 0, (CxListComparator) cmp_int); 3.477 3.478 - CU_ASSERT_PTR_NULL(begin->prev) 3.479 - CU_ASSERT_EQUAL(begin->data, expected[0]) 3.480 struct node *check = begin; 3.481 struct node *check_last = NULL; 3.482 + CU_ASSERT_PTR_NULL(check->prev) 3.483 + CU_ASSERT_EQUAL(check->data, expected[0]) 3.484 for (int i = 0; i < 100; i++) { 3.485 CU_ASSERT_EQUAL(check->data, expected[i]) 3.486 CU_ASSERT_PTR_EQUAL(check->prev, check_last) 3.487 @@ -557,53 +503,31 @@ 3.488 check = check->next; 3.489 } 3.490 CU_ASSERT_PTR_NULL(check) 3.491 - CU_ASSERT_EQUAL(end->data, expected[99]) 3.492 + CU_ASSERT_PTR_EQUAL(end, check_last) 3.493 + 3.494 + destroy_test_data(begin); 3.495 } 3.496 3.497 void test_linked_list_reverse(void) { 3.498 - struct node { 3.499 - void *next; 3.500 - }; 3.501 - struct dnode { 3.502 - void *next; 3.503 - void *prev; 3.504 - }; 3.505 - ptrdiff_t loc = offsetof(struct node, next); 3.506 - ptrdiff_t ploc = offsetof(struct dnode, prev); 3.507 + void *begin, *end; 3.508 3.509 - void *begin; 3.510 - void *end; 3.511 + int data[] = {2, 4, 6, 8}; 3.512 + int reversed[] = {8, 6, 4, 2}; 3.513 3.514 - // single linked list 3.515 - struct node third = {NULL}; 3.516 - struct node second = {&third}; 3.517 - struct node first = {&second}; 3.518 - begin = &first; 3.519 + void *list = create_test_data(4, data); 3.520 + void *expected = create_test_data(4, reversed); 3.521 3.522 - cx_linked_list_reverse(&begin, NULL, -1, loc); 3.523 - CU_ASSERT_PTR_EQUAL(begin, &third) 3.524 - CU_ASSERT_PTR_EQUAL(third.next, &second) 3.525 - CU_ASSERT_PTR_EQUAL(second.next, &first) 3.526 - CU_ASSERT_PTR_NULL(first.next) 3.527 + begin = list; 3.528 + end = cx_linked_list_last(list, loc_next); 3.529 3.530 - // doubly linked list 3.531 - struct dnode dthird = {NULL , NULL}; 3.532 - struct dnode dsecond = {&dthird, NULL}; 3.533 - struct dnode dfirst = {&dsecond, NULL}; 3.534 - dthird.prev = &dsecond; 3.535 - dsecond.prev = &dfirst; 3.536 - begin = &dfirst; 3.537 - end = &dthird; 3.538 + cx_linked_list_reverse(&begin, &end, loc_prev, loc_next); 3.539 + CU_ASSERT_PTR_EQUAL(end, list) 3.540 + CU_ASSERT_PTR_EQUAL(begin, cx_linked_list_first(end, loc_prev)) 3.541 + CU_ASSERT_TRUE(0 == cx_linked_list_compare(begin, expected, loc_next, loc_data, 3.542 + 0, (CxListComparator) cmp_int)) 3.543 3.544 - cx_linked_list_reverse(&begin, &end, ploc, loc); 3.545 - CU_ASSERT_PTR_EQUAL(begin, &dthird) 3.546 - CU_ASSERT_PTR_EQUAL(end, &dfirst) 3.547 - CU_ASSERT_PTR_EQUAL(dthird.next, &dsecond) 3.548 - CU_ASSERT_PTR_EQUAL(dsecond.next, &dfirst) 3.549 - CU_ASSERT_PTR_NULL(dfirst.next) 3.550 - CU_ASSERT_PTR_NULL(dthird.prev) 3.551 - CU_ASSERT_PTR_EQUAL(dsecond.prev, &dthird) 3.552 - CU_ASSERT_PTR_EQUAL(dfirst.prev, &dsecond) 3.553 + destroy_test_data(begin); 3.554 + destroy_test_data(expected); 3.555 } 3.556 3.557 void test_hl_linked_list_create(void) { 3.558 @@ -1028,6 +952,7 @@ 3.559 3.560 cu_add_test(suite, test_linked_list_link_unlink); 3.561 cu_add_test(suite, test_linked_list_at); 3.562 + cu_add_test(suite, test_linked_list_compare); 3.563 cu_add_test(suite, test_linked_list_prepend); 3.564 cu_add_test(suite, test_linked_list_add); 3.565 cu_add_test(suite, test_linked_list_insert);