135c4bbdfSmrg/**
235c4bbdfSmrg * Copyright © 2011 Red Hat, Inc.
335c4bbdfSmrg *
435c4bbdfSmrg *  Permission is hereby granted, free of charge, to any person obtaining a
535c4bbdfSmrg *  copy of this software and associated documentation files (the "Software"),
635c4bbdfSmrg *  to deal in the Software without restriction, including without limitation
735c4bbdfSmrg *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
835c4bbdfSmrg *  and/or sell copies of the Software, and to permit persons to whom the
935c4bbdfSmrg *  Software is furnished to do so, subject to the following conditions:
1035c4bbdfSmrg *
1135c4bbdfSmrg *  The above copyright notice and this permission notice (including the next
1235c4bbdfSmrg *  paragraph) shall be included in all copies or substantial portions of the
1335c4bbdfSmrg *  Software.
1435c4bbdfSmrg *
1535c4bbdfSmrg *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1635c4bbdfSmrg *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1735c4bbdfSmrg *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1835c4bbdfSmrg *  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1935c4bbdfSmrg *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2035c4bbdfSmrg *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2135c4bbdfSmrg *  DEALINGS IN THE SOFTWARE.
2235c4bbdfSmrg */
2335c4bbdfSmrg
24ed6184dfSmrg/* Test relies on assert() */
25ed6184dfSmrg#undef NDEBUG
26ed6184dfSmrg
2735c4bbdfSmrg#ifdef HAVE_DIX_CONFIG_H
2835c4bbdfSmrg#include <dix-config.h>
2935c4bbdfSmrg#endif
3035c4bbdfSmrg
3135c4bbdfSmrg#include <X11/Xlib.h>
3235c4bbdfSmrg#include <list.h>
3335c4bbdfSmrg#include <string.h>
3435c4bbdfSmrg#include <assert.h>
3535c4bbdfSmrg#include <stdlib.h>
3635c4bbdfSmrg
371b5d61b8Smrg#include "tests-common.h"
381b5d61b8Smrg
3935c4bbdfSmrgstruct parent {
4035c4bbdfSmrg    int a;
4135c4bbdfSmrg    struct xorg_list children;
4235c4bbdfSmrg    int b;
4335c4bbdfSmrg};
4435c4bbdfSmrg
4535c4bbdfSmrgstruct child {
4635c4bbdfSmrg    int foo;
4735c4bbdfSmrg    int bar;
4835c4bbdfSmrg    struct xorg_list node;
4935c4bbdfSmrg};
5035c4bbdfSmrg
5135c4bbdfSmrgstatic void
5235c4bbdfSmrgtest_xorg_list_init(void)
5335c4bbdfSmrg{
5435c4bbdfSmrg    struct parent parent, tmp;
5535c4bbdfSmrg
5635c4bbdfSmrg    memset(&parent, 0, sizeof(parent));
5735c4bbdfSmrg    parent.a = 0xa5a5a5;
5835c4bbdfSmrg    parent.b = ~0xa5a5a5;
5935c4bbdfSmrg
6035c4bbdfSmrg    tmp = parent;
6135c4bbdfSmrg
6235c4bbdfSmrg    xorg_list_init(&parent.children);
6335c4bbdfSmrg
6435c4bbdfSmrg    /* test we haven't touched anything else. */
6535c4bbdfSmrg    assert(parent.a == tmp.a);
6635c4bbdfSmrg    assert(parent.b == tmp.b);
6735c4bbdfSmrg
6835c4bbdfSmrg    assert(xorg_list_is_empty(&parent.children));
6935c4bbdfSmrg}
7035c4bbdfSmrg
7135c4bbdfSmrgstatic void
7235c4bbdfSmrgtest_xorg_list_add(void)
7335c4bbdfSmrg{
7435c4bbdfSmrg    struct parent parent = { 0 };
7535c4bbdfSmrg    struct child child[3];
7635c4bbdfSmrg    struct child *c;
7735c4bbdfSmrg
7835c4bbdfSmrg    xorg_list_init(&parent.children);
7935c4bbdfSmrg
8035c4bbdfSmrg    xorg_list_add(&child[0].node, &parent.children);
8135c4bbdfSmrg    assert(!xorg_list_is_empty(&parent.children));
8235c4bbdfSmrg
8335c4bbdfSmrg    c = xorg_list_first_entry(&parent.children, struct child, node);
8435c4bbdfSmrg
8535c4bbdfSmrg    assert(memcmp(c, &child[0], sizeof(struct child)) == 0);
8635c4bbdfSmrg
8735c4bbdfSmrg    /* note: xorg_list_add prepends */
8835c4bbdfSmrg    xorg_list_add(&child[1].node, &parent.children);
8935c4bbdfSmrg    c = xorg_list_first_entry(&parent.children, struct child, node);
9035c4bbdfSmrg
9135c4bbdfSmrg    assert(memcmp(c, &child[1], sizeof(struct child)) == 0);
9235c4bbdfSmrg
9335c4bbdfSmrg    xorg_list_add(&child[2].node, &parent.children);
9435c4bbdfSmrg    c = xorg_list_first_entry(&parent.children, struct child, node);
9535c4bbdfSmrg
9635c4bbdfSmrg    assert(memcmp(c, &child[2], sizeof(struct child)) == 0);
9735c4bbdfSmrg};
9835c4bbdfSmrg
9935c4bbdfSmrgstatic void
10035c4bbdfSmrgtest_xorg_list_append(void)
10135c4bbdfSmrg{
10235c4bbdfSmrg    struct parent parent = { 0 };
10335c4bbdfSmrg    struct child child[3];
10435c4bbdfSmrg    struct child *c;
10535c4bbdfSmrg    int i;
10635c4bbdfSmrg
10735c4bbdfSmrg    xorg_list_init(&parent.children);
10835c4bbdfSmrg
10935c4bbdfSmrg    xorg_list_append(&child[0].node, &parent.children);
11035c4bbdfSmrg    assert(!xorg_list_is_empty(&parent.children));
11135c4bbdfSmrg
11235c4bbdfSmrg    c = xorg_list_first_entry(&parent.children, struct child, node);
11335c4bbdfSmrg
11435c4bbdfSmrg    assert(memcmp(c, &child[0], sizeof(struct child)) == 0);
11535c4bbdfSmrg    c = xorg_list_last_entry(&parent.children, struct child, node);
11635c4bbdfSmrg
11735c4bbdfSmrg    assert(memcmp(c, &child[0], sizeof(struct child)) == 0);
11835c4bbdfSmrg
11935c4bbdfSmrg    xorg_list_append(&child[1].node, &parent.children);
12035c4bbdfSmrg    c = xorg_list_first_entry(&parent.children, struct child, node);
12135c4bbdfSmrg
12235c4bbdfSmrg    assert(memcmp(c, &child[0], sizeof(struct child)) == 0);
12335c4bbdfSmrg    c = xorg_list_last_entry(&parent.children, struct child, node);
12435c4bbdfSmrg
12535c4bbdfSmrg    assert(memcmp(c, &child[1], sizeof(struct child)) == 0);
12635c4bbdfSmrg
12735c4bbdfSmrg    xorg_list_append(&child[2].node, &parent.children);
12835c4bbdfSmrg    c = xorg_list_first_entry(&parent.children, struct child, node);
12935c4bbdfSmrg
13035c4bbdfSmrg    assert(memcmp(c, &child[0], sizeof(struct child)) == 0);
13135c4bbdfSmrg    c = xorg_list_last_entry(&parent.children, struct child, node);
13235c4bbdfSmrg
13335c4bbdfSmrg    assert(memcmp(c, &child[2], sizeof(struct child)) == 0);
13435c4bbdfSmrg
13535c4bbdfSmrg    i = 0;
13635c4bbdfSmrg    xorg_list_for_each_entry(c, &parent.children, node) {
13735c4bbdfSmrg        assert(memcmp(c, &child[i++], sizeof(struct child)) == 0);
13835c4bbdfSmrg    }
13935c4bbdfSmrg};
14035c4bbdfSmrg
14135c4bbdfSmrgstatic void
14235c4bbdfSmrgtest_xorg_list_del(void)
14335c4bbdfSmrg{
14435c4bbdfSmrg    struct parent parent = { 0 };
14535c4bbdfSmrg    struct child child[2];
14635c4bbdfSmrg    struct child *c;
14735c4bbdfSmrg
14835c4bbdfSmrg    xorg_list_init(&parent.children);
14935c4bbdfSmrg
15035c4bbdfSmrg    xorg_list_add(&child[0].node, &parent.children);
15135c4bbdfSmrg    assert(!xorg_list_is_empty(&parent.children));
15235c4bbdfSmrg
15335c4bbdfSmrg    xorg_list_del(&parent.children);
15435c4bbdfSmrg    assert(xorg_list_is_empty(&parent.children));
15535c4bbdfSmrg
15635c4bbdfSmrg    xorg_list_add(&child[0].node, &parent.children);
15735c4bbdfSmrg    xorg_list_del(&child[0].node);
15835c4bbdfSmrg    assert(xorg_list_is_empty(&parent.children));
15935c4bbdfSmrg
16035c4bbdfSmrg    xorg_list_add(&child[0].node, &parent.children);
16135c4bbdfSmrg    xorg_list_add(&child[1].node, &parent.children);
16235c4bbdfSmrg
16335c4bbdfSmrg    c = xorg_list_first_entry(&parent.children, struct child, node);
16435c4bbdfSmrg
16535c4bbdfSmrg    assert(memcmp(c, &child[1], sizeof(struct child)) == 0);
16635c4bbdfSmrg
16735c4bbdfSmrg    /* delete first node */
16835c4bbdfSmrg    xorg_list_del(&child[1].node);
16935c4bbdfSmrg    assert(!xorg_list_is_empty(&parent.children));
17035c4bbdfSmrg    assert(xorg_list_is_empty(&child[1].node));
17135c4bbdfSmrg    c = xorg_list_first_entry(&parent.children, struct child, node);
17235c4bbdfSmrg
17335c4bbdfSmrg    assert(memcmp(c, &child[0], sizeof(struct child)) == 0);
17435c4bbdfSmrg
17535c4bbdfSmrg    /* delete last node */
17635c4bbdfSmrg    xorg_list_add(&child[1].node, &parent.children);
17735c4bbdfSmrg    xorg_list_del(&child[0].node);
17835c4bbdfSmrg    c = xorg_list_first_entry(&parent.children, struct child, node);
17935c4bbdfSmrg
18035c4bbdfSmrg    assert(memcmp(c, &child[1], sizeof(struct child)) == 0);
18135c4bbdfSmrg
18235c4bbdfSmrg    /* delete list head */
18335c4bbdfSmrg    xorg_list_add(&child[0].node, &parent.children);
18435c4bbdfSmrg    xorg_list_del(&parent.children);
18535c4bbdfSmrg    assert(xorg_list_is_empty(&parent.children));
18635c4bbdfSmrg    assert(!xorg_list_is_empty(&child[0].node));
18735c4bbdfSmrg    assert(!xorg_list_is_empty(&child[1].node));
18835c4bbdfSmrg}
18935c4bbdfSmrg
19035c4bbdfSmrgstatic void
19135c4bbdfSmrgtest_xorg_list_for_each(void)
19235c4bbdfSmrg{
19335c4bbdfSmrg    struct parent parent = { 0 };
19435c4bbdfSmrg    struct child child[3];
19535c4bbdfSmrg    struct child *c;
19635c4bbdfSmrg    int i = 0;
19735c4bbdfSmrg
19835c4bbdfSmrg    xorg_list_init(&parent.children);
19935c4bbdfSmrg
20035c4bbdfSmrg    xorg_list_add(&child[2].node, &parent.children);
20135c4bbdfSmrg    xorg_list_add(&child[1].node, &parent.children);
20235c4bbdfSmrg    xorg_list_add(&child[0].node, &parent.children);
20335c4bbdfSmrg
20435c4bbdfSmrg    xorg_list_for_each_entry(c, &parent.children, node) {
20535c4bbdfSmrg        assert(memcmp(c, &child[i], sizeof(struct child)) == 0);
20635c4bbdfSmrg        i++;
20735c4bbdfSmrg    }
20835c4bbdfSmrg
20935c4bbdfSmrg    /* foreach on empty list */
21035c4bbdfSmrg    xorg_list_del(&parent.children);
21135c4bbdfSmrg    assert(xorg_list_is_empty(&parent.children));
21235c4bbdfSmrg
21335c4bbdfSmrg    xorg_list_for_each_entry(c, &parent.children, node) {
21435c4bbdfSmrg        assert(0);              /* we must not get here */
21535c4bbdfSmrg    }
21635c4bbdfSmrg}
21735c4bbdfSmrg
21835c4bbdfSmrgstruct foo {
21935c4bbdfSmrg    char a;
22035c4bbdfSmrg    struct foo *next;
22135c4bbdfSmrg    char b;
22235c4bbdfSmrg};
22335c4bbdfSmrg
22435c4bbdfSmrgstatic void
22535c4bbdfSmrgtest_nt_list_init(void)
22635c4bbdfSmrg{
22735c4bbdfSmrg    struct foo foo;
22835c4bbdfSmrg
22935c4bbdfSmrg    foo.a = 10;
23035c4bbdfSmrg    foo.b = 20;
23135c4bbdfSmrg    nt_list_init(&foo, next);
23235c4bbdfSmrg
23335c4bbdfSmrg    assert(foo.a == 10);
23435c4bbdfSmrg    assert(foo.b == 20);
23535c4bbdfSmrg    assert(foo.next == NULL);
23635c4bbdfSmrg    assert(nt_list_next(&foo, next) == NULL);
23735c4bbdfSmrg}
23835c4bbdfSmrg
23935c4bbdfSmrgstatic void
24035c4bbdfSmrgtest_nt_list_append(void)
24135c4bbdfSmrg{
24235c4bbdfSmrg    int i;
24335c4bbdfSmrg    struct foo *foo = calloc(10, sizeof(struct foo));
24435c4bbdfSmrg    struct foo *item;
24535c4bbdfSmrg
24635c4bbdfSmrg    for (item = foo, i = 1; i <= 10; i++, item++) {
24735c4bbdfSmrg        item->a = i;
24835c4bbdfSmrg        item->b = i * 2;
24935c4bbdfSmrg        nt_list_init(item, next);
25035c4bbdfSmrg
25135c4bbdfSmrg        if (item != foo)
25235c4bbdfSmrg            nt_list_append(item, foo, struct foo, next);
25335c4bbdfSmrg    }
25435c4bbdfSmrg
25535c4bbdfSmrg    /* Test using nt_list_next */
25635c4bbdfSmrg    for (item = foo, i = 1; i <= 10; i++, item = nt_list_next(item, next)) {
25735c4bbdfSmrg        assert(item->a == i);
25835c4bbdfSmrg        assert(item->b == i * 2);
25935c4bbdfSmrg    }
26035c4bbdfSmrg
26135c4bbdfSmrg    /* Test using nt_list_for_each_entry */
26235c4bbdfSmrg    i = 1;
26335c4bbdfSmrg    nt_list_for_each_entry(item, foo, next) {
26435c4bbdfSmrg        assert(item->a == i);
26535c4bbdfSmrg        assert(item->b == i * 2);
26635c4bbdfSmrg        i++;
26735c4bbdfSmrg    }
26835c4bbdfSmrg    assert(i == 11);
26935c4bbdfSmrg}
27035c4bbdfSmrg
27135c4bbdfSmrgstatic void
27235c4bbdfSmrgtest_nt_list_insert(void)
27335c4bbdfSmrg{
27435c4bbdfSmrg    int i;
27535c4bbdfSmrg    struct foo *foo = calloc(10, sizeof(struct foo));
27635c4bbdfSmrg    struct foo *item;
27735c4bbdfSmrg
27835c4bbdfSmrg    foo->a = 1;
27935c4bbdfSmrg    foo->b = 2;
28035c4bbdfSmrg    nt_list_init(foo, next);
28135c4bbdfSmrg
28235c4bbdfSmrg    for (item = &foo[1], i = 10; i > 1; i--, item++) {
28335c4bbdfSmrg        item->a = i;
28435c4bbdfSmrg        item->b = i * 2;
28535c4bbdfSmrg        nt_list_init(item, next);
28635c4bbdfSmrg        nt_list_insert(item, foo, struct foo, next);
28735c4bbdfSmrg    }
28835c4bbdfSmrg
28935c4bbdfSmrg    /* Test using nt_list_next */
29035c4bbdfSmrg    for (item = foo, i = 1; i <= 10; i++, item = nt_list_next(item, next)) {
29135c4bbdfSmrg        assert(item->a == i);
29235c4bbdfSmrg        assert(item->b == i * 2);
29335c4bbdfSmrg    }
29435c4bbdfSmrg
29535c4bbdfSmrg    /* Test using nt_list_for_each_entry */
29635c4bbdfSmrg    i = 1;
29735c4bbdfSmrg    nt_list_for_each_entry(item, foo, next) {
29835c4bbdfSmrg        assert(item->a == i);
29935c4bbdfSmrg        assert(item->b == i * 2);
30035c4bbdfSmrg        i++;
30135c4bbdfSmrg    }
30235c4bbdfSmrg    assert(i == 11);
30335c4bbdfSmrg}
30435c4bbdfSmrg
30535c4bbdfSmrgstatic void
30635c4bbdfSmrgtest_nt_list_delete(void)
30735c4bbdfSmrg{
30835c4bbdfSmrg    int i = 1;
30935c4bbdfSmrg    struct foo *list = calloc(10, sizeof(struct foo));
31035c4bbdfSmrg    struct foo *foo = list;
31135c4bbdfSmrg    struct foo *item, *tmp;
31235c4bbdfSmrg    struct foo *empty_list = foo;
31335c4bbdfSmrg
31435c4bbdfSmrg    nt_list_init(empty_list, next);
31535c4bbdfSmrg    nt_list_del(empty_list, empty_list, struct foo, next);
31635c4bbdfSmrg
31735c4bbdfSmrg    assert(!empty_list);
31835c4bbdfSmrg
31935c4bbdfSmrg    for (item = foo, i = 1; i <= 10; i++, item++) {
32035c4bbdfSmrg        item->a = i;
32135c4bbdfSmrg        item->b = i * 2;
32235c4bbdfSmrg        nt_list_init(item, next);
32335c4bbdfSmrg
32435c4bbdfSmrg        if (item != foo)
32535c4bbdfSmrg            nt_list_append(item, foo, struct foo, next);
32635c4bbdfSmrg    }
32735c4bbdfSmrg
32835c4bbdfSmrg    i = 0;
32935c4bbdfSmrg    nt_list_for_each_entry(item, foo, next) {
33035c4bbdfSmrg        i++;
33135c4bbdfSmrg    }
33235c4bbdfSmrg    assert(i == 10);
33335c4bbdfSmrg
33435c4bbdfSmrg    /* delete last item */
33535c4bbdfSmrg    nt_list_del(&foo[9], foo, struct foo, next);
33635c4bbdfSmrg
33735c4bbdfSmrg    i = 0;
33835c4bbdfSmrg    nt_list_for_each_entry(item, foo, next) {
33935c4bbdfSmrg        assert(item->a != 10);  /* element 10 is gone now */
34035c4bbdfSmrg        i++;
34135c4bbdfSmrg    }
34235c4bbdfSmrg    assert(i == 9);             /* 9 elements left */
34335c4bbdfSmrg
34435c4bbdfSmrg    /* delete second item */
34535c4bbdfSmrg    nt_list_del(foo->next, foo, struct foo, next);
34635c4bbdfSmrg
34735c4bbdfSmrg    assert(foo->next->a == 3);
34835c4bbdfSmrg
34935c4bbdfSmrg    i = 0;
35035c4bbdfSmrg    nt_list_for_each_entry(item, foo, next) {
35135c4bbdfSmrg        assert(item->a != 10);  /* element 10 is gone now */
35235c4bbdfSmrg        assert(item->a != 2);   /* element 2 is gone now */
35335c4bbdfSmrg        i++;
35435c4bbdfSmrg    }
35535c4bbdfSmrg    assert(i == 8);             /* 9 elements left */
35635c4bbdfSmrg
35735c4bbdfSmrg    item = foo;
35835c4bbdfSmrg    /* delete first item */
35935c4bbdfSmrg    nt_list_del(foo, foo, struct foo, next);
36035c4bbdfSmrg
36135c4bbdfSmrg    assert(item != foo);
36235c4bbdfSmrg    assert(item->next == NULL);
36335c4bbdfSmrg    assert(foo->a == 3);
36435c4bbdfSmrg    assert(foo->next->a == 4);
36535c4bbdfSmrg
36635c4bbdfSmrg    nt_list_for_each_entry_safe(item, tmp, foo, next) {
36735c4bbdfSmrg        nt_list_del(item, foo, struct foo, next);
36835c4bbdfSmrg    }
36935c4bbdfSmrg
37035c4bbdfSmrg    assert(!foo);
37135c4bbdfSmrg    assert(!item);
37235c4bbdfSmrg
37335c4bbdfSmrg    free(list);
37435c4bbdfSmrg}
37535c4bbdfSmrg
37635c4bbdfSmrgint
3771b5d61b8Smrglist_test(void)
37835c4bbdfSmrg{
37935c4bbdfSmrg    test_xorg_list_init();
38035c4bbdfSmrg    test_xorg_list_add();
38135c4bbdfSmrg    test_xorg_list_append();
38235c4bbdfSmrg    test_xorg_list_del();
38335c4bbdfSmrg    test_xorg_list_for_each();
38435c4bbdfSmrg
38535c4bbdfSmrg    test_nt_list_init();
38635c4bbdfSmrg    test_nt_list_append();
38735c4bbdfSmrg    test_nt_list_insert();
38835c4bbdfSmrg    test_nt_list_delete();
38935c4bbdfSmrg
39035c4bbdfSmrg    return 0;
39135c4bbdfSmrg}
392