1*4882a593Smuzhiyun /**
2*4882a593Smuzhiyun * Copyright © 2011 Red Hat, Inc.
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Permission is hereby granted, free of charge, to any person obtaining a
5*4882a593Smuzhiyun * copy of this software and associated documentation files (the "Software"),
6*4882a593Smuzhiyun * to deal in the Software without restriction, including without limitation
7*4882a593Smuzhiyun * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*4882a593Smuzhiyun * and/or sell copies of the Software, and to permit persons to whom the
9*4882a593Smuzhiyun * Software is furnished to do so, subject to the following conditions:
10*4882a593Smuzhiyun *
11*4882a593Smuzhiyun * The above copyright notice and this permission notice (including the next
12*4882a593Smuzhiyun * paragraph) shall be included in all copies or substantial portions of the
13*4882a593Smuzhiyun * Software.
14*4882a593Smuzhiyun *
15*4882a593Smuzhiyun * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*4882a593Smuzhiyun * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*4882a593Smuzhiyun * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18*4882a593Smuzhiyun * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*4882a593Smuzhiyun * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*4882a593Smuzhiyun * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21*4882a593Smuzhiyun * DEALINGS IN THE SOFTWARE.
22*4882a593Smuzhiyun */
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun #ifdef HAVE_DIX_CONFIG_H
25*4882a593Smuzhiyun #include <dix-config.h>
26*4882a593Smuzhiyun #endif
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun #include <X11/Xlib.h>
29*4882a593Smuzhiyun #include <list.h>
30*4882a593Smuzhiyun #include <string.h>
31*4882a593Smuzhiyun #include <assert.h>
32*4882a593Smuzhiyun #include <stdlib.h>
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun #include "tests-common.h"
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun struct parent {
37*4882a593Smuzhiyun int a;
38*4882a593Smuzhiyun struct xorg_list children;
39*4882a593Smuzhiyun int b;
40*4882a593Smuzhiyun };
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun struct child {
43*4882a593Smuzhiyun int foo;
44*4882a593Smuzhiyun int bar;
45*4882a593Smuzhiyun struct xorg_list node;
46*4882a593Smuzhiyun };
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun static void
test_xorg_list_init(void)49*4882a593Smuzhiyun test_xorg_list_init(void)
50*4882a593Smuzhiyun {
51*4882a593Smuzhiyun struct parent parent, tmp;
52*4882a593Smuzhiyun
53*4882a593Smuzhiyun memset(&parent, 0, sizeof(parent));
54*4882a593Smuzhiyun parent.a = 0xa5a5a5;
55*4882a593Smuzhiyun parent.b = ~0xa5a5a5;
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun tmp = parent;
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun xorg_list_init(&parent.children);
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun /* test we haven't touched anything else. */
62*4882a593Smuzhiyun assert(parent.a == tmp.a);
63*4882a593Smuzhiyun assert(parent.b == tmp.b);
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun assert(xorg_list_is_empty(&parent.children));
66*4882a593Smuzhiyun }
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun static void
test_xorg_list_add(void)69*4882a593Smuzhiyun test_xorg_list_add(void)
70*4882a593Smuzhiyun {
71*4882a593Smuzhiyun struct parent parent = { 0 };
72*4882a593Smuzhiyun struct child child[3];
73*4882a593Smuzhiyun struct child *c;
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun xorg_list_init(&parent.children);
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun xorg_list_add(&child[0].node, &parent.children);
78*4882a593Smuzhiyun assert(!xorg_list_is_empty(&parent.children));
79*4882a593Smuzhiyun
80*4882a593Smuzhiyun c = xorg_list_first_entry(&parent.children, struct child, node);
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun assert(memcmp(c, &child[0], sizeof(struct child)) == 0);
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun /* note: xorg_list_add prepends */
85*4882a593Smuzhiyun xorg_list_add(&child[1].node, &parent.children);
86*4882a593Smuzhiyun c = xorg_list_first_entry(&parent.children, struct child, node);
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun assert(memcmp(c, &child[1], sizeof(struct child)) == 0);
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun xorg_list_add(&child[2].node, &parent.children);
91*4882a593Smuzhiyun c = xorg_list_first_entry(&parent.children, struct child, node);
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun assert(memcmp(c, &child[2], sizeof(struct child)) == 0);
94*4882a593Smuzhiyun };
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun static void
test_xorg_list_append(void)97*4882a593Smuzhiyun test_xorg_list_append(void)
98*4882a593Smuzhiyun {
99*4882a593Smuzhiyun struct parent parent = { 0 };
100*4882a593Smuzhiyun struct child child[3];
101*4882a593Smuzhiyun struct child *c;
102*4882a593Smuzhiyun int i;
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun xorg_list_init(&parent.children);
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun xorg_list_append(&child[0].node, &parent.children);
107*4882a593Smuzhiyun assert(!xorg_list_is_empty(&parent.children));
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun c = xorg_list_first_entry(&parent.children, struct child, node);
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun assert(memcmp(c, &child[0], sizeof(struct child)) == 0);
112*4882a593Smuzhiyun c = xorg_list_last_entry(&parent.children, struct child, node);
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun assert(memcmp(c, &child[0], sizeof(struct child)) == 0);
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun xorg_list_append(&child[1].node, &parent.children);
117*4882a593Smuzhiyun c = xorg_list_first_entry(&parent.children, struct child, node);
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun assert(memcmp(c, &child[0], sizeof(struct child)) == 0);
120*4882a593Smuzhiyun c = xorg_list_last_entry(&parent.children, struct child, node);
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun assert(memcmp(c, &child[1], sizeof(struct child)) == 0);
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun xorg_list_append(&child[2].node, &parent.children);
125*4882a593Smuzhiyun c = xorg_list_first_entry(&parent.children, struct child, node);
126*4882a593Smuzhiyun
127*4882a593Smuzhiyun assert(memcmp(c, &child[0], sizeof(struct child)) == 0);
128*4882a593Smuzhiyun c = xorg_list_last_entry(&parent.children, struct child, node);
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun assert(memcmp(c, &child[2], sizeof(struct child)) == 0);
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun i = 0;
133*4882a593Smuzhiyun xorg_list_for_each_entry(c, &parent.children, node) {
134*4882a593Smuzhiyun assert(memcmp(c, &child[i++], sizeof(struct child)) == 0);
135*4882a593Smuzhiyun }
136*4882a593Smuzhiyun };
137*4882a593Smuzhiyun
138*4882a593Smuzhiyun static void
test_xorg_list_del(void)139*4882a593Smuzhiyun test_xorg_list_del(void)
140*4882a593Smuzhiyun {
141*4882a593Smuzhiyun struct parent parent = { 0 };
142*4882a593Smuzhiyun struct child child[2];
143*4882a593Smuzhiyun struct child *c;
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun xorg_list_init(&parent.children);
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun xorg_list_add(&child[0].node, &parent.children);
148*4882a593Smuzhiyun assert(!xorg_list_is_empty(&parent.children));
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun xorg_list_del(&parent.children);
151*4882a593Smuzhiyun assert(xorg_list_is_empty(&parent.children));
152*4882a593Smuzhiyun
153*4882a593Smuzhiyun xorg_list_add(&child[0].node, &parent.children);
154*4882a593Smuzhiyun xorg_list_del(&child[0].node);
155*4882a593Smuzhiyun assert(xorg_list_is_empty(&parent.children));
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun xorg_list_add(&child[0].node, &parent.children);
158*4882a593Smuzhiyun xorg_list_add(&child[1].node, &parent.children);
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun c = xorg_list_first_entry(&parent.children, struct child, node);
161*4882a593Smuzhiyun
162*4882a593Smuzhiyun assert(memcmp(c, &child[1], sizeof(struct child)) == 0);
163*4882a593Smuzhiyun
164*4882a593Smuzhiyun /* delete first node */
165*4882a593Smuzhiyun xorg_list_del(&child[1].node);
166*4882a593Smuzhiyun assert(!xorg_list_is_empty(&parent.children));
167*4882a593Smuzhiyun assert(xorg_list_is_empty(&child[1].node));
168*4882a593Smuzhiyun c = xorg_list_first_entry(&parent.children, struct child, node);
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun assert(memcmp(c, &child[0], sizeof(struct child)) == 0);
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun /* delete last node */
173*4882a593Smuzhiyun xorg_list_add(&child[1].node, &parent.children);
174*4882a593Smuzhiyun xorg_list_del(&child[0].node);
175*4882a593Smuzhiyun c = xorg_list_first_entry(&parent.children, struct child, node);
176*4882a593Smuzhiyun
177*4882a593Smuzhiyun assert(memcmp(c, &child[1], sizeof(struct child)) == 0);
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun /* delete list head */
180*4882a593Smuzhiyun xorg_list_add(&child[0].node, &parent.children);
181*4882a593Smuzhiyun xorg_list_del(&parent.children);
182*4882a593Smuzhiyun assert(xorg_list_is_empty(&parent.children));
183*4882a593Smuzhiyun assert(!xorg_list_is_empty(&child[0].node));
184*4882a593Smuzhiyun assert(!xorg_list_is_empty(&child[1].node));
185*4882a593Smuzhiyun }
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun static void
test_xorg_list_for_each(void)188*4882a593Smuzhiyun test_xorg_list_for_each(void)
189*4882a593Smuzhiyun {
190*4882a593Smuzhiyun struct parent parent = { 0 };
191*4882a593Smuzhiyun struct child child[3];
192*4882a593Smuzhiyun struct child *c;
193*4882a593Smuzhiyun int i = 0;
194*4882a593Smuzhiyun
195*4882a593Smuzhiyun xorg_list_init(&parent.children);
196*4882a593Smuzhiyun
197*4882a593Smuzhiyun xorg_list_add(&child[2].node, &parent.children);
198*4882a593Smuzhiyun xorg_list_add(&child[1].node, &parent.children);
199*4882a593Smuzhiyun xorg_list_add(&child[0].node, &parent.children);
200*4882a593Smuzhiyun
201*4882a593Smuzhiyun xorg_list_for_each_entry(c, &parent.children, node) {
202*4882a593Smuzhiyun assert(memcmp(c, &child[i], sizeof(struct child)) == 0);
203*4882a593Smuzhiyun i++;
204*4882a593Smuzhiyun }
205*4882a593Smuzhiyun
206*4882a593Smuzhiyun /* foreach on empty list */
207*4882a593Smuzhiyun xorg_list_del(&parent.children);
208*4882a593Smuzhiyun assert(xorg_list_is_empty(&parent.children));
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun xorg_list_for_each_entry(c, &parent.children, node) {
211*4882a593Smuzhiyun assert(0); /* we must not get here */
212*4882a593Smuzhiyun }
213*4882a593Smuzhiyun }
214*4882a593Smuzhiyun
215*4882a593Smuzhiyun struct foo {
216*4882a593Smuzhiyun char a;
217*4882a593Smuzhiyun struct foo *next;
218*4882a593Smuzhiyun char b;
219*4882a593Smuzhiyun };
220*4882a593Smuzhiyun
221*4882a593Smuzhiyun static void
test_nt_list_init(void)222*4882a593Smuzhiyun test_nt_list_init(void)
223*4882a593Smuzhiyun {
224*4882a593Smuzhiyun struct foo foo;
225*4882a593Smuzhiyun
226*4882a593Smuzhiyun foo.a = 10;
227*4882a593Smuzhiyun foo.b = 20;
228*4882a593Smuzhiyun nt_list_init(&foo, next);
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun assert(foo.a == 10);
231*4882a593Smuzhiyun assert(foo.b == 20);
232*4882a593Smuzhiyun assert(foo.next == NULL);
233*4882a593Smuzhiyun assert(nt_list_next(&foo, next) == NULL);
234*4882a593Smuzhiyun }
235*4882a593Smuzhiyun
236*4882a593Smuzhiyun static void
test_nt_list_append(void)237*4882a593Smuzhiyun test_nt_list_append(void)
238*4882a593Smuzhiyun {
239*4882a593Smuzhiyun int i;
240*4882a593Smuzhiyun struct foo *foo = calloc(10, sizeof(struct foo));
241*4882a593Smuzhiyun struct foo *item;
242*4882a593Smuzhiyun
243*4882a593Smuzhiyun for (item = foo, i = 1; i <= 10; i++, item++) {
244*4882a593Smuzhiyun item->a = i;
245*4882a593Smuzhiyun item->b = i * 2;
246*4882a593Smuzhiyun nt_list_init(item, next);
247*4882a593Smuzhiyun
248*4882a593Smuzhiyun if (item != foo)
249*4882a593Smuzhiyun nt_list_append(item, foo, struct foo, next);
250*4882a593Smuzhiyun }
251*4882a593Smuzhiyun
252*4882a593Smuzhiyun /* Test using nt_list_next */
253*4882a593Smuzhiyun for (item = foo, i = 1; i <= 10; i++, item = nt_list_next(item, next)) {
254*4882a593Smuzhiyun assert(item->a == i);
255*4882a593Smuzhiyun assert(item->b == i * 2);
256*4882a593Smuzhiyun }
257*4882a593Smuzhiyun
258*4882a593Smuzhiyun /* Test using nt_list_for_each_entry */
259*4882a593Smuzhiyun i = 1;
260*4882a593Smuzhiyun nt_list_for_each_entry(item, foo, next) {
261*4882a593Smuzhiyun assert(item->a == i);
262*4882a593Smuzhiyun assert(item->b == i * 2);
263*4882a593Smuzhiyun i++;
264*4882a593Smuzhiyun }
265*4882a593Smuzhiyun assert(i == 11);
266*4882a593Smuzhiyun }
267*4882a593Smuzhiyun
268*4882a593Smuzhiyun static void
test_nt_list_insert(void)269*4882a593Smuzhiyun test_nt_list_insert(void)
270*4882a593Smuzhiyun {
271*4882a593Smuzhiyun int i;
272*4882a593Smuzhiyun struct foo *foo = calloc(10, sizeof(struct foo));
273*4882a593Smuzhiyun struct foo *item;
274*4882a593Smuzhiyun
275*4882a593Smuzhiyun foo->a = 1;
276*4882a593Smuzhiyun foo->b = 2;
277*4882a593Smuzhiyun nt_list_init(foo, next);
278*4882a593Smuzhiyun
279*4882a593Smuzhiyun for (item = &foo[1], i = 10; i > 1; i--, item++) {
280*4882a593Smuzhiyun item->a = i;
281*4882a593Smuzhiyun item->b = i * 2;
282*4882a593Smuzhiyun nt_list_init(item, next);
283*4882a593Smuzhiyun nt_list_insert(item, foo, struct foo, next);
284*4882a593Smuzhiyun }
285*4882a593Smuzhiyun
286*4882a593Smuzhiyun /* Test using nt_list_next */
287*4882a593Smuzhiyun for (item = foo, i = 1; i <= 10; i++, item = nt_list_next(item, next)) {
288*4882a593Smuzhiyun assert(item->a == i);
289*4882a593Smuzhiyun assert(item->b == i * 2);
290*4882a593Smuzhiyun }
291*4882a593Smuzhiyun
292*4882a593Smuzhiyun /* Test using nt_list_for_each_entry */
293*4882a593Smuzhiyun i = 1;
294*4882a593Smuzhiyun nt_list_for_each_entry(item, foo, next) {
295*4882a593Smuzhiyun assert(item->a == i);
296*4882a593Smuzhiyun assert(item->b == i * 2);
297*4882a593Smuzhiyun i++;
298*4882a593Smuzhiyun }
299*4882a593Smuzhiyun assert(i == 11);
300*4882a593Smuzhiyun }
301*4882a593Smuzhiyun
302*4882a593Smuzhiyun static void
test_nt_list_delete(void)303*4882a593Smuzhiyun test_nt_list_delete(void)
304*4882a593Smuzhiyun {
305*4882a593Smuzhiyun int i = 1;
306*4882a593Smuzhiyun struct foo *list = calloc(10, sizeof(struct foo));
307*4882a593Smuzhiyun struct foo *foo = list;
308*4882a593Smuzhiyun struct foo *item, *tmp;
309*4882a593Smuzhiyun struct foo *empty_list = foo;
310*4882a593Smuzhiyun
311*4882a593Smuzhiyun nt_list_init(empty_list, next);
312*4882a593Smuzhiyun nt_list_del(empty_list, empty_list, struct foo, next);
313*4882a593Smuzhiyun
314*4882a593Smuzhiyun assert(!empty_list);
315*4882a593Smuzhiyun
316*4882a593Smuzhiyun for (item = foo, i = 1; i <= 10; i++, item++) {
317*4882a593Smuzhiyun item->a = i;
318*4882a593Smuzhiyun item->b = i * 2;
319*4882a593Smuzhiyun nt_list_init(item, next);
320*4882a593Smuzhiyun
321*4882a593Smuzhiyun if (item != foo)
322*4882a593Smuzhiyun nt_list_append(item, foo, struct foo, next);
323*4882a593Smuzhiyun }
324*4882a593Smuzhiyun
325*4882a593Smuzhiyun i = 0;
326*4882a593Smuzhiyun nt_list_for_each_entry(item, foo, next) {
327*4882a593Smuzhiyun i++;
328*4882a593Smuzhiyun }
329*4882a593Smuzhiyun assert(i == 10);
330*4882a593Smuzhiyun
331*4882a593Smuzhiyun /* delete last item */
332*4882a593Smuzhiyun nt_list_del(&foo[9], foo, struct foo, next);
333*4882a593Smuzhiyun
334*4882a593Smuzhiyun i = 0;
335*4882a593Smuzhiyun nt_list_for_each_entry(item, foo, next) {
336*4882a593Smuzhiyun assert(item->a != 10); /* element 10 is gone now */
337*4882a593Smuzhiyun i++;
338*4882a593Smuzhiyun }
339*4882a593Smuzhiyun assert(i == 9); /* 9 elements left */
340*4882a593Smuzhiyun
341*4882a593Smuzhiyun /* delete second item */
342*4882a593Smuzhiyun nt_list_del(foo->next, foo, struct foo, next);
343*4882a593Smuzhiyun
344*4882a593Smuzhiyun assert(foo->next->a == 3);
345*4882a593Smuzhiyun
346*4882a593Smuzhiyun i = 0;
347*4882a593Smuzhiyun nt_list_for_each_entry(item, foo, next) {
348*4882a593Smuzhiyun assert(item->a != 10); /* element 10 is gone now */
349*4882a593Smuzhiyun assert(item->a != 2); /* element 2 is gone now */
350*4882a593Smuzhiyun i++;
351*4882a593Smuzhiyun }
352*4882a593Smuzhiyun assert(i == 8); /* 9 elements left */
353*4882a593Smuzhiyun
354*4882a593Smuzhiyun item = foo;
355*4882a593Smuzhiyun /* delete first item */
356*4882a593Smuzhiyun nt_list_del(foo, foo, struct foo, next);
357*4882a593Smuzhiyun
358*4882a593Smuzhiyun assert(item != foo);
359*4882a593Smuzhiyun assert(item->next == NULL);
360*4882a593Smuzhiyun assert(foo->a == 3);
361*4882a593Smuzhiyun assert(foo->next->a == 4);
362*4882a593Smuzhiyun
363*4882a593Smuzhiyun nt_list_for_each_entry_safe(item, tmp, foo, next) {
364*4882a593Smuzhiyun nt_list_del(item, foo, struct foo, next);
365*4882a593Smuzhiyun }
366*4882a593Smuzhiyun
367*4882a593Smuzhiyun assert(!foo);
368*4882a593Smuzhiyun assert(!item);
369*4882a593Smuzhiyun
370*4882a593Smuzhiyun free(list);
371*4882a593Smuzhiyun }
372*4882a593Smuzhiyun
373*4882a593Smuzhiyun int
list_test(void)374*4882a593Smuzhiyun list_test(void)
375*4882a593Smuzhiyun {
376*4882a593Smuzhiyun test_xorg_list_init();
377*4882a593Smuzhiyun test_xorg_list_add();
378*4882a593Smuzhiyun test_xorg_list_append();
379*4882a593Smuzhiyun test_xorg_list_del();
380*4882a593Smuzhiyun test_xorg_list_for_each();
381*4882a593Smuzhiyun
382*4882a593Smuzhiyun test_nt_list_init();
383*4882a593Smuzhiyun test_nt_list_append();
384*4882a593Smuzhiyun test_nt_list_insert();
385*4882a593Smuzhiyun test_nt_list_delete();
386*4882a593Smuzhiyun
387*4882a593Smuzhiyun return 0;
388*4882a593Smuzhiyun }
389