1 /* |
|
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
|
3 * |
|
4 * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved. |
|
5 * |
|
6 * Redistribution and use in source and binary forms, with or without |
|
7 * modification, are permitted provided that the following conditions are met: |
|
8 * |
|
9 * 1. Redistributions of source code must retain the above copyright |
|
10 * notice, this list of conditions and the following disclaimer. |
|
11 * |
|
12 * 2. Redistributions in binary form must reproduce the above copyright |
|
13 * notice, this list of conditions and the following disclaimer in the |
|
14 * documentation and/or other materials provided with the distribution. |
|
15 * |
|
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
|
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
|
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
|
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
|
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
|
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
|
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
26 * POSSIBILITY OF SUCH DAMAGE. |
|
27 */ |
|
28 |
|
29 #include "cx/linked_list.h" |
|
30 #include "cx/utils.h" |
|
31 #include "test_config.h" |
|
32 #include "util_allocator.h" |
|
33 |
|
34 static int cmp_int_impl( |
|
35 int const *l, |
|
36 int const *r |
|
37 ) { |
|
38 int left = *l, right = *r; |
|
39 return left == right ? 0 : (left < right ? -1 : 1); |
|
40 } |
|
41 |
|
42 #define cmp_int ((CxListComparator) cmp_int_impl) |
|
43 |
|
44 struct node { |
|
45 struct node *next; |
|
46 struct node *prev; |
|
47 int data; |
|
48 }; |
|
49 |
|
50 #define nd(name) name = {0} |
|
51 |
|
52 const ptrdiff_t loc_prev = offsetof(struct node, prev); |
|
53 const ptrdiff_t loc_next = offsetof(struct node, next); |
|
54 const ptrdiff_t loc_data = offsetof(struct node, data); |
|
55 |
|
56 static struct node *create_nodes_test_data( |
|
57 size_t n, |
|
58 int const data[] |
|
59 ) { |
|
60 CU_ASSERT_NOT_EQUAL_FATAL(n, 0) |
|
61 struct node *begin = calloc(1, sizeof(struct node)); |
|
62 struct node *prev = begin; |
|
63 if (data) begin->data = data[0]; |
|
64 for (size_t i = 1; i < n; i++) { |
|
65 struct node *node = calloc(1, sizeof(struct node)); |
|
66 if (data) node->data = data[i]; |
|
67 cx_linked_list_link(prev, node, loc_prev, loc_next); |
|
68 prev = node; |
|
69 } |
|
70 return begin; |
|
71 } |
|
72 |
|
73 static void destroy_nodes_test_data(struct node *begin) { |
|
74 struct node *node = begin; |
|
75 while (node) { |
|
76 struct node *next = node->next; |
|
77 free(node); |
|
78 node = next; |
|
79 } |
|
80 } |
|
81 |
|
82 static int *create_ints_test_data(size_t len) { |
|
83 int *data = malloc(sizeof(int) * len); |
|
84 cx_for_n (i, len) data[i] = rand(); // NOLINT(cert-msc50-cpp) |
|
85 return data; |
|
86 } |
|
87 |
|
88 void test_linked_list_link_unlink(void) { |
|
89 |
|
90 struct node nd(a), nd(b), nd(c); |
|
91 |
|
92 cx_linked_list_link(&a, &b, loc_prev, loc_next); |
|
93 CU_ASSERT_PTR_NULL(a.prev) |
|
94 CU_ASSERT_PTR_EQUAL(a.next, &b) |
|
95 CU_ASSERT_PTR_EQUAL(b.prev, &a) |
|
96 CU_ASSERT_PTR_NULL(b.next) |
|
97 |
|
98 cx_linked_list_unlink(&a, &b, loc_prev, loc_next); |
|
99 CU_ASSERT_PTR_NULL(a.prev) |
|
100 CU_ASSERT_PTR_NULL(a.next) |
|
101 CU_ASSERT_PTR_NULL(b.prev) |
|
102 CU_ASSERT_PTR_NULL(b.next) |
|
103 |
|
104 cx_linked_list_link(&b, &c, loc_prev, loc_next); |
|
105 cx_linked_list_link(&a, &b, loc_prev, loc_next); |
|
106 cx_linked_list_unlink(&b, &c, loc_prev, loc_next); |
|
107 CU_ASSERT_PTR_NULL(a.prev) |
|
108 CU_ASSERT_PTR_EQUAL(a.next, &b) |
|
109 CU_ASSERT_PTR_EQUAL(b.prev, &a) |
|
110 CU_ASSERT_PTR_NULL(b.next) |
|
111 CU_ASSERT_PTR_NULL(c.prev) |
|
112 CU_ASSERT_PTR_NULL(c.next) |
|
113 } |
|
114 |
|
115 void test_linked_list_at(void) { |
|
116 struct node nd(a), nd(b), nd(c), nd(d); |
|
117 cx_linked_list_link(&a, &b, loc_prev, loc_next); |
|
118 cx_linked_list_link(&b, &c, loc_prev, loc_next); |
|
119 cx_linked_list_link(&c, &d, loc_prev, loc_next); |
|
120 |
|
121 CU_ASSERT_PTR_EQUAL(cx_linked_list_at(&a, 0, loc_next, 0), &a) |
|
122 CU_ASSERT_PTR_EQUAL(cx_linked_list_at(&a, 0, loc_next, 1), &b) |
|
123 CU_ASSERT_PTR_EQUAL(cx_linked_list_at(&a, 0, loc_next, 2), &c) |
|
124 CU_ASSERT_PTR_EQUAL(cx_linked_list_at(&a, 0, loc_next, 3), &d) |
|
125 CU_ASSERT_PTR_NULL(cx_linked_list_at(&a, 0, loc_next, 4)) |
|
126 |
|
127 CU_ASSERT_PTR_EQUAL(cx_linked_list_at(&b, 1, loc_prev, 0), &a) |
|
128 CU_ASSERT_PTR_EQUAL(cx_linked_list_at(&b, 1, loc_next, 1), &b) |
|
129 CU_ASSERT_PTR_EQUAL(cx_linked_list_at(&b, 1, loc_next, 2), &c) |
|
130 CU_ASSERT_PTR_EQUAL(cx_linked_list_at(&b, 1, loc_next, 3), &d) |
|
131 CU_ASSERT_PTR_NULL(cx_linked_list_at(&b, 1, loc_next, 4)) |
|
132 |
|
133 CU_ASSERT_PTR_EQUAL(cx_linked_list_at(&d, 3, loc_prev, 0), &a) |
|
134 CU_ASSERT_PTR_EQUAL(cx_linked_list_at(&d, 3, loc_prev, 1), &b) |
|
135 } |
|
136 |
|
137 void test_linked_list_find(void) { |
|
138 int data[] = {2, 4, 6, 8}; |
|
139 void *list = create_nodes_test_data(4, data); |
|
140 int s; |
|
141 |
|
142 s = 2; |
|
143 CU_ASSERT_EQUAL(cx_linked_list_find(list, loc_next, loc_data, |
|
144 false, cmp_int, &s), 0) |
|
145 s = 4; |
|
146 CU_ASSERT_EQUAL(cx_linked_list_find(list, loc_next, loc_data, |
|
147 false, cmp_int, &s), 1) |
|
148 s = 6; |
|
149 CU_ASSERT_EQUAL(cx_linked_list_find(list, loc_next, loc_data, |
|
150 false, cmp_int, &s), 2) |
|
151 s = 8; |
|
152 CU_ASSERT_EQUAL(cx_linked_list_find(list, loc_next, loc_data, |
|
153 false, cmp_int, &s), 3) |
|
154 s = 10; |
|
155 CU_ASSERT_EQUAL(cx_linked_list_find(list, loc_next, loc_data, |
|
156 false, cmp_int, &s), 4) |
|
157 s = -2; |
|
158 CU_ASSERT_EQUAL(cx_linked_list_find(list, loc_next, loc_data, |
|
159 false, cmp_int, &s), 4) |
|
160 } |
|
161 |
|
162 void test_linked_list_compare(void) { |
|
163 int a[] = {2, 4, 6, 8}; |
|
164 int b[] = {2, 4, 6}; |
|
165 int c[] = {2, 4, 6, 9}; |
|
166 |
|
167 void *la = create_nodes_test_data(4, a); |
|
168 void *lb = create_nodes_test_data(3, b); |
|
169 void *lc = create_nodes_test_data(4, c); |
|
170 |
|
171 CU_ASSERT_TRUE(0 < cx_linked_list_compare(la, lb, loc_next, loc_data, |
|
172 false, cmp_int) |
|
173 ) |
|
174 CU_ASSERT_TRUE(0 > cx_linked_list_compare(lb, la, loc_next, loc_data, |
|
175 false, cmp_int) |
|
176 ) |
|
177 CU_ASSERT_TRUE(0 < cx_linked_list_compare(lc, la, loc_next, loc_data, |
|
178 false, cmp_int) |
|
179 ) |
|
180 CU_ASSERT_TRUE(0 > cx_linked_list_compare(la, lc, loc_next, loc_data, |
|
181 false, cmp_int) |
|
182 ) |
|
183 CU_ASSERT_TRUE(0 == cx_linked_list_compare(la, la, loc_next, loc_data, |
|
184 false, cmp_int) |
|
185 ) |
|
186 |
|
187 destroy_nodes_test_data(la); |
|
188 destroy_nodes_test_data(lb); |
|
189 destroy_nodes_test_data(lc); |
|
190 } |
|
191 |
|
192 void test_linked_list_add(void) { |
|
193 struct node nodes[4]; |
|
194 void *begin, *end; |
|
195 |
|
196 // test with begin, end / prev, next |
|
197 memset(nodes, 0, 4 * sizeof(struct node)); |
|
198 begin = end = NULL; |
|
199 |
|
200 cx_linked_list_add(&begin, &end, loc_prev, loc_next, &nodes[0]); |
|
201 CU_ASSERT_PTR_EQUAL(begin, &nodes[0]) |
|
202 CU_ASSERT_PTR_EQUAL(end, &nodes[0]) |
|
203 CU_ASSERT_PTR_NULL(nodes[0].prev) |
|
204 CU_ASSERT_PTR_NULL(nodes[0].next) |
|
205 |
|
206 cx_linked_list_add(&begin, &end, loc_prev, loc_next, &nodes[1]); |
|
207 CU_ASSERT_PTR_EQUAL(begin, &nodes[0]) |
|
208 CU_ASSERT_PTR_EQUAL(end, &nodes[1]) |
|
209 CU_ASSERT_PTR_EQUAL(nodes[0].next, &nodes[1]) |
|
210 CU_ASSERT_PTR_EQUAL(nodes[1].prev, &nodes[0]) |
|
211 |
|
212 // test with begin only / prev, next |
|
213 memset(nodes, 0, 4 * sizeof(struct node)); |
|
214 begin = end = NULL; |
|
215 |
|
216 cx_linked_list_add(&begin, NULL, loc_prev, loc_next, &nodes[0]); |
|
217 CU_ASSERT_PTR_EQUAL(begin, &nodes[0]) |
|
218 cx_linked_list_add(&begin, NULL, loc_prev, loc_next, &nodes[1]); |
|
219 CU_ASSERT_PTR_EQUAL(begin, &nodes[0]) |
|
220 CU_ASSERT_PTR_EQUAL(nodes[0].next, &nodes[1]) |
|
221 CU_ASSERT_PTR_EQUAL(nodes[1].prev, &nodes[0]) |
|
222 |
|
223 cx_linked_list_add(&begin, NULL, loc_prev, loc_next, &nodes[2]); |
|
224 CU_ASSERT_PTR_EQUAL(nodes[1].next, &nodes[2]) |
|
225 CU_ASSERT_PTR_EQUAL(nodes[2].prev, &nodes[1]) |
|
226 |
|
227 // test with end only / prev, next |
|
228 memset(nodes, 0, 4 * sizeof(struct node)); |
|
229 begin = end = NULL; |
|
230 |
|
231 cx_linked_list_add(NULL, &end, loc_prev, loc_next, &nodes[0]); |
|
232 CU_ASSERT_PTR_EQUAL(end, &nodes[0]) |
|
233 cx_linked_list_add(NULL, &end, loc_prev, loc_next, &nodes[1]); |
|
234 CU_ASSERT_PTR_EQUAL(end, &nodes[1]) |
|
235 CU_ASSERT_PTR_EQUAL(nodes[0].next, &nodes[1]) |
|
236 CU_ASSERT_PTR_EQUAL(nodes[1].prev, &nodes[0]) |
|
237 |
|
238 cx_linked_list_add(NULL, &end, loc_prev, loc_next, &nodes[2]); |
|
239 CU_ASSERT_PTR_EQUAL(end, &nodes[2]) |
|
240 CU_ASSERT_PTR_EQUAL(nodes[1].next, &nodes[2]) |
|
241 CU_ASSERT_PTR_EQUAL(nodes[2].prev, &nodes[1]) |
|
242 |
|
243 // test with begin, end / next |
|
244 memset(nodes, 0, 4 * sizeof(struct node)); |
|
245 begin = end = NULL; |
|
246 |
|
247 cx_linked_list_add(&begin, &end, -1, loc_next, &nodes[0]); |
|
248 CU_ASSERT_PTR_EQUAL(begin, &nodes[0]) |
|
249 CU_ASSERT_PTR_EQUAL(end, &nodes[0]) |
|
250 cx_linked_list_add(&begin, &end, -1, loc_next, &nodes[1]); |
|
251 CU_ASSERT_PTR_EQUAL(end, &nodes[1]) |
|
252 CU_ASSERT_PTR_EQUAL(nodes[0].next, &nodes[1]) |
|
253 CU_ASSERT_PTR_NULL(nodes[1].prev) |
|
254 } |
|
255 |
|
256 void test_linked_list_prepend(void) { |
|
257 struct node nodes[4]; |
|
258 void *begin, *end; |
|
259 |
|
260 // test with begin, end / prev, next |
|
261 memset(nodes, 0, 4 * sizeof(struct node)); |
|
262 begin = end = NULL; |
|
263 |
|
264 cx_linked_list_prepend(&begin, &end, loc_prev, loc_next, &nodes[0]); |
|
265 CU_ASSERT_PTR_EQUAL(begin, &nodes[0]) |
|
266 CU_ASSERT_PTR_EQUAL(end, &nodes[0]) |
|
267 CU_ASSERT_PTR_NULL(nodes[0].prev) |
|
268 CU_ASSERT_PTR_NULL(nodes[0].next) |
|
269 |
|
270 cx_linked_list_prepend(&begin, &end, loc_prev, loc_next, &nodes[1]); |
|
271 CU_ASSERT_PTR_EQUAL(begin, &nodes[1]) |
|
272 CU_ASSERT_PTR_EQUAL(end, &nodes[0]) |
|
273 CU_ASSERT_PTR_EQUAL(nodes[1].next, &nodes[0]) |
|
274 CU_ASSERT_PTR_EQUAL(nodes[0].prev, &nodes[1]) |
|
275 |
|
276 // test with begin only / prev, next |
|
277 memset(nodes, 0, 4 * sizeof(struct node)); |
|
278 begin = end = NULL; |
|
279 |
|
280 cx_linked_list_prepend(&begin, NULL, loc_prev, loc_next, &nodes[0]); |
|
281 CU_ASSERT_PTR_EQUAL(begin, &nodes[0]) |
|
282 cx_linked_list_prepend(&begin, NULL, loc_prev, loc_next, &nodes[1]); |
|
283 CU_ASSERT_PTR_EQUAL(begin, &nodes[1]) |
|
284 CU_ASSERT_PTR_EQUAL(nodes[1].next, &nodes[0]) |
|
285 CU_ASSERT_PTR_EQUAL(nodes[0].prev, &nodes[1]) |
|
286 |
|
287 cx_linked_list_prepend(&begin, NULL, loc_prev, loc_next, &nodes[2]); |
|
288 CU_ASSERT_PTR_EQUAL(begin, &nodes[2]) |
|
289 CU_ASSERT_PTR_EQUAL(nodes[2].next, &nodes[1]) |
|
290 CU_ASSERT_PTR_EQUAL(nodes[1].prev, &nodes[2]) |
|
291 |
|
292 // test with end only / prev, next |
|
293 memset(nodes, 0, 4 * sizeof(struct node)); |
|
294 begin = end = NULL; |
|
295 |
|
296 cx_linked_list_prepend(NULL, &end, loc_prev, loc_next, &nodes[0]); |
|
297 CU_ASSERT_PTR_EQUAL(end, &nodes[0]) |
|
298 cx_linked_list_prepend(NULL, &end, loc_prev, loc_next, &nodes[1]); |
|
299 CU_ASSERT_PTR_EQUAL(end, &nodes[0]) |
|
300 CU_ASSERT_PTR_EQUAL(nodes[1].next, &nodes[0]) |
|
301 CU_ASSERT_PTR_EQUAL(nodes[0].prev, &nodes[1]) |
|
302 |
|
303 cx_linked_list_prepend(NULL, &end, loc_prev, loc_next, &nodes[2]); |
|
304 CU_ASSERT_PTR_EQUAL(end, &nodes[0]) |
|
305 CU_ASSERT_PTR_EQUAL(nodes[2].next, &nodes[1]) |
|
306 CU_ASSERT_PTR_EQUAL(nodes[1].prev, &nodes[2]) |
|
307 |
|
308 // test with begin, end / next |
|
309 memset(nodes, 0, 4 * sizeof(struct node)); |
|
310 begin = end = NULL; |
|
311 |
|
312 cx_linked_list_prepend(&begin, &end, -1, loc_next, &nodes[0]); |
|
313 CU_ASSERT_PTR_EQUAL(begin, &nodes[0]) |
|
314 CU_ASSERT_PTR_EQUAL(end, &nodes[0]) |
|
315 cx_linked_list_prepend(&begin, &end, -1, loc_next, &nodes[1]); |
|
316 cx_linked_list_prepend(&begin, &end, -1, loc_next, &nodes[2]); |
|
317 CU_ASSERT_PTR_EQUAL(begin, &nodes[2]) |
|
318 CU_ASSERT_PTR_EQUAL(end, &nodes[0]) |
|
319 CU_ASSERT_PTR_EQUAL(nodes[1].next, &nodes[0]) |
|
320 CU_ASSERT_PTR_EQUAL(nodes[2].next, &nodes[1]) |
|
321 CU_ASSERT_PTR_NULL(nodes[1].prev) |
|
322 CU_ASSERT_PTR_NULL(nodes[0].prev) |
|
323 } |
|
324 |
|
325 void test_linked_list_insert(void) { |
|
326 struct node nodes[4]; |
|
327 void *begin, *end; |
|
328 |
|
329 // insert mid list |
|
330 memset(nodes, 0, 4 * sizeof(struct node)); |
|
331 begin = &nodes[0]; |
|
332 end = &nodes[2]; |
|
333 |
|
334 cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next); |
|
335 cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next); |
|
336 |
|
337 cx_linked_list_insert(&begin, &end, loc_prev, loc_next, &nodes[1], &nodes[3]); |
|
338 CU_ASSERT_PTR_EQUAL(begin, &nodes[0]) |
|
339 CU_ASSERT_PTR_EQUAL(end, &nodes[2]) |
|
340 CU_ASSERT_PTR_EQUAL(nodes[1].next, &nodes[3]) |
|
341 CU_ASSERT_PTR_EQUAL(nodes[2].prev, &nodes[3]) |
|
342 CU_ASSERT_PTR_EQUAL(nodes[3].prev, &nodes[1]) |
|
343 CU_ASSERT_PTR_EQUAL(nodes[3].next, &nodes[2]) |
|
344 |
|
345 // insert end |
|
346 memset(nodes, 0, 4 * sizeof(struct node)); |
|
347 begin = &nodes[0]; |
|
348 end = &nodes[2]; |
|
349 |
|
350 cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next); |
|
351 cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next); |
|
352 |
|
353 cx_linked_list_insert(&begin, &end, loc_prev, loc_next, &nodes[2], &nodes[3]); |
|
354 CU_ASSERT_PTR_EQUAL(begin, &nodes[0]) |
|
355 CU_ASSERT_PTR_EQUAL(end, &nodes[3]) |
|
356 CU_ASSERT_PTR_EQUAL(nodes[2].next, &nodes[3]) |
|
357 CU_ASSERT_PTR_EQUAL(nodes[3].prev, &nodes[2]) |
|
358 CU_ASSERT_PTR_NULL(nodes[3].next) |
|
359 |
|
360 // insert begin |
|
361 memset(nodes, 0, 4 * sizeof(struct node)); |
|
362 begin = &nodes[0]; |
|
363 end = &nodes[2]; |
|
364 |
|
365 cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next); |
|
366 cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next); |
|
367 |
|
368 cx_linked_list_insert(&begin, &end, loc_prev, loc_next, NULL, &nodes[3]); |
|
369 CU_ASSERT_PTR_EQUAL(begin, &nodes[3]) |
|
370 CU_ASSERT_PTR_EQUAL(end, &nodes[2]) |
|
371 CU_ASSERT_PTR_EQUAL(nodes[0].prev, &nodes[3]) |
|
372 CU_ASSERT_PTR_NULL(nodes[3].prev) |
|
373 CU_ASSERT_PTR_EQUAL(nodes[3].next, &nodes[0]) |
|
374 } |
|
375 |
|
376 void test_linked_list_insert_chain(void) { |
|
377 struct node nodes[5]; |
|
378 void *begin, *end; |
|
379 |
|
380 // insert mid list |
|
381 memset(nodes, 0, 5 * sizeof(struct node)); |
|
382 begin = &nodes[0]; |
|
383 end = &nodes[2]; |
|
384 |
|
385 cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next); |
|
386 cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next); |
|
387 cx_linked_list_link(&nodes[3], &nodes[4], loc_prev, loc_next); |
|
388 |
|
389 cx_linked_list_insert_chain(&begin, &end, loc_prev, loc_next, &nodes[1], &nodes[3], NULL); |
|
390 CU_ASSERT_PTR_EQUAL(begin, &nodes[0]) |
|
391 CU_ASSERT_PTR_EQUAL(end, &nodes[2]) |
|
392 CU_ASSERT_PTR_EQUAL(nodes[1].next, &nodes[3]) |
|
393 CU_ASSERT_PTR_EQUAL(nodes[2].prev, &nodes[4]) |
|
394 CU_ASSERT_PTR_EQUAL(nodes[3].prev, &nodes[1]) |
|
395 CU_ASSERT_PTR_EQUAL(nodes[4].next, &nodes[2]) |
|
396 |
|
397 // insert end |
|
398 memset(nodes, 0, 5 * sizeof(struct node)); |
|
399 begin = &nodes[0]; |
|
400 end = &nodes[2]; |
|
401 |
|
402 cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next); |
|
403 cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next); |
|
404 cx_linked_list_link(&nodes[3], &nodes[4], loc_prev, loc_next); |
|
405 |
|
406 cx_linked_list_insert_chain(&begin, &end, loc_prev, loc_next, &nodes[2], &nodes[3], NULL); |
|
407 CU_ASSERT_PTR_EQUAL(begin, &nodes[0]) |
|
408 CU_ASSERT_PTR_EQUAL(end, &nodes[4]) |
|
409 CU_ASSERT_PTR_EQUAL(nodes[2].next, &nodes[3]) |
|
410 CU_ASSERT_PTR_EQUAL(nodes[3].prev, &nodes[2]) |
|
411 CU_ASSERT_PTR_NULL(nodes[4].next) |
|
412 |
|
413 // insert begin |
|
414 memset(nodes, 0, 5 * sizeof(struct node)); |
|
415 begin = &nodes[0]; |
|
416 end = &nodes[2]; |
|
417 |
|
418 cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next); |
|
419 cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next); |
|
420 cx_linked_list_link(&nodes[3], &nodes[4], loc_prev, loc_next); |
|
421 |
|
422 cx_linked_list_insert_chain(&begin, &end, loc_prev, loc_next, NULL, &nodes[3], NULL); |
|
423 CU_ASSERT_PTR_EQUAL(begin, &nodes[3]) |
|
424 CU_ASSERT_PTR_EQUAL(end, &nodes[2]) |
|
425 CU_ASSERT_PTR_EQUAL(nodes[0].prev, &nodes[4]) |
|
426 CU_ASSERT_PTR_NULL(nodes[3].prev) |
|
427 CU_ASSERT_PTR_EQUAL(nodes[4].next, &nodes[0]) |
|
428 } |
|
429 |
|
430 void test_linked_list_first(void) { |
|
431 struct node *begin = create_nodes_test_data(3, NULL); |
|
432 CU_ASSERT_PTR_EQUAL(cx_linked_list_first(begin, loc_prev), begin) |
|
433 CU_ASSERT_PTR_EQUAL(cx_linked_list_first(begin->next, loc_prev), begin) |
|
434 CU_ASSERT_PTR_EQUAL(cx_linked_list_first(begin->next->next, loc_prev), begin) |
|
435 destroy_nodes_test_data(begin); |
|
436 } |
|
437 |
|
438 void test_linked_list_last(void) { |
|
439 struct node *begin = create_nodes_test_data(3, NULL); |
|
440 struct node *end = begin->next->next; |
|
441 CU_ASSERT_PTR_EQUAL(cx_linked_list_last(begin, loc_next), end) |
|
442 CU_ASSERT_PTR_EQUAL(cx_linked_list_last(begin->next, loc_next), end) |
|
443 CU_ASSERT_PTR_EQUAL(cx_linked_list_last(begin->next->next, loc_next), end) |
|
444 destroy_nodes_test_data(begin); |
|
445 } |
|
446 |
|
447 void test_linked_list_prev(void) { |
|
448 struct node *begin = create_nodes_test_data(3, NULL); |
|
449 CU_ASSERT_PTR_NULL(cx_linked_list_prev(begin, loc_next, begin)) |
|
450 CU_ASSERT_PTR_EQUAL(cx_linked_list_prev(begin, loc_next, begin->next), begin) |
|
451 CU_ASSERT_PTR_EQUAL(cx_linked_list_prev(begin, loc_next, begin->next->next), begin->next) |
|
452 destroy_nodes_test_data(begin); |
|
453 } |
|
454 |
|
455 void test_linked_list_remove(void) { |
|
456 void *begin, *end; |
|
457 |
|
458 int data[] = {2, 4, 6}; |
|
459 begin = create_nodes_test_data(3, data); |
|
460 struct node *first = begin; |
|
461 struct node *second = first->next; |
|
462 struct node *third = second->next; |
|
463 end = third; |
|
464 |
|
465 cx_linked_list_remove(&begin, &end, loc_prev, loc_next, second); |
|
466 CU_ASSERT_PTR_EQUAL(begin, first) |
|
467 CU_ASSERT_PTR_EQUAL(end, third) |
|
468 CU_ASSERT_PTR_NULL(first->prev) |
|
469 CU_ASSERT_PTR_EQUAL(first->next, third) |
|
470 CU_ASSERT_PTR_EQUAL(third->prev, first) |
|
471 CU_ASSERT_PTR_NULL(third->next) |
|
472 |
|
473 cx_linked_list_remove(&begin, &end, loc_prev, loc_next, third); |
|
474 CU_ASSERT_PTR_EQUAL(begin, first) |
|
475 CU_ASSERT_PTR_EQUAL(end, first) |
|
476 CU_ASSERT_PTR_NULL(first->prev) |
|
477 CU_ASSERT_PTR_NULL(first->next) |
|
478 |
|
479 cx_linked_list_remove(&begin, &end, loc_prev, loc_next, first); |
|
480 CU_ASSERT_PTR_NULL(begin) |
|
481 CU_ASSERT_PTR_NULL(end) |
|
482 |
|
483 free(first); |
|
484 free(second); |
|
485 free(third); |
|
486 } |
|
487 |
|
488 void test_linked_list_size(void) { |
|
489 struct node *list; |
|
490 |
|
491 CU_ASSERT_PTR_EQUAL(cx_linked_list_size(NULL, loc_next), 0) |
|
492 |
|
493 list = create_nodes_test_data(5, NULL); |
|
494 CU_ASSERT_EQUAL(cx_linked_list_size(list, loc_next), 5) |
|
495 destroy_nodes_test_data(list); |
|
496 |
|
497 list = create_nodes_test_data(13, NULL); |
|
498 CU_ASSERT_EQUAL(cx_linked_list_size(list, loc_next), 13) |
|
499 destroy_nodes_test_data(list); |
|
500 } |
|
501 |
|
502 void test_linked_list_sort(void) { |
|
503 int expected[] = { |
|
504 14, 30, 151, 163, 227, 300, 315, 317, 363, 398, 417, 424, 438, 446, 508, 555, 605, 713, 716, 759, 761, 880, |
|
505 894, 1034, 1077, 1191, 1231, 1264, 1297, 1409, 1423, 1511, 1544, 1659, 1686, 1707, 1734, 1771, 1874, 1894, |
|
506 1976, 2079, 2124, 2130, 2135, 2266, 2338, 2358, 2430, 2500, 2540, 2542, 2546, 2711, 2733, 2754, 2764, 2797, |
|
507 2888, 2900, 3020, 3053, 3109, 3244, 3275, 3302, 3362, 3363, 3364, 3441, 3515, 3539, 3579, 3655, 3675, 3677, |
|
508 3718, 3724, 3757, 3866, 3896, 3906, 3941, 3984, 3994, 4016, 4085, 4121, 4254, 4319, 4366, 4459, 4514, 4681, |
|
509 4785, 4791, 4801, 4859, 4903, 4973 |
|
510 }; |
|
511 int scrambled[] = { |
|
512 759, 716, 880, 761, 2358, 2542, 2500, 2540, 2546, 2711, 2430, 1707, 1874, 1771, 1894, 1734, 1976, 2079, |
|
513 2124, 2130, 2135, 2266, 2338, 2733, 2754, 2764, 2797, 3362, 3363, 3364, 3441, 3515, 3539, 3579, 3655, 2888, |
|
514 2900, 3020, 3053, 3109, 3244, 3275, 3302, 438, 446, 508, 555, 605, 713, 14, 30, 151, 163, 227, 300, |
|
515 894, 1034, 1077, 1191, 1231, 1264, 1297, 1409, 1423, 1511, 1544, 1659, 1686, 315, 317, 363, 398, 417, 424, |
|
516 3675, 3677, 3718, 3724, 3757, 3866, 3896, 3906, 3941, 3984, 3994, 4785, 4791, 4801, 4859, 4903, 4973, |
|
517 4016, 4085, 4121, 4254, 4319, 4366, 4459, 4514, 4681 |
|
518 }; |
|
519 |
|
520 void *begin = create_nodes_test_data(100, scrambled); |
|
521 void *end = cx_linked_list_last(begin, loc_next); |
|
522 |
|
523 cx_linked_list_sort(&begin, &end, loc_prev, loc_next, loc_data, |
|
524 false, cmp_int); |
|
525 |
|
526 struct node *check = begin; |
|
527 struct node *check_last = NULL; |
|
528 CU_ASSERT_PTR_NULL(check->prev) |
|
529 CU_ASSERT_EQUAL(check->data, expected[0]) |
|
530 cx_for_n (i, 100) { |
|
531 CU_ASSERT_EQUAL(check->data, expected[i]) |
|
532 CU_ASSERT_PTR_EQUAL(check->prev, check_last) |
|
533 if (i < 99) { |
|
534 CU_ASSERT_PTR_NOT_NULL(check->next) |
|
535 } |
|
536 check_last = check; |
|
537 check = check->next; |
|
538 } |
|
539 CU_ASSERT_PTR_NULL(check) |
|
540 CU_ASSERT_PTR_EQUAL(end, check_last) |
|
541 |
|
542 destroy_nodes_test_data(begin); |
|
543 } |
|
544 |
|
545 void test_linked_list_reverse(void) { |
|
546 void *begin, *end; |
|
547 |
|
548 int data[] = {2, 4, 6, 8}; |
|
549 int reversed[] = {8, 6, 4, 2}; |
|
550 |
|
551 void *list = create_nodes_test_data(4, data); |
|
552 void *expected = create_nodes_test_data(4, reversed); |
|
553 |
|
554 begin = list; |
|
555 end = cx_linked_list_last(list, loc_next); |
|
556 |
|
557 cx_linked_list_reverse(&begin, &end, loc_prev, loc_next); |
|
558 CU_ASSERT_PTR_EQUAL(end, list) |
|
559 CU_ASSERT_PTR_EQUAL(begin, cx_linked_list_first(end, loc_prev)) |
|
560 CU_ASSERT_TRUE(0 == cx_linked_list_compare(begin, expected, loc_next, loc_data, |
|
561 0, cmp_int)) |
|
562 |
|
563 destroy_nodes_test_data(begin); |
|
564 destroy_nodes_test_data(expected); |
|
565 } |
|
566 |
|
567 static void verify_linked_list_create(CxList *list) { |
|
568 CU_ASSERT_EQUAL(list->size, 0) |
|
569 CU_ASSERT_EQUAL(list->capacity, (size_t) -1) |
|
570 CU_ASSERT_PTR_EQUAL(list->allocator, cxTestingAllocator) |
|
571 CU_ASSERT_PTR_EQUAL(list->cmpfunc, cmp_int) |
|
572 |
|
573 cxListDestroy(list); |
|
574 } |
|
575 |
|
576 void test_hl_linked_list_create(void) { |
|
577 CxList *list = cxLinkedListCreate(cxTestingAllocator, cmp_int, sizeof(int)); |
|
578 CU_ASSERT_EQUAL(list->itemsize, sizeof(int)) |
|
579 verify_linked_list_create(list); |
|
580 } |
|
581 |
|
582 void test_hl_ptr_linked_list_create(void) { |
|
583 CxList *list = cxPointerLinkedListCreate(cxTestingAllocator, cmp_int); |
|
584 CU_ASSERT_EQUAL(list->itemsize, sizeof(void *)) |
|
585 verify_linked_list_create(list); |
|
586 } |
|
587 |
|
588 void test_hl_linked_list_from_array(void) { |
|
589 int data[] = {2, 4, 5, 7, 10, 15}; |
|
590 |
|
591 CxList *expected = cxLinkedListCreate(cxTestingAllocator, cmp_int, sizeof(int)); |
|
592 cx_for_n (i, 5) cxListAdd(expected, &data[i]); |
|
593 |
|
594 CxList *list = cxLinkedListFromArray(cxTestingAllocator, cmp_int, sizeof(int), 5, data); |
|
595 |
|
596 CU_ASSERT_TRUE(0 == cxListCompare(list, expected)) |
|
597 |
|
598 cxListDestroy(list); |
|
599 cxListDestroy(expected); |
|
600 } |
|
601 |
|
602 static void verify_hl_linked_list_add( |
|
603 CxList *list, |
|
604 int data[], |
|
605 size_t len, |
|
606 bool write_through |
|
607 ) { |
|
608 cx_for_n (i, len) CU_ASSERT_EQUAL(cxListAdd(list, &data[i]), 0) |
|
609 CU_ASSERT_EQUAL(list->size, len) |
|
610 CU_ASSERT_TRUE(list->capacity >= list->size) |
|
611 cx_for_n (i, len) CU_ASSERT_EQUAL(*(int *) cxListAt(list, i), data[i]) |
|
612 cx_for_n (i, len) ++data[i]; |
|
613 if (write_through) { |
|
614 cx_for_n (i, len) CU_ASSERT_EQUAL(*(int *) cxListAt(list, i), data[i]) |
|
615 } else { |
|
616 cx_for_n (i, len) CU_ASSERT_EQUAL(*(int *) cxListAt(list, i), data[i] - 1) |
|
617 } |
|
618 cxListDestroy(list); |
|
619 } |
|
620 |
|
621 void test_hl_linked_list_add(void) { |
|
622 CxList *list = cxLinkedListCreate(cxTestingAllocator, cmp_int, sizeof(int)); |
|
623 int data[] = {5, 47, 13, 9, 18, 1, 42}; |
|
624 verify_hl_linked_list_add(list, data, sizeof(data) / sizeof(int), false); |
|
625 } |
|
626 |
|
627 void test_hl_ptr_linked_list_add(void) { |
|
628 CxList *list = cxPointerLinkedListCreate(cxTestingAllocator, cmp_int); |
|
629 int data[] = {5, 47, 84, 13, 9, 18, 90, 1, 42}; |
|
630 verify_hl_linked_list_add(list, data, sizeof(data) / sizeof(int), true); |
|
631 } |
|
632 |
|
633 static void verify_hl_linked_list_insert(CxList *list) { |
|
634 int a = 5, b = 47, c = 13, d = 42; |
|
635 |
|
636 CU_ASSERT_NOT_EQUAL(cxListInsert(list, 1, &a), 0) |
|
637 CU_ASSERT_EQUAL(list->size, 0) |
|
638 CU_ASSERT_EQUAL(cxListInsert(list, 0, &a), 0) |
|
639 CU_ASSERT_EQUAL(list->size, 1) |
|
640 CU_ASSERT_EQUAL(cxListInsert(list, 0, &b), 0) |
|
641 CU_ASSERT_EQUAL(list->size, 2) |
|
642 CU_ASSERT_EQUAL(cxListInsert(list, 1, &c), 0) |
|
643 CU_ASSERT_EQUAL(list->size, 3) |
|
644 CU_ASSERT_EQUAL(cxListInsert(list, 3, &d), 0) |
|
645 |
|
646 CU_ASSERT_EQUAL(list->size, 4) |
|
647 CU_ASSERT_TRUE(list->capacity >= list->size) |
|
648 |
|
649 CU_ASSERT_EQUAL(*(int *) cxListAt(list, 0), 47) |
|
650 CU_ASSERT_EQUAL(*(int *) cxListAt(list, 1), 13) |
|
651 CU_ASSERT_EQUAL(*(int *) cxListAt(list, 2), 5) |
|
652 CU_ASSERT_EQUAL(*(int *) cxListAt(list, 3), 42) |
|
653 |
|
654 cxListDestroy(list); |
|
655 } |
|
656 |
|
657 void test_hl_linked_list_insert(void) { |
|
658 verify_hl_linked_list_insert(cxLinkedListCreate(cxTestingAllocator, cmp_int, sizeof(int))); |
|
659 } |
|
660 |
|
661 void test_hl_ptr_linked_list_insert(void) { |
|
662 verify_hl_linked_list_insert(cxPointerLinkedListCreate(cxTestingAllocator, cmp_int)); |
|
663 } |
|
664 |
|
665 static void verify_hl_linked_list_remove(CxList *list) { |
|
666 CU_ASSERT_EQUAL(list->size, 4) |
|
667 CU_ASSERT_TRUE(list->capacity >= list->size) |
|
668 |
|
669 CU_ASSERT_NOT_EQUAL(cxListRemove(list, 4), 0) |
|
670 |
|
671 CU_ASSERT_EQUAL(cxListRemove(list, 2), 0) |
|
672 CU_ASSERT_EQUAL(list->size, 3) |
|
673 CU_ASSERT_TRUE(list->capacity >= list->size) |
|
674 CU_ASSERT_EQUAL(*(int *) cxListAt(list, 0), 5) |
|
675 CU_ASSERT_EQUAL(*(int *) cxListAt(list, 1), 47) |
|
676 CU_ASSERT_EQUAL(*(int *) cxListAt(list, 2), 13) |
|
677 |
|
678 CU_ASSERT_EQUAL(cxListRemove(list, 0), 0) |
|
679 CU_ASSERT_EQUAL(list->size, 2) |
|
680 CU_ASSERT_TRUE(list->capacity >= list->size) |
|
681 CU_ASSERT_EQUAL(*(int *) cxListAt(list, 0), 47) |
|
682 CU_ASSERT_EQUAL(*(int *) cxListAt(list, 1), 13) |
|
683 |
|
684 CU_ASSERT_EQUAL(cxListRemove(list, 1), 0) |
|
685 CU_ASSERT_EQUAL(list->size, 1) |
|
686 CU_ASSERT_TRUE(list->capacity >= list->size) |
|
687 CU_ASSERT_EQUAL(*(int *) cxListAt(list, 0), 47) |
|
688 |
|
689 CU_ASSERT_EQUAL(cxListRemove(list, 0), 0) |
|
690 CU_ASSERT_EQUAL(list->size, 0) |
|
691 CU_ASSERT_TRUE(list->capacity >= list->size) |
|
692 |
|
693 CU_ASSERT_NOT_EQUAL(cxListRemove(list, 0), 0) |
|
694 |
|
695 cxListDestroy(list); |
|
696 } |
|
697 |
|
698 void test_hl_linked_list_remove(void) { |
|
699 int data[] = {5, 47, 42, 13}; |
|
700 CxList *list = cxLinkedListFromArray(cxTestingAllocator, cmp_int, |
|
701 sizeof(int), 4, data); |
|
702 verify_hl_linked_list_remove(list); |
|
703 } |
|
704 |
|
705 void test_hl_ptr_linked_list_remove(void) { |
|
706 int a = 5, b = 47, c = 42, d = 13; |
|
707 CxList *list = cxPointerLinkedListCreate(cxTestingAllocator, cmp_int); |
|
708 cxListAdd(list, &a); |
|
709 cxListAdd(list, &b); |
|
710 cxListAdd(list, &c); |
|
711 cxListAdd(list, &d); |
|
712 verify_hl_linked_list_remove(list); |
|
713 } |
|
714 |
|
715 static void verify_hl_linked_list_at( |
|
716 CxList *list, |
|
717 size_t len, |
|
718 int *data |
|
719 ) { |
|
720 CU_ASSERT_EQUAL(list->size, len) |
|
721 cx_for_n (i, len) CU_ASSERT_EQUAL(*(int *) cxListAt(list, i), data[i]) |
|
722 CU_ASSERT_PTR_NULL(cxListAt(list, len)) |
|
723 free(data); |
|
724 cxListDestroy(list); |
|
725 } |
|
726 |
|
727 void test_hl_linked_list_at(void) { |
|
728 size_t len = 100; |
|
729 int *data = create_ints_test_data(len); |
|
730 CxList *list = cxLinkedListFromArray(cxTestingAllocator, cmp_int, |
|
731 sizeof(int), len, data); |
|
732 verify_hl_linked_list_at(list, len, data); |
|
733 } |
|
734 |
|
735 void test_hl_ptr_linked_list_at(void) { |
|
736 size_t len = 250; |
|
737 int *data = create_ints_test_data(len); |
|
738 CxList *list = cxPointerLinkedListCreate(cxTestingAllocator, cmp_int); |
|
739 cx_for_n (i, len) cxListAdd(list, &data[i]); |
|
740 verify_hl_linked_list_at(list, len, data); |
|
741 } |
|
742 |
|
743 static void verify_hl_linked_list_find( |
|
744 CxList *list, |
|
745 size_t len, |
|
746 int *data |
|
747 ) { |
|
748 cx_for_n (attempt, 100) { |
|
749 size_t exp = rand() % len; // NOLINT(cert-msc50-cpp) |
|
750 int val = data[exp]; |
|
751 cx_for_n (i, exp) { |
|
752 if (data[i] == val) { |
|
753 exp = i; |
|
754 break; |
|
755 } |
|
756 } |
|
757 CU_ASSERT_EQUAL(cxListFind(list, &val), exp) |
|
758 } |
|
759 free(data); |
|
760 cxListDestroy(list); |
|
761 } |
|
762 |
|
763 void test_hl_linked_list_find(void) { |
|
764 size_t len = 100; |
|
765 int *data = create_ints_test_data(len); |
|
766 CxList *list = cxLinkedListFromArray(cxTestingAllocator, cmp_int, sizeof(int), len, data); |
|
767 verify_hl_linked_list_find(list, len, data); |
|
768 } |
|
769 |
|
770 void test_hl_ptr_linked_list_find(void) { |
|
771 size_t len = 250; |
|
772 int *data = create_ints_test_data(len); |
|
773 CxList *list = cxPointerLinkedListCreate(cxTestingAllocator, cmp_int); |
|
774 cx_for_n (i, len) cxListAdd(list, &data[i]); |
|
775 verify_hl_linked_list_find(list, len, data); |
|
776 } |
|
777 |
|
778 struct sort_test_data { |
|
779 size_t len; |
|
780 int *data; |
|
781 int *sorted; |
|
782 }; |
|
783 |
|
784 static struct sort_test_data create_sort_test_data(void) { |
|
785 size_t len = 1000; |
|
786 int *data = create_ints_test_data(len); |
|
787 int *sorted = malloc(sizeof(int) * len); |
|
788 memcpy(sorted, data, sizeof(int) * len); |
|
789 qsort(sorted, len, sizeof(int), cmp_int); |
|
790 struct sort_test_data s = {len, data, sorted}; |
|
791 return s; |
|
792 } |
|
793 |
|
794 static void free_sort_test_data(struct sort_test_data s) { |
|
795 free(s.data); |
|
796 free(s.sorted); |
|
797 } |
|
798 |
|
799 static void verify_hl_linked_list_sort( |
|
800 CxList *list, |
|
801 struct sort_test_data td |
|
802 ) { |
|
803 cxListSort(list); |
|
804 cx_for_n (i, td.len) CU_ASSERT_EQUAL_FATAL(*(int *) cxListAt(list, i), td.sorted[i]) |
|
805 free_sort_test_data(td); |
|
806 cxListDestroy(list); |
|
807 } |
|
808 |
|
809 void test_hl_linked_list_sort(void) { |
|
810 struct sort_test_data td = create_sort_test_data(); |
|
811 CxList *list = cxLinkedListFromArray(cxTestingAllocator, cmp_int, sizeof(int), td.len, td.data); |
|
812 verify_hl_linked_list_sort(list, td); |
|
813 } |
|
814 |
|
815 void test_hl_ptr_linked_list_sort(void) { |
|
816 struct sort_test_data td = create_sort_test_data(); |
|
817 CxList *list = cxPointerLinkedListCreate(cxTestingAllocator, cmp_int); |
|
818 cx_for_n (i, td.len) cxListAdd(list, &td.data[i]); |
|
819 verify_hl_linked_list_sort(list, td); |
|
820 } |
|
821 |
|
822 void verify_hl_linked_list_iterator(CxList *list) { |
|
823 int i = 0; |
|
824 CxIterator iter = cxListBegin(list); |
|
825 cx_foreach(int*, x, iter) { |
|
826 CU_ASSERT_EQUAL(iter.index, (size_t) (i + 1) / 2) |
|
827 CU_ASSERT_EQUAL(*x, i) |
|
828 if (*x % 2 == 1) iter.remove = true; |
|
829 i++; |
|
830 } |
|
831 CU_ASSERT_EQUAL(i, 10) |
|
832 CU_ASSERT_EQUAL_FATAL(list->size, 5) |
|
833 cx_for_n(j, 5) CU_ASSERT_EQUAL(*(int *) cxListAt(list, j), (int) j * 2) |
|
834 cxListDestroy(list); |
|
835 } |
|
836 |
|
837 void test_hl_linked_list_iterator(void) { |
|
838 CxList *list = cxLinkedListCreate(cxTestingAllocator, cmp_int, sizeof(int)); |
|
839 cx_for_n (i, 10) cxListAdd(list, &i); |
|
840 verify_hl_linked_list_iterator(list); |
|
841 } |
|
842 |
|
843 void test_hl_ptr_linked_list_iterator(void) { |
|
844 CxList *list = cxPointerLinkedListCreate(cxTestingAllocator, cmp_int); |
|
845 int data[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; |
|
846 cx_for_n (i, 10) cxListAdd(list, &data[i]); |
|
847 verify_hl_linked_list_iterator(list); |
|
848 } |
|
849 |
|
850 static void verify_hl_linked_list_insert_via_iterator( |
|
851 CxList *list, |
|
852 int *testdata |
|
853 ) { |
|
854 CxIterator iter = cxListIterator(list, 2); |
|
855 CU_ASSERT_EQUAL(iter.index, 2) |
|
856 CU_ASSERT_EQUAL(*(int *) cxIteratorCurrent(&iter), 2) |
|
857 size_t i = 4; |
|
858 |
|
859 ++i; |
|
860 cxListInsertAfter(&iter, &testdata[i]); |
|
861 CU_ASSERT_EQUAL(iter.index, 2) |
|
862 CU_ASSERT_EQUAL(*(int *) cxIteratorCurrent(&iter), 2) |
|
863 ++i; |
|
864 cxListInsertBefore(&iter, &testdata[i]); |
|
865 CU_ASSERT_EQUAL(iter.index, 3) |
|
866 CU_ASSERT_EQUAL(*(int *) cxIteratorCurrent(&iter), 2) |
|
867 |
|
868 iter = cxListBegin(list); |
|
869 ++i; |
|
870 cxListInsertBefore(&iter, &testdata[i]); |
|
871 CU_ASSERT_EQUAL(iter.index, 1) |
|
872 CU_ASSERT_EQUAL(*(int *) cxIteratorCurrent(&iter), 0) |
|
873 iter = cxListIterator(list, list->size); |
|
874 ++i; |
|
875 cxListInsertBefore(&iter, &testdata[i]); |
|
876 CU_ASSERT_EQUAL(iter.index, 9) |
|
877 CU_ASSERT_FALSE(cxIteratorValid(&iter)) |
|
878 iter = cxListIterator(list, list->size); |
|
879 ++i; |
|
880 cxListInsertAfter(&iter, &testdata[i]); |
|
881 CU_ASSERT_EQUAL(iter.index, 10) |
|
882 CU_ASSERT_FALSE(cxIteratorValid(&iter)) |
|
883 |
|
884 int expdata[] = {30, 0, 1, 20, 2, 10, 3, 4, 40, 50}; |
|
885 cx_for_n (j, 10) CU_ASSERT_EQUAL(*(int *) cxListAt(list, j), expdata[j]) |
|
886 cxListDestroy(list); |
|
887 } |
|
888 |
|
889 void test_hl_linked_list_insert_via_iterator(void) { |
|
890 int testdata[] = {0, 1, 2, 3, 4, 10, 20, 30, 40, 50}; |
|
891 // only add the first five elements, the remaining five will be inserted |
|
892 CxList *list = cxLinkedListFromArray(cxTestingAllocator, cmp_int, sizeof(int), 5, testdata); |
|
893 verify_hl_linked_list_insert_via_iterator(list, testdata); |
|
894 } |
|
895 |
|
896 void test_hl_ptr_linked_list_insert_via_iterator(void) { |
|
897 int testdata[] = {0, 1, 2, 3, 4, 10, 20, 30, 40, 50}; |
|
898 CxList *list = cxPointerLinkedListCreate(cxTestingAllocator, cmp_int); |
|
899 // only add the first five elements, the remaining five will be inserted |
|
900 cx_for_n (i, 5) cxListAdd(list, &testdata[i]); |
|
901 verify_hl_linked_list_insert_via_iterator(list, testdata); |
|
902 } |
|
903 |
|
904 static void test_setup_allocator(void) { |
|
905 cxTestingAllocatorReset(); |
|
906 } |
|
907 |
|
908 static void test_verify_allocator(void) { |
|
909 CU_ASSERT_TRUE(cxTestingAllocatorVerify()) |
|
910 } |
|
911 |
|
912 int main() { |
|
913 CU_pSuite suite = NULL; |
|
914 |
|
915 if (CUE_SUCCESS != CU_initialize_registry()) { |
|
916 return CU_get_error(); |
|
917 } |
|
918 |
|
919 suite = CU_add_suite("low level linked list", NULL, NULL); |
|
920 |
|
921 cu_add_test(suite, test_linked_list_link_unlink); |
|
922 cu_add_test(suite, test_linked_list_at); |
|
923 cu_add_test(suite, test_linked_list_find); |
|
924 cu_add_test(suite, test_linked_list_compare); |
|
925 cu_add_test(suite, test_linked_list_prepend); |
|
926 cu_add_test(suite, test_linked_list_add); |
|
927 cu_add_test(suite, test_linked_list_insert); |
|
928 cu_add_test(suite, test_linked_list_insert_chain); |
|
929 cu_add_test(suite, test_linked_list_first); |
|
930 cu_add_test(suite, test_linked_list_last); |
|
931 cu_add_test(suite, test_linked_list_prev); |
|
932 cu_add_test(suite, test_linked_list_remove); |
|
933 cu_add_test(suite, test_linked_list_size); |
|
934 cu_add_test(suite, test_linked_list_sort); |
|
935 cu_add_test(suite, test_linked_list_reverse); |
|
936 |
|
937 suite = CU_add_suite_with_setup_and_teardown( |
|
938 "high level linked list", NULL, NULL, |
|
939 test_setup_allocator, test_verify_allocator); |
|
940 |
|
941 cu_add_test(suite, test_hl_linked_list_create); |
|
942 cu_add_test(suite, test_hl_linked_list_from_array); |
|
943 cu_add_test(suite, test_hl_linked_list_add); |
|
944 cu_add_test(suite, test_hl_linked_list_insert); |
|
945 cu_add_test(suite, test_hl_linked_list_remove); |
|
946 cu_add_test(suite, test_hl_linked_list_at); |
|
947 cu_add_test(suite, test_hl_linked_list_find); |
|
948 cu_add_test(suite, test_hl_linked_list_sort); |
|
949 cu_add_test(suite, test_hl_linked_list_iterator); |
|
950 cu_add_test(suite, test_hl_linked_list_insert_via_iterator); |
|
951 |
|
952 suite = CU_add_suite_with_setup_and_teardown( |
|
953 "high level pointer linked list", NULL, NULL, |
|
954 test_setup_allocator, test_verify_allocator); |
|
955 |
|
956 cu_add_test(suite, test_hl_ptr_linked_list_create); |
|
957 cu_add_test(suite, test_hl_ptr_linked_list_add); |
|
958 cu_add_test(suite, test_hl_ptr_linked_list_insert); |
|
959 cu_add_test(suite, test_hl_ptr_linked_list_remove); |
|
960 cu_add_test(suite, test_hl_ptr_linked_list_at); |
|
961 cu_add_test(suite, test_hl_ptr_linked_list_find); |
|
962 cu_add_test(suite, test_hl_ptr_linked_list_sort); |
|
963 cu_add_test(suite, test_hl_ptr_linked_list_iterator); |
|
964 cu_add_test(suite, test_hl_ptr_linked_list_insert_via_iterator); |
|
965 |
|
966 CU_basic_set_mode(UCX_CU_BRM); |
|
967 |
|
968 int exitcode; |
|
969 if (CU_basic_run_tests()) { |
|
970 exitcode = CU_get_error(); |
|
971 } else { |
|
972 exitcode = CU_get_number_of_failures() == 0 ? 0 : 1; |
|
973 } |
|
974 CU_cleanup_registry(); |
|
975 return exitcode; |
|
976 } |
|