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