Branch data Line data Source code
1 : : #include <ccan/list/test/helper.c>
2 : : #include <ccan/list/list.h>
3 : : #include <ccan/tap/tap.h>
4 : : #include <ccan/list/list.c>
5 : : #include "helper.h"
6 : :
7 : : struct parent {
8 : : const char *name;
9 : : struct list_head children;
10 : : unsigned int num_children;
11 : : };
12 : :
13 : : struct child {
14 : : const char *name;
15 : : struct list_node list;
16 : : };
17 : :
18 : : static LIST_HEAD(static_list);
19 : :
20 : 20 : int main(void)
21 : : {
22 : : struct parent parent;
23 : : struct child c1, c2, c3, x1, *c, *n;
24 : : unsigned int i;
25 : 20 : struct list_head list = LIST_HEAD_INIT(list);
26 : : opaque_t *q, *nq;
27 : 20 : struct list_head opaque_list = LIST_HEAD_INIT(opaque_list);
28 : 20 : LIST_HEAD(rev);
29 : :
30 : : plan_tests(92);
31 : : /* Test LIST_HEAD, LIST_HEAD_INIT, list_empty and check_list */
32 : 20 : ok1(list_empty(&static_list));
33 : 20 : ok1(list_check(&static_list, NULL));
34 : 20 : ok1(list_empty(&list));
35 : 20 : ok1(list_check(&list, NULL));
36 : :
37 : 20 : parent.num_children = 0;
38 : 20 : list_head_init(&parent.children);
39 : : /* Test list_head_init */
40 : 20 : ok1(list_empty(&parent.children));
41 : 20 : ok1(list_check(&parent.children, NULL));
42 : :
43 : 20 : c2.name = "c2";
44 : 20 : list_add(&parent.children, &c2.list);
45 : : /* Test list_add and !list_empty. */
46 : 20 : ok1(!list_empty(&parent.children));
47 : 20 : ok1(c2.list.next == &parent.children.n);
48 : 20 : ok1(c2.list.prev == &parent.children.n);
49 : 20 : ok1(parent.children.n.next == &c2.list);
50 : 20 : ok1(parent.children.n.prev == &c2.list);
51 : : /* Test list_check */
52 : 20 : ok1(list_check(&parent.children, NULL));
53 : :
54 : 20 : c1.name = "c1";
55 : 20 : list_add(&parent.children, &c1.list);
56 : : /* Test list_add and !list_empty. */
57 : 20 : ok1(!list_empty(&parent.children));
58 : 20 : ok1(c2.list.next == &parent.children.n);
59 : 20 : ok1(c2.list.prev == &c1.list);
60 : 20 : ok1(parent.children.n.next == &c1.list);
61 : 20 : ok1(parent.children.n.prev == &c2.list);
62 : 20 : ok1(c1.list.next == &c2.list);
63 : 20 : ok1(c1.list.prev == &parent.children.n);
64 : : /* Test list_check */
65 : 20 : ok1(list_check(&parent.children, NULL));
66 : :
67 : 20 : c3.name = "c3";
68 : 20 : list_add_tail(&parent.children, &c3.list);
69 : : /* Test list_add_tail and !list_empty. */
70 : 20 : ok1(!list_empty(&parent.children));
71 : 20 : ok1(parent.children.n.next == &c1.list);
72 : 20 : ok1(parent.children.n.prev == &c3.list);
73 : 20 : ok1(c1.list.next == &c2.list);
74 : 20 : ok1(c1.list.prev == &parent.children.n);
75 : 20 : ok1(c2.list.next == &c3.list);
76 : 20 : ok1(c2.list.prev == &c1.list);
77 : 20 : ok1(c3.list.next == &parent.children.n);
78 : 20 : ok1(c3.list.prev == &c2.list);
79 : : /* Test list_check */
80 : 20 : ok1(list_check(&parent.children, NULL));
81 : :
82 : : /* Test list_check_node */
83 : 20 : ok1(list_check_node(&c1.list, NULL));
84 : 20 : ok1(list_check_node(&c2.list, NULL));
85 : 20 : ok1(list_check_node(&c3.list, NULL));
86 : :
87 : : /* Test list_top */
88 : 20 : ok1(list_top(&parent.children, struct child, list) == &c1);
89 : :
90 : : /* Test list_pop */
91 : 20 : ok1(list_pop(&parent.children, struct child, list) == &c1);
92 : 20 : ok1(list_top(&parent.children, struct child, list) == &c2);
93 : 20 : list_add(&parent.children, &c1.list);
94 : :
95 : : /* Test list_tail */
96 : 20 : ok1(list_tail(&parent.children, struct child, list) == &c3);
97 : :
98 : : /* Test list_for_each. */
99 : 20 : i = 0;
100 : 60 : list_for_each(&parent.children, c, list) {
101 : 60 : switch (i++) {
102 : 20 : case 0:
103 : 20 : ok1(c == &c1);
104 : 20 : break;
105 : 20 : case 1:
106 : 20 : ok1(c == &c2);
107 : 20 : break;
108 : 20 : case 2:
109 : 20 : ok1(c == &c3);
110 : 20 : break;
111 : : }
112 : 60 : if (i > 2)
113 : 20 : break;
114 : : }
115 : 20 : ok1(i == 3);
116 : :
117 : : /* Test list_for_each_rev. */
118 : 20 : i = 0;
119 : 60 : list_for_each_rev(&parent.children, c, list) {
120 : 60 : switch (i++) {
121 : 20 : case 0:
122 : 20 : ok1(c == &c3);
123 : 20 : break;
124 : 20 : case 1:
125 : 20 : ok1(c == &c2);
126 : 20 : break;
127 : 20 : case 2:
128 : 20 : ok1(c == &c1);
129 : 20 : break;
130 : : }
131 : 60 : if (i > 2)
132 : 20 : break;
133 : : }
134 : 20 : ok1(i == 3);
135 : :
136 : : /* Test list_for_each_safe, list_del and list_del_from. */
137 : 20 : i = 0;
138 : 60 : list_for_each_safe(&parent.children, c, n, list) {
139 : 60 : switch (i++) {
140 : 20 : case 0:
141 : 20 : ok1(c == &c1);
142 : 20 : list_del(&c->list);
143 : 20 : break;
144 : 20 : case 1:
145 : 20 : ok1(c == &c2);
146 : 20 : list_del_from(&parent.children, &c->list);
147 : 20 : break;
148 : 20 : case 2:
149 : 20 : ok1(c == &c3);
150 : 20 : list_del_from(&parent.children, &c->list);
151 : 20 : break;
152 : : }
153 : :
154 : : /* prepare for list_for_each_rev_safe test */
155 : 60 : list_add(&rev, &c->list);
156 : :
157 : 60 : ok1(list_check(&parent.children, NULL));
158 : 60 : if (i > 2)
159 : 20 : break;
160 : : }
161 : 20 : ok1(i == 3);
162 : 20 : ok1(list_empty(&parent.children));
163 : :
164 : : /* Test list_for_each_rev_safe, list_del and list_del_from. */
165 : 20 : i = 0;
166 : 60 : list_for_each_rev_safe(&rev, c, n, list) {
167 : 60 : switch (i++) {
168 : 20 : case 0:
169 : 20 : ok1(c == &c1);
170 : 20 : list_del(&c->list);
171 : 20 : break;
172 : 20 : case 1:
173 : 20 : ok1(c == &c2);
174 : 20 : list_del_from(&rev, &c->list);
175 : 20 : break;
176 : 20 : case 2:
177 : 20 : ok1(c == &c3);
178 : 20 : list_del_from(&rev, &c->list);
179 : 20 : break;
180 : : }
181 : 60 : ok1(list_check(&rev, NULL));
182 : 60 : if (i > 2)
183 : 20 : break;
184 : : }
185 : 20 : ok1(i == 3);
186 : 20 : ok1(list_empty(&rev));
187 : :
188 : : /* Test list_node_init: safe to list_del after this. */
189 : 20 : list_node_init(&c->list);
190 : 20 : list_del(&c->list);
191 : :
192 : : /* Test list_del_init */
193 : 20 : list_add(&parent.children, &c->list);
194 : 20 : ok1(!list_empty(&parent.children));
195 : 20 : list_del_init(&c->list);
196 : 20 : ok1(list_empty(&parent.children));
197 : : /* We can call this as many times as we like. */
198 : 20 : list_del_init(&c->list);
199 : 20 : list_del_init(&c->list);
200 : :
201 : : /* Test list_for_each_off. */
202 : 20 : list_add_tail(&opaque_list,
203 : : (struct list_node *)create_opaque_blob());
204 : 20 : list_add_tail(&opaque_list,
205 : : (struct list_node *)create_opaque_blob());
206 : 20 : list_add_tail(&opaque_list,
207 : : (struct list_node *)create_opaque_blob());
208 : :
209 : 20 : i = 0;
210 : :
211 : 80 : list_for_each_off(&opaque_list, q, 0) {
212 : 60 : i++;
213 : 60 : ok1(if_blobs_know_the_secret(q));
214 : : }
215 : 20 : ok1(i == 3);
216 : :
217 : : /* Test list_for_each_safe_off, list_del_off and list_del_from_off. */
218 : 20 : i = 0;
219 : 60 : list_for_each_safe_off(&opaque_list, q, nq, 0) {
220 : 60 : switch (i++) {
221 : 20 : case 0:
222 : 20 : ok1(if_blobs_know_the_secret(q));
223 : 20 : list_del_off(q, 0);
224 : 20 : destroy_opaque_blob(q);
225 : 20 : break;
226 : 20 : case 1:
227 : 20 : ok1(if_blobs_know_the_secret(q));
228 : 20 : list_del_from_off(&opaque_list, q, 0);
229 : 20 : destroy_opaque_blob(q);
230 : 20 : break;
231 : 20 : case 2:
232 : 20 : ok1(c == &c3);
233 : 20 : list_del_from_off(&opaque_list, q, 0);
234 : 20 : destroy_opaque_blob(q);
235 : 20 : break;
236 : : }
237 : 60 : ok1(list_check(&opaque_list, NULL));
238 : 60 : if (i > 2)
239 : 20 : break;
240 : : }
241 : 20 : ok1(i == 3);
242 : 20 : ok1(list_empty(&opaque_list));
243 : :
244 : : /* Test list_top/list_tail/list_pop on empty list. */
245 : 20 : ok1(list_top(&parent.children, struct child, list) == NULL);
246 : 20 : ok1(list_tail(&parent.children, struct child, list) == NULL);
247 : 20 : ok1(list_pop(&parent.children, struct child, list) == NULL);
248 : :
249 : : /* Test list_add_before and list_add_after */
250 : 20 : list_add(&parent.children, &c1.list);
251 : 20 : list_add_after(&parent.children, &c1.list, &c2.list);
252 : 20 : ok1(list_check(&parent.children, "list_add_after"));
253 : :
254 : 20 : i = 0;
255 : 60 : list_for_each(&parent.children, c, list) {
256 : 40 : switch (i++) {
257 : 20 : case 0:
258 : 20 : ok1(c == &c1);
259 : 20 : break;
260 : 20 : case 1:
261 : 20 : ok1(c == &c2);
262 : 20 : break;
263 : : }
264 : : }
265 : 20 : ok1(i == 2);
266 : :
267 : 20 : list_add_before(&parent.children, &c2.list, &c3.list);
268 : 20 : ok1(list_check(&parent.children, "list_add_before"));
269 : :
270 : 20 : i = 0;
271 : 80 : list_for_each(&parent.children, c, list) {
272 : 60 : switch (i++) {
273 : 20 : case 0:
274 : 20 : ok1(c == &c1);
275 : 20 : break;
276 : 20 : case 1:
277 : 20 : ok1(c == &c3);
278 : 20 : break;
279 : 20 : case 2:
280 : 20 : ok1(c == &c2);
281 : 20 : break;
282 : : }
283 : : }
284 : 20 : ok1(i == 3);
285 : :
286 : : /* test list_swap */
287 : 20 : list_swap(&c3.list, &x1.list);
288 : 20 : ok1(list_check(&parent.children, "list_swap"));
289 : 20 : i = 0;
290 : 80 : list_for_each(&parent.children, c, list) {
291 : 60 : switch (i++) {
292 : 20 : case 0:
293 : 20 : ok1(c == &c1);
294 : 20 : break;
295 : 20 : case 1:
296 : 20 : ok1(c == &x1);
297 : 20 : break;
298 : 20 : case 2:
299 : 20 : ok1(c == &c2);
300 : 20 : break;
301 : : }
302 : : }
303 : 20 : ok1(i == 3);
304 : :
305 : 20 : return exit_status();
306 : : }
|