]> git.lizzy.rs Git - dragonnet.git/blob - typegen/main.c
Implement deallocators
[dragonnet.git] / typegen / main.c
1 #include <ctype.h>
2 #include <dragonport/asprintf.h>
3 #include <dragontype/number.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7
8 #define FUNC "__attribute__((unused)) static inline "
9
10 static size_t split(char ***strs, char *s, const char *delim)
11 {
12         size_t i = 0;
13         *strs = malloc((1+i) * sizeof(char *));
14
15         // Can't be allocated on the stack for some reason
16         char *str = malloc(1+strlen(s));
17         strcpy(str, s);
18
19         char *tok = strtok(str, delim);
20         while (tok != NULL) {
21                 *strs = realloc(*strs, (1+i) * sizeof(char *));
22                 (*strs)[i++] = strdup(tok);
23                 tok = strtok(NULL, delim);
24         }
25
26         free(str);
27         return i;
28 }
29
30 static void free_split(char **strs, size_t n)
31 {
32         for (size_t i = 0; i < n; ++i)
33                 free(strs[i]);
34
35         free(strs);
36 }
37
38 #define INDENT for (size_t i = 0; i < lvls + 1; i++) fprintf(fp, "\t")
39
40 static char *process_array(FILE *fp, char *src)
41 {
42         size_t lvls = 0;
43
44         size_t len = 1;
45         char *str = malloc(1);
46
47         *str = '\0';
48
49         for (; *src != '\0'; src++) {
50                 if (*src == '[') {
51                         *src++ = '\0';
52
53                         size_t arrlen;
54                         src += sscanf(src, "%lu", &arrlen);
55
56                         INDENT; fprintf(fp, "for (size_t i%lu = 0; i%lu < %lu; i%lu++)\n", lvls, lvls, arrlen, lvls);
57
58                         char *buf;
59                         str = realloc(str, len += asprintf(&buf, "[i%lu]", lvls));
60                         strcat(str, buf);
61                         free(buf);
62
63                         lvls++;
64                 }
65         }
66
67         INDENT; return str;
68 }
69
70 #undef INDENT
71
72 // Socket based
73
74 static void gen_serializers(FILE *c_fp)
75 {
76         fprintf(c_fp, FUNC "void raw_buf_read(Blob blob, void *data, size_t len)\n");
77         fprintf(c_fp, "{\n");
78         fprintf(c_fp, "\tmemcpy(data, blob->data, len);\n");
79         fprintf(c_fp, "\tmemcpy(blob->data, &blob->data[len], -len + blob->siz);\n");
80         fprintf(c_fp, "\tblob->data = realloc(blob->data, -len + blob->siz);\n");
81         fprintf(c_fp, "\tblob->siz -= len;\n");
82         fprintf(c_fp, "\t}\n\n");
83
84         fprintf(c_fp, FUNC "void raw_buf_write(Blob blob, const void *data, size_t len)\n");
85         fprintf(c_fp, "{\n");
86         fprintf(c_fp, "\tblob->data = realloc(blob->data, len + blob->siz);\n");
87         fprintf(c_fp, "\tmemcpy(&blob->data[blob->siz], data, len);\n");
88         fprintf(c_fp, "\tblob->siz += len;\n");
89         fprintf(c_fp, "}\n\n");
90
91         for (u8 bits = 8; bits <= 64; bits *= 2) {
92                 char *fmt_u = FUNC "void send_u%d(DragonnetPeer *p, bool submit, u%d v)\n";
93                 char *fmt_s = FUNC "void send_s%d(DragonnetPeer *p, bool submit, s%d v)\n";
94
95                 fprintf(c_fp, fmt_u, bits, bits);
96                 fprintf(c_fp, "{\n");
97                 fprintf(c_fp, "\tu%d be = htobe%d(v);\n", bits, bits);
98                 fprintf(c_fp, "\tdragonnet_send_raw(p, submit, &be, sizeof be);\n");
99                 fprintf(c_fp, "}\n\n");
100
101                 fprintf(c_fp, fmt_s, bits, bits, "");
102                 fprintf(c_fp, "{\n");
103                 fprintf(c_fp, "\tsend_u%d(p, submit, (u%d) v);\n", bits, bits);
104                 fprintf(c_fp, "}\n\n");
105
106                 if (bits >= 32) {
107                         char *fmt_f = FUNC "void send_f%d(DragonnetPeer *p, bool submit, f%d v)\n";
108
109                         fprintf(c_fp, fmt_f, bits, bits);
110                         fprintf(c_fp, "{\n");
111                         fprintf(c_fp, "\tsend_u%d(p, submit, (u%d) v);\n", bits, bits);
112                         fprintf(c_fp, "}\n\n");
113                 }
114         }
115
116         for (u8 elems = 2; elems <= 4; ++elems) {
117                 for (u8 bits = 8; bits <= 64; bits *= 2) {
118                         char *fmt_u = FUNC "void send_v%du%d(DragonnetPeer *p, bool submit, v%du%d v)\n";
119                         char *fmt_s = FUNC "void send_v%ds%d(DragonnetPeer *p, bool submit, v%ds%d v)\n";
120
121                         fprintf(c_fp, fmt_u, elems, bits, elems, bits);
122                         fprintf(c_fp, "{\n");
123                         fprintf(c_fp, "\tu%d *ptr = &v.x;\n", bits);
124                         fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems);
125                         fprintf(c_fp, "\t\tsend_u%d(p, (i == %d-1) ? submit : false, *ptr++);\n", bits, elems);
126                         fprintf(c_fp, "\t}\n");
127                         fprintf(c_fp, "}\n\n");
128
129                         fprintf(c_fp, fmt_s, elems, bits, elems, bits);
130                         fprintf(c_fp, "{\n");
131                         fprintf(c_fp, "\ts%d *ptr = &v.x;\n", bits);
132                         fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems);
133                         fprintf(c_fp, "\t\tsend_s%d(p, (i == %d-1) ? submit : false, *ptr++);\n", bits, elems);
134                         fprintf(c_fp, "\t}\n");
135                         fprintf(c_fp, "}\n\n");
136
137                         if (bits >= 32) {
138                                 char *fmt_f = FUNC "void send_v%df%d(DragonnetPeer *p, bool submit, v%df%d v)\n";
139
140                                 fprintf(c_fp, fmt_f, elems, bits, elems, bits);
141                                 fprintf(c_fp, "{\n");
142                                 fprintf(c_fp, "\tf%d *ptr = &v.x;\n", bits);
143                                 fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems);
144                                 fprintf(c_fp, "\t\tsend_f%d(p, (i == %d-1) ? submit : false, *ptr++);\n", bits, elems);
145                                 fprintf(c_fp, "\t}\n");
146                                 fprintf(c_fp, "}\n\n");
147                         }
148                 }
149         }
150
151         for (u8 elems = 2; elems <= 4; ++elems) {
152                 for (u8 bits = 8; bits <= 64; bits *= 2) {
153                         char *fmt_u = FUNC "void send_aabb%du%d(DragonnetPeer *p, bool submit, aabb%du%d v)\n";
154                         char *fmt_s = FUNC "void send_aabb%ds%d(DragonnetPeer *p, bool submit, aabb%ds%d v)\n";
155
156                         fprintf(c_fp, fmt_u, elems, bits, elems, bits);
157                         fprintf(c_fp, "{\n");
158                         fprintf(c_fp, "\tv%du%d *ptr = &v.min;\n", elems, bits);
159                         fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n");
160                         fprintf(c_fp, "\t\tsend_v%du%d(p, (i == 1) ? submit : false, *ptr++);\n", elems, bits);
161                         fprintf(c_fp, "\t}\n");
162                         fprintf(c_fp, "}\n\n");
163
164                         fprintf(c_fp, fmt_s, elems, bits, elems, bits);
165                         fprintf(c_fp, "{\n");
166                         fprintf(c_fp, "\tv%ds%d *ptr = &v.min;\n", elems, bits);
167                         fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n");
168                         fprintf(c_fp, "\t\tsend_v%ds%d(p, (i == 1) ? submit : false, *ptr++);\n", elems, bits);
169                         fprintf(c_fp, "\t}\n");
170                         fprintf(c_fp, "}\n\n");
171
172                         if (bits >= 32) {
173                                 char *fmt_f = FUNC "void send_aabb%df%d(DragonnetPeer *p, bool submit, aabb%df%d v)\n";
174
175                                 fprintf(c_fp, fmt_f, elems, bits, elems, bits);
176                                 fprintf(c_fp, "{\n");
177                                 fprintf(c_fp, "\tv%df%d *ptr = &v.min;\n", elems, bits);
178                                 fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n");
179                                 fprintf(c_fp, "\t\tsend_v%df%d(p, (i == 1) ? submit : false, *ptr++);\n", elems, bits);
180                                 fprintf(c_fp, "\t}\n");
181                                 fprintf(c_fp, "}\n\n");
182                         }
183                 }
184         }
185
186         fprintf(c_fp, FUNC "void send_string(DragonnetPeer *p, bool submit, string v)\n");
187         fprintf(c_fp, "{\n");
188         fprintf(c_fp, "\tdragonnet_send_raw(p, submit, v, strlen(v));\n");
189         fprintf(c_fp, "}\n\n");
190
191         fprintf(c_fp, FUNC "void send_Blob(DragonnetPeer *p, bool submit, Blob v)\n");
192         fprintf(c_fp, "{\n");
193         fprintf(c_fp, "\tsend_u32(p, false, v->siz);\n");
194         fprintf(c_fp, "\tdragonnet_send_raw(p, submit, v->data, v->siz);\n");
195         fprintf(c_fp, "}\n\n");
196
197         fprintf(c_fp, FUNC "void send_CompressedBlob(DragonnetPeer *p, bool submit, CompressedBlob v)\n\n");
198         fprintf(c_fp, "{\n");
199         fprintf(c_fp, "\tchar compr[2 + v->blob->siz];\n\n");
200         fprintf(c_fp, "\tz_stream s;\n");
201         fprintf(c_fp, "\ts.zalloc = Z_NULL;\n");
202         fprintf(c_fp , "\ts.zfree = Z_NULL;\n");
203         fprintf(c_fp, "\ts.opaque = Z_NULL;\n\n");
204         fprintf(c_fp, "\ts.avail_in = v->blob->siz;\n");
205         fprintf(c_fp, "\ts.avail_out = 3 + v->blob->siz;\n");
206         fprintf(c_fp, "\ts.next_in = (Bytef *) v->blob->data;\n");
207         fprintf(c_fp, "\ts.next_out = (Bytef *) compr;\n\n");
208         fprintf(c_fp, "\tdeflateInit(&s, Z_BEST_COMPRESSION);\n");
209         fprintf(c_fp, "\tdeflate(&s, Z_FINISH);\n");
210         fprintf(c_fp, "\tdeflateEnd(&s);\n\n");
211         fprintf(c_fp, "\tv->siz = s.total_out;\n");
212         fprintf(c_fp, "\tsend_u32(p, false, v->siz);\n");
213         fprintf(c_fp, "\tsend_u32(p, false, v->blob->siz);\n");
214         fprintf(c_fp, "\tdragonnet_send_raw(p, submit, compr, v->siz);\n");
215         fprintf(c_fp, "}\n\n");
216 }
217
218 static void gen_deserializers(FILE *c_fp)
219 {
220         for (u8 bits = 8; bits <= 64; bits *= 2) {
221                 char *fmt = FUNC "void recv_n%d(DragonnetPeer *p, void *buf)\n";
222
223                 fprintf(c_fp, fmt, bits);
224                 fprintf(c_fp, "{\n");
225                 fprintf(c_fp, "\tu%d be;\n", bits);
226                 fprintf(c_fp, "\tdragonnet_recv_raw(p, &be, sizeof be);\n");
227                 fprintf(c_fp, "\tbe = be%dtoh(be);\n", bits);
228                 fprintf(c_fp, "\tmemcpy(buf, &be, sizeof be);\n");
229                 fprintf(c_fp, "}\n\n");
230         }
231
232         for (u8 elems = 2; elems <= 4; ++elems) {
233                 for (u8 bits = 8; bits <= 64; bits *= 2) {
234                         char *fmt = FUNC "void recv_v%dn%d(DragonnetPeer *p, void *buf)\n";
235
236                         fprintf(c_fp, fmt, elems, bits);
237                         fprintf(c_fp, "{\n");
238                         fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i)\n", elems);
239                         fprintf(c_fp, "\t\trecv_n%d(p, buf);\n", bits);
240                         fprintf(c_fp, "}\n\n");
241                 }
242         }
243
244         for (u8 elems = 2; elems <= 4; ++elems) {
245                 for (u8 bits = 8; bits <= 64; bits *= 2) {
246                         char *fmt = FUNC "void recv_aabb%dn%d(DragonnetPeer *p, void *buf)\n";
247
248                         fprintf(c_fp, fmt, elems, bits);
249                         fprintf(c_fp, "{\n");
250                         fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i)\n");
251                         fprintf(c_fp, "\t\trecv_v%dn%d(p, buf);\n", elems, bits);
252                         fprintf(c_fp, "}\n\n");
253                 }
254         }
255
256         fprintf(c_fp, FUNC "void recv_string(DragonnetPeer *p, void *buf)\n");
257         fprintf(c_fp, "{\n");
258         fprintf(c_fp, "\tstring v = malloc(1 + (1 << 16));\n\n");
259         fprintf(c_fp, "\tchar ch;\n");
260         fprintf(c_fp, "\tfor (u16 i = 0; ch != '\\0'; ++i) {\n");
261         fprintf(c_fp, "\t\trecv_n8(p, &ch);\n");
262         fprintf(c_fp, "\t\tv[i] = ch;\n");
263         fprintf(c_fp, "\t}\n\n");
264         fprintf(c_fp, "\tv = realloc(v, strlen(v));\n");
265         fprintf(c_fp, "\tmemcpy(buf, v, strlen(v));\n");
266         fprintf(c_fp, "}\n\n");
267
268         fprintf(c_fp, FUNC "void recv_Blob(DragonnetPeer *p, void *buf)\n");
269         fprintf(c_fp, "{\n");
270         fprintf(c_fp, "\tBlob v = (Blob) buf;\n");
271         fprintf(c_fp, "\trecv_n32(p, &v->siz);\n");
272         fprintf(c_fp, "\tv->data = malloc(v->siz);\n");
273         fprintf(c_fp, "\tdragonnet_recv_raw(p, v->data, v->siz);\n\n");
274         fprintf(c_fp, "\tmemcpy(buf, v, v->siz + sizeof v);\n");
275         fprintf(c_fp, "}\n\n");
276
277         fprintf(c_fp, FUNC "void recv_CompressedBlob(DragonnetPeer *p, void *buf)\n");
278         fprintf(c_fp, "{\n");
279         fprintf(c_fp, "\tCompressedBlob v = *(CompressedBlob *) buf;\n");
280         fprintf(c_fp, "\tv->blob = malloc(sizeof *v->blob);\n\n");
281         fprintf(c_fp, "\trecv_n32(p, &v->siz);\n");
282         fprintf(c_fp, "\trecv_n32(p, &v->blob->siz);\n");
283         fprintf(c_fp, "\tv->blob->data = malloc(v->blob->siz);\n\n");
284         fprintf(c_fp, "\tchar compr[v->siz];\n");
285         fprintf(c_fp, "\tdragonnet_recv_raw(p, compr, sizeof compr);\n\n");
286         fprintf(c_fp, "\tz_stream s;\n");
287         fprintf(c_fp, "\ts.zalloc = Z_NULL;\n");
288         fprintf(c_fp, "\ts.zfree = Z_NULL;\n");
289         fprintf(c_fp, "\ts.opaque = Z_NULL;\n\n");
290         fprintf(c_fp, "\ts.avail_in = v->siz;\n");
291         fprintf(c_fp, "\ts.next_in = (Bytef *) compr;\n");
292         fprintf(c_fp, "\ts.avail_out = v->blob->siz;\n");
293         fprintf(c_fp, "\ts.next_out = (Bytef *) v->blob->data;\n\n");
294         fprintf(c_fp, "\tinflateInit(&s);\n");
295         fprintf(c_fp, "\tinflate(&s, Z_NO_FLUSH);\n");
296         fprintf(c_fp, "\tinflateEnd(&s);\n");
297         fprintf(c_fp, "}\n\n");
298 }
299
300 // Buffer based
301
302 static void gen_buffer_serializers(FILE *c_fp)
303 {
304         for (u8 bits = 8; bits <= 64; bits *= 2) {
305                 char *fmt_u = FUNC "void buf_write_u%d(Blob blob, u%d v)\n";
306                 char *fmt_s = FUNC "void buf_write_s%d(Blob blob, s%d v)\n";
307
308                 fprintf(c_fp, fmt_u, bits, bits);
309                 fprintf(c_fp, "{\n");
310                 fprintf(c_fp, "\tu%d be = htobe%d(v);\n", bits, bits);
311                 fprintf(c_fp, "\traw_buf_write(blob, &be, sizeof be);\n");
312                 fprintf(c_fp, "}\n\n");
313
314                 fprintf(c_fp, fmt_s, bits, bits, "");
315                 fprintf(c_fp, "{\n");
316                 fprintf(c_fp, "\tbuf_write_u%d(blob, (u%d) v);\n", bits, bits);
317                 fprintf(c_fp, "}\n\n");
318
319                 if (bits >= 32) {
320                         char *fmt_f = FUNC "void buf_write_f%d(Blob blob, f%d v)\n";
321
322                         fprintf(c_fp, fmt_f, bits, bits);
323                         fprintf(c_fp, "{\n");
324                         fprintf(c_fp, "\tbuf_write_u%d(blob, (u%d) v);\n", bits, bits);
325                         fprintf(c_fp, "}\n\n");
326                 }
327         }
328
329         for (u8 elems = 2; elems <= 4; ++elems) {
330                 for (u8 bits = 8; bits <= 64; bits *= 2) {
331                         char *fmt_u = FUNC "void buf_write_v%du%d(Blob blob, v%du%d v)\n";
332                         char *fmt_s = FUNC "void buf_write_v%ds%d(Blob blob, v%ds%d v)\n";
333
334                         fprintf(c_fp, fmt_u, elems, bits, elems, bits);
335                         fprintf(c_fp, "{\n");
336                         fprintf(c_fp, "\tu%d *ptr = &v.x;\n", bits);
337                         fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems);
338                         fprintf(c_fp, "\t\tbuf_write_u%d(blob, *ptr++);\n", bits);
339                         fprintf(c_fp, "\t}\n");
340                         fprintf(c_fp, "}\n\n");
341
342                         fprintf(c_fp, fmt_s, elems, bits, elems, bits);
343                         fprintf(c_fp, "{\n");
344                         fprintf(c_fp, "\ts%d *ptr = &v.x;\n", bits);
345                         fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems);
346                         fprintf(c_fp, "\t\tbuf_write_s%d(blob, *ptr++);\n", bits);
347                         fprintf(c_fp, "\t}\n");
348                         fprintf(c_fp, "}\n\n");
349
350                         if (bits >= 32) {
351                                 char *fmt_f = FUNC "void buf_write_v%df%d(Blob blob, v%df%d v)\n";
352
353                                 fprintf(c_fp, fmt_f, elems, bits, elems, bits);
354                                 fprintf(c_fp, "{\n");
355                                 fprintf(c_fp, "\tf%d *ptr = &v.x;\n", bits);
356                                 fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems);
357                                 fprintf(c_fp, "\t\tbuf_write_f%d(blob, *ptr++);\n", bits);
358                                 fprintf(c_fp, "\t}\n");
359                                 fprintf(c_fp, "}\n\n");
360                         }
361                 }
362         }
363
364         for (u8 elems = 2; elems <= 4; ++elems) {
365                 for (u8 bits = 8; bits <= 64; bits *= 2) {
366                         char *fmt_u = FUNC "void buf_write_aabb%du%d(Blob blob, aabb%du%d v)\n";
367                         char *fmt_s = FUNC "void buf_write_aabb%ds%d(Blob blob, aabb%ds%d v)\n";
368
369                         fprintf(c_fp, fmt_u, elems, bits, elems, bits);
370                         fprintf(c_fp, "{\n");
371                         fprintf(c_fp, "\tv%du%d *ptr = &v.min;\n", elems, bits);
372                         fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n");
373                         fprintf(c_fp, "\t\tbuf_write_v%du%d(blob, *ptr++);\n", elems, bits);
374                         fprintf(c_fp, "\t}\n");
375                         fprintf(c_fp, "}\n\n");
376
377                         fprintf(c_fp, fmt_s, elems, bits, elems, bits);
378                         fprintf(c_fp, "{\n");
379                         fprintf(c_fp, "\tv%ds%d *ptr = &v.min;\n", elems, bits);
380                         fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n");
381                         fprintf(c_fp, "\t\tbuf_write_v%ds%d(blob, *ptr++);\n", elems, bits);
382                         fprintf(c_fp, "\t}\n");
383                         fprintf(c_fp, "}\n\n");
384
385                         if (bits >= 32) {
386                                 char *fmt_f = FUNC "void buf_write_aabb%df%d(Blob blob, aabb%df%d v)\n";
387
388                                 fprintf(c_fp, fmt_f, elems, bits, elems, bits);
389                                 fprintf(c_fp, "{\n");
390                                 fprintf(c_fp, "\tv%df%d *ptr = &v.min;\n", elems, bits);
391                                 fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n");
392                                 fprintf(c_fp, "\t\tbuf_write_v%df%d(blob, *ptr++);\n", elems, bits);
393                                 fprintf(c_fp, "\t}\n");
394                                 fprintf(c_fp, "}\n\n");
395                         }
396                 }
397         }
398
399         fprintf(c_fp, FUNC "void buf_write_string(Blob blob, string v)\n");
400         fprintf(c_fp, "{\n");
401         fprintf(c_fp, "\traw_buf_write(blob, v, strlen(v));\n");
402         fprintf(c_fp, "}\n\n");
403
404         fprintf(c_fp, FUNC "void buf_write_Blob(Blob blob, Blob v)\n\n");
405         fprintf(c_fp, "{\n");
406         fprintf(c_fp, "\tbuf_write_u32(blob, v->siz);\n");
407         fprintf(c_fp, "\traw_buf_write(blob, v->data, v->siz);\n");
408         fprintf(c_fp, "}\n\n");
409
410         fprintf(c_fp, FUNC "void buf_write_CompressedBlob(Blob blob, CompressedBlob v)\n\n");
411         fprintf(c_fp, "{\n");
412         fprintf(c_fp, "\tchar compr[2 + v->blob->siz];\n\n");
413         fprintf(c_fp, "\tz_stream s;\n");
414         fprintf(c_fp, "\ts.zalloc = Z_NULL;\n");
415         fprintf(c_fp , "\ts.zfree = Z_NULL;\n");
416         fprintf(c_fp, "\ts.opaque = Z_NULL;\n\n");
417         fprintf(c_fp, "\ts.avail_in = v->blob->siz;\n");
418         fprintf(c_fp, "\ts.avail_out = 3 + v->blob->siz;\n");
419         fprintf(c_fp, "\ts.next_in = (Bytef *) v->blob->data;\n");
420         fprintf(c_fp, "\ts.next_out = (Bytef *) compr;\n\n");
421         fprintf(c_fp, "\tdeflateInit(&s, Z_BEST_COMPRESSION);\n");
422         fprintf(c_fp, "\tdeflate(&s, Z_FINISH);\n");
423         fprintf(c_fp, "\tdeflateEnd(&s);\n\n");
424         fprintf(c_fp, "\tv->siz = s.total_out;\n");
425         fprintf(c_fp, "\tbuf_write_u32(blob, v->siz);\n");
426         fprintf(c_fp, "\tbuf_write_u32(blob, v->blob->siz);\n");
427         fprintf(c_fp, "\traw_buf_write(blob, compr, v->siz);\n");
428         fprintf(c_fp, "}\n\n");
429 }
430
431 static void gen_buffer_deserializers(FILE *c_fp)
432 {
433         for (u8 bits = 8; bits <= 64; bits *= 2) {
434                 char *fmt_u = FUNC "u%d buf_read_u%d(Blob blob)\n";
435                 char *fmt_s = FUNC "s%d buf_read_s%d(Blob blob)\n";
436
437                 fprintf(c_fp, fmt_u, bits, bits);
438                 fprintf(c_fp, "{\n");
439                 fprintf(c_fp, "\tu%d be;\n", bits);
440                 fprintf(c_fp, "\traw_buf_read(blob, &be, sizeof be);\n");
441                 fprintf(c_fp, "\treturn be%dtoh(be);\n", bits);
442                 fprintf(c_fp, "}\n\n");
443
444                 fprintf(c_fp, fmt_s, bits, bits);
445                 fprintf(c_fp, "{\n");
446                 fprintf(c_fp, "\treturn (s%d) buf_read_u%d(blob);\n", bits, bits);
447                 fprintf(c_fp, "}\n\n");
448
449                 if (bits >= 32) {
450                         char *fmt_f = FUNC "f%d buf_read_f%d(Blob blob)\n";
451
452                         fprintf(c_fp, fmt_f, bits, bits);
453                         fprintf(c_fp, "{\n");
454                         fprintf(c_fp, "\treturn (f%d) buf_read_u%d(blob);\n", bits, bits);
455                         fprintf(c_fp, "}\n\n");
456                 }
457         }
458
459         for (u8 elems = 2; elems <= 4; ++elems) {
460                 for (u8 bits = 8; bits <= 64; bits *= 2) {
461                         char *fmt_u = FUNC "v%du%d buf_read_v%du%d(Blob blob)\n";
462                         char *fmt_s = FUNC "v%ds%d buf_read_v%ds%d(Blob blob)\n";
463
464                         fprintf(c_fp, fmt_u, elems, bits, elems, bits);
465                         fprintf(c_fp, "{\n");
466                         fprintf(c_fp, "\tv%du%d v = {0};\n", elems, bits);
467                         fprintf(c_fp, "\tu%d *ptr = &v.x;\n\n", bits);
468                         fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems);
469                         fprintf(c_fp, "\t\t*ptr++ = buf_read_u%d(blob);\n", bits);
470                         fprintf(c_fp, "\t}\n\n");
471                         fprintf(c_fp, "\treturn v;\n");
472                         fprintf(c_fp, "}\n\n");
473
474                         fprintf(c_fp, fmt_s, elems, bits, elems, bits);
475                         fprintf(c_fp, "{\n");
476                         fprintf(c_fp, "\tv%ds%d v = {0};\n", elems, bits);
477                         fprintf(c_fp, "\ts%d *ptr = &v.x;\n\n", bits);
478                         fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems);
479                         fprintf(c_fp, "\t\t*ptr++ = buf_read_s%d(blob);\n", bits);
480                         fprintf(c_fp, "\t}\n\n");
481                         fprintf(c_fp, "\treturn v;\n");
482                         fprintf(c_fp, "}\n\n");
483
484                         if (bits >= 32) {
485                                 char *fmt_f = FUNC "v%df%d buf_read_v%df%d(Blob blob)\n";
486
487                                 fprintf(c_fp, fmt_f, elems, bits, elems, bits);
488                                 fprintf(c_fp, "{\n");
489                                 fprintf(c_fp, "\tv%df%d v = {0};\n", elems, bits);
490                                 fprintf(c_fp, "\tf%d *ptr = &v.x;\n\n", bits);
491                                 fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems);
492                                 fprintf(c_fp, "\t\t*ptr++ = buf_read_f%d(blob);\n", bits);
493                                 fprintf(c_fp, "\t}\n\n");
494                                 fprintf(c_fp, "\treturn v;\n");
495                                 fprintf(c_fp, "}\n\n");
496                         }
497                 }
498         }
499
500         for (u8 elems = 2; elems <= 4; ++elems) {
501                 for (u8 bits = 8; bits <= 64; bits *= 2) {
502                         char *fmt_u = FUNC "aabb%du%d buf_read_aabb%du%d(Blob blob)\n";
503                         char *fmt_s = FUNC "aabb%ds%d buf_read_aabb%ds%d(Blob blob)\n";
504
505                         fprintf(c_fp, fmt_u, elems, bits, elems, bits);
506                         fprintf(c_fp, "{\n");
507                         fprintf(c_fp, "\taabb%du%d v = {0};\n", elems, bits);
508                         fprintf(c_fp, "\tv%du%d *ptr = &v.min;\n\n", elems, bits);
509                         fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n");
510                         fprintf(c_fp, "\t\t*ptr++ = buf_read_v%du%d(blob);\n", elems, bits);
511                         fprintf(c_fp, "\t}\n\n");
512                         fprintf(c_fp, "\treturn v;\n");
513                         fprintf(c_fp, "}\n\n");
514
515                         fprintf(c_fp, fmt_s, elems, bits, elems, bits);
516                         fprintf(c_fp, "{\n");
517                         fprintf(c_fp, "\taabb%ds%d v = {0};\n", elems, bits);
518                         fprintf(c_fp, "\tv%ds%d *ptr = &v.min;\n\n", elems, bits);
519                         fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n");
520                         fprintf(c_fp, "\t\t*ptr++ = buf_read_v%ds%d(blob);\n", elems, bits);
521                         fprintf(c_fp, "\t}\n\n");
522                         fprintf(c_fp, "\treturn v;\n");
523                         fprintf(c_fp, "}\n\n");
524
525                         if (bits >= 32) {
526                                 char *fmt_f = FUNC "aabb%df%d buf_read_aabb%df%d(Blob blob)\n";
527
528                                 fprintf(c_fp, fmt_f, elems, bits, elems, bits);
529                                 fprintf(c_fp, "{\n");
530                                 fprintf(c_fp, "\taabb%df%d v = {0};\n", elems, bits);
531                                 fprintf(c_fp, "\tv%df%d *ptr = &v.min;\n\n", elems, bits);
532                                 fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n");
533                                 fprintf(c_fp, "\t\t*ptr++ = buf_read_v%df%d(blob);\n", elems, bits);
534                                 fprintf(c_fp, "\t}\n\n");
535                                 fprintf(c_fp, "\treturn v;\n");
536                                 fprintf(c_fp, "}\n\n");
537                         }
538                 }
539         }
540
541         fprintf(c_fp, FUNC "string buf_read_string(Blob blob)\n");
542         fprintf(c_fp, "{\n");
543         fprintf(c_fp, "\tstring v = malloc(sizeof(u16));\n\n");
544         fprintf(c_fp, "\tchar ch;\n");
545         fprintf(c_fp, "\tfor (u16 i = 0; ch != '\\0'; ++i) {\n");
546         fprintf(c_fp, "\t\tch = buf_read_s8(blob);\n");
547         fprintf(c_fp, "\t\tv[i] = ch;\n");
548         fprintf(c_fp, "\t}\n\n");
549         fprintf(c_fp, "\tv = realloc(v, strlen(v));\n");
550         fprintf(c_fp, "\treturn v;\n");
551         fprintf(c_fp, "}\n\n");
552
553         fprintf(c_fp, FUNC "Blob buf_read_Blob(Blob blob)\n");
554         fprintf(c_fp, "{\n");
555         fprintf(c_fp, "\tBlob v = malloc(sizeof *v);\n");
556         fprintf(c_fp, "\tv->siz = buf_read_u32(blob);\n");
557         fprintf(c_fp, "\tv->data = malloc(v->siz);\n");
558         fprintf(c_fp, "\traw_buf_read(blob, v->data, v->siz);\n\n");
559         fprintf(c_fp, "\treturn v;\n");
560         fprintf(c_fp, "}\n\n");
561
562         fprintf(c_fp, FUNC "CompressedBlob buf_read_CompressedBlob(Blob blob)\n");
563         fprintf(c_fp, "{\n");
564         fprintf(c_fp, "\tCompressedBlob v = malloc(sizeof *v);\n");
565         fprintf(c_fp, "\tv->blob = malloc(sizeof *v->blob);\n\n");
566         fprintf(c_fp, "\tv->siz = buf_read_u32(blob);\n");
567         fprintf(c_fp, "\tv->blob->siz = buf_read_u32(blob);\n");
568         fprintf(c_fp, "\tv->blob->data = malloc(v->blob->siz);\n\n");
569         fprintf(c_fp, "\tchar compr[v->siz];\n");
570         fprintf(c_fp, "\traw_buf_read(blob, compr, sizeof compr);\n\n");
571         fprintf(c_fp, "\tz_stream s;\n");
572         fprintf(c_fp, "\ts.zalloc = Z_NULL;\n");
573         fprintf(c_fp, "\ts.zfree = Z_NULL;\n");
574         fprintf(c_fp, "\ts.opaque = Z_NULL;\n\n");
575         fprintf(c_fp, "\ts.avail_in = v->siz;\n");
576         fprintf(c_fp, "\ts.next_in = (Bytef *) compr;\n");
577         fprintf(c_fp, "\ts.avail_out = v->blob->siz;\n");
578         fprintf(c_fp, "\ts.next_out = (Bytef *) v->blob->data;\n\n");
579         fprintf(c_fp, "\tinflateInit(&s);\n");
580         fprintf(c_fp, "\tinflate(&s, Z_NO_FLUSH);\n");
581         fprintf(c_fp, "\tinflateEnd(&s);\n\n");
582         fprintf(c_fp, "\treturn v;\n");
583         fprintf(c_fp, "}\n\n");
584 }
585
586 static void gen_deallocators(FILE *c_fp)
587 {
588         for (u8 bits = 8; bits <= 64; bits *= 2) {
589                 fprintf(c_fp, FUNC "void free_u%d(__attribute__((unused)) u%d v) {}\n", bits, bits);
590                 fprintf(c_fp, FUNC "void free_s%d(__attribute__((unused)) s%d v) {}\n", bits, bits);
591                 if (bits >= 32)
592                         fprintf(c_fp, FUNC "void free_f%d(__attribute__((unused)) f%d v) {}\n", bits, bits);
593
594                 for (u8 elems = 2; elems <= 4; ++elems) {
595                         fprintf(c_fp, FUNC "void free_v%du%d(__attribute__((unused)) v%du%d v) {}\n", elems, bits, elems, bits);
596                         fprintf(c_fp, FUNC "void free_v%ds%d(__attribute__((unused)) v%ds%d v) {}\n", elems, bits, elems, bits);
597                         if (bits >= 32)
598                                 fprintf(c_fp, FUNC "void free_v%df%d(__attribute__((unused)) v%df%d v) {}\n", elems, bits, elems, bits);
599
600                         fprintf(c_fp, FUNC "void free_aabb%du%d(__attribute__((unused)) aabb%du%d v) {}\n", elems, bits, elems, bits);
601                         fprintf(c_fp, FUNC "void free_aabb%ds%d(__attribute__((unused)) aabb%ds%d v) {}\n", elems, bits, elems, bits);
602                         if (bits >= 32)
603                                 fprintf(c_fp, FUNC "void free_aabb%df%d(__attribute__((unused)) aabb%df%d v) {}\n", elems, bits, elems, bits);
604                 }
605         }
606
607         fprintf(c_fp, FUNC "\nvoid free_string(string str)\n{\n\tfree(str);\n}\n\n");
608         fprintf(c_fp, FUNC "void free_Blob(Blob blob)\n{\n\tdragonnet_free_Blob(blob);\n}\n\n");
609         fprintf(c_fp, FUNC "void free_CompressedBlob(CompressedBlob comp)\n{\n\tdragonnet_free_CompressedBlob(comp);\n}\n\n");
610 }
611
612 int main(__attribute((unused)) int argc, __attribute((unused)) char **argv)
613 {
614         FILE *fp = fopen("types.dnet", "r");
615
616         char data[1 << 16];
617         memset(data, '\0', sizeof data);
618         fread(data, sizeof *data, sizeof data, fp);
619
620         fclose(fp);
621         fp = NULL;
622
623         FILE *c_fp = fopen("dnet-types.c", "w");
624         fprintf(c_fp, "/*\n");
625         fprintf(c_fp, "\tThis file was automatically generated by Dragonnet.\n");
626         fprintf(c_fp, "\tDo NOT edit it manually. Instead, edit types.dnet and re-run DragonnetTypegen.\n");
627         fprintf(c_fp, "*/\n\n");
628         fprintf(c_fp, "#include <dragonnet/recv.h>\n");
629         fprintf(c_fp, "#include <dragonnet/send.h>\n");
630         fprintf(c_fp, "#include <endian.h/endian.h>\n");
631         fprintf(c_fp, "#include <errno.h>\n");
632         fprintf(c_fp, "#include <stdbool.h>\n");
633         fprintf(c_fp, "#include <stdio.h>\n");
634         fprintf(c_fp, "#include <stdlib.h>\n");
635         fprintf(c_fp, "#include <string.h>\n");
636         fprintf(c_fp, "#include <zlib.h>\n\n");
637
638         fprintf(c_fp, "#define htobe8(x) (x)\n");
639         fprintf(c_fp, "#define be8toh(x) (x)\n\n");
640         fprintf(c_fp, "#include \"dnet-types.h\"\n\n");
641
642         FILE *h_fp = fopen("dnet-types.h", "w");
643         fprintf(h_fp, "/*\n");
644         fprintf(h_fp, "\tThis file was automatically generated by Dragonnet.\n");
645         fprintf(h_fp, "\tDo NOT edit it manually. Instead, edit types.dnet and re-run DragonnetTypegen.\n");
646         fprintf(h_fp, "*/\n\n");
647         fprintf(h_fp, "#ifndef _DRAGONNET_TYPES_H_\n");
648         fprintf(h_fp, "#define _DRAGONNET_TYPES_H_\n");
649         fprintf(h_fp, "#include <dragonnet/peer.h>\n");
650         fprintf(h_fp, "#include <dragontype/number.h>\n");
651         fprintf(h_fp, "#include <stddef.h>\n");
652         fprintf(h_fp, "typedef char *string;\n\n");
653         fprintf(h_fp, "typedef struct {\n\tu32 siz;\n\tu8 *data;\n} *Blob;\n\n");
654         fprintf(h_fp, "typedef struct {\n");
655         fprintf(h_fp, "\tu32 siz;\n");
656         fprintf(h_fp, "\tBlob blob;\n");
657         fprintf(h_fp, "} *CompressedBlob;\n\n");
658
659         // buffer allocation
660         fprintf(h_fp, "Blob dragonnet_create_Blob();\n");
661         fprintf(h_fp, "void dragonnet_free_Blob(Blob blob);\n\n");
662         fprintf(h_fp, "CompressedBlob dragonnet_create_CompressedBlob();\n");
663         fprintf(h_fp, "void dragonnet_free_CompressedBlob(CompressedBlob comp);\n\n");
664
665         fprintf(c_fp, "Blob dragonnet_create_Blob()\n");
666         fprintf(c_fp, "{\n");
667         fprintf(c_fp, "\tBlob blob = malloc(sizeof *blob);\n");
668         fprintf(c_fp, "\tblob->data = NULL;\n");
669         fprintf(c_fp, "\tblob->siz = 0;\n");
670         fprintf(c_fp, "\treturn blob;\n");
671         fprintf(c_fp, "}\n\n");
672
673         fprintf(c_fp, "void dragonnet_free_Blob(Blob blob)\n");
674         fprintf(c_fp, "{\n");
675         fprintf(c_fp, "\tif (blob->data)\n");
676         fprintf(c_fp, "\t\tfree(blob->data);\n");
677         fprintf(c_fp, "\tfree(blob);\n");
678         fprintf(c_fp, "}\n\n");
679
680         fprintf(c_fp, "CompressedBlob dragonnet_create_CompressedBlob()\n");
681         fprintf(c_fp, "{\n");
682         fprintf(c_fp, "\tCompressedBlob comp = malloc(sizeof *comp);\n");
683         fprintf(c_fp, "\tcomp->blob = dragonnet_create_Blob();\n");
684         fprintf(c_fp, "\tcomp->siz = 0;\n");
685         fprintf(c_fp, "\treturn comp;\n");
686         fprintf(c_fp, "}\n\n");
687
688         fprintf(c_fp, "void dragonnet_free_CompressedBlob(CompressedBlob comp)\n");
689         fprintf(c_fp, "{\n");
690         fprintf(c_fp, "\tdragonnet_free_Blob(comp->blob);\n");
691         fprintf(c_fp, "\tfree(comp);\n");
692         fprintf(c_fp, "}\n\n");
693
694         gen_serializers(c_fp);
695         gen_deserializers(c_fp);
696
697         gen_buffer_serializers(c_fp);
698         gen_buffer_deserializers(c_fp);
699
700         gen_deallocators(c_fp);
701
702         char **msgs;
703         size_t msgs_len = split(&msgs, data, "\n");
704
705         // Create data types
706         char *msg = NULL;
707         for (size_t i = 0; i < msgs_len; ++i) {
708                 if (msgs[i][0] != '\t') {
709                         if (msg != NULL)
710                                 fprintf(h_fp, "} %s;\n\n", msg);
711
712                         msg = msgs[i];
713                         fprintf(h_fp, "typedef struct {\n");
714                 } else {
715                         char **tokens;
716                         size_t tokens_len = split(&tokens, msgs[i], " ");
717
718                         fprintf(h_fp, "\t%s %s;\n", &tokens[0][1], tokens[1]);
719                         free_split(tokens, tokens_len);
720                         tokens = NULL;
721                 }
722         }
723
724         fprintf(h_fp, "} %s;\n\n", msg);
725         msg = NULL;
726
727         // Create (de)serialization functions
728         for (size_t i = 0; i < msgs_len; ++i) {
729                 if (msgs[i][0] != '\t') {
730                         if (msg != NULL)
731                                 fprintf(c_fp, "}\n\n");
732
733                         msg = msgs[i];
734                         fprintf(c_fp, FUNC "void send_%s(DragonnetPeer *p, bool submit, %s type)\n{\n", msg, msg);
735                 } else {
736                         char **tokens;
737                         size_t tokens_len = split(&tokens, msgs[i], " ");
738
739                         char *arr = process_array(c_fp, tokens[1]);
740                         fprintf(c_fp, "send_%s(p, %s, type.%s%s);\n", &tokens[0][1], (i == msgs_len - 1 || msgs[i + 1][0] != '\t') ? "submit" : "false", tokens[1], arr);
741                         free(arr);
742
743                         free_split(tokens, tokens_len);
744                         tokens = NULL;
745                 }
746         }
747
748         fprintf(c_fp, "}\n\n");
749         msg = NULL;
750
751         for (size_t i = 0; i < msgs_len; ++i) {
752                 if (msgs[i][0] != '\t') {
753                         if (msg != NULL)
754                                 fprintf(c_fp, "}\n\n");
755
756                         msg = msgs[i];
757                         fprintf(h_fp, "void dragonnet_peer_send_%s(DragonnetPeer *p, %s *type);\n", msg, msg);
758                         fprintf(c_fp, "void dragonnet_peer_send_%s(DragonnetPeer *p, %s *type)\n{\n", msg, msg);
759
760                         char upper[1 + strlen(msgs[i])];
761                         char *ptr = upper;
762                         strcpy(upper, msg);
763
764                         while ((*ptr = *ptr ? toupper(*ptr) : '\0'))
765                                 ++ptr;
766
767                         fprintf(c_fp, "\tsend_u16(p, false, DRAGONNET_TYPE_%s);\n", upper);
768                 } else {
769                         char **tokens;
770                         size_t tokens_len = split(&tokens, msgs[i], " ");
771
772                         char *arr = process_array(c_fp, tokens[1]);
773                         if (i >= msgs_len-1 || msgs[1+i][0] != '\t')
774                                 fprintf(c_fp, "send_%s(p, true, type->%s%s);\n", &tokens[0][1], tokens[1], arr);
775                         else
776                                 fprintf(c_fp, "send_%s(p, false, type->%s%s);\n", &tokens[0][1], tokens[1], arr);
777                         free(arr);
778
779                         free_split(tokens, tokens_len);
780                         tokens = NULL;
781                 }
782         }
783
784         fprintf(c_fp, "}\n\n");
785         msg = NULL;
786
787         for (size_t i = 0; i < msgs_len; ++i) {
788                 if (msgs[i][0] != '\t') {
789                         if (msg != NULL) {
790                                 fprintf(c_fp, "}\n\n");
791                         }
792
793                         msg = msgs[i];
794                         fprintf(c_fp, FUNC "void recv_%s(DragonnetPeer *p, void *buf)\n{\n", msg);
795                         fprintf(c_fp, "\t%s *type = (%s *) buf;\n", msg, msg);
796                 } else {
797                         char **tokens;
798                         size_t tokens_len = split(&tokens, msgs[i], " ");
799
800                         char type[strlen(&tokens[0][1])];
801                         strcpy(type, &tokens[0][1]);
802
803                         for (char *tptr = type; *tptr != '\0'; tptr++) {
804                                 for (size_t bits = 8; bits <= 64; bits *= 2) {
805                                         const char *fmt[] = {"u%d", "s%d", "f%d"};
806                                         for (size_t j = 0; j < sizeof fmt / sizeof *fmt; ++j) {
807                                                 char *cmp;
808                                                 asprintf(&cmp, fmt[j], bits);
809                                                 size_t diff = strcmp(tptr, cmp);
810                                                 free(cmp);
811
812                                                 if (diff == 0) {
813                                                         sprintf(tptr, "n%ld", bits);
814                                                         goto n_done;
815                                                 }
816                                         }
817                                 }
818                         }
819
820                         n_done: (void) 0;
821
822                         char *arr = process_array(c_fp, tokens[1]);
823                         fprintf(c_fp, "recv_%s(p, &type->%s%s);\n", type, tokens[1], arr);
824                         free(arr);
825
826                         free_split(tokens, tokens_len);
827                         tokens = NULL;
828                 }
829         }
830
831         fprintf(c_fp, "}\n\n");
832         msg = NULL;
833
834         // Buffer (de)serialization
835         for (size_t i = 0; i < msgs_len; ++i) {
836                 if (msgs[i][0] != '\t') {
837                         if (msg != NULL)
838                                 fprintf(c_fp, "}\n\n");
839
840                         msg = msgs[i];
841                         fprintf(h_fp, "void dragonnet_buf_write_%s(Blob blob, %s type);", msg, msg);
842                         fprintf(c_fp, "void buf_write_%s(Blob blob, %s type)\n{\n", msg, msg);
843                         fprintf(c_fp, "\ndragonnet_buf_write_%s(blob, type);\n}\n\n", msg);
844                         fprintf(c_fp, "void dragonnet_buf_write_%s(Blob blob, %s type)\n{\n", msg, msg);
845                 } else {
846                         char **tokens;
847                         size_t tokens_len = split(&tokens, msgs[i], " ");
848
849                         char *arr = process_array(c_fp, tokens[1]);
850                         fprintf(c_fp, "buf_write_%s(blob, type.%s%s);\n", &tokens[0][1], tokens[1], arr);
851                         free(arr);
852
853                         free_split(tokens, tokens_len);
854                         tokens = NULL;
855                 }
856         }
857
858         fprintf(c_fp, "}\n\n");
859         msg = NULL;
860
861         for (size_t i = 0; i < msgs_len; ++i) {
862                 if (msgs[i][0] != '\t') {
863                         if (msg != NULL) {
864                                 fprintf(c_fp, "\treturn type;\n");
865                                 fprintf(c_fp, "}\n\n");
866                         }
867
868                         msg = msgs[i];
869                         fprintf(h_fp, "%s dragonnet_buf_read_%s(Blob blob);\n", msg, msg);
870                         fprintf(c_fp, FUNC "%s buf_read_%s(Blob blob){\n", msg, msg);
871                         fprintf(c_fp, "\treturn dragonnet_buf_read_%s(blob);\n}\n\n", msg);
872                         fprintf(c_fp, "%s dragonnet_buf_read_%s(Blob blob)\n{\n", msg, msg);
873                         fprintf(c_fp, "\t%s type = {0};\n", msg);
874                 } else {
875                         char **tokens;
876                         size_t tokens_len = split(&tokens, msgs[i], " ");
877
878                         char *arr = process_array(c_fp, tokens[1]);
879                         fprintf(c_fp, "type.%s%s = buf_read_%s(blob);\n", tokens[1], arr, &tokens[0][1]);
880                         free(arr);
881
882                         free_split(tokens, tokens_len);
883                         tokens = NULL;
884                 }
885         }
886
887         fprintf(h_fp, "\n");
888         fprintf(c_fp, "\treturn type;\n");
889         fprintf(c_fp, "}\n\n");
890         msg = NULL;
891
892         // Deallocators
893         for (size_t i = 0; i < msgs_len; ++i) {
894                 if (msgs[i][0] != '\t') {
895                         if (msg != NULL)
896                                 fprintf(c_fp, "}\n\n");
897
898                         msg = msgs[i];
899                         fprintf(h_fp, "void dragonnet_free_%s(%s type);", msg, msg);
900                         fprintf(c_fp, "void free_%s(%s type)\n{\n", msg, msg);
901                         fprintf(c_fp, "\tdragonnet_free_%s(type);\n}\n\n", msg);
902                         fprintf(c_fp, "void dragonnet_free_%s(%s type)\n{\n", msg, msg);
903                 } else {
904                         char **tokens;
905                         size_t tokens_len = split(&tokens, msgs[i], " ");
906
907                         char *arr = process_array(c_fp, tokens[1]);
908                         fprintf(c_fp, "free_%s(type.%s%s);\n", &tokens[0][1], tokens[1], arr);
909                         free(arr);
910
911                         free_split(tokens, tokens_len);
912                         tokens = NULL;
913                 }
914         }
915
916         fprintf(c_fp, "}\n\n");
917         msg = NULL;
918
919         // Create type enum
920         fprintf(h_fp, "typedef enum {\n");
921         for (size_t i = 0; i < msgs_len; ++i) {
922                 if (msgs[i][0] == '\t')
923                         continue;
924
925                 char upper[1 + strlen(msgs[i])];
926                 char *ptr = upper;
927                 strcpy(upper, msgs[i]);
928
929                 while ((*ptr = *ptr ? toupper(*ptr) : '\0'))
930                         ++ptr;
931
932                 fprintf(h_fp, "\tDRAGONNET_TYPE_%s,\n", upper);
933         }
934
935         fprintf(h_fp, "\tDRAGONNET_NUM_TYPES\n");
936         fprintf(h_fp, "} DragonnetTypeNum;\n");
937         fprintf(h_fp, "\n#endif\n");
938
939         // ABI
940         fprintf(c_fp, "u16 dragonnet_num_types = DRAGONNET_NUM_TYPES;\n");
941         fprintf(c_fp, "DragonnetType dragonnet_types[] = {\n");
942
943         for (size_t i = 0; i < msgs_len; ++i) {
944                 if (msgs[i][0] == '\t')
945                         continue;
946
947                 fprintf(c_fp, "\t{\n");
948                 fprintf(c_fp, "\t\t.siz = sizeof(%s),\n", msgs[i]);
949                 fprintf(c_fp, "\t\t.deserialize = &recv_%s\n", msgs[i]);
950                 fprintf(c_fp, "\t},\n");
951         }
952
953         fprintf(c_fp, "};\n");
954
955         free_split(msgs, msgs_len);
956         msgs = NULL;
957
958         fclose(c_fp);
959         fclose(h_fp);
960         c_fp = NULL;
961         h_fp = NULL;
962 }