compiler: RETURNS_NONNULL macro
[ccan] / ccan / list / test / run-check-corrupt.c
1 #include <setjmp.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <stdarg.h>
5 #include <string.h>
6 #include <err.h>
7
8 /* We don't actually want it to exit... */
9 static jmp_buf aborted;
10 #define abort() longjmp(aborted, 1)
11
12 #define fprintf my_fprintf
13 static char printf_buffer[1000];
14
15 static int my_fprintf(FILE *stream, const char *format, ...)
16 {
17         va_list ap;
18         int ret;
19         (void)stream;
20         va_start(ap, format);
21         ret = vsprintf(printf_buffer, format, ap);
22         va_end(ap);
23         return ret;
24 }
25
26 #include <ccan/list/list.h>
27 #include <ccan/tap/tap.h>
28 #include <ccan/list/list.c>
29
30 int main(void)
31 {
32         struct list_head list;
33         struct list_node n1;
34         char expect[100];
35
36         plan_tests(9);
37         /* Empty list. */
38         list.n.next = &list.n;
39         list.n.prev = &list.n;
40         ok1(list_check(&list, NULL) == &list);
41
42         /* Bad back ptr */
43         list.n.prev = &n1;
44         /* Non-aborting version. */
45         ok1(list_check(&list, NULL) == NULL);
46
47         /* Aborting version. */
48         sprintf(expect, "test message: prev corrupt in node %p (0) of %p\n",
49                 &list, &list);
50         if (setjmp(aborted) == 0) {
51                 list_check(&list, "test message");
52                 fail("list_check on empty with bad back ptr didn't fail!");
53         } else {
54                 ok1(strcmp(printf_buffer, expect) == 0);
55         }
56
57         /* n1 in list. */
58         list.n.next = &n1;
59         list.n.prev = &n1;
60         n1.prev = &list.n;
61         n1.next = &list.n;
62         ok1(list_check(&list, NULL) == &list);
63         ok1(list_check_node(&n1, NULL) == &n1);
64
65         /* Bad back ptr */
66         n1.prev = &n1;
67         ok1(list_check(&list, NULL) == NULL);
68         ok1(list_check_node(&n1, NULL) == NULL);
69
70         /* Aborting version. */
71         sprintf(expect, "test message: prev corrupt in node %p (1) of %p\n",
72                 &n1, &list);
73         if (setjmp(aborted) == 0) {
74                 list_check(&list, "test message");
75                 fail("list_check on n1 bad back ptr didn't fail!");
76         } else {
77                 ok1(strcmp(printf_buffer, expect) == 0);
78         }
79
80         sprintf(expect, "test message: prev corrupt in node %p (0) of %p\n",
81                 &n1, &n1);
82         if (setjmp(aborted) == 0) {
83                 list_check_node(&n1, "test message");
84                 fail("list_check_node on n1 bad back ptr didn't fail!");
85         } else {
86                 ok1(strcmp(printf_buffer, expect) == 0);
87         }
88
89         return exit_status();
90 }