compiler: RETURNS_NONNULL macro
[ccan] / ccan / jmap / test / run-ptridx-type.c
1 #include <ccan/tap/tap.h>
2 #include <ccan/jmap/jmap.c>
3
4 struct foo;
5 struct idx;
6
7 struct jmap_foo {
8         JMAP_MEMBERS(struct idx *, struct foo *);
9 };
10
11 #define NUM 100
12
13 static int cmp_ptr(const void *a, const void *b)
14 {
15         return *(char **)a - *(char **)b;
16 }
17
18 int main(int argc, char *argv[])
19 {
20         struct jmap_foo *map;
21         struct foo *foo[NUM+1], **foop;
22         struct idx *idx[NUM+1], *index;
23
24         unsigned int i;
25
26         plan_tests(25 + NUM*2 + 6);
27         for (i = 0; i < NUM+1; i++)
28                 foo[i] = malloc(20);
29
30         qsort(foo, NUM, sizeof(foo[0]), cmp_ptr);
31
32         /* idx[i] == foo[i] + 1, for easy checking */
33         for (i = 0; i < NUM+1; i++)
34                 idx[i] = (void *)((char *)foo[i] + 1);
35
36         map = jmap_new(struct jmap_foo);
37         ok1(jmap_error(map) == NULL);
38
39         ok1(jmap_test(map, idx[NUM]) == false);
40         ok1(jmap_get(map, idx[NUM]) == (struct foo *)NULL);
41         ok1(jmap_count(map) == 0);
42         ok1(jmap_first(map) == (struct idx *)NULL);
43         ok1(jmap_del(map, idx[0]) == false);
44
45         /* Set only works on existing cases. */
46         ok1(jmap_set(map, idx[0], foo[0]) == false);
47         ok1(jmap_add(map, idx[0], foo[1]) == true);
48         ok1(jmap_get(map, idx[0]) == foo[1]);
49         ok1(jmap_set(map, idx[0], foo[0]) == true);
50         ok1(jmap_get(map, idx[0]) == foo[0]);
51
52         ok1(jmap_test(map, idx[0]) == true);
53         ok1(jmap_count(map) == 1);
54         ok1(jmap_first(map) == idx[0]);
55         ok1(jmap_next(map, idx[0]) == NULL);
56
57         ok1(jmap_del(map, idx[0]) == true);
58         ok1(jmap_test(map, idx[0]) == false);
59         ok1(jmap_count(map) == 0);
60
61         for (i = 0; i < NUM; i++)
62                 jmap_add(map, idx[i], foo[i]);
63
64         ok1(jmap_count(map) == NUM);
65
66         ok1(jmap_first(map) == idx[0]);
67         ok1(jmap_next(map, idx[0]) == idx[1]);
68         ok1(jmap_next(map, idx[NUM-1]) == NULL);
69
70         ok1(jmap_get(map, idx[0]) == foo[0]);
71         ok1(jmap_get(map, idx[NUM-1]) == foo[NUM-1]);
72         ok1(jmap_get(map, (void *)((char *)idx[NUM-1] + 1)) == NULL);
73
74         /* Reverse values in map. */
75         for (i = 0; i < NUM; i++) {
76                 foop = jmap_getval(map, idx[i]);
77                 ok1(*foop == foo[i]);
78                 *foop = foo[NUM-1-i];
79                 jmap_putval(map, &foop);
80         }
81         for (i = 0; i < NUM; i++)
82                 ok1(jmap_get(map, idx[i]) == foo[NUM-1-i]);
83
84         foop = jmap_firstval(map, &index);
85         ok1(index == idx[0]);
86         ok1(*foop == foo[NUM-1]);
87         jmap_putval(map, &foop);
88
89         foop = jmap_nextval(map, &index);
90         ok1(index == idx[1]);
91         ok1(*foop == foo[NUM-2]);
92         jmap_putval(map, &foop);
93
94         index = idx[NUM-1];
95         foop = jmap_nextval(map, &index);
96         ok1(foop == NULL);
97
98         ok1(jmap_error(map) == NULL);
99         jmap_free(map);
100
101         for (i = 0; i < NUM+1; i++)
102                 free(foo[i]);
103
104         return exit_status();
105 }