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