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