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