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