cdump: new module.
[ccan] / ccan / cdump / test / run.c
1 #include <ccan/cdump/cdump.h>
2 /* Include the C files directly. */
3 #include <ccan/cdump/cdump.c>
4 #include <ccan/tap/tap.h>
5
6 int main(void)
7 {
8         struct cdump_definitions *defs;
9         const struct cdump_type *t, *p;
10         char *ctx = tal(NULL, char), *problems;
11
12         /* This is how many tests you plan to run */
13         plan_tests(94);
14
15         defs = cdump_extract(ctx, "enum foo { BAR };", NULL);
16         ok1(defs);
17         ok1(tal_parent(defs) == ctx);
18
19         ok1(strmap_empty(&defs->structs));
20         ok1(strmap_empty(&defs->unions));
21         t = strmap_get(&defs->enums, "foo");
22         ok1(t);
23         ok1(t->kind == CDUMP_ENUM);
24         ok1(streq(t->name, "foo"));
25         ok1(tal_count(t->u.enum_vals) == 1);
26         ok1(streq(t->u.enum_vals[0].name, "BAR"));
27         ok1(!t->u.enum_vals[0].value);
28
29         defs = cdump_extract(ctx, "enum foo { BAR = 7 };", &problems);
30         ok1(defs);
31         ok1(tal_parent(defs) == ctx);
32         ok1(!problems);
33
34         ok1(strmap_empty(&defs->structs));
35         ok1(strmap_empty(&defs->unions));
36         t = strmap_get(&defs->enums, "foo");
37         ok1(t);
38         ok1(t->kind == CDUMP_ENUM);
39         ok1(streq(t->name, "foo"));
40         ok1(tal_count(t->u.enum_vals) == 1);
41         ok1(streq(t->u.enum_vals[0].name, "BAR"));
42         ok1(streq(t->u.enum_vals[0].value, "7"));
43
44         defs = cdump_extract(ctx, "enum foo { BAR = 7, BAZ, FUZZ };", &problems);
45         ok1(defs);
46         ok1(tal_parent(defs) == ctx);
47         ok1(!problems);
48
49         ok1(strmap_empty(&defs->structs));
50         ok1(strmap_empty(&defs->unions));
51         t = strmap_get(&defs->enums, "foo");
52         ok1(t);
53         ok1(t->kind == CDUMP_ENUM);
54         ok1(streq(t->name, "foo"));
55         ok1(tal_count(t->u.enum_vals) == 3);
56         ok1(streq(t->u.enum_vals[0].name, "BAR"));
57         ok1(streq(t->u.enum_vals[0].value, "7"));
58         ok1(streq(t->u.enum_vals[1].name, "BAZ"));
59         ok1(!t->u.enum_vals[1].value);
60         ok1(streq(t->u.enum_vals[2].name, "FUZZ"));
61         ok1(!t->u.enum_vals[2].value);
62
63         defs = cdump_extract(ctx, "struct foo { int x; };", &problems);
64         ok1(defs);
65         ok1(tal_parent(defs) == ctx);
66         ok1(!problems);
67
68         ok1(strmap_empty(&defs->enums));
69         ok1(strmap_empty(&defs->unions));
70         t = strmap_get(&defs->structs, "foo");
71         ok1(t);
72         ok1(t->kind == CDUMP_STRUCT);
73         ok1(streq(t->name, "foo"));
74         ok1(tal_count(t->u.members) == 1);
75         ok1(streq(t->u.members[0].name, "x"));
76         ok1(t->u.members[0].type->kind == CDUMP_UNKNOWN);
77         ok1(streq(t->u.members[0].type->name, "int"));
78
79         defs = cdump_extract(ctx, "struct foo { int x[5<< 1]; struct foo *next; struct unknown **ptrs[10]; };", &problems);
80         ok1(defs);
81         ok1(tal_parent(defs) == ctx);
82         ok1(!problems);
83
84         ok1(strmap_empty(&defs->enums));
85         ok1(strmap_empty(&defs->unions));
86         t = strmap_get(&defs->structs, "foo");
87         ok1(t);
88         ok1(t->kind == CDUMP_STRUCT);
89         ok1(streq(t->name, "foo"));
90         ok1(tal_count(t->u.members) == 3);
91
92         ok1(streq(t->u.members[0].name, "x"));
93         ok1(t->u.members[0].type->kind == CDUMP_ARRAY);
94         ok1(streq(t->u.members[0].type->u.arr.size, "5<< 1"));
95         ok1(t->u.members[0].type->u.arr.type->kind == CDUMP_UNKNOWN);
96         ok1(streq(t->u.members[0].type->u.arr.type->name, "int"));
97
98         ok1(streq(t->u.members[1].name, "next"));
99         ok1(t->u.members[1].type->kind == CDUMP_POINTER);
100         ok1(t->u.members[1].type->u.ptr == t);
101
102         ok1(streq(t->u.members[2].name, "ptrs"));
103         p = t->u.members[2].type;
104         ok1(p->kind == CDUMP_ARRAY);
105         ok1(streq(p->u.arr.size, "10"));
106         p = p->u.arr.type;
107         ok1(p->kind == CDUMP_POINTER);
108         p = p->u.ptr;
109         ok1(p->kind == CDUMP_POINTER);
110         p = p->u.ptr;
111         ok1(p->kind == CDUMP_STRUCT);
112         ok1(streq(p->name, "unknown"));
113         ok1(p->u.members == NULL);
114
115         /* We don't put undefined structs into definition maps. */
116         ok1(!strmap_get(&defs->structs, "unknown"));
117
118         /* unions and comments. */
119         defs = cdump_extract(ctx, "#if 0\n"
120                              "/* Normal comment */\n"
121                              "struct foo { int x[5 * 7/* Comment */]; };\n"
122                              "// One-line comment\n"
123                              "union bar { enum sometype x; union yun// Comment\n"
124                              " y;};\n"
125                              "#endif", &problems);
126         ok1(defs);
127         ok1(tal_parent(defs) == ctx);
128         ok1(!problems);
129         t = strmap_get(&defs->structs, "foo");
130         ok1(t);
131         ok1(tal_count(t->u.members) == 1);
132         ok1(streq(t->u.members[0].name, "x"));
133         ok1(t->u.members[0].type->kind == CDUMP_ARRAY);
134         ok1(streq(t->u.members[0].type->u.arr.size, "5 * 7"));
135         ok1(t->u.members[0].type->u.arr.type->kind == CDUMP_UNKNOWN);
136         ok1(streq(t->u.members[0].type->u.arr.type->name, "int"));
137
138         t = strmap_get(&defs->unions, "bar");
139         ok1(t);
140         ok1(tal_count(t->u.members) == 2);
141         ok1(streq(t->u.members[0].name, "x"));
142         ok1(t->u.members[0].type->kind == CDUMP_ENUM);
143         ok1(streq(t->u.members[0].type->name, "sometype"));
144         ok1(!t->u.members[0].type->u.enum_vals);
145         ok1(streq(t->u.members[1].name, "y"));
146         ok1(t->u.members[1].type->kind == CDUMP_UNION);
147         ok1(streq(t->u.members[1].type->name, "yun"));
148         ok1(!t->u.members[1].type->u.members);
149
150         /* This exits depending on whether all tests passed */
151         return exit_status();
152 }