tal: new module.
[ccan] / ccan / tal / test / run-test-backend.c
1 #include <stdlib.h>
2 #include <stdbool.h>
3
4 /* Make sure it always uses our allocation/resize/free fns! */
5 static bool my_alloc_called;
6
7 static void *my_alloc(size_t len)
8 {
9         my_alloc_called = true;
10         return (char *)malloc(len + 16) + 16;
11 }
12
13 static void my_free(void *p)
14 {
15         return free((char *)p - 16);
16 }
17
18 static void *my_realloc(void *old, size_t new_size)
19 {
20         return (char *)realloc((char *)old - 16, new_size + 16) + 16;
21 }
22
23 #define free ((void (*)(void *))abort)
24 #define malloc ((void *(*)(size_t))abort)
25 #define realloc ((void *(*)(void *, size_t))abort)
26
27 #include <ccan/tal/tal.h>
28 #include <ccan/tal/tal.c>
29 #include <ccan/tap/tap.h>
30
31 #define NUM_ALLOCS 1000
32
33 static void destroy_p(void *p)
34 {
35 }
36
37 int main(void)
38 {
39         void *p, *c[NUM_ALLOCS];
40         int i;
41         char *name;
42
43         /* Mostly we rely on the allocator (or valgrind) crashing. */
44         plan_tests(1);
45
46         tal_set_backend(my_alloc, my_realloc, my_free, NULL);
47
48         p = tal(NULL, char);
49         ok1(my_alloc_called);
50
51         /* Adding properties makes us allocated. */
52         tal_add_destructor(p, destroy_p);
53
54         tal_set_name(p, "test");
55         name = tal_asprintf(NULL, "test2");
56         tal_set_name(p, name);
57         /* makes us free old name */
58         tal_set_name(p, name);
59         tal_free(name);
60
61         /* Add lots of children. */
62         for (i = 0; i < NUM_ALLOCS; i++)
63                 c[i] = tal(p, char);
64
65         /* Now steal a few. */
66         for (i = 1; i < NUM_ALLOCS / 2; i++)
67                 tal_steal(c[0], c[i]);
68
69         /* Now free individual ones.. */
70         for (i = NUM_ALLOCS / 2; i < NUM_ALLOCS; i++)
71                 tal_free(c[i]);
72
73         /* Finally, free the parent. */
74         tal_free(p);
75
76         return exit_status();
77 }