1 /* Make sure macros only evaluate their args once. */
2 #include <ccan/list/list.h>
3 #include <ccan/tap/tap.h>
4 #include <ccan/list/list.c>
8 struct ccan_list_head children
;
9 unsigned int num_children
;
15 struct ccan_list_node list
;
18 static CCAN_LIST_HEAD(static_list
);
20 #define ref(obj, counter) ((counter)++, (obj))
22 int main(int argc
, char *argv
[])
25 struct child c1
, c2
, c3
, *c
, *n
;
27 unsigned int static_count
= 0, parent_count
= 0, list_count
= 0,
29 struct ccan_list_head list
= CCAN_LIST_HEAD_INIT(list
);
32 /* Test CCAN_LIST_HEAD, CCAN_LIST_HEAD_INIT, ccan_list_empty and check_list */
33 ok1(ccan_list_empty(ref(&static_list
, static_count
)));
34 ok1(static_count
== 1);
35 ok1(ccan_list_check(ref(&static_list
, static_count
), NULL
));
36 ok1(static_count
== 2);
37 ok1(ccan_list_empty(ref(&list
, list_count
)));
39 ok1(ccan_list_check(ref(&list
, list_count
), NULL
));
42 parent
.num_children
= 0;
43 ccan_list_head_init(ref(&parent
.children
, parent_count
));
44 ok1(parent_count
== 1);
45 /* Test ccan_list_head_init */
46 ok1(ccan_list_empty(ref(&parent
.children
, parent_count
)));
47 ok1(parent_count
== 2);
48 ok1(ccan_list_check(ref(&parent
.children
, parent_count
), NULL
));
49 ok1(parent_count
== 3);
52 ccan_list_add(ref(&parent
.children
, parent_count
), &c2
.list
);
53 ok1(parent_count
== 4);
54 /* Test ccan_list_add and !ccan_list_empty. */
55 ok1(!ccan_list_empty(ref(&parent
.children
, parent_count
)));
56 ok1(parent_count
== 5);
57 ok1(c2
.list
.next
== &parent
.children
.n
);
58 ok1(c2
.list
.prev
== &parent
.children
.n
);
59 ok1(parent
.children
.n
.next
== &c2
.list
);
60 ok1(parent
.children
.n
.prev
== &c2
.list
);
61 /* Test ccan_list_check */
62 ok1(ccan_list_check(ref(&parent
.children
, parent_count
), NULL
));
63 ok1(parent_count
== 6);
66 ccan_list_add(ref(&parent
.children
, parent_count
), &c1
.list
);
67 ok1(parent_count
== 7);
68 /* Test ccan_list_add and !ccan_list_empty. */
69 ok1(!ccan_list_empty(ref(&parent
.children
, parent_count
)));
70 ok1(parent_count
== 8);
71 ok1(c2
.list
.next
== &parent
.children
.n
);
72 ok1(c2
.list
.prev
== &c1
.list
);
73 ok1(parent
.children
.n
.next
== &c1
.list
);
74 ok1(parent
.children
.n
.prev
== &c2
.list
);
75 ok1(c1
.list
.next
== &c2
.list
);
76 ok1(c1
.list
.prev
== &parent
.children
.n
);
77 /* Test ccan_list_check */
78 ok1(ccan_list_check(ref(&parent
.children
, parent_count
), NULL
));
79 ok1(parent_count
== 9);
82 ccan_list_add_tail(ref(&parent
.children
, parent_count
), &c3
.list
);
83 ok1(parent_count
== 10);
84 /* Test ccan_list_add_tail and !ccan_list_empty. */
85 ok1(!ccan_list_empty(ref(&parent
.children
, parent_count
)));
86 ok1(parent_count
== 11);
87 ok1(parent
.children
.n
.next
== &c1
.list
);
88 ok1(parent
.children
.n
.prev
== &c3
.list
);
89 ok1(c1
.list
.next
== &c2
.list
);
90 ok1(c1
.list
.prev
== &parent
.children
.n
);
91 ok1(c2
.list
.next
== &c3
.list
);
92 ok1(c2
.list
.prev
== &c1
.list
);
93 ok1(c3
.list
.next
== &parent
.children
.n
);
94 ok1(c3
.list
.prev
== &c2
.list
);
95 /* Test ccan_list_check */
96 ok1(ccan_list_check(ref(&parent
.children
, parent_count
), NULL
));
97 ok1(parent_count
== 12);
99 /* Test ccan_list_check_node */
100 ok1(ccan_list_check_node(&c1
.list
, NULL
));
101 ok1(ccan_list_check_node(&c2
.list
, NULL
));
102 ok1(ccan_list_check_node(&c3
.list
, NULL
));
104 /* Test ccan_list_top */
105 ok1(ccan_list_top(ref(&parent
.children
, parent_count
), struct child
, list
) == &c1
);
106 ok1(parent_count
== 13);
108 /* Test ccan_list_tail */
109 ok1(ccan_list_tail(ref(&parent
.children
, parent_count
), struct child
, list
) == &c3
);
110 ok1(parent_count
== 14);
112 /* Test ccan_list_for_each. */
114 ccan_list_for_each(&parent
.children
, c
, list
) {
131 /* Test ccan_list_for_each_safe, ccan_list_del and ccan_list_del_from. */
133 ccan_list_for_each_safe(&parent
.children
, c
, n
, list
) {
137 ccan_list_del(ref(&c
->list
, node_count
));
138 ok1(node_count
== 1);
142 ccan_list_del_from(ref(&parent
.children
, parent_count
),
143 ref(&c
->list
, node_count
));
144 ok1(node_count
== 2);
148 ccan_list_del_from(ref(&parent
.children
, parent_count
),
149 ref(&c
->list
, node_count
));
150 ok1(node_count
== 3);
153 ok1(ccan_list_check(ref(&parent
.children
, parent_count
), NULL
));
158 ok1(parent_count
== 19);
159 ok1(ccan_list_empty(ref(&parent
.children
, parent_count
)));
160 ok1(parent_count
== 20);
162 /* Test ccan_list_top/ccan_list_tail on empty list. */
163 ok1(ccan_list_top(ref(&parent
.children
, parent_count
), struct child
, list
) == NULL
);
164 ok1(parent_count
== 21);
165 ok1(ccan_list_tail(ref(&parent
.children
, parent_count
), struct child
, list
) == NULL
);
166 ok1(parent_count
== 22);
167 return exit_status();