]> git.ozlabs.org Git - ccan/blob - ccan/list/test/run-single-eval.c
f90eed357ac9875d2cca6bc031612aca4d307160
[ccan] / ccan / list / test / run-single-eval.c
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>
5
6 struct parent {
7         const char *name;
8         struct list_head children;
9         unsigned int num_children;
10         int eval_count;
11 };
12
13 struct child {
14         const char *name;
15         struct list_node list;
16 };
17
18 static LIST_HEAD(static_list);
19
20 #define ref(obj, counter) ((counter)++, (obj))
21
22 int main(int argc, char *argv[])
23 {
24         struct parent parent;
25         struct child c1, c2, c3, *c, *n;
26         unsigned int i;
27         unsigned int static_count = 0, parent_count = 0, list_count = 0,
28                 node_count = 0;
29         struct list_head list = LIST_HEAD_INIT(list);
30
31         plan_tests(74);
32         /* Test LIST_HEAD, LIST_HEAD_INIT, list_empty and check_list */
33         ok1(list_empty(ref(&static_list, static_count)));
34         ok1(static_count == 1);
35         ok1(list_check(ref(&static_list, static_count), NULL));
36         ok1(static_count == 2);
37         ok1(list_empty(ref(&list, list_count)));
38         ok1(list_count == 1);
39         ok1(list_check(ref(&list, list_count), NULL));
40         ok1(list_count == 2);
41
42         parent.num_children = 0;
43         list_head_init(ref(&parent.children, parent_count));
44         ok1(parent_count == 1);
45         /* Test list_head_init */
46         ok1(list_empty(ref(&parent.children, parent_count)));
47         ok1(parent_count == 2);
48         ok1(list_check(ref(&parent.children, parent_count), NULL));
49         ok1(parent_count == 3);
50
51         c2.name = "c2";
52         list_add(ref(&parent.children, parent_count), &c2.list);
53         ok1(parent_count == 4);
54         /* Test list_add and !list_empty. */
55         ok1(!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 list_check */
62         ok1(list_check(ref(&parent.children, parent_count), NULL));
63         ok1(parent_count == 6);
64
65         c1.name = "c1";
66         list_add(ref(&parent.children, parent_count), &c1.list);
67         ok1(parent_count == 7);
68         /* Test list_add and !list_empty. */
69         ok1(!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 list_check */
78         ok1(list_check(ref(&parent.children, parent_count), NULL));
79         ok1(parent_count == 9);
80
81         c3.name = "c3";
82         list_add_tail(ref(&parent.children, parent_count), &c3.list);
83         ok1(parent_count == 10);
84         /* Test list_add_tail and !list_empty. */
85         ok1(!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 list_check */
96         ok1(list_check(ref(&parent.children, parent_count), NULL));
97         ok1(parent_count == 12);
98
99         /* Test list_check_node */
100         ok1(list_check_node(&c1.list, NULL));
101         ok1(list_check_node(&c2.list, NULL));
102         ok1(list_check_node(&c3.list, NULL));
103
104         /* Test list_top */
105         ok1(list_top(ref(&parent.children, parent_count), struct child, list) == &c1);
106         ok1(parent_count == 13);
107
108         /* Test list_tail */
109         ok1(list_tail(ref(&parent.children, parent_count), struct child, list) == &c3);
110         ok1(parent_count == 14);
111
112         /* Test list_for_each. */
113         i = 0;
114         list_for_each(&parent.children, c, list) {
115                 switch (i++) {
116                 case 0:
117                         ok1(c == &c1);
118                         break;
119                 case 1:
120                         ok1(c == &c2);
121                         break;
122                 case 2:
123                         ok1(c == &c3);
124                         break;
125                 }
126                 if (i > 2)
127                         break;
128         }
129         ok1(i == 3);
130
131         /* Test list_for_each_safe, list_del and list_del_from. */
132         i = 0;
133         list_for_each_safe(&parent.children, c, n, list) {
134                 switch (i++) {
135                 case 0:
136                         ok1(c == &c1);
137                         list_del(ref(&c->list, node_count));
138                         ok1(node_count == 1);
139                         break;
140                 case 1:
141                         ok1(c == &c2);
142                         list_del_from(ref(&parent.children, parent_count),
143                                       ref(&c->list, node_count));
144                         ok1(node_count == 2);
145                         break;
146                 case 2:
147                         ok1(c == &c3);
148                         list_del_from(ref(&parent.children, parent_count),
149                                       ref(&c->list, node_count));
150                         ok1(node_count == 3);
151                         break;
152                 }
153                 ok1(list_check(ref(&parent.children, parent_count), NULL));
154                 if (i > 2)
155                         break;
156         }
157         ok1(i == 3);
158         ok1(parent_count == 19);
159         ok1(list_empty(ref(&parent.children, parent_count)));
160         ok1(parent_count == 20);
161
162         /* Test list_top/list_tail on empty list. */
163         ok1(list_top(ref(&parent.children, parent_count), struct child, list) == NULL);
164         ok1(parent_count == 21);
165         ok1(list_tail(ref(&parent.children, parent_count), struct child, list) == NULL);
166         ok1(parent_count == 22);
167         return exit_status();
168 }