The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
dcursor_tests.c
Go to the documentation of this file.
1#include <freeradius-devel/util/acutest.h>
2
3#include "dcursor.c"
4
5typedef struct {
6 char const *name;
9
13
14static void *test_iter(fr_dlist_head_t *list, void *current, UNUSED void *uctx)
15{
16 return fr_dlist_next(list, current);
17}
18
19/** @hidecallergraph */
21{
23}
24
25/** Verify internal state is initialised correctly
26 *
27 */
28static void test_init_null_item(void)
29{
30 fr_dcursor_t cursor;
31 test_item_t *item_p;
33
34 test_list_init(&list);
35
36 item_p = fr_dcursor_iter_init(&cursor, &list.head, test_iter, NULL, &cursor);
37 TEST_CHECK(!item_p);
38 TEST_CHECK((cursor.dlist) == &list.head);
41 TEST_CHECK(cursor.iter_uctx == &cursor);
42}
43
44static void test_init_1i_start(void)
45{
46 fr_dcursor_t cursor;
47 test_item_t item1 = { "item1", { NULL, NULL} };
48 test_item_t *item_p;
50
51 test_list_init(&list);
52 fr_dlist_insert_tail(&list.head, &item1);
53
54 item_p = fr_dcursor_init(&cursor, &list.head);
55 TEST_CHECK(item_p == &item1);
56 TEST_CHECK((cursor.dlist) == &list.head);
57 TEST_CHECK(fr_dcursor_current(&cursor) == &item1);
58}
59
60static void test_init_2i_start(void)
61{
62 fr_dcursor_t cursor;
63 test_item_t item1 = { "item1", { NULL, NULL } };
64 test_item_t item2 = { "item2", { NULL, NULL } };
65 test_item_t *item_p;
67
68 test_list_init(&list);
69 fr_dlist_insert_tail(&list.head, &item1);
70 fr_dlist_insert_tail(&list.head, &item2);
71
72 item_p = fr_dcursor_init(&cursor, &list.head);
73 TEST_CHECK(item_p == &item1);
74 TEST_CHECK(fr_dcursor_current(&cursor) == &item1);
75}
76
77static void test_next(void)
78{
79 fr_dcursor_t cursor;
80 test_item_t item1 = { "item1", { NULL, NULL } };
81 test_item_t item2 = { "item2", { NULL, NULL } };
82 test_item_t *item_p;
84
85 test_list_init(&list);
86 fr_dlist_insert_tail(&list.head, &item1);
87 fr_dlist_insert_tail(&list.head, &item2);
88
89 fr_dcursor_init(&cursor, &list.head);
90 TEST_CHECK(fr_dcursor_next_peek(&cursor) == &item2);
91
92 item_p = fr_dcursor_next(&cursor);
93 TEST_CHECK(item_p == &item2);
94 TEST_CHECK(fr_dcursor_current(&cursor) == &item2);
96}
97
98static void test_next_wrap(void)
99{
100 fr_dcursor_t cursor;
101 test_item_t item1 = { "item1", { NULL, NULL } };
102 test_item_t item2 = { "item2", { NULL, NULL } };
103 test_item_t *item_p;
104 test_item_list_t list;
105
106 test_list_init(&list);
107 fr_dlist_insert_tail(&list.head, &item1);
108 fr_dlist_insert_tail(&list.head, &item2);
109
110 fr_dcursor_init(&cursor, &list.head);
111 fr_dcursor_next(&cursor);
112 item_p = fr_dcursor_next(&cursor);
113 TEST_CHECK(!item_p);
116
117 item_p = fr_dcursor_next(&cursor);
118 TEST_CHECK(!item_p);
121}
122
124{
125 fr_dcursor_t cursor;
126 test_item_list_t list;
127
128 test_list_init(&list);
129
130 fr_dcursor_init(&cursor, &list.head);
132 TEST_CHECK(!fr_dcursor_head(&cursor));
133 TEST_CHECK(!fr_dcursor_tail(&cursor));
134}
135
136static void test_dcursor_head(void)
137{
138 fr_dcursor_t cursor;
139 test_item_t item1 = { "item1", { NULL, NULL } };
140 test_item_t item2 = { "item2", { NULL, NULL } };
141 test_item_t item3 = { "item3", { NULL, NULL } };
142 test_item_t *item_p;
143 test_item_list_t list;
144
145 test_list_init(&list);
146 fr_dlist_insert_tail(&list.head, &item1);
147 fr_dlist_insert_tail(&list.head, &item2);
148 fr_dlist_insert_tail(&list.head, &item3);
149
150 fr_dcursor_init(&cursor, &list.head);
151 item_p = fr_dcursor_head(&cursor);
152 TEST_CHECK(item_p == &item1);
153}
154
155static void test_dcursor_head_reset(void)
156{
157 fr_dcursor_t cursor;
158 test_item_t item1 = { "item1", { NULL, NULL } };
159 test_item_t item2 = { "item2", { NULL, NULL } };
160 test_item_t *item_p;
161 test_item_list_t list;
162
163 test_list_init(&list);
164 fr_dlist_insert_tail(&list.head, &item1);
165 fr_dlist_insert_tail(&list.head, &item2);
166
167 fr_dcursor_init(&cursor, &list.head);
168
169 item_p = fr_dcursor_head(&cursor);
170 TEST_CHECK(item_p == &item1);
171
172 item_p = fr_dcursor_next(&cursor);
173 TEST_CHECK(item_p == &item2);
174
175 item_p = fr_dcursor_next(&cursor);
176 TEST_CHECK(item_p == NULL);
177
178 item_p = fr_dcursor_head(&cursor);
179 TEST_CHECK(item_p == &item1);
180}
181
183{
184 fr_dcursor_t cursor;
185 test_item_t item1 = { "item1", { NULL, NULL } };
186 test_item_t item2 = { "item2", { NULL, NULL } };
187 test_item_t *item_p;
188 test_item_list_t list;
189
190 test_list_init(&list);
191 fr_dlist_insert_tail(&list.head, &item1);
192 fr_dlist_insert_tail(&list.head, &item2);
193
194 item_p = fr_dcursor_iter_init(&cursor, &list.head, test_iter, NULL, &cursor);
195 TEST_CHECK(item_p == &item1);
196
197 item_p = fr_dcursor_next(&cursor);
198 TEST_CHECK(item_p == &item2);
199
200 item_p = fr_dcursor_next(&cursor);
201 TEST_CHECK(item_p == NULL);
202
203 item_p = fr_dcursor_head(&cursor);
204 TEST_CHECK(item_p == &item1);
205}
206
208{
209 fr_dcursor_t cursor;
210 test_item_t item1 = { "item1", { NULL, NULL } };
211 test_item_t item2 = { "item2", { NULL, NULL } };
212 test_item_t item3 = { "item3", { NULL, NULL } };
213 test_item_t *item_p;
214 test_item_list_t list;
215
216 test_list_init(&list);
217 fr_dlist_insert_tail(&list.head, &item1);
218 fr_dlist_insert_tail(&list.head, &item2);
219 fr_dlist_insert_tail(&list.head, &item3);
220
221 fr_dcursor_init(&cursor, &list.head);
222 fr_dcursor_next(&cursor);
223 item_p = fr_dcursor_head(&cursor);
224 TEST_CHECK(item_p == &item1);
225}
226
227static void test_dcursor_tail(void)
228{
229 fr_dcursor_t cursor;
230 test_item_t item1 = { "item1", { NULL, NULL } };
231 test_item_t item2 = { "item2", { NULL, NULL } };
232 test_item_t item3 = { "item3", { NULL, NULL } };
233 test_item_t *item_p;
234 test_item_list_t list;
235
236 test_list_init(&list);
237 fr_dlist_insert_tail(&list.head, &item1);
238 fr_dlist_insert_tail(&list.head, &item2);
239 fr_dlist_insert_tail(&list.head, &item3);
240
241 fr_dcursor_init(&cursor, &list.head);
242 fr_dcursor_next(&cursor);
243 item_p = fr_dcursor_tail(&cursor);
244 TEST_CHECK(item_p == &item3);
245}
246
248{
249 fr_dcursor_t cursor;
250 test_item_t item1 = { "item1", { NULL, NULL } };
251 test_item_t item2 = { "item2", { NULL, NULL } };
252 test_item_t item3 = { "item3", { NULL, NULL } };
253 test_item_t *item_p;
254 test_item_list_t list;
255
256 test_list_init(&list);
257 fr_dlist_insert_tail(&list.head, &item1);
258 fr_dlist_insert_tail(&list.head, &item2);
259 fr_dlist_insert_tail(&list.head, &item3);
260
261 fr_dcursor_init(&cursor, &list.head);
262 fr_dcursor_tail(&cursor);
263 item_p = fr_dcursor_head(&cursor);
264 TEST_CHECK(item_p == &item1);
265}
266
268{
269 fr_dcursor_t cursor;
270 test_item_t item1 = { "item1", { NULL, NULL } };
271 test_item_t item2 = { "item2", { NULL, NULL } };
272 test_item_t item3 = { "item3", { NULL, NULL } };
273 test_item_t *item_p;
274 test_item_list_t list;
275
276 test_list_init(&list);
277 fr_dlist_insert_tail(&list.head, &item1);
278 fr_dlist_insert_tail(&list.head, &item2);
279 fr_dlist_insert_tail(&list.head, &item3);
280
281 fr_dcursor_init(&cursor, &list.head);
282 fr_dcursor_tail(&cursor);
283 item_p = fr_dcursor_next(&cursor);
284 TEST_CHECK(!item_p);
285
286 item_p = fr_dcursor_next(&cursor);
287 TEST_CHECK(!item_p);
288}
289
291{
292 fr_dcursor_t cursor;
293 test_item_t item1 = { "item1", { NULL, NULL } };
294 test_item_t item2 = { "item2", { NULL, NULL } };
295 test_item_t item3 = { "item3", { NULL, NULL } };
296 test_item_t *item_p;
297 test_item_list_t list;
298
299 test_list_init(&list);
300 fr_dlist_insert_tail(&list.head, &item1);
301 fr_dlist_insert_tail(&list.head, &item2);
302 fr_dlist_insert_tail(&list.head, &item3);
303
304 fr_dcursor_init(&cursor, &list.head);
305 fr_dcursor_head(&cursor);
306 TEST_CHECK(fr_dcursor_current(&cursor) == &item1);
307
308 item_p = fr_dcursor_set_current(&cursor, &item2);
309 TEST_CHECK(item_p == &item2);
310 TEST_CHECK(fr_dcursor_current(&cursor) == &item2);
311 TEST_CHECK(fr_dcursor_next_peek(&cursor) == &item3);
312}
313
315{
316 fr_dcursor_t cursor;
317 test_item_t item1 = { "item1", { NULL, NULL } };
318 test_item_t item2 = { "item2", { NULL, NULL } };
319 test_item_t item3 = { "item3", { NULL, NULL } };
320 test_item_t *item_p;
321 test_item_list_t list;
322
323 test_list_init(&list);
324 fr_dlist_insert_tail(&list.head, &item1);
325 fr_dlist_insert_tail(&list.head, &item2);
326
327 fr_dcursor_init(&cursor, &list.head);
328 fr_dcursor_head(&cursor);
329 TEST_CHECK(fr_dcursor_current(&cursor) == &item1);
330
331 item_p = fr_dcursor_set_current(&cursor, &item3);
332 TEST_CHECK(item_p == NULL);
333 TEST_CHECK(fr_dcursor_current(&cursor) == &item1);
334 TEST_CHECK(fr_dcursor_next_peek(&cursor) == &item2);
335}
336
338{
339 fr_dcursor_t cursor;
340 test_item_t *item_p;
341 test_item_t item1 = { "item1", { NULL, NULL } };
342 test_item_list_t list;
343
344 test_list_init(&list);
345
346 fr_dcursor_init(&cursor, &list.head);
347 fr_dcursor_append(&cursor, &item1);
348
349 item_p = fr_dcursor_current(&cursor);
350 TEST_CHECK(!item_p);
351 TEST_CHECK(fr_dcursor_next_peek(&cursor) == &item1);
352}
353
355{
356 fr_dcursor_t cursor;
357 test_item_t *item_p;
358 test_item_t item1 = { "item1", { NULL, NULL } };
359 test_item_t item2 = { "item2", { NULL, NULL } };
360 test_item_t item3 = { "item3", { NULL, NULL } };
361 test_item_list_t list;
362
363 test_list_init(&list);
364
365 fr_dcursor_init(&cursor, &list.head);
366 fr_dcursor_append(&cursor, &item1);
367 fr_dcursor_append(&cursor, &item2);
368 fr_dcursor_append(&cursor, &item3);
369
370 item_p = fr_dcursor_current(&cursor);
371 TEST_CHECK(!item_p);
372 TEST_CHECK(fr_dcursor_next(&cursor) == &item1);
373 TEST_CHECK(fr_dcursor_next(&cursor) == &item2);
374 TEST_CHECK(fr_dcursor_tail(&cursor) == &item3);
375}
376
378{
379 fr_dcursor_t cursor;
380 test_item_t *item_p;
381 test_item_t item1 = { "item1", { NULL, NULL } };
382 test_item_list_t list;
383
384 test_list_init(&list);
385
386 fr_dcursor_init(&cursor, &list.head);
387 fr_dcursor_prepend(&cursor, &item1);
388
389 item_p = fr_dcursor_current(&cursor);
390 TEST_CHECK(!item_p);
391 TEST_CHECK(fr_dcursor_next_peek(&cursor) == &item1);
392}
393
395{
396 fr_dcursor_t cursor;
397 test_item_t *item_p;
398 test_item_t item1 = { "item1", { NULL, NULL } };
399 test_item_list_t list;
400
401 test_list_init(&list);
402
403 fr_dcursor_init(&cursor, &list.head);
404 fr_dcursor_insert(&cursor, &item1);
405
406 item_p = fr_dcursor_current(&cursor);
407 TEST_CHECK(!item_p);
408 TEST_CHECK(fr_dcursor_next_peek(&cursor) == &item1);
409}
410
412{
413 fr_dcursor_t cursor;
414 test_item_t *item_p;
415 test_item_t item1 = { "item1", { NULL, NULL } };
416 test_item_t item2 = { "item2", { NULL, NULL } };
417 test_item_t item3 = { "item3", { NULL, NULL } };
418 test_item_list_t list;
419
420 test_list_init(&list);
421
422 fr_dcursor_init(&cursor, &list.head);
423 fr_dcursor_insert(&cursor, &item1);
424 fr_dcursor_insert(&cursor, &item2);
425 fr_dcursor_insert(&cursor, &item3);
426
427 item_p = fr_dcursor_current(&cursor);
428 TEST_CHECK(!item_p);
429 TEST_CHECK(fr_dcursor_next(&cursor) == &item1);
430 TEST_CHECK(fr_dcursor_next(&cursor) == &item2);
431 TEST_CHECK(fr_dcursor_tail(&cursor) == &item3);
432}
433
435{
436 fr_dcursor_t cursor;
437 test_item_t *item_p;
438 test_item_t item1 = { "item1", { NULL, NULL } };
439 test_item_list_t list;
440
441 test_list_init(&list);
442
443 fr_dcursor_init(&cursor, &list.head);
444 TEST_CHECK(!fr_dcursor_replace(&cursor, &item1));
445
446 item_p = fr_dcursor_current(&cursor);
447 TEST_CHECK(!item_p);
448 TEST_CHECK(fr_dcursor_next_peek(&cursor) == &item1);
449}
450
452{
453 fr_dcursor_t cursor;
454 test_item_t item1 = { "item1", { NULL, NULL } };
455 test_item_t item2 = { "item2", { NULL, NULL } };
456 test_item_t *item_p;
457 test_item_list_t list;
458
459 test_list_init(&list);
460 fr_dlist_insert_tail(&list.head, &item1);
461
462 fr_dcursor_init(&cursor, &list.head);
463 fr_dcursor_prepend(&cursor, &item2);
464
465 TEST_CHECK(fr_dcursor_current(&cursor) == &item1);
467
468 item_p = fr_dcursor_next(&cursor);
469 TEST_CHECK(!item_p);
470
471 item_p = fr_dcursor_head(&cursor);
472 TEST_CHECK(item_p == &item2);
473
474 item_p = fr_dcursor_tail(&cursor);
475 TEST_CHECK(item_p == &item1);
476}
477
479{
480 fr_dcursor_t cursor;
481 test_item_t item1 = { "item1", { NULL, NULL } };
482 test_item_t item2 = { "item2", { NULL, NULL } };
483 test_item_t *item_p;
484 test_item_list_t list;
485
486 test_list_init(&list);
487 fr_dlist_insert_tail(&list.head, &item1);
488
489 fr_dcursor_init(&cursor, &list.head);
490 fr_dcursor_append(&cursor, &item2);
491
492 TEST_CHECK(fr_dcursor_current(&cursor) == &item1);
493 TEST_CHECK(fr_dcursor_next_peek(&cursor) == &item2);
494
495 item_p = fr_dcursor_next(&cursor);
496 TEST_CHECK(item_p == &item2);
497
498 item_p = fr_dcursor_head(&cursor);
499 TEST_CHECK(item_p == &item1);
500
501 item_p = fr_dcursor_tail(&cursor);
502 TEST_CHECK(item_p == &item2);
503}
504
506{
507 fr_dcursor_t cursor;
508 test_item_t item1 = { "item1", { NULL, NULL } };
509 test_item_t item2 = { "item2", { NULL, NULL } };
510 test_item_t *item_p;
511 test_item_list_t list;
512
513 test_list_init(&list);
514 fr_dlist_insert_tail(&list.head, &item1);
515
516 fr_dcursor_init(&cursor, &list.head);
517 fr_dcursor_insert(&cursor, &item2);
518
519 TEST_CHECK(fr_dcursor_current(&cursor) == &item1);
520 TEST_CHECK(fr_dcursor_next_peek(&cursor) == &item2);
521
522 item_p = fr_dcursor_next(&cursor);
523 TEST_CHECK(item_p == &item2);
524
525 item_p = fr_dcursor_head(&cursor);
526 TEST_CHECK(item_p == &item1);
527
528 item_p = fr_dcursor_tail(&cursor);
529 TEST_CHECK(item_p == &item2);
530}
531
533{
534 fr_dcursor_t cursor;
535 test_item_t item1 = { "item1", { NULL, NULL } };
536 test_item_t item2 = { "item2", { NULL, NULL } };
537 test_item_t *item_p;
538 test_item_list_t list;
539
540 test_list_init(&list);
541 fr_dlist_insert_tail(&list.head, &item1);
542
543 fr_dcursor_init(&cursor, &list.head);
544 item_p = fr_dcursor_replace(&cursor, &item2);
545 TEST_CHECK(item_p == &item1);
546
547 item_p = fr_dcursor_current(&cursor);
548 TEST_CHECK(item_p == &item2);
549
550 item_p = fr_dcursor_head(&cursor);
551 TEST_CHECK(item_p == &item2);
552
553 item_p = fr_dcursor_tail(&cursor);
554 TEST_CHECK(item_p == &item2);
555}
556
558{
559 fr_dcursor_t cursor;
560 test_item_t item1 = { "item1", { NULL, NULL } };
561 test_item_t item2 = { "item2", { NULL, NULL } };
562 test_item_t item3 = { "item3", { NULL, NULL } };
563 test_item_t *item_p;
564 test_item_list_t list;
565
566 test_list_init(&list);
567 fr_dlist_insert_tail(&list.head, &item1);
568 fr_dlist_insert_tail(&list.head, &item2);
569
570 fr_dcursor_init(&cursor, &list.head);
571 fr_dcursor_prepend(&cursor, &item3);
572
573 TEST_CHECK(fr_dcursor_current(&cursor) == &item1);
574 TEST_CHECK(fr_dcursor_next_peek(&cursor) == &item2);
575
576 item_p = fr_dcursor_next(&cursor);
577 TEST_CHECK(item_p == &item2);
578
579 item_p = fr_dcursor_next(&cursor);
580 TEST_CHECK(!item_p);
581
582 item_p = fr_dcursor_head(&cursor);
583 TEST_CHECK(item_p == &item3);
584
585 item_p = fr_dcursor_tail(&cursor);
586 TEST_CHECK(item_p == &item2);
587}
588
590{
591 fr_dcursor_t cursor;
592 test_item_t item1 = { "item1", { NULL, NULL } };
593 test_item_t item2 = { "item2", { NULL, NULL } };
594 test_item_t item3 = { "item3", { NULL, NULL } };
595 test_item_t *item_p;
596 test_item_list_t list;
597
598 test_list_init(&list);
599 fr_dlist_insert_tail(&list.head, &item1);
600 fr_dlist_insert_tail(&list.head, &item2);
601
602 fr_dcursor_init(&cursor, &list.head);
603 fr_dcursor_append(&cursor, &item3);
604
605 TEST_CHECK(fr_dcursor_current(&cursor) == &item1);
606 TEST_CHECK(fr_dcursor_next_peek(&cursor) == &item2);
607
608 item_p = fr_dcursor_next(&cursor);
609 TEST_CHECK(item_p == &item2);
610
611 item_p = fr_dcursor_head(&cursor);
612 TEST_CHECK(item_p == &item1);
613
614 item_p = fr_dcursor_tail(&cursor);
615 TEST_CHECK(item_p == &item3);
616}
617
619{
620 fr_dcursor_t cursor;
621 test_item_t item1 = { "item1", { NULL, NULL } };
622 test_item_t item2 = { "item2", { NULL, NULL } };
623 test_item_t item3 = { "item3", { NULL, NULL } };
624 test_item_t *item_p;
625 test_item_list_t list;
626
627 test_list_init(&list);
628 fr_dlist_insert_tail(&list.head, &item1);
629 fr_dlist_insert_tail(&list.head, &item2);
630
631 fr_dcursor_init(&cursor, &list.head);
632 fr_dcursor_insert(&cursor, &item3);
633
634 /*
635 * Order should be
636 *
637 * item1 - HEAD
638 * item3
639 * item2 - TAIL
640 */
641 TEST_CHECK(fr_dcursor_current(&cursor) == &item1);
642 TEST_CHECK(fr_dcursor_next_peek(&cursor) == &item3);
643
644 item_p = fr_dcursor_next(&cursor);
645 TEST_CHECK(item_p == &item3);
646
647 item_p = fr_dcursor_next(&cursor);
648 TEST_CHECK(item_p == &item2);
649
650 item_p = fr_dcursor_head(&cursor);
651 TEST_CHECK(item_p == &item1);
652
653 item_p = fr_dcursor_tail(&cursor);
654 TEST_CHECK(item_p == &item2);
655}
656
658{
659 fr_dcursor_t cursor;
660 test_item_t item1 = { "item1", { NULL, NULL } };
661 test_item_t item2 = { "item2", { NULL, NULL } };
662 test_item_t item3 = { "item3", { NULL, NULL } };
663 test_item_t *item_p;
664 test_item_list_t list;
665
666 test_list_init(&list);
667 fr_dlist_insert_tail(&list.head, &item1);
668 fr_dlist_insert_tail(&list.head, &item2);
669
670 /*
671 * Order should be
672 *
673 * item3 - HEAD
674 * item2 - TAIL
675 */
676 fr_dcursor_init(&cursor, &list.head);
677 item_p = fr_dcursor_replace(&cursor, &item3);
678 TEST_CHECK(item_p == &item1);
679
680 item_p = fr_dcursor_current(&cursor);
681 TEST_CHECK(item_p == &item3);
682
683 item_p = fr_dcursor_head(&cursor);
684 TEST_CHECK(item_p == &item3);
685
686 item_p = fr_dcursor_tail(&cursor);
687 TEST_CHECK(item_p == &item2);
688}
689
691{
692 fr_dcursor_t cursor;
693 test_item_t item1 = { "item1", { NULL, NULL } };
694 test_item_t item2 = { "item2", { NULL, NULL } };
695 test_item_t item3 = { "item3", { NULL, NULL } };
696 test_item_t item4 = { "item4", { NULL, NULL } };
697 test_item_t *item_p;
698 test_item_list_t list;
699
700 test_list_init(&list);
701 fr_dlist_insert_tail(&list.head, &item1);
702 fr_dlist_insert_tail(&list.head, &item2);
703 fr_dlist_insert_tail(&list.head, &item3);
704
705 fr_dcursor_init(&cursor, &list.head);
706 fr_dcursor_next(&cursor);
707 fr_dcursor_prepend(&cursor, &item4);
708
709 TEST_CHECK(fr_dcursor_current(&cursor) == &item2);
710 TEST_CHECK(fr_dcursor_next_peek(&cursor) == &item3);
711
712 item_p = fr_dcursor_next(&cursor);
713 TEST_CHECK(item_p == &item3);
714
715 item_p = fr_dcursor_next(&cursor);
716 TEST_CHECK(!item_p);
717
718 item_p = fr_dcursor_head(&cursor);
719 TEST_CHECK(item_p == &item4);
720
721 item_p = fr_dcursor_tail(&cursor);
722 TEST_CHECK(item_p == &item3);
723}
724
726{
727 fr_dcursor_t cursor;
728 test_item_t item1 = { "item1", { NULL, NULL } };
729 test_item_t item2 = { "item2", { NULL, NULL } };
730 test_item_t item3 = { "item3", { NULL, NULL } };
731 test_item_t item4 = { "item4", { NULL, NULL } };
732 test_item_t *item_p;
733 test_item_list_t list;
734
735 test_list_init(&list);
736 fr_dlist_insert_tail(&list.head, &item1);
737 fr_dlist_insert_tail(&list.head, &item2);
738 fr_dlist_insert_tail(&list.head, &item3);
739
740 fr_dcursor_init(&cursor, &list.head);
741 fr_dcursor_next(&cursor);
742 fr_dcursor_append(&cursor, &item4);
743
744 TEST_CHECK(fr_dcursor_current(&cursor) == &item2);
745 TEST_CHECK(fr_dcursor_next_peek(&cursor) == &item3);
746
747 item_p = fr_dcursor_next(&cursor);
748 TEST_CHECK(item_p == &item3);
749
750 item_p = fr_dcursor_head(&cursor);
751 TEST_CHECK(item_p == &item1);
752
753 item_p = fr_dcursor_tail(&cursor);
754 TEST_CHECK(item_p == &item4);
755}
756
758{
759 fr_dcursor_t cursor;
760 test_item_t item1 = { "item1", { NULL, NULL } };
761 test_item_t item2 = { "item2", { NULL, NULL } };
762 test_item_t item3 = { "item3", { NULL, NULL } };
763 test_item_t item4 = { "item4", { NULL, NULL } };
764 test_item_t *item_p;
765 test_item_list_t list;
766
767 test_list_init(&list);
768 fr_dlist_insert_tail(&list.head, &item1);
769 fr_dlist_insert_tail(&list.head, &item2);
770 fr_dlist_insert_tail(&list.head, &item3);
771
772 fr_dcursor_init(&cursor, &list.head);
773 fr_dcursor_next(&cursor);
774 fr_dcursor_insert(&cursor, &item4);
775
776 TEST_CHECK(fr_dcursor_current(&cursor) == &item2);
777 TEST_CHECK(fr_dcursor_next_peek(&cursor) == &item4);
778
779 item_p = fr_dcursor_next(&cursor);
780 TEST_CHECK(item_p == &item4);
781
782 item_p = fr_dcursor_next(&cursor);
783 TEST_CHECK(item_p == &item3);
784
785 item_p = fr_dcursor_head(&cursor);
786 TEST_CHECK(item_p == &item1);
787
788 item_p = fr_dcursor_tail(&cursor);
789 TEST_CHECK(item_p == &item3);
790}
791
793{
794 fr_dcursor_t cursor;
795 test_item_t item1 = { "item1", { NULL, NULL } };
796 test_item_t item2 = { "item2", { NULL, NULL } };
797 test_item_t item3 = { "item3", { NULL, NULL } };
798 test_item_t item4 = { "item4", { NULL, NULL } };
799 test_item_t *item_p;
800 test_item_list_t list;
801
802 test_list_init(&list);
803 fr_dlist_insert_tail(&list.head, &item1);
804 fr_dlist_insert_tail(&list.head, &item2);
805 fr_dlist_insert_tail(&list.head, &item3);
806
807 fr_dcursor_init(&cursor, &list.head);
808 fr_dcursor_next(&cursor);
809 item_p = fr_dcursor_replace(&cursor, &item4);
810 TEST_CHECK(item_p == &item2);
811
812 item_p = fr_dcursor_current(&cursor);
813 TEST_CHECK(item_p == &item4);
814
815 TEST_CHECK(fr_dcursor_next_peek(&cursor) == &item3);
816
817 item_p = fr_dcursor_head(&cursor);
818 TEST_CHECK(item_p == &item1);
819
820 item_p = fr_dcursor_tail(&cursor);
821 TEST_CHECK(item_p == &item3);
822}
823
825{
826 fr_dcursor_t cursor;
827 test_item_t item1 = { "item1", { NULL, NULL } };
828 test_item_t item2 = { "item2", { NULL, NULL } };
829 test_item_t item3 = { "item3", { NULL, NULL } };
830 test_item_t item4 = { "item4", { NULL, NULL } };
831 test_item_t *item_p;
832 test_item_list_t list;
833
834 test_list_init(&list);
835 fr_dlist_insert_tail(&list.head, &item1);
836 fr_dlist_insert_tail(&list.head, &item2);
837 fr_dlist_insert_tail(&list.head, &item3);
838
839 fr_dcursor_init(&cursor, &list.head);
840 fr_dcursor_next(&cursor);
841 fr_dcursor_next(&cursor);
842 fr_dcursor_prepend(&cursor, &item4);
843
844 TEST_CHECK(fr_dcursor_current(&cursor) == &item3);
846
847 item_p = fr_dcursor_next(&cursor);
848 TEST_CHECK(!item_p);
849
850 item_p = fr_dcursor_head(&cursor);
851 TEST_CHECK(item_p == &item4);
852
853 item_p = fr_dcursor_tail(&cursor);
854 TEST_CHECK(item_p == &item3);
855}
856
858{
859 fr_dcursor_t cursor;
860 test_item_t item1 = { "item1", { NULL, NULL } };
861 test_item_t item2 = { "item2", { NULL, NULL } };
862 test_item_t item3 = { "item3", { NULL, NULL } };
863 test_item_t item4 = { "item4", { NULL, NULL } };
864 test_item_t *item_p;
865 test_item_list_t list;
866
867 test_list_init(&list);
868 fr_dlist_insert_tail(&list.head, &item1);
869 fr_dlist_insert_tail(&list.head, &item2);
870 fr_dlist_insert_tail(&list.head, &item3);
871
872 fr_dcursor_init(&cursor, &list.head);
873 fr_dcursor_next(&cursor);
874 fr_dcursor_next(&cursor);
875 fr_dcursor_append(&cursor, &item4);
876
877 TEST_CHECK(fr_dcursor_current(&cursor) == &item3);
878 TEST_CHECK(fr_dcursor_next_peek(&cursor) == &item4);
879
880 item_p = fr_dcursor_next(&cursor);
881 TEST_CHECK(item_p == &item4);
882
883 item_p = fr_dcursor_head(&cursor);
884 TEST_CHECK(item_p == &item1);
885
886 item_p = fr_dcursor_tail(&cursor);
887 TEST_CHECK(item_p == &item4);
888}
889
891{
892 fr_dcursor_t cursor;
893 test_item_t item1 = { "item1", { NULL, NULL } };
894 test_item_t item2 = { "item2", { NULL, NULL } };
895 test_item_t item3 = { "item3", { NULL, NULL } };
896 test_item_t item4 = { "item4", { NULL, NULL } };
897 test_item_t *item_p;
898 test_item_list_t list;
899
900 test_list_init(&list);
901 fr_dlist_insert_tail(&list.head, &item1);
902 fr_dlist_insert_tail(&list.head, &item2);
903 fr_dlist_insert_tail(&list.head, &item3);
904
905 fr_dcursor_init(&cursor, &list.head);
906 fr_dcursor_next(&cursor);
907 fr_dcursor_next(&cursor);
908 fr_dcursor_insert(&cursor, &item4);
909
910 TEST_CHECK(fr_dcursor_current(&cursor) == &item3);
911 TEST_CHECK(fr_dcursor_next_peek(&cursor) == &item4);
912
913 item_p = fr_dcursor_next(&cursor);
914 TEST_CHECK(item_p == &item4);
915
916 item_p = fr_dcursor_next(&cursor);
917 TEST_CHECK(!item_p);
918
919 item_p = fr_dcursor_head(&cursor);
920 TEST_CHECK(item_p == &item1);
921
922 item_p = fr_dcursor_tail(&cursor);
923 TEST_CHECK(item_p == &item4);
924}
925
927{
928 fr_dcursor_t cursor;
929 test_item_t item1 = { "item1", { NULL, NULL } };
930 test_item_t item2 = { "item2", { NULL, NULL } };
931 test_item_t item3 = { "item3", { NULL, NULL } };
932 test_item_t item4 = { "item4", { NULL, NULL } };
933 test_item_t *item_p;
934 test_item_list_t list;
935
936 test_list_init(&list);
937 fr_dlist_insert_tail(&list.head, &item1);
938 fr_dlist_insert_tail(&list.head, &item2);
939 fr_dlist_insert_tail(&list.head, &item3);
940
941 fr_dcursor_init(&cursor, &list.head);
942 fr_dcursor_next(&cursor);
943 fr_dcursor_next(&cursor);
944 item_p = fr_dcursor_replace(&cursor, &item4);
945 TEST_CHECK(item_p == &item3);
946
947 item_p = fr_dcursor_current(&cursor);
948 TEST_CHECK(item_p == &item4);
949
951
952 item_p = fr_dcursor_head(&cursor);
953 TEST_CHECK(item_p == &item1);
954
955 item_p = fr_dcursor_tail(&cursor);
956 TEST_CHECK(item_p == &item4);
957}
958
960{
961 fr_dcursor_t cursor;
962 test_item_list_t list;
963
964 test_list_init(&list);
965
966 _fr_dcursor_init(&cursor, (fr_dlist_head_t *)&list, test_iter, NULL, NULL, NULL, NULL, NULL, false);
967 TEST_CHECK(!fr_dcursor_remove(&cursor));
968}
969
970static void test_dcursor_remove_1i(void)
971{
972 fr_dcursor_t cursor;
973 test_item_t item1 = { "item1", { NULL, NULL } };
974 test_item_t *item_p;
975 test_item_list_t list;
976
977 test_list_init(&list);
978 fr_dlist_insert_tail(&list.head, &item1);
979
980 fr_dcursor_init(&cursor, &list.head);
981
982 item_p = fr_dcursor_remove(&cursor);
983 TEST_CHECK(item_p == &item1);
984
986 TEST_CHECK(!fr_dcursor_next(&cursor));
987 TEST_CHECK(!fr_dcursor_tail(&cursor));
988 TEST_CHECK(!fr_dcursor_head(&cursor));
989}
990
991static void test_dcursor_remove_2i(void)
992{
993 fr_dcursor_t cursor;
994 test_item_t item1 = { "item1", { NULL, NULL } };
995 test_item_t item2 = { "item2", { NULL, NULL } };
996 test_item_t *item_p;
997 test_item_list_t list;
998
999 test_list_init(&list);
1000 fr_dlist_insert_tail(&list.head, &item1);
1001 fr_dlist_insert_tail(&list.head, &item2);
1002
1003 fr_dcursor_init(&cursor, &list.head);
1004 item_p = fr_dcursor_remove(&cursor);
1005
1006 TEST_CHECK(item_p == &item1);
1007 TEST_CHECK(fr_dcursor_current(&cursor) == &item2);
1008 TEST_CHECK(!fr_dcursor_next(&cursor));
1009 TEST_CHECK(fr_dcursor_tail(&cursor) == &item2);
1010 TEST_CHECK(fr_dcursor_head(&cursor) == &item2);
1011
1012 item_p = fr_dcursor_remove(&cursor);
1013 TEST_CHECK(item_p == &item2);
1014
1015 TEST_CHECK(!fr_dcursor_current(&cursor));
1016 TEST_CHECK(!fr_dcursor_next(&cursor));
1017 TEST_CHECK(!fr_dcursor_tail(&cursor));
1018 TEST_CHECK(!fr_dcursor_head(&cursor));
1019}
1020
1022{
1023 fr_dcursor_t cursor;
1024 test_item_t item1 = { "item1", { NULL, NULL } };
1025 test_item_t item2 = { "item2", { NULL, NULL } };
1026 test_item_t item3 = { "item3", { NULL, NULL } };
1027 test_item_t *item_p;
1028 test_item_list_t list;
1029
1030 test_list_init(&list);
1031 fr_dlist_insert_tail(&list.head, &item1);
1032 fr_dlist_insert_tail(&list.head, &item2);
1033 fr_dlist_insert_tail(&list.head, &item3);
1034
1035 fr_dcursor_init(&cursor, &list.head);
1036 item_p = fr_dcursor_remove(&cursor);
1037 TEST_CHECK(item_p == &item1);
1038 TEST_CHECK(fr_dcursor_current(&cursor) == &item2);
1039 TEST_CHECK(fr_dcursor_next_peek(&cursor) == &item3);
1040
1041 item_p = fr_dcursor_remove(&cursor);
1042 TEST_CHECK(item_p == &item2);
1043 TEST_CHECK(fr_dcursor_current(&cursor) == &item3);
1045
1046 item_p = fr_dcursor_remove(&cursor);
1047 TEST_CHECK(item_p == &item3);
1048
1049 TEST_CHECK(!fr_dcursor_tail(&cursor));
1050 TEST_CHECK(!fr_dcursor_head(&cursor));
1051}
1052
1054{
1055 fr_dcursor_t cursor;
1056 test_item_t item1 = { "item1", { NULL, NULL } };
1057 test_item_t item2 = { "item2", { NULL, NULL } };
1058 test_item_t item3 = { "item3", { NULL, NULL } };
1059 test_item_t *item_p;
1060 test_item_list_t list;
1061
1062 test_list_init(&list);
1063 fr_dlist_insert_tail(&list.head, &item1);
1064 fr_dlist_insert_tail(&list.head, &item2);
1065 fr_dlist_insert_tail(&list.head, &item3);
1066
1067 fr_dcursor_init(&cursor, &list.head);
1068 fr_dcursor_next(&cursor);
1069
1070 item_p = fr_dcursor_remove(&cursor);
1071 TEST_CHECK(item_p == &item2);
1072 TEST_CHECK(fr_dcursor_current(&cursor) == &item3);
1074
1075 item_p = fr_dcursor_remove(&cursor);
1076 TEST_CHECK(item_p == &item3);
1077
1078 /*
1079 * We just removed the end of the list
1080 * so current is now NULL.
1081 *
1082 * We don't implicitly start moving backwards.
1083 */
1084 TEST_CHECK(!fr_dcursor_current(&cursor));
1086
1087 item_p = fr_dcursor_remove(&cursor);
1088 TEST_CHECK(!item_p);
1089
1090 TEST_CHECK(fr_dcursor_tail(&cursor) == &item1);
1091 TEST_CHECK(fr_dcursor_head(&cursor) == &item1);
1092}
1093
1095{
1096 fr_dcursor_t cursor;
1097 test_item_t item1 = { "item1", { NULL, NULL } };
1098 test_item_t item2 = { "item2", { NULL, NULL } };
1099 test_item_t item3 = { "item3", { NULL, NULL } };
1100 test_item_t *item_p;
1101 test_item_list_t list;
1102
1103 test_list_init(&list);
1104 fr_dlist_insert_tail(&list.head, &item1);
1105 fr_dlist_insert_tail(&list.head, &item2);
1106 fr_dlist_insert_tail(&list.head, &item3);
1107
1108 fr_dcursor_init(&cursor, &list.head);
1109 fr_dcursor_tail(&cursor);
1110
1111 item_p = fr_dcursor_remove(&cursor);
1112 TEST_CHECK(item_p == &item3);
1113 TEST_CHECK(!fr_dcursor_current(&cursor));
1115
1116 item_p = fr_dcursor_remove(&cursor);
1117 TEST_CHECK(!item_p);
1118
1119 TEST_CHECK(!fr_dcursor_current(&cursor));
1121}
1122
1124{
1125 fr_dcursor_t cursor_a, cursor_b;
1126
1127 test_item_t item1a = { "item1a", { NULL, NULL } };
1128 test_item_t item2a = { "item2a", { NULL, NULL } };
1129 test_item_t item3a = { "item3a", { NULL, NULL } };
1130
1131 test_item_t item1b = { "item1b", { NULL, NULL } };
1132 test_item_t item2b = { "item2b", { NULL, NULL } };
1133 test_item_t item3b = { "item3b", { NULL, NULL } };
1134
1135 test_item_list_t list_a;
1136 test_item_list_t list_b;
1137
1138 test_list_init(&list_a);
1139 fr_dlist_insert_tail(&list_a.head, &item1a);
1140 fr_dlist_insert_tail(&list_a.head, &item2a);
1141 fr_dlist_insert_tail(&list_a.head, &item3a);
1142
1143 test_list_init(&list_b);
1144 fr_dlist_insert_tail(&list_b.head, &item1b);
1145 fr_dlist_insert_tail(&list_b.head, &item2b);
1146 fr_dlist_insert_tail(&list_b.head, &item3b);
1147
1148 fr_dcursor_init(&cursor_a, &list_a.head);
1149 fr_dcursor_init(&cursor_b, &list_b.head);
1150 fr_dcursor_merge(&cursor_a, &cursor_b);
1151
1152 /*
1153 * First item in cursor_a remains unchanged
1154 *
1155 * The insertion point into cursor_a is
1156 * directly after the current item.
1157 */
1158 TEST_CHECK(fr_dcursor_current(&cursor_a) == &item1a);
1159 TEST_MSG("Expected %s", item1a.name);
1160 TEST_MSG("Got %s", ((test_item_t *)fr_dcursor_current(&cursor_a))->name);
1161
1162 /*
1163 * Next three items should be from cursor_b
1164 */
1165 TEST_CHECK(fr_dcursor_next(&cursor_a) == &item1b);
1166 TEST_MSG("Expected %s", item1b.name);
1167 TEST_MSG("Got %s", ((test_item_t *)fr_dcursor_current(&cursor_a))->name);
1168 TEST_CHECK(fr_dcursor_next(&cursor_a) == &item2b);
1169 TEST_MSG("Expected %s", item2b.name);
1170 TEST_MSG("Got %s", ((test_item_t *)fr_dcursor_current(&cursor_a))->name);
1171 TEST_CHECK(fr_dcursor_next(&cursor_a) == &item3b);
1172 TEST_MSG("Expected %s", item3b.name);
1173 TEST_MSG("Got %s", ((test_item_t *)fr_dcursor_current(&cursor_a))->name);
1174
1175 /*
1176 * With the final two from cursor_a
1177 */
1178 TEST_CHECK(fr_dcursor_next(&cursor_a) == &item2a);
1179 TEST_MSG("Expected %s", item2a.name);
1180 TEST_MSG("Got %s", ((test_item_t *)fr_dcursor_current(&cursor_a))->name);
1181 TEST_CHECK(fr_dcursor_next(&cursor_a) == &item3a);
1182 TEST_MSG("Expected %s", item3a.name);
1183 TEST_MSG("Got %s", ((test_item_t *)fr_dcursor_current(&cursor_a))->name);
1184 TEST_CHECK(!fr_dcursor_next(&cursor_a));
1185
1186 TEST_CHECK(!fr_dcursor_current(&cursor_b));
1188}
1189
1191{
1192 fr_dcursor_t cursor_a, cursor_b;
1193
1194 test_item_t item1a = { "item1a", { NULL, NULL } };
1195 test_item_t item2a = { "item2a", { NULL, NULL } };
1196 test_item_t item3a = { "item3a", { NULL, NULL } };
1197
1198 test_item_t item1b = { "item1b", { NULL, NULL } };
1199 test_item_t item2b = { "item2b", { NULL, NULL } };
1200 test_item_t item3b = { "item3b", { NULL, NULL } };
1201
1202 test_item_list_t list_a;
1203 test_item_list_t list_b;
1204
1205 test_list_init(&list_a);
1206 fr_dlist_insert_tail(&list_a.head, &item1a);
1207 fr_dlist_insert_tail(&list_a.head, &item2a);
1208 fr_dlist_insert_tail(&list_a.head, &item3a);
1209
1210 test_list_init(&list_b);
1211 fr_dlist_insert_tail(&list_b.head, &item1b);
1212 fr_dlist_insert_tail(&list_b.head, &item2b);
1213 fr_dlist_insert_tail(&list_b.head, &item3b);
1214
1215 fr_dcursor_init(&cursor_a, &list_a.head);
1216 fr_dcursor_init(&cursor_b, &list_b.head);
1217 fr_dcursor_next(&cursor_a);
1218 fr_dcursor_merge(&cursor_a, &cursor_b);
1219
1220 /*
1221 * Should be second item in cursor a
1222 */
1223 TEST_CHECK(fr_dcursor_current(&cursor_a) == &item2a);
1224 TEST_MSG("Expected %s", item2a.name);
1225 TEST_MSG("Got %s", ((test_item_t *)fr_dcursor_current(&cursor_a))->name);
1226
1227 /*
1228 * Next three items should be from cursor_b
1229 */
1230 TEST_CHECK(fr_dcursor_next(&cursor_a) == &item1b);
1231 TEST_MSG("Expected %s", item1b.name);
1232 TEST_MSG("Got %s", ((test_item_t *)fr_dcursor_current(&cursor_a))->name);
1233 TEST_CHECK(fr_dcursor_next(&cursor_a) == &item2b);
1234 TEST_MSG("Expected %s", item2b.name);
1235 TEST_MSG("Got %s", ((test_item_t *)fr_dcursor_current(&cursor_a))->name);
1236 TEST_CHECK(fr_dcursor_next(&cursor_a) == &item3b);
1237 TEST_MSG("Expected %s", item3b.name);
1238 TEST_MSG("Got %s", ((test_item_t *)fr_dcursor_current(&cursor_a))->name);
1239
1240 /*
1241 * Final item should be from cursor a
1242 */
1243 TEST_CHECK(fr_dcursor_next(&cursor_a) == &item3a);
1244 TEST_MSG("Expected %s", item3a.name);
1245 TEST_MSG("Got %s", ((test_item_t *)fr_dcursor_current(&cursor_a))->name);
1246 TEST_CHECK(!fr_dcursor_next(&cursor_a));
1247
1248 TEST_CHECK(!fr_dcursor_current(&cursor_b));
1250}
1251
1253{
1254 fr_dcursor_t cursor_a, cursor_b;
1255
1256 test_item_t item1a = { "item1a", { NULL, NULL } };
1257 test_item_t item2a = { "item2a", { NULL, NULL } };
1258 test_item_t item3a = { "item3a", { NULL, NULL } };
1259
1260 test_item_t item1b = { "item1b", { NULL, NULL } };
1261 test_item_t item2b = { "item2b", { NULL, NULL } };
1262 test_item_t item3b = { "item3b", { NULL, NULL } };
1263
1264 test_item_list_t list_a;
1265 test_item_list_t list_b;
1266
1267 test_list_init(&list_a);
1268 fr_dlist_insert_tail(&list_a.head, &item1a);
1269 fr_dlist_insert_tail(&list_a.head, &item2a);
1270 fr_dlist_insert_tail(&list_a.head, &item3a);
1271
1272 test_list_init(&list_b);
1273 fr_dlist_insert_tail(&list_b.head, &item1b);
1274 fr_dlist_insert_tail(&list_b.head, &item2b);
1275 fr_dlist_insert_tail(&list_b.head, &item3b);
1276
1277 fr_dcursor_init(&cursor_a, &list_a.head);
1278 fr_dcursor_init(&cursor_b, &list_b.head);
1279 fr_dcursor_tail(&cursor_a);
1280 fr_dcursor_merge(&cursor_a, &cursor_b);
1281
1282 /*
1283 * Should be final item in cursor_a
1284 */
1285 TEST_CHECK(fr_dcursor_current(&cursor_a) == &item3a);
1286 TEST_MSG("Expected %s", item3a.name);
1287 TEST_MSG("Got %s", ((test_item_t *)fr_dcursor_current(&cursor_a))->name);
1288
1289 /*
1290 * Next three items should be from cursor_b
1291 */
1292 TEST_CHECK(fr_dcursor_next(&cursor_a) == &item1b);
1293 TEST_MSG("Expected %s", item1b.name);
1294 TEST_MSG("Got %s", ((test_item_t *)fr_dcursor_current(&cursor_a))->name);
1295 TEST_CHECK(fr_dcursor_next(&cursor_a) == &item2b);
1296 TEST_MSG("Expected %s", item2b.name);
1297 TEST_MSG("Got %s", ((test_item_t *)fr_dcursor_current(&cursor_a))->name);
1298 TEST_CHECK(fr_dcursor_next(&cursor_a) == &item3b);
1299 TEST_MSG("Expected %s", item3b.name);
1300 TEST_MSG("Got %s", ((test_item_t *)fr_dcursor_current(&cursor_a))->name);
1301
1302 /*
1303 * Should be no more items...
1304 */
1306 TEST_CHECK(!fr_dcursor_current(&cursor_b));
1308}
1309
1311{
1312 fr_dcursor_t cursor_a, cursor_b;
1313
1314 test_item_t item1a = { "item1a", { NULL, NULL } };
1315 test_item_t item2a = { "item2a", { NULL, NULL } };
1316 test_item_t item3a = { "item3a", { NULL, NULL } };
1317
1318 test_item_t item1b = { "item1b", { NULL, NULL } };
1319 test_item_t item2b = { "item2b", { NULL, NULL } };
1320 test_item_t item3b = { "item3b", { NULL, NULL } };
1321
1322 test_item_list_t list_a;
1323 test_item_list_t list_b;
1324
1325 test_list_init(&list_a);
1326 fr_dlist_insert_tail(&list_a.head, &item1a);
1327 fr_dlist_insert_tail(&list_a.head, &item2a);
1328 fr_dlist_insert_tail(&list_a.head, &item3a);
1329
1330 test_list_init(&list_b);
1331 fr_dlist_insert_tail(&list_b.head, &item1b);
1332 fr_dlist_insert_tail(&list_b.head, &item2b);
1333 fr_dlist_insert_tail(&list_b.head, &item3b);
1334
1335 fr_dcursor_init(&cursor_a, &list_a.head);
1336 fr_dcursor_init(&cursor_b, &list_b.head);
1337 fr_dcursor_next(&cursor_b);
1338 fr_dcursor_merge(&cursor_a, &cursor_b);
1339
1340 /*
1341 * First item in cursor_a remains unchanged
1342 *
1343 * The insertion point into cursor_a is
1344 * directly after the current item.
1345 */
1346 TEST_CHECK(fr_dcursor_current(&cursor_a) == &item1a);
1347 TEST_MSG("Expected %s", item1a.name);
1348 TEST_MSG("Got %s", ((test_item_t *)fr_dcursor_current(&cursor_a))->name);
1349
1350 /*
1351 * Next two items should be from cursor_b
1352 */
1353 TEST_CHECK(fr_dcursor_next(&cursor_a) == &item2b);
1354 TEST_MSG("Expected %s", item2b.name);
1355 TEST_MSG("Got %s", ((test_item_t *)fr_dcursor_current(&cursor_a))->name);
1356 TEST_CHECK(fr_dcursor_next(&cursor_a) == &item3b);
1357 TEST_MSG("Expected %s", item3b.name);
1358 TEST_MSG("Got %s", ((test_item_t *)fr_dcursor_current(&cursor_a))->name);
1359
1360 /*
1361 * Next two items should be from cursor_a
1362 */
1363 TEST_CHECK(fr_dcursor_next(&cursor_a) == &item2a);
1364 TEST_MSG("Expected %s", item2a.name);
1365 TEST_MSG("Got %s", ((test_item_t *)fr_dcursor_current(&cursor_a))->name);
1366 TEST_CHECK(fr_dcursor_next(&cursor_a) == &item3a);
1367 TEST_MSG("Expected %s", item3a.name);
1368 TEST_MSG("Got %s", ((test_item_t *)fr_dcursor_current(&cursor_a))->name);
1369 TEST_CHECK(!fr_dcursor_next(&cursor_a));
1370
1371 TEST_CHECK(!fr_dcursor_current(&cursor_b));
1373}
1374
1376{
1377 fr_dcursor_t cursor_a, cursor_b;
1378
1379 test_item_t item1a = { "item1a", { NULL, NULL } };
1380 test_item_t item2a = { "item2a", { NULL, NULL } };
1381 test_item_t item3a = { "item3a", { NULL, NULL } };
1382
1383 test_item_t item1b = { "item1b", { NULL, NULL } };
1384 test_item_t item2b = { "item2b", { NULL, NULL } };
1385 test_item_t item3b = { "item3b", { NULL, NULL } };
1386
1387 test_item_list_t list_a;
1388 test_item_list_t list_b;
1389
1390 test_list_init(&list_a);
1391 fr_dlist_insert_tail(&list_a.head, &item1a);
1392 fr_dlist_insert_tail(&list_a.head, &item2a);
1393 fr_dlist_insert_tail(&list_a.head, &item3a);
1394
1395 test_list_init(&list_b);
1396 fr_dlist_insert_tail(&list_b.head, &item1b);
1397 fr_dlist_insert_tail(&list_b.head, &item2b);
1398 fr_dlist_insert_tail(&list_b.head, &item3b);
1399
1400 fr_dcursor_init(&cursor_a, &list_a.head);
1401 fr_dcursor_init(&cursor_b, &list_b.head);
1402 fr_dcursor_next(&cursor_b);
1403 fr_dcursor_next(&cursor_b);
1404 fr_dcursor_merge(&cursor_a, &cursor_b);
1405
1406 /*
1407 * First item in cursor_a remains unchanged
1408 *
1409 * The insertion point into cursor_a is
1410 * directly after the current item.
1411 */
1412 TEST_CHECK(fr_dcursor_current(&cursor_a) == &item1a);
1413 TEST_MSG("Expected %s", item1a.name);
1414 TEST_MSG("Got %s", ((test_item_t *)fr_dcursor_current(&cursor_a))->name);
1415
1416 /*
1417 * Next item should be from cursor_b
1418 */
1419 TEST_CHECK(fr_dcursor_next(&cursor_a) == &item3b);
1420 TEST_MSG("Expected %s", item3b.name);
1421
1422 /*
1423 * Next two items should be from cursor_a
1424 */
1425 TEST_MSG("Got %s", ((test_item_t *)fr_dcursor_current(&cursor_a))->name);
1426 TEST_CHECK(fr_dcursor_next(&cursor_a) == &item2a);
1427 TEST_MSG("Expected %s", item2a.name);
1428 TEST_MSG("Got %s", ((test_item_t *)fr_dcursor_current(&cursor_a))->name);
1429 TEST_CHECK(fr_dcursor_next(&cursor_a) == &item3a);
1430 TEST_MSG("Expected %s", item3a.name);
1431 TEST_MSG("Got %s", ((test_item_t *)fr_dcursor_current(&cursor_a))->name);
1432 TEST_CHECK(!fr_dcursor_next(&cursor_a));
1433
1434 TEST_CHECK(!fr_dcursor_current(&cursor_b));
1435 TEST_CHECK(fr_dcursor_head(&cursor_b) == &item1b);
1436}
1437
1439{
1440 fr_dcursor_t cursor_a, cursor_b;
1441
1442 test_item_t item1b = { "item1b", { NULL, NULL } };
1443 test_item_t item2b = { "item2b", { NULL, NULL } };
1444 test_item_t item3b = { "item3b", { NULL, NULL } };
1445
1446 test_item_list_t list_a;
1447 test_item_list_t list_b;
1448
1449 test_list_init(&list_a);
1450 test_list_init(&list_b);
1451 fr_dlist_insert_tail(&list_b.head, &item1b);
1452 fr_dlist_insert_tail(&list_b.head, &item2b);
1453 fr_dlist_insert_tail(&list_b.head, &item3b);
1454
1455 fr_dcursor_init(&cursor_a, &list_a.head);
1456 fr_dcursor_init(&cursor_b, &list_b.head);
1457 fr_dcursor_merge(&cursor_a, &cursor_b);
1458
1459 TEST_CHECK(fr_dcursor_head(&cursor_a) == &item1b);
1460 TEST_CHECK(fr_dcursor_next(&cursor_a) == &item2b);
1461 TEST_CHECK(fr_dcursor_next(&cursor_a) == &item3b);
1462
1463 TEST_CHECK(!fr_dcursor_current(&cursor_b));
1465}
1466
1468{
1469 fr_dcursor_t cursor_a, cursor_b;
1470
1471 test_item_t item1a = { "item1a", { NULL, NULL } };
1472 test_item_t item2a = { "item2a", { NULL, NULL } };
1473 test_item_t item3a = { "item3a", { NULL, NULL } };
1474
1475 test_item_list_t list_a;
1476 test_item_list_t list_b;
1477
1478 test_list_init(&list_a);
1479 fr_dlist_insert_tail(&list_a.head, &item1a);
1480 fr_dlist_insert_tail(&list_a.head, &item2a);
1481 fr_dlist_insert_tail(&list_a.head, &item3a);
1482 test_list_init(&list_b);
1483
1484 fr_dcursor_init(&cursor_a, &list_a.head);
1485 fr_dcursor_init(&cursor_b, &list_b.head);
1486 fr_dcursor_merge(&cursor_a, &cursor_b);
1487
1488 TEST_CHECK(fr_dcursor_head(&cursor_a) == &item1a);
1489 TEST_CHECK(fr_dcursor_next(&cursor_a) == &item2a);
1490 TEST_CHECK(fr_dcursor_next(&cursor_a) == &item3a);
1491}
1492
1493static void test_dcursor_copy(void)
1494{
1495 fr_dcursor_t cursor_a, cursor_b;
1496
1497 test_item_t item1 = { "item1", { NULL, NULL } };
1498 test_item_t item2 = { "item2", { NULL, NULL } };
1499 test_item_t item3 = { "item3", { NULL, NULL } };
1500
1501 test_item_list_t list;
1502
1503 test_list_init(&list);
1504 fr_dlist_insert_tail(&list.head, &item1);
1505 fr_dlist_insert_tail(&list.head, &item2);
1506 fr_dlist_insert_tail(&list.head, &item3);
1507
1508 fr_dcursor_init(&cursor_a, &list.head);
1509 fr_dcursor_copy(&cursor_b, &cursor_a);
1510
1511 TEST_CHECK(fr_dcursor_head(&cursor_b) == &item1);
1512 TEST_CHECK(fr_dcursor_next(&cursor_b) == &item2);
1513 TEST_CHECK(fr_dcursor_next(&cursor_b) == &item3);
1514}
1515
1516static void test_dcursor_free(void)
1517{
1518 test_item_t *item1, *item2, *item3;
1519 test_item_list_t list;
1520 fr_dcursor_t cursor;
1521 void *item_p;
1522
1523 test_list_init(&list);
1524
1525 item1 = talloc_zero(NULL, test_item_t);
1526 item2 = talloc_zero(NULL, test_item_t);
1527 item3 = talloc_zero(NULL, test_item_t);
1528
1529 fr_dcursor_init(&cursor, &list.head);
1530 fr_dcursor_append(&cursor, item1);
1531 fr_dcursor_append(&cursor, item2);
1532 fr_dcursor_append(&cursor, item3);
1533
1534 fr_dcursor_next(&cursor);
1535 fr_dcursor_free_list(&cursor);
1536
1537 TEST_CHECK(fr_dcursor_current(&cursor) == NULL);
1538 TEST_CHECK(!fr_dcursor_tail(&cursor));
1539 TEST_CHECK(!fr_dcursor_head(&cursor));
1540
1541 item_p = fr_dcursor_remove(&cursor);
1542 talloc_free(item_p);
1543}
1544
1545static void test_dcursor_free_item(void)
1546{
1547 test_item_t *item1, *item2, *item3;
1548 test_item_list_t list;
1549 fr_dcursor_t cursor;
1550
1551 test_list_init(&list);
1552
1553 item1 = talloc_zero(NULL, test_item_t);
1554 item2 = talloc_zero(NULL, test_item_t);
1555 item3 = talloc_zero(NULL, test_item_t);
1556
1557 fr_dcursor_init(&cursor, &list.head);
1558 fr_dcursor_append(&cursor, item1);
1559 fr_dcursor_append(&cursor, item2);
1560 fr_dcursor_append(&cursor, item3);
1561
1562 fr_dcursor_head(&cursor);
1563 fr_dcursor_free_item(&cursor);
1564
1565 TEST_CHECK(fr_dcursor_current(&cursor) == item2);
1566 TEST_CHECK(fr_dcursor_tail(&cursor) == item3);
1567 TEST_CHECK(fr_dcursor_head(&cursor) == item2);
1568
1569 fr_dcursor_free_item(&cursor);
1570 fr_dcursor_free_item(&cursor);
1571
1572 TEST_CHECK(fr_dcursor_current(&cursor) == NULL);
1573 TEST_CHECK(!fr_dcursor_tail(&cursor));
1574 TEST_CHECK(!fr_dcursor_head(&cursor));
1575}
1576
1577
1578typedef struct {
1579 int pos;
1580 char val;
1581} item_filter;
1582
1583static void *iter_name_check(fr_dlist_head_t *list, void *current, void *uctx)
1584{
1585 test_item_t *c = current;
1586 item_filter *f = uctx;
1587
1588 while((c = fr_dlist_next(list, c))) {
1589 if (c->name[f->pos] == f->val) break;
1590 }
1591
1592 return c;
1593}
1594
1596{
1597 fr_dcursor_t cursor_a, cursor_b;
1598
1599 test_item_t item1 = {"item1", { NULL, NULL } };
1600 test_item_t item2 = {"item2", { NULL, NULL } };
1601 test_item_list_t list_a;
1602 test_item_list_t list_b;
1603
1604 test_list_init(&list_a);
1605 fr_dlist_insert_tail(&list_a.head, &item1);
1606 test_list_init(&list_b);
1607 fr_dlist_insert_tail(&list_b.head, &item2);
1608
1609 fr_dcursor_init(&cursor_a, &list_a.head);
1610 fr_dcursor_init(&cursor_b, &list_b.head);
1611
1612 TEST_CHECK(fr_dcursor_intersect_head(&cursor_a, &cursor_b) == NULL);
1613}
1614
1616{
1617 fr_dcursor_t cursor_a, cursor_b;
1618
1619 test_item_t item1 = { "item1", { NULL, NULL } };
1620 test_item_t item2 = { "item2", { NULL, NULL } };
1621 test_item_t item3 = { "item3", { NULL, NULL } };
1622 test_item_t *item4 = NULL;
1623 test_item_list_t list;
1624
1625 test_list_init(&list);
1626 fr_dlist_insert_tail(&list.head, &item1);
1627 fr_dlist_insert_tail(&list.head, &item2);
1628 fr_dlist_insert_tail(&list.head, &item3);
1629
1630 fr_dcursor_init(&cursor_a, &list.head);
1631 fr_dcursor_init(&cursor_b, &list.head);
1632
1633 item4 = fr_dcursor_intersect_head(&cursor_a, &cursor_b);
1634 TEST_CHECK(item4 == &item1);
1635 // TEST_CHECK(fr_dcursor_intersect_head(&cursor_a, &cursor_b) == &item1);
1636 TEST_CHECK(fr_dcursor_intersect_next(&cursor_a, &cursor_b) == &item2);
1637 TEST_CHECK(fr_dcursor_intersect_next(&cursor_a, &cursor_b) == &item3);
1638 TEST_CHECK(fr_dcursor_intersect_next(&cursor_a, &cursor_b) == NULL);
1639}
1640
1642{
1643 fr_dcursor_t cursor_a, cursor_b;
1644
1645 test_item_t item1 = { "actor", { NULL, NULL } };
1646 test_item_t item2 = { "alter", { NULL, NULL } };
1647 test_item_t item3 = { "extra", { NULL, NULL } };
1648 test_item_t item4 = { "after", { NULL, NULL } };
1649 test_item_list_t list;
1650 item_filter filter_a = { 0, 'a' };
1651
1652 test_list_init(&list);
1653 fr_dlist_insert_tail(&list.head, &item1);
1654 fr_dlist_insert_tail(&list.head, &item2);
1655 fr_dlist_insert_tail(&list.head, &item3);
1656 fr_dlist_insert_tail(&list.head, &item4);
1657
1658 fr_dcursor_iter_init(&cursor_a, &list.head, iter_name_check, NULL, &filter_a);
1659 fr_dcursor_init(&cursor_b, &list.head);
1660
1661 TEST_CHECK(fr_dcursor_intersect_head(&cursor_a, &cursor_b) == &item1);
1662 TEST_CHECK(fr_dcursor_intersect_next(&cursor_a, &cursor_b) == &item2);
1663 TEST_CHECK(fr_dcursor_intersect_next(&cursor_a, &cursor_b) == &item4);
1664 TEST_CHECK(fr_dcursor_intersect_next(&cursor_a, &cursor_b) == NULL);
1665}
1666
1668{
1669 fr_dcursor_t cursor_a, cursor_b;
1670
1671 test_item_t item1 = { "blink", { NULL, NULL } };
1672 test_item_t item2 = { "alter", { NULL, NULL } };
1673 test_item_t item3 = { "basic", { NULL, NULL } };
1674 test_item_t item4 = { "bland", { NULL, NULL } };
1675 test_item_list_t list;
1676 item_filter filter_b = { 0, 'b'};
1677
1678 test_list_init(&list);
1679 fr_dlist_insert_tail(&list.head, &item1);
1680 fr_dlist_insert_tail(&list.head, &item2);
1681 fr_dlist_insert_tail(&list.head, &item3);
1682 fr_dlist_insert_tail(&list.head, &item4);
1683
1684 fr_dcursor_init(&cursor_a, &list.head);
1685 fr_dcursor_iter_init(&cursor_b, &list.head, iter_name_check, NULL, &filter_b);
1686
1687 TEST_CHECK(fr_dcursor_intersect_head(&cursor_a, &cursor_b) == &item1);
1688 TEST_CHECK(fr_dcursor_intersect_next(&cursor_a, &cursor_b) == &item3);
1689 TEST_CHECK(fr_dcursor_intersect_next(&cursor_a, &cursor_b) == &item4);
1690}
1691
1693{
1694 fr_dcursor_t cursor_a, cursor_b;
1695
1696 test_item_t item1 = { "baits", { NULL, NULL } };
1697 test_item_t item2 = { "alter", { NULL, NULL } };
1698 test_item_t item3 = { "basic", { NULL, NULL } };
1699 test_item_t item4 = { "cavil", { NULL, NULL } };
1700 test_item_t item5 = { "bland", { NULL, NULL } };
1701 test_item_list_t list;
1702 item_filter filter_a = { 1, 'a' };
1703 item_filter filter_b = { 0, 'b' };
1704
1705 test_list_init(&list);
1706 fr_dlist_insert_tail(&list.head, &item1);
1707 fr_dlist_insert_tail(&list.head, &item2);
1708 fr_dlist_insert_tail(&list.head, &item3);
1709 fr_dlist_insert_tail(&list.head, &item4);
1710 fr_dlist_insert_tail(&list.head, &item5);
1711
1712 fr_dcursor_iter_init(&cursor_a, &list.head, iter_name_check, NULL, &filter_a);
1713 fr_dcursor_iter_init(&cursor_b, &list.head, iter_name_check, NULL, &filter_b);
1714
1715 TEST_CHECK(fr_dcursor_intersect_head(&cursor_a, &cursor_b) == &item1);
1716 TEST_CHECK(fr_dcursor_intersect_next(&cursor_a, &cursor_b) == &item3);
1717 TEST_MSG("Expected %s", item3.name);
1718 TEST_MSG("Current %p", fr_dcursor_current(&cursor_a));
1719 TEST_CHECK(fr_dcursor_intersect_next(&cursor_a, &cursor_b) == NULL);
1720}
1721
1723{
1724 fr_dcursor_t cursor_a, cursor_b;
1725
1726 test_item_t item1 = { "baits", { NULL, NULL } };
1727 test_item_t item2 = { "alter", { NULL, NULL } };
1728 test_item_t item3 = { "basic", { NULL, NULL } };
1729 test_item_t item4 = { "cavil", { NULL, NULL } };
1730 test_item_t item5 = { "bland", { NULL, NULL } };
1731 test_item_list_t list;
1732 item_filter filter_a = { 0, 'a' };
1733 item_filter filter_b = { 0, 'b' };
1734
1735 test_list_init(&list);
1736 fr_dlist_insert_tail(&list.head, &item1);
1737 fr_dlist_insert_tail(&list.head, &item2);
1738 fr_dlist_insert_tail(&list.head, &item3);
1739 fr_dlist_insert_tail(&list.head, &item4);
1740 fr_dlist_insert_tail(&list.head, &item5);
1741
1742 fr_dcursor_iter_init(&cursor_a, &list.head, iter_name_check, NULL, &filter_a);
1743 fr_dcursor_iter_init(&cursor_b, &list.head, iter_name_check, NULL, &filter_b);
1744
1745 TEST_CHECK(fr_dcursor_intersect_head(&cursor_a, &cursor_b) == NULL);
1746}
1747
1748static bool eval_eq(void const *item, void const *uctx)
1749{
1750 test_item_t const *t = item;
1751 char const *s = uctx;
1752
1753 return strcmp(t->name, s) == 0;
1754}
1755
1756static void test_filter_head_next(void)
1757{
1758 fr_dcursor_t cursor;
1759
1760 test_item_t item1 = { "yes", { NULL, NULL } };
1761 test_item_t item2 = { "no", { NULL, NULL } };
1762 test_item_t item3 = { "yes", { NULL, NULL } };
1763 test_item_t item4 = { "no", { NULL, NULL } };
1764 test_item_t item5 = { "yes", { NULL, NULL } };
1765 test_item_t item6 = { "no", { NULL, NULL } };
1766 test_item_list_t list;
1767
1768 test_list_init(&list);
1769 fr_dlist_insert_tail(&list.head, &item1);
1770 fr_dlist_insert_tail(&list.head, &item2);
1771 fr_dlist_insert_tail(&list.head, &item3);
1772 fr_dlist_insert_tail(&list.head, &item4);
1773 fr_dlist_insert_tail(&list.head, &item5);
1774 fr_dlist_insert_tail(&list.head, &item6);
1775
1776 fr_dcursor_init(&cursor, &list.head);
1777
1778 TEST_CHECK(fr_dcursor_filter_head(&cursor, eval_eq, "yes") == &item1);
1779 TEST_CHECK(fr_dcursor_filter_next(&cursor, eval_eq, "yes") == &item3);
1780 TEST_CHECK(fr_dcursor_filter_next(&cursor, eval_eq, "yes") == &item5);
1781 TEST_CHECK(fr_dcursor_filter_next(&cursor, eval_eq, "yes") == NULL);
1782}
1783
1784static void test_filter_current(void)
1785{
1786 fr_dcursor_t cursor;
1787
1788 test_item_t item1 = { "yes", { NULL, NULL } };
1789 test_item_t item2 = { "no", { NULL, NULL } };
1790 test_item_t item3 = { "yes", { NULL, NULL } };
1791 test_item_t item4 = { "no", { NULL, NULL } };
1792 test_item_t item5 = { "yes", { NULL, NULL } };
1793 test_item_t item6 = { "no", { NULL, NULL } };
1794 test_item_list_t list;
1795
1796 test_list_init(&list);
1797 fr_dlist_insert_tail(&list.head, &item1);
1798 fr_dlist_insert_tail(&list.head, &item2);
1799 fr_dlist_insert_tail(&list.head, &item3);
1800 fr_dlist_insert_tail(&list.head, &item4);
1801 fr_dlist_insert_tail(&list.head, &item5);
1802 fr_dlist_insert_tail(&list.head, &item6);
1803
1804 fr_dcursor_init(&cursor, &list.head);
1805
1806 TEST_CHECK(fr_dcursor_filter_current(&cursor, eval_eq, "yes") == &item1);
1807 fr_dcursor_next(&cursor);
1808 TEST_CHECK(fr_dcursor_filter_current(&cursor, eval_eq, "yes") == &item3);
1809 fr_dcursor_next(&cursor);
1810 TEST_CHECK(fr_dcursor_filter_current(&cursor, eval_eq, "yes") == &item5);
1811 fr_dcursor_next(&cursor);
1812 TEST_CHECK(fr_dcursor_filter_current(&cursor, eval_eq, "yes") == NULL);
1813}
1814
1815static void test_filter_no_match(void)
1816{
1817 fr_dcursor_t cursor;
1818
1819 test_item_t item1 = { "yes", { NULL, NULL } };
1820 test_item_t item2 = { "no", { NULL, NULL } };
1821 test_item_t item3 = { "yes", { NULL, NULL } };
1822 test_item_t item4 = { "no", { NULL, NULL } };
1823 test_item_t item5 = { "yes", { NULL, NULL } };
1824 test_item_t item6 = { "no", { NULL, NULL } };
1825 test_item_list_t list;
1826
1827 test_list_init(&list);
1828 fr_dlist_insert_tail(&list.head, &item1);
1829 fr_dlist_insert_tail(&list.head, &item2);
1830 fr_dlist_insert_tail(&list.head, &item3);
1831 fr_dlist_insert_tail(&list.head, &item4);
1832 fr_dlist_insert_tail(&list.head, &item5);
1833 fr_dlist_insert_tail(&list.head, &item6);
1834
1835 fr_dcursor_init(&cursor, &list.head);
1836
1837 TEST_CHECK(fr_dcursor_filter_current(&cursor, eval_eq, "maybe") == NULL);
1838}
1839
1841 /*
1842 * Initialisation
1843 */
1844 { "init_null", test_init_null_item },
1845 { "init_one", test_init_1i_start },
1846 { "init_two", test_init_2i_start },
1847
1848 /*
1849 * Normal iteration
1850 */
1851 { "next", test_next },
1852 { "next_wrap", test_next_wrap }, /* should not wrap */
1853
1854 /*
1855 * Jump to head/tail
1856 */
1857 { "head_tail_null", test_dcursor_head_tail_null },
1858 { "head", test_dcursor_head },
1859 { "head_reset", test_dcursor_head_reset },
1860 { "head_iter_reset", test_dcursor_iter_head_reset },
1861 { "head_after_next", test_dcursor_head_after_next },
1862 { "tail", test_dcursor_tail },
1863 { "head_after_tail", test_dcursor_head_after_tail },
1864 { "wrap_after_tail", test_dcursor_wrap_after_tail },
1865
1866 /*
1867 * Set current
1868 */
1869 { "current_valid", test_dcursor_current_set_valid },
1870 { "current_invalid", test_dcursor_current_set_invalid },
1871
1872 /*
1873 * Insert with empty list
1874 */
1875 { "prepend_empty", test_dcursor_prepend_empty },
1876 { "append_empty", test_dcursor_append_empty },
1877 { "append_empty_3", test_dcursor_append_empty_3 },
1878 { "insert_into_empty", test_dcursor_insert_into_empty },
1879 { "insert_into_empty_3", test_dcursor_insert_into_empty_3 },
1880 { "replace_in_empty", test_dcursor_replace_in_empty },
1881
1882 /*
1883 * Insert with one item list
1884 */
1885 { "prepend_1i_start", test_dcursor_prepend_1i_start},
1886 { "append_1i_start", test_dcursor_append_1i_start },
1887 { "insert_1i_start", test_dcursor_insert_1i_start },
1888 { "replace_1i_start", test_dcursor_replace_1i_start },
1889
1890 /*
1891 * Insert with two item list
1892 */
1893 { "prepend_2i_start", test_dcursor_prepend_2i_start },
1894 { "append_2i_start", test_dcursor_append_2i_start },
1895 { "insert_2i_start", test_dcursor_insert_2i_start },
1896 { "replace_2i_start", test_dcursor_replace_2i_start },
1897
1898 /*
1899 * Insert with three item list (with cursor on item2)
1900 */
1901 { "prepend_3i_mid", test_dcursor_prepend_3i_mid },
1902 { "append_3i_mid", test_dcursor_append_3i_mid },
1903 { "insert_3i_mid", test_dcursor_insert_3i_mid },
1904 { "replace_3i_mid", test_dcursor_replace_3i_mid },
1905
1906 /*
1907 * Insert with three item list (with cursor on item3)
1908 */
1909 { "prepend_3i_end", test_dcursor_prepend_3i_end },
1910 { "append_3i_end", test_dcursor_append_3i_end },
1911 { "insert_3i_end", test_dcursor_insert_3i_end },
1912 { "replace_3i_end", test_dcursor_replace_3i_end },
1913
1914 /*
1915 * Remove
1916 */
1917 { "remove_empty", test_dcursor_remove_empty },
1918 { "remove_1i", test_dcursor_remove_1i },
1919 { "remove_2i", test_dcursor_remove_2i },
1920 { "remove_3i_start", test_dcursor_remove_3i_start },
1921 { "remove_3i_mid", test_dcursor_remove_3i_mid },
1922 { "remove_3i_end", test_dcursor_remove_3i_end },
1923
1924 /*
1925 * Merge
1926 */
1927 { "merge_start_a_b", test_dcursor_merge_start_a_b },
1928 { "merge_mid_a", test_dcursor_merge_mid_a },
1929 { "merge_end_a", test_dcursor_merge_end_a },
1930 { "merge_mid_b", test_dcursor_merge_mid_b },
1931 { "merge_end_b", test_dcursor_merge_end_b },
1932 { "merge_with_empty", test_dcursor_merge_with_empty },
1933 { "merge_empty", test_dcursor_merge_empty },
1934
1935 /*
1936 * Copy
1937 */
1938 { "copy", test_dcursor_copy },
1939
1940 /*
1941 * Free
1942 */
1943 { "free", test_dcursor_free },
1944 { "free_item", test_dcursor_free_item },
1945 /*
1946 * Intersect
1947 */
1948 { "differing_lists", test_intersect_differing_lists },
1949 { "no_iterators", test_intersect_no_iterators },
1950 { "iterator_a", test_intersect_iterator_a },
1951 { "iterator_b", test_intersect_iterator_b },
1952 { "iterator_ab", test_intersect_iterator_ab },
1953 { "iterator_disjoint", test_intersect_iterator_disjoint },
1954 /*
1955 * Filter
1956 */
1957 { "head_next", test_filter_head_next },
1958 { "current", test_filter_current },
1959 { "no_match", test_filter_no_match },
1960
1961 { NULL }
1962};
#define TEST_CHECK(cond)
Definition acutest.h:85
#define TEST_MSG(...)
Definition acutest.h:215
#define UNUSED
Definition build.h:315
Functions to iterate over a sets and subsets of items in dlists.
void * fr_dcursor_intersect_head(fr_dcursor_t *a, fr_dcursor_t *b)
Return the first item matching the iterator in cursor a and cursor b.
Definition dcursor.c:47
void * fr_dcursor_intersect_next(fr_dcursor_t *a, fr_dcursor_t *b)
Return the next item matching the iterator in cursor a and cursor b.
Definition dcursor.c:76
static void * fr_dcursor_next(fr_dcursor_t *cursor)
Advanced the cursor to the next item.
Definition dcursor.h:288
static void * fr_dcursor_filter_current(fr_dcursor_t *cursor, fr_dcursor_eval_t eval, void const *uctx)
Return the next item, starting with the current item, that satisfies an evaluation function.
Definition dcursor.h:586
static void * fr_dcursor_filter_head(fr_dcursor_t *cursor, fr_dcursor_eval_t eval, void const *uctx)
Return the first item that satisfies an evaluation function.
Definition dcursor.h:566
static void * fr_dcursor_list_next_peek(fr_dcursor_t *cursor)
Returns the next list item without advancing the cursor.
Definition dcursor.h:322
static int fr_dcursor_append(fr_dcursor_t *cursor, void *v)
Insert a single item at the end of the list.
Definition dcursor.h:406
static void fr_dcursor_copy(fr_dcursor_t *out, fr_dcursor_t const *in)
Copy cursor parameters and state.
Definition dcursor.h:192
static void fr_dcursor_merge(fr_dcursor_t *cursor, fr_dcursor_t *to_append)
Moves items from one cursor to another.
Definition dcursor.h:520
static void * fr_dcursor_tail(fr_dcursor_t *cursor)
Wind cursor to the tail item in the list.
Definition dcursor.h:259
static void * fr_dcursor_next_peek(fr_dcursor_t *cursor)
Return the next iterator item without advancing the cursor.
Definition dcursor.h:303
#define fr_dcursor_iter_init(_cursor, _head, _iter, _peek, _uctx)
Initialise a cursor with a custom iterator.
Definition dcursor.h:713
static void * fr_dcursor_replace(fr_dcursor_t *cursor, void *r)
Replace the current item.
Definition dcursor.h:610
static int fr_dcursor_insert(fr_dcursor_t *cursor, void *v)
Insert directly after the current item.
Definition dcursor.h:435
#define fr_dcursor_init(_cursor, _head)
Initialise a cursor.
Definition dcursor.h:732
static void * fr_dcursor_set_current(fr_dcursor_t *cursor, void *item)
Set the cursor to a specified item.
Definition dcursor.h:353
static void * fr_dcursor_filter_next(fr_dcursor_t *cursor, fr_dcursor_eval_t eval, void const *uctx)
Return the next item, skipping the current item, that satisfies an evaluation function.
Definition dcursor.h:545
static void fr_dcursor_free_item(fr_dcursor_t *cursor)
talloc_free the current item
Definition dcursor.h:805
static void * fr_dcursor_remove(fr_dcursor_t *cursor)
Remove the current item.
Definition dcursor.h:480
static void fr_dcursor_free_list(fr_dcursor_t *cursor)
Free the current item and all items after it.
Definition dcursor.h:663
static void * fr_dcursor_current(fr_dcursor_t *cursor)
Return the item the cursor current points to.
Definition dcursor.h:337
static void * fr_dcursor_head(fr_dcursor_t *cursor)
Rewind cursor to the start of the list.
Definition dcursor.h:234
fr_dlist_head_t * dlist
Head of the doubly linked list being iterated over.
Definition dcursor.h:94
static int fr_dcursor_prepend(fr_dcursor_t *cursor, void *v)
Insert a single item at the start of the list.
Definition dcursor.h:376
void * iter_uctx
to pass to iterator function.
Definition dcursor.h:100
static void * _fr_dcursor_init(fr_dcursor_t *cursor, fr_dlist_head_t const *head, fr_dcursor_iter_t iter, fr_dcursor_iter_t peek, void const *iter_uctx, fr_dcursor_insert_t insert, fr_dcursor_remove_t remove, void const *mod_uctx, bool is_const)
Setup a cursor to iterate over attribute items in dlists.
Definition dcursor.h:759
static void test_dcursor_append_3i_end(void)
static void test_intersect_iterator_b(void)
static void test_dcursor_replace_3i_mid(void)
static void test_dcursor_free(void)
TEST_LIST
static void test_intersect_iterator_a(void)
static void test_dcursor_merge_empty(void)
static void test_dcursor_prepend_empty(void)
static void test_dcursor_merge_end_b(void)
static void test_dcursor_append_empty(void)
static void test_dcursor_replace_2i_start(void)
static void test_dcursor_free_item(void)
static void test_dcursor_head_tail_null(void)
static void test_dcursor_replace_1i_start(void)
static void test_dcursor_prepend_3i_end(void)
static void test_dcursor_remove_3i_mid(void)
static void test_dcursor_insert_2i_start(void)
static void test_dcursor_copy(void)
static void * test_iter(fr_dlist_head_t *list, void *current, UNUSED void *uctx)
static void test_init_2i_start(void)
static void test_dcursor_remove_3i_start(void)
static void test_dcursor_merge_mid_a(void)
static void test_dcursor_wrap_after_tail(void)
static void test_dcursor_append_3i_mid(void)
static void test_filter_no_match(void)
static void test_dcursor_append_1i_start(void)
static void test_dcursor_prepend_2i_start(void)
static void test_intersect_iterator_disjoint(void)
static void test_dcursor_iter_head_reset(void)
static void test_dcursor_tail(void)
static void test_dcursor_head(void)
static void test_dcursor_current_set_invalid(void)
static void test_next(void)
static void test_dcursor_remove_2i(void)
static void test_dcursor_current_set_valid(void)
static void test_dcursor_remove_empty(void)
static void test_intersect_no_iterators(void)
static void test_dcursor_replace_in_empty(void)
static void test_dcursor_insert_1i_start(void)
static bool eval_eq(void const *item, void const *uctx)
static void test_dcursor_head_after_next(void)
static void test_dcursor_merge_start_a_b(void)
static void test_dcursor_head_reset(void)
static void test_dcursor_merge_with_empty(void)
static void test_dcursor_append_2i_start(void)
static void test_dcursor_prepend_3i_mid(void)
static void test_next_wrap(void)
static void test_dcursor_merge_mid_b(void)
static void test_dcursor_replace_3i_end(void)
static void test_init_null_item(void)
Verify internal state is initialised correctly.
static void test_dcursor_insert_into_empty_3(void)
static void test_intersect_differing_lists(void)
static void test_filter_head_next(void)
static void test_dcursor_head_after_tail(void)
static void test_dcursor_prepend_1i_start(void)
static void test_dcursor_append_empty_3(void)
static void test_dcursor_insert_into_empty(void)
static void test_dcursor_remove_1i(void)
static void test_filter_current(void)
static void test_intersect_iterator_ab(void)
static void test_dcursor_insert_3i_mid(void)
static void test_dcursor_insert_3i_end(void)
static void * iter_name_check(fr_dlist_head_t *list, void *current, void *uctx)
static void test_list_init(test_item_list_t *list)
fr_dlist_head_t head
static void test_init_1i_start(void)
static void test_dcursor_merge_end_a(void)
static void test_dcursor_remove_3i_end(void)
char const * name
fr_dlist_t entry
static int fr_dlist_insert_tail(fr_dlist_head_t *list_head, void *ptr)
Insert an item into the tail of a list.
Definition dlist.h:378
#define fr_dlist_talloc_init(_head, _type, _field)
Initialise the head structure of a doubly linked list.
Definition dlist.h:275
static void * fr_dlist_next(fr_dlist_head_t const *list_head, void const *ptr)
Get the next item in a list.
Definition dlist.h:555
Head of a doubly linked list.
Definition dlist.h:51
Entry in a doubly linked list.
Definition dlist.h:41
talloc_free(reap)
static void * item(fr_lst_t const *lst, fr_lst_index_t idx)
Definition lst.c:122
static rc_request_t * current
static char const * name