jmap: fix aliasing issues, one real testcase bug
[ccan] / ccan / jmap / test / run-ptridx-type.c
1 #include <ccan/tap/tap.h>
2 #include <ccan/jmap/jmap_type.h>
3 #include <ccan/jmap/jmap.c>
4
5 struct foo;
6 struct idx;
7
8 JMAP_DEFINE_PTRIDX_TYPE(struct idx, struct foo, foo);
9
10 #define NUM 100
11
12 static int cmp_ptr(const void *a, const void *b)
13 {
14         return *(char **)a - *(char **)b;
15 }
16
17 int main(int argc, char *argv[])
18 {
19         struct jmap_foo *map;
20         struct foo *foo[NUM], **foop;
21         struct idx *idx[NUM+1], *index;
22
23         unsigned int i;
24
25         plan_tests(25 + NUM*2 + 6);
26         for (i = 0; i < NUM+1; i++)
27                 foo[i] = malloc(20);
28
29         qsort(foo, NUM, sizeof(foo[0]), cmp_ptr);
30
31         /* idx[i] == foo[i] + 1, for easy checking */
32         for (i = 0; i < NUM+1; i++)
33                 idx[i] = (void *)((char *)foo[i] + 1);
34
35         map = jmap_foo_new();
36         ok1(jmap_foo_error(map) == NULL);
37
38         ok1(jmap_foo_test(map, idx[NUM]) == false);
39         ok1(jmap_foo_get(map, idx[NUM]) == (struct foo *)NULL);
40         ok1(jmap_foo_count(map) == 0);
41         ok1(jmap_foo_first(map) == (struct idx *)NULL);
42         ok1(jmap_foo_del(map, idx[0]) == false);
43
44         /* Set only works on existing cases. */
45         ok1(jmap_foo_set(map, idx[0], foo[0]) == false);
46         ok1(jmap_foo_add(map, idx[0], foo[1]) == true);
47         ok1(jmap_foo_get(map, idx[0]) == foo[1]);
48         ok1(jmap_foo_set(map, idx[0], foo[0]) == true);
49         ok1(jmap_foo_get(map, idx[0]) == foo[0]);
50
51         ok1(jmap_foo_test(map, idx[0]) == true);
52         ok1(jmap_foo_count(map) == 1);
53         ok1(jmap_foo_first(map) == idx[0]);
54         ok1(jmap_foo_next(map, idx[0]) == NULL);
55
56         ok1(jmap_foo_del(map, idx[0]) == true);
57         ok1(jmap_foo_test(map, idx[0]) == false);
58         ok1(jmap_foo_count(map) == 0);
59
60         for (i = 0; i < NUM; i++)
61                 jmap_foo_add(map, idx[i], foo[i]);
62
63         ok1(jmap_foo_count(map) == NUM);
64
65         ok1(jmap_foo_first(map) == idx[0]);
66         ok1(jmap_foo_next(map, idx[0]) == idx[1]);
67         ok1(jmap_foo_next(map, idx[NUM-1]) == NULL);
68
69         ok1(jmap_foo_get(map, idx[0]) == foo[0]);
70         ok1(jmap_foo_get(map, idx[NUM-1]) == foo[NUM-1]);
71         ok1(jmap_foo_get(map, (void *)((char *)idx[NUM-1] + 1)) == NULL);
72
73         /* Reverse values in map. */
74         for (i = 0; i < NUM; i++) {
75                 foop = jmap_foo_getval(map, idx[i]);
76                 ok1(*foop == foo[i]);
77                 *foop = foo[NUM-1-i];
78                 jmap_foo_putval(map, &foop);
79         }
80         for (i = 0; i < NUM; i++)
81                 ok1(jmap_foo_get(map, idx[i]) == foo[NUM-1-i]);
82
83         foop = jmap_foo_firstval(map, &index);
84         ok1(index == idx[0]);
85         ok1(*foop == foo[NUM-1]);
86         jmap_foo_putval(map, &foop);
87
88         foop = jmap_foo_nextval(map, &index);
89         ok1(index == idx[1]);
90         ok1(*foop == foo[NUM-2]);
91         jmap_foo_putval(map, &foop);
92
93         index = idx[NUM-1];
94         foop = jmap_foo_nextval(map, &index);
95         ok1(foop == NULL);
96
97         ok1(jmap_foo_error(map) == NULL);
98         jmap_foo_free(map);
99
100         return exit_status();
101 }