2 #include <dragontype/number.h>
7 static size_t split(char ***strs, char *s, const char *delim)
10 *strs = malloc((1+i) * sizeof(char *));
12 // Can't be allocated on the stack for some reason
13 char *str = malloc(1+strlen(s));
16 char *tok = strtok(str, delim);
18 *strs = realloc(*strs, (1+i) * sizeof(char *));
19 (*strs)[i++] = strdup(tok);
20 tok = strtok(NULL, delim);
27 static void free_split(char **strs, size_t n)
29 for (size_t i = 0; i < n; ++i)
35 static void gen_serializers(FILE *c_fp, FILE *h_fp)
37 fprintf(h_fp, "typedef char *string;\n");
38 fprintf(h_fp, "typedef struct {\n\tu32 siz;\n\tu8 *data;\n} Blob;\n\n");
40 for (u8 bits = 8; bits <= 64; bits *= 2) {
41 char *fmt_u = "void send_u%d(DragonnetPeer *p, bool submit, u%d v)%s\n";
42 char *fmt_s = "void send_s%d(DragonnetPeer *p, bool submit, s%d v)%s\n";
44 fprintf(h_fp, fmt_u, bits, bits, ";");
45 fprintf(h_fp, fmt_s, bits, bits, ";");
47 fprintf(c_fp, fmt_u, bits, bits, "");
49 fprintf(c_fp, "\tu%d be = htobe%d(v);\n", bits, bits);
50 fprintf(c_fp, "\tsend_raw(p, submit, &be, sizeof be);\n");
51 fprintf(c_fp, "}\n\n");
53 fprintf(c_fp, fmt_s, bits, bits, "");
55 fprintf(c_fp, "\tsend_u%d(p, submit, (u%d) v);\n", bits, bits);
56 fprintf(c_fp, "}\n\n");
59 char *fmt_f = "void send_f%d(DragonnetPeer *p, bool submit, f%d v)%s\n";
60 fprintf(h_fp, fmt_f, bits, bits, ";");
62 fprintf(c_fp, fmt_f, bits, bits, "");
64 fprintf(c_fp, "\tsend_u%d(p, submit, (u%d) v);\n", bits, bits);
65 fprintf(c_fp, "}\n\n");
71 for (u8 elems = 2; elems <= 4; ++elems) {
72 for (u8 bits = 8; bits <= 64; bits *= 2) {
73 char *fmt_u = "void send_v%du%d(DragonnetPeer *p, bool submit, v%du%d v)%s\n";
74 char *fmt_s = "void send_v%ds%d(DragonnetPeer *p, bool submit, v%ds%d v)%s\n";
76 fprintf(h_fp, fmt_u, elems, bits, elems, bits, ";");
77 fprintf(h_fp, fmt_s, elems, bits, elems, bits, ";");
79 fprintf(c_fp, fmt_u, elems, bits, elems, bits, "");
81 fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems);
82 fprintf(c_fp, "\t\tsend_u%d(p, (i == %d-1) ? submit : false, v[i]);\n", bits, elems);
83 fprintf(c_fp, "\t}\n");
84 fprintf(c_fp, "}\n\n");
86 fprintf(c_fp, fmt_s, elems, bits, elems, bits, "");
88 fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems);
89 fprintf(c_fp, "\t\tsend_s%d(p, (i == %d-1) ? submit : false, v[i]);\n", bits, elems);
90 fprintf(c_fp, "\t}\n");
91 fprintf(c_fp, "}\n\n");
94 char *fmt_f = "void send_v%df%d(DragonnetPeer *p, bool submit, v%df%d v)%s\n";
95 fprintf(h_fp, fmt_f, elems, bits, elems, bits, ";");
97 fprintf(c_fp, fmt_f, elems, bits, elems, bits, "");
99 fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems);
100 fprintf(c_fp, "\t\tsend_s%d(p, (i == %d-1) ? submit : false, v[i]);\n", bits, elems);
101 fprintf(c_fp, "\t}\n");
102 fprintf(c_fp, "}\n\n");
109 for (u8 elems = 2; elems <= 4; ++elems) {
110 for (u8 bits = 8; bits <= 64; bits *= 2) {
111 char *fmt_u = "void send_aabb%du%d(DragonnetPeer *p, bool submit, aabb%du%d v)\n";
112 char *fmt_s = "void send_aabb%ds%d(DragonnetPeer *p, bool submit, aabb%ds%d v)\n";
114 fprintf(h_fp, fmt_u, elems, bits, elems, bits, ";");
115 fprintf(h_fp, fmt_s, elems, bits, elems, bits, ";");
117 fprintf(c_fp, fmt_u, elems, bits, elems, bits, "");
118 fprintf(c_fp, "{\n");
119 fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n");
120 fprintf(c_fp, "\t\tsend_v%du%d(p, (i == 1) ? submit : false, v[i]);\n", elems, bits);
121 fprintf(c_fp, "\t}\n");
122 fprintf(c_fp, "}\n\n");
124 fprintf(c_fp, fmt_s, elems, bits, elems, bits, "");
125 fprintf(c_fp, "{\n");
126 fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n");
127 fprintf(c_fp, "\t\tsend_v%ds%d(p, (i == 1) ? submit : false, v[i]);\n", elems, bits);
128 fprintf(c_fp, "\t}\n");
129 fprintf(c_fp, "}\n\n");
132 char *fmt_f = "void send_aabb%df%d(DragonnetPeer *p, bool submit, aabb%df%d v);\n";
133 fprintf(h_fp, fmt_f, elems, bits, elems, bits, ";");
135 fprintf(c_fp, fmt_f, elems, bits, elems, bits, "");
136 fprintf(c_fp, "{\n");
137 fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n");
138 fprintf(c_fp, "\t\tsend_v%df%d(p, (i == 1) ? submit : false, v[i]);\n", elems, bits);
139 fprintf(c_fp, "\t}\n");
140 fprintf(c_fp, "}\n\n");
147 char *fmt_str = "void send_string(DragonnetPeer *p, bool submit, string v)%s\n";
148 char *fmt_blob = "void send_Blob(DragonnetPeer *p, bool submit, Blob *v)%s\n\n";
150 fprintf(h_fp, fmt_str, ";");
151 fprintf(h_fp, fmt_blob, ";");
153 fprintf(c_fp, fmt_str, "");
154 fprintf(c_fp, "{\n");
155 fprintf(c_fp, "\tsend_raw(p, submit, v, strlen(v));\n");
156 fprintf(c_fp, "}\n\n");
158 fprintf(c_fp, fmt_blob, "");
159 fprintf(c_fp, "{\n");
160 fprintf(c_fp, "\tsend_u32(p, false, v->siz);\n");
161 fprintf(c_fp, "\tsend_raw(p, submit, v->data, v->siz);\n");
162 fprintf(c_fp, "}\n\n");
165 static void gen_deserializers(FILE *c_fp, FILE *h_fp)
168 for (u8 bits = 8; bits <= 64; bits *= 2) {
169 char *fmt_u = "u%d recv_u%d(DragonnetPeer *p)%s\n";
170 char *fmt_s = "s%d recv_s%d(DragonnetPeer *p)%s\n";
172 fprintf(h_fp, fmt_u, bits, bits, ";");
173 fprintf(h_fp, fmt_s, bits, bits, ";");
175 fprintf(c_fp, fmt_u, bits, bits, "");
176 fprintf(c_fp, "{\n");
177 fprintf(c_fp, "\tu%d be = recv_raw(p, &be, sizeof be);\n", bits);
178 fprintf(c_fp, "\treturn be%dtoh(be);\n", bits);
179 fprintf(c_fp, "}\n\n");
181 fprintf(c_fp, fmt_s, bits, bits, "");
182 fprintf(c_fp, "{\n");
183 fprintf(c_fp, "\treturn (s%d) recv_u%d(p);\n", bits, bits);
184 fprintf(c_fp, "}\n\n");
187 char *fmt_f = "f%d recv_f%d(DragonnetPeer *p)%s\n";
188 fprintf(h_fp, fmt_f, bits, bits, ";");
190 fprintf(c_fp, fmt_f, bits, bits, "");
191 fprintf(c_fp, "{\n");
192 fprintf(c_fp, "\treturn (f%d) recv_u%d(p);\n", bits, bits);
193 fprintf(c_fp, "}\n\n");
199 for (u8 elems = 2; elems <= 4; ++elems) {
200 for (u8 bits = 8; bits <= 64; bits *= 2) {
201 char *fmt_u = "v%du%d recv_v%du%d(DragonnetPeer *p)%s\n";
202 char *fmt_s = "v%ds%d recv_v%ds%d(DragonnetPeer *p)%s\n";
204 fprintf(h_fp, fmt_u, elems, bits, elems, bits, ";");
205 fprintf(h_fp, fmt_s, elems, bits, elems, bits, ";");
207 fprintf(c_fp, fmt_u, elems, bits, elems, bits, "");
208 fprintf(c_fp, "{\n");
209 fprintf(c_fp, "\tv%du%d v = {0};\n", elems, bits);
210 fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems);
211 fprintf(c_fp, "\t\tv[i] = recv_u%d(p);\n", bits);
212 fprintf(c_fp, "\t}\n\n");
213 fprintf(c_fp, "\treturn v;\n");
214 fprintf(c_fp, "}\n\n");
216 fprintf(c_fp, fmt_s, elems, bits, elems, bits, "");
217 fprintf(c_fp, "{\n");
218 fprintf(c_fp, "\tv%ds%d v = {0};\n", elems, bits);
219 fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems);
220 fprintf(c_fp, "\t\tv[i] = recv_s%d(p);\n", bits);
221 fprintf(c_fp, "\t}\n\n");
222 fprintf(c_fp, "\treturn v;\n");
223 fprintf(c_fp, "}\n\n");
226 char *fmt_f = "v%df%d recv_v%df%d(DragonnetPeer *p)%s\n";
227 fprintf(h_fp, fmt_f, elems, bits, elems, bits, ";");
229 fprintf(c_fp, fmt_f, elems, bits, elems, bits, "");
230 fprintf(c_fp, "{\n");
231 fprintf(c_fp, "\tv%df%d v = {0};\n", elems, bits);
232 fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems);
233 fprintf(c_fp, "\t\tv[i] = recv_f%d(p);\n", bits);
234 fprintf(c_fp, "\t}\n\n");
235 fprintf(c_fp, "\treturn v;\n");
236 fprintf(c_fp, "}\n\n");
243 for (u8 elems = 2; elems <= 4; ++elems) {
244 for (u8 bits = 8; bits <= 64; bits *= 2) {
245 char *fmt_u = "aabb%du%d recv_aabb%du%d(DragonnetPeer *p)%s\n";
246 char *fmt_s = "aabb%ds%d recv_aabb%ds%d(DragonnetPeer *p)%s\n";
248 fprintf(h_fp, fmt_u, elems, bits, elems, bits, ";");
249 fprintf(h_fp, fmt_s, elems, bits, elems, bits, ";");
251 fprintf(c_fp, fmt_u, elems, bits, elems, bits, "");
252 fprintf(c_fp, "{\n");
253 fprintf(c_fp, "\taabb%du%d v = {0};\n", elems, bits);
254 fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n");
255 fprintf(c_fp, "\t\tv[i] = recv_v%du%d(p);\n", elems, bits);
256 fprintf(c_fp, "\t}\n\n");
257 fprintf(c_fp, "\treturn v;\n");
258 fprintf(c_fp, "}\n\n");
260 fprintf(c_fp, fmt_s, elems, bits, elems, bits, "");
261 fprintf(c_fp, "{\n");
262 fprintf(c_fp, "\taabb%ds%d v = {0};\n", elems, bits);
263 fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n");
264 fprintf(c_fp, "\t\tv[i] = recv_v%ds%d(p);\n", elems, bits);
265 fprintf(c_fp, "\t}\n\n");
266 fprintf(c_fp, "\treturn v;\n");
267 fprintf(c_fp, "}\n\n");
270 char *fmt_f = "aabb%df%d recv_aabb%df%d(DragonnetPeer *p)%s\n";
271 fprintf(h_fp, fmt_f, elems, bits, elems, bits, ";");
273 fprintf(c_fp, fmt_f, elems, bits, elems, bits, "");
274 fprintf(c_fp, "{\n");
275 fprintf(c_fp, "\taabb%df%d v = {0};\n", elems, bits);
276 fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n");
277 fprintf(c_fp, "\t\tv[i] = recv_v%ds%d(p);\n", elems, bits);
278 fprintf(c_fp, "\t}\n\n");
279 fprintf(c_fp, "\treturn v;\n");
280 fprintf(c_fp, "}\n\n");
287 char *fmt_str = "string recv_string(DragonnetPeer *p)%s\n";
288 char *fmt_blob = "Blob *recv_Blob(DragonnetPeer *p)%s\n\n";
290 fprintf(h_fp, fmt_str, ";");
291 fprintf(h_fp, fmt_blob, ";");
293 fprintf(c_fp, fmt_str, "");
294 fprintf(c_fp, "{\n");
295 fprintf(c_fp, "\tstring v = malloc(sizeof(u16));\n\n");
296 fprintf(c_fp, "\tchar ch;\n");
297 fprintf(c_fp, "\tfor (u16 i = 0; ch != '\\0'; ++i) {\n");
298 fprintf(c_fp, "\t\tch = recv_s8(p);\n");
299 fprintf(c_fp, "\t\tv[i] = ch;\n");
300 fprintf(c_fp, "\t}\n\n");
301 fprintf(c_fp, "\tv = realloc(v, strlen(v));\n");
302 fprintf(c_fp, "\treturn v;\n");
303 fprintf(c_fp, "}\n\n");
305 fprintf(c_fp, fmt_blob, "");
306 fprintf(c_fp, "{\n");
307 fprintf(c_fp, "\tBlob *v = malloc(sizeof *v);\n");
308 fprintf(c_fp, "\tv->siz = recv_u32(p, false, v->siz);\n");
309 fprintf(c_fp, "\tv->data = malloc(v->siz);\n");
310 fprintf(c_fp, "\trecv_raw(p, v->data, v->siz);\n\n");
311 fprintf(c_fp, "\treturn v;\n");
312 fprintf(c_fp, "}\n\n");
315 int main(__attribute((unused)) int argc, __attribute((unused)) char **argv)
317 FILE *fp = fopen("types.dnet", "r");
320 memset(data, '\0', sizeof data);
321 fread(data, sizeof *data, sizeof data, fp);
326 FILE *c_fp = fopen("dnet-types.c", "w");
327 fprintf(c_fp, "#include <dragonnet/recv.h>\n");
328 fprintf(c_fp, "#include <dragonnet/send.h>\n\n");
329 fprintf(c_fp, "#include \"dnet-types.h\"\n\n");
331 FILE *h_fp = fopen("dnet-types.h", "w");
332 fprintf(h_fp, "#include <dragontype/number.h>\n\n");
333 fprintf(h_fp, "#define htobe8(x) (x)\n");
334 fprintf(h_fp, "#define be8toh(x) (x)\n\n");
336 gen_serializers(c_fp, h_fp);
337 gen_deserializers(c_fp, h_fp);
340 size_t msgs_len = split(&msgs, data, "\n");
344 for (size_t i = 0; i < msgs_len; ++i) {
345 if (msgs[i][0] != '\t') {
347 fprintf(h_fp, "} %s;\n\n", msg);
350 fprintf(h_fp, "typedef struct {\n");
353 size_t tokens_len = split(&tokens, msgs[i], " ");
355 fprintf(h_fp, "\t%s %s;\n", &tokens[0][1], tokens[1]);
356 free_split(tokens, tokens_len);
361 fprintf(h_fp, "} %s;\n\n", msg);
364 // Create (de)serialization functions
365 for (size_t i = 0; i < msgs_len; ++i) {
366 if (msgs[i][0] != '\t') {
368 fprintf(c_fp, "}\n\n");
371 fprintf(c_fp, "void dragonnet_send_%s(DragonnetPeer *p, %s type)\n{\n", msg, msg);
374 size_t tokens_len = split(&tokens, msgs[i], " ");
376 if (i >= msgs_len-1 || msgs[1+i][0] != '\t')
377 fprintf(c_fp, "\tsend_%s(p, true, type.%s);\n", &tokens[0][1], tokens[1]);
379 fprintf(c_fp, "\tsend_%s(p, false, type.%s);\n", &tokens[0][1], tokens[1]);
381 free_split(tokens, tokens_len);
386 fprintf(c_fp, "}\n\n");
389 for (size_t i = 0; i < msgs_len; ++i) {
390 if (msgs[i][0] != '\t') {
392 fprintf(c_fp, "\treturn type;\n");
393 fprintf(c_fp, "}\n\n");
397 fprintf(c_fp, "%s dragonnet_recv_%s(DragonnetPeer *p)\n{\n", msg, msg);
398 fprintf(c_fp, "\t%s type = {0};\n", msg);
401 size_t tokens_len = split(&tokens, msgs[i], " ");
403 fprintf(c_fp, "\ttype.%s = recv_%s(p);\n", tokens[1], &tokens[0][1]);
404 free_split(tokens, tokens_len);
409 fprintf(c_fp, "\treturn type;\n");
410 fprintf(c_fp, "}\n");
415 for (size_t i = 0; i < msgs_len; ++i)
416 if (msgs[i][0] != '\t')
419 fprintf(h_fp, "typedef enum {\n");
420 for (size_t i = 0; i < msgs_len; ++i) {
421 if (msgs[i][0] == '\t')
424 char upper[1 + strlen(msgs[i])];
426 strcpy(upper, msgs[i]);
428 while ((*ptr = *ptr ? toupper(*ptr) : '\0'))
432 fprintf(h_fp, "\tDRAGONNET_TYPE_%s\n", upper);
434 fprintf(h_fp, "\tDRAGONNET_TYPE_%s,\n", upper);
437 fprintf(h_fp, "} DragonnetType;\n");
439 free_split(msgs, msgs_len);