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