Branch data Line data Source code
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 : 10 : int main(void)
23 : : {
24 : : struct parent parent;
25 : : struct child c1, c2, c3, *c, *n;
26 : : unsigned int i;
27 : 10 : unsigned int static_count = 0, parent_count = 0, list_count = 0,
28 : 10 : node_count = 0;
29 : 10 : 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 : 10 : ok1(list_empty(ref(&static_list, static_count)));
34 : 10 : ok1(static_count == 1);
35 : 10 : ok1(list_check(ref(&static_list, static_count), NULL));
36 : 10 : ok1(static_count == 2);
37 : 10 : ok1(list_empty(ref(&list, list_count)));
38 : 10 : ok1(list_count == 1);
39 : 10 : ok1(list_check(ref(&list, list_count), NULL));
40 : 10 : ok1(list_count == 2);
41 : :
42 : 10 : parent.num_children = 0;
43 : 10 : list_head_init(ref(&parent.children, parent_count));
44 : 10 : ok1(parent_count == 1);
45 : : /* Test list_head_init */
46 : 10 : ok1(list_empty(ref(&parent.children, parent_count)));
47 : 10 : ok1(parent_count == 2);
48 : 10 : ok1(list_check(ref(&parent.children, parent_count), NULL));
49 : 10 : ok1(parent_count == 3);
50 : :
51 : 10 : c2.name = "c2";
52 : 10 : list_add(ref(&parent.children, parent_count), &c2.list);
53 : 10 : ok1(parent_count == 4);
54 : : /* Test list_add and !list_empty. */
55 : 10 : ok1(!list_empty(ref(&parent.children, parent_count)));
56 : 10 : ok1(parent_count == 5);
57 : 10 : ok1(c2.list.next == &parent.children.n);
58 : 10 : ok1(c2.list.prev == &parent.children.n);
59 : 10 : ok1(parent.children.n.next == &c2.list);
60 : 10 : ok1(parent.children.n.prev == &c2.list);
61 : : /* Test list_check */
62 : 10 : ok1(list_check(ref(&parent.children, parent_count), NULL));
63 : 10 : ok1(parent_count == 6);
64 : :
65 : 10 : c1.name = "c1";
66 : 10 : list_add(ref(&parent.children, parent_count), &c1.list);
67 : 10 : ok1(parent_count == 7);
68 : : /* Test list_add and !list_empty. */
69 : 10 : ok1(!list_empty(ref(&parent.children, parent_count)));
70 : 10 : ok1(parent_count == 8);
71 : 10 : ok1(c2.list.next == &parent.children.n);
72 : 10 : ok1(c2.list.prev == &c1.list);
73 : 10 : ok1(parent.children.n.next == &c1.list);
74 : 10 : ok1(parent.children.n.prev == &c2.list);
75 : 10 : ok1(c1.list.next == &c2.list);
76 : 10 : ok1(c1.list.prev == &parent.children.n);
77 : : /* Test list_check */
78 : 10 : ok1(list_check(ref(&parent.children, parent_count), NULL));
79 : 10 : ok1(parent_count == 9);
80 : :
81 : 10 : c3.name = "c3";
82 : 10 : list_add_tail(ref(&parent.children, parent_count), &c3.list);
83 : 10 : ok1(parent_count == 10);
84 : : /* Test list_add_tail and !list_empty. */
85 : 10 : ok1(!list_empty(ref(&parent.children, parent_count)));
86 : 10 : ok1(parent_count == 11);
87 : 10 : ok1(parent.children.n.next == &c1.list);
88 : 10 : ok1(parent.children.n.prev == &c3.list);
89 : 10 : ok1(c1.list.next == &c2.list);
90 : 10 : ok1(c1.list.prev == &parent.children.n);
91 : 10 : ok1(c2.list.next == &c3.list);
92 : 10 : ok1(c2.list.prev == &c1.list);
93 : 10 : ok1(c3.list.next == &parent.children.n);
94 : 10 : ok1(c3.list.prev == &c2.list);
95 : : /* Test list_check */
96 : 10 : ok1(list_check(ref(&parent.children, parent_count), NULL));
97 : 10 : ok1(parent_count == 12);
98 : :
99 : : /* Test list_check_node */
100 : 10 : ok1(list_check_node(&c1.list, NULL));
101 : 10 : ok1(list_check_node(&c2.list, NULL));
102 : 10 : ok1(list_check_node(&c3.list, NULL));
103 : :
104 : : /* Test list_top */
105 : 10 : ok1(list_top(ref(&parent.children, parent_count), struct child, list) == &c1);
106 : 10 : ok1(parent_count == 13);
107 : :
108 : : /* Test list_tail */
109 : 10 : ok1(list_tail(ref(&parent.children, parent_count), struct child, list) == &c3);
110 : 10 : ok1(parent_count == 14);
111 : :
112 : : /* Test list_for_each. */
113 : 10 : i = 0;
114 : 30 : list_for_each(&parent.children, c, list) {
115 : 30 : switch (i++) {
116 : 10 : case 0:
117 : 10 : ok1(c == &c1);
118 : 10 : break;
119 : 10 : case 1:
120 : 10 : ok1(c == &c2);
121 : 10 : break;
122 : 10 : case 2:
123 : 10 : ok1(c == &c3);
124 : 10 : break;
125 : : }
126 : 30 : if (i > 2)
127 : 10 : break;
128 : : }
129 : 10 : ok1(i == 3);
130 : :
131 : : /* Test list_for_each_safe, list_del and list_del_from. */
132 : 10 : i = 0;
133 : 30 : list_for_each_safe(&parent.children, c, n, list) {
134 : 30 : switch (i++) {
135 : 10 : case 0:
136 : 10 : ok1(c == &c1);
137 : 10 : list_del(ref(&c->list, node_count));
138 : 10 : ok1(node_count == 1);
139 : 10 : break;
140 : 10 : case 1:
141 : 10 : ok1(c == &c2);
142 : 10 : list_del_from(ref(&parent.children, parent_count),
143 : 10 : ref(&c->list, node_count));
144 : 10 : ok1(node_count == 2);
145 : 10 : break;
146 : 10 : case 2:
147 : 10 : ok1(c == &c3);
148 : 10 : list_del_from(ref(&parent.children, parent_count),
149 : 10 : ref(&c->list, node_count));
150 : 10 : ok1(node_count == 3);
151 : 10 : break;
152 : : }
153 : 30 : ok1(list_check(ref(&parent.children, parent_count), NULL));
154 : 30 : if (i > 2)
155 : 10 : break;
156 : : }
157 : 10 : ok1(i == 3);
158 : 10 : ok1(parent_count == 19);
159 : 10 : ok1(list_empty(ref(&parent.children, parent_count)));
160 : 10 : ok1(parent_count == 20);
161 : :
162 : : /* Test list_top/list_tail on empty list. */
163 : 10 : ok1(list_top(ref(&parent.children, parent_count), struct child, list) == NULL);
164 : 10 : ok1(parent_count == 21);
165 : 10 : ok1(list_tail(ref(&parent.children, parent_count), struct child, list) == NULL);
166 : 10 : ok1(parent_count == 22);
167 : 10 : return exit_status();
168 : : }
|