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