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 = "__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";
44 fprintf(c_fp, fmt_u, bits, bits);
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");
50 fprintf(c_fp, fmt_s, bits, bits, "");
52 fprintf(c_fp, "\tsend_u%d(p, submit, (u%d) v);\n", bits, bits);
53 fprintf(c_fp, "}\n\n");
56 char *fmt_f = "static void send_f%d(DragonnetPeer *p, bool submit, f%d v)\n";
58 fprintf(c_fp, fmt_f, bits, bits);
60 fprintf(c_fp, "\tsend_u%d(p, submit, (u%d) v);\n", bits, bits);
61 fprintf(c_fp, "}\n\n");
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";
70 fprintf(c_fp, fmt_u, elems, bits, elems, bits);
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");
78 fprintf(c_fp, fmt_s, elems, bits, elems, bits);
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");
87 char *fmt_f = "__attribute__((unused)) static void send_v%df%d(DragonnetPeer *p, bool submit, v%df%d v)\n";
89 fprintf(c_fp, fmt_f, elems, bits, elems, bits);
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");
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";
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");
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");
122 char *fmt_f = "__attribute__((unused)) static void send_aabb%df%d(DragonnetPeer *p, bool submit, aabb%df%d v)\n";
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");
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");
140 fprintf(c_fp, "__attribute__((unused)) static void send_Blob(DragonnetPeer *p, bool submit, Blob *v)\n\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");
147 static void gen_deserializers(FILE *c_fp)
149 for (u8 bits = 8; bits <= 64; bits *= 2) {
150 char *fmt_u = "__attribute__((unused)) static u%d recv_u%d(DragonnetPeer *p)\n";
151 char *fmt_s = "__attribute__((unused)) static s%d recv_s%d(DragonnetPeer *p)\n";
153 fprintf(c_fp, fmt_u, bits, bits);
154 fprintf(c_fp, "{\n");
155 fprintf(c_fp, "\tu%d be;\n", bits);
156 fprintf(c_fp, "\tdragonnet_recv_raw(p, &be, sizeof be);\n");
157 fprintf(c_fp, "\treturn be%dtoh(be);\n", bits);
158 fprintf(c_fp, "}\n\n");
160 fprintf(c_fp, fmt_s, bits, bits);
161 fprintf(c_fp, "{\n");
162 fprintf(c_fp, "\treturn (s%d) recv_u%d(p);\n", bits, bits);
163 fprintf(c_fp, "}\n\n");
166 char *fmt_f = "__attribute__((unused)) static f%d recv_f%d(DragonnetPeer *p)\n";
168 fprintf(c_fp, fmt_f, bits, bits);
169 fprintf(c_fp, "{\n");
170 fprintf(c_fp, "\treturn (f%d) recv_u%d(p);\n", bits, bits);
171 fprintf(c_fp, "}\n\n");
175 for (u8 elems = 2; elems <= 4; ++elems) {
176 for (u8 bits = 8; bits <= 64; bits *= 2) {
177 char *fmt_u = "__attribute__((unused)) static v%du%d recv_v%du%d(DragonnetPeer *p)\n";
178 char *fmt_s = "__attribute__((unused)) static v%ds%d recv_v%ds%d(DragonnetPeer *p)\n";
180 fprintf(c_fp, fmt_u, elems, bits, elems, bits);
181 fprintf(c_fp, "{\n");
182 fprintf(c_fp, "\tv%du%d v = {0};\n", elems, bits);
183 fprintf(c_fp, "\tu%d *ptr = &v.x;\n\n", bits);
184 fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems);
185 fprintf(c_fp, "\t\t*ptr++ = recv_u%d(p);\n", bits);
186 fprintf(c_fp, "\t}\n\n");
187 fprintf(c_fp, "\treturn v;\n");
188 fprintf(c_fp, "}\n\n");
190 fprintf(c_fp, fmt_s, elems, bits, elems, bits);
191 fprintf(c_fp, "{\n");
192 fprintf(c_fp, "\tv%ds%d v = {0};\n", elems, bits);
193 fprintf(c_fp, "\ts%d *ptr = &v.x;\n\n", bits);
194 fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems);
195 fprintf(c_fp, "\t\t*ptr++ = recv_s%d(p);\n", bits);
196 fprintf(c_fp, "\t}\n\n");
197 fprintf(c_fp, "\treturn v;\n");
198 fprintf(c_fp, "}\n\n");
201 char *fmt_f = "__attribute__((unused)) static v%df%d recv_v%df%d(DragonnetPeer *p)\n";
203 fprintf(c_fp, fmt_f, elems, bits, elems, bits);
204 fprintf(c_fp, "{\n");
205 fprintf(c_fp, "\tv%df%d v = {0};\n", elems, bits);
206 fprintf(c_fp, "\tf%d *ptr = &v.x;\n\n", bits);
207 fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems);
208 fprintf(c_fp, "\t\t*ptr++ = recv_f%d(p);\n", bits);
209 fprintf(c_fp, "\t}\n\n");
210 fprintf(c_fp, "\treturn v;\n");
211 fprintf(c_fp, "}\n\n");
216 for (u8 elems = 2; elems <= 4; ++elems) {
217 for (u8 bits = 8; bits <= 64; bits *= 2) {
218 char *fmt_u = "__attribute__((unused)) static aabb%du%d recv_aabb%du%d(DragonnetPeer *p)\n";
219 char *fmt_s = "__attribute__((unused)) static aabb%ds%d recv_aabb%ds%d(DragonnetPeer *p)\n";
221 fprintf(c_fp, fmt_u, elems, bits, elems, bits);
222 fprintf(c_fp, "{\n");
223 fprintf(c_fp, "\taabb%du%d v = {0};\n", elems, bits);
224 fprintf(c_fp, "\tv%du%d *ptr = &v.min;\n\n", elems, bits);
225 fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n");
226 fprintf(c_fp, "\t\t*ptr++ = recv_v%du%d(p);\n", elems, bits);
227 fprintf(c_fp, "\t}\n\n");
228 fprintf(c_fp, "\treturn v;\n");
229 fprintf(c_fp, "}\n\n");
231 fprintf(c_fp, fmt_s, elems, bits, elems, bits);
232 fprintf(c_fp, "{\n");
233 fprintf(c_fp, "\taabb%ds%d v = {0};\n", elems, bits);
234 fprintf(c_fp, "\tv%ds%d *ptr = &v.min;\n\n", elems, bits);
235 fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n");
236 fprintf(c_fp, "\t\t*ptr++ = recv_v%ds%d(p);\n", elems, bits);
237 fprintf(c_fp, "\t}\n\n");
238 fprintf(c_fp, "\treturn v;\n");
239 fprintf(c_fp, "}\n\n");
242 char *fmt_f = "__attribute__((unused)) static aabb%df%d recv_aabb%df%d(DragonnetPeer *p)\n";
244 fprintf(c_fp, fmt_f, elems, bits, elems, bits);
245 fprintf(c_fp, "{\n");
246 fprintf(c_fp, "\taabb%df%d v = {0};\n", elems, bits);
247 fprintf(c_fp, "\tv%df%d *ptr = &v.min;\n\n", elems, bits);
248 fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n");
249 fprintf(c_fp, "\t\t*ptr++ = recv_v%df%d(p);\n", elems, bits);
250 fprintf(c_fp, "\t}\n\n");
251 fprintf(c_fp, "\treturn v;\n");
252 fprintf(c_fp, "}\n\n");
257 fprintf(c_fp, "__attribute__((unused)) static string recv_string(DragonnetPeer *p)\n");
258 fprintf(c_fp, "{\n");
259 fprintf(c_fp, "\tstring v = malloc(sizeof(u16));\n\n");
260 fprintf(c_fp, "\tchar ch;\n");
261 fprintf(c_fp, "\tfor (u16 i = 0; ch != '\\0'; ++i) {\n");
262 fprintf(c_fp, "\t\tch = recv_s8(p);\n");
263 fprintf(c_fp, "\t\tv[i] = ch;\n");
264 fprintf(c_fp, "\t}\n\n");
265 fprintf(c_fp, "\tv = realloc(v, strlen(v));\n");
266 fprintf(c_fp, "\treturn v;\n");
267 fprintf(c_fp, "}\n\n");
269 fprintf(c_fp, "__attribute__((unused)) static Blob *recv_Blob(DragonnetPeer *p)\n\n");
270 fprintf(c_fp, "{\n");
271 fprintf(c_fp, "\tBlob *v = malloc(sizeof *v);\n");
272 fprintf(c_fp, "\tv->siz = recv_u32(p);\n");
273 fprintf(c_fp, "\tv->data = malloc(v->siz);\n");
274 fprintf(c_fp, "\tdragonnet_recv_raw(p, v->data, v->siz);\n\n");
275 fprintf(c_fp, "\treturn v;\n");
276 fprintf(c_fp, "}\n\n");
279 int main(__attribute((unused)) int argc, __attribute((unused)) char **argv)
281 FILE *fp = fopen("types.dnet", "r");
284 memset(data, '\0', sizeof data);
285 fread(data, sizeof *data, sizeof data, fp);
290 FILE *c_fp = fopen("dnet-types.c", "w");
291 fprintf(c_fp, "#include <stdlib.h>\n");
292 fprintf(c_fp, "#include <string.h>\n");
293 fprintf(c_fp, "#include <dragonnet/recv.h>\n");
294 fprintf(c_fp, "#include <dragonnet/send.h>\n\n");
295 fprintf(c_fp, "#include \"dnet-types.h\"\n\n");
297 FILE *h_fp = fopen("dnet-types.h", "w");
298 fprintf(h_fp, "#include <dragontype/number.h>\n\n");
299 fprintf(h_fp, "#define htobe8(x) (x)\n");
300 fprintf(h_fp, "#define be8toh(x) (x)\n\n");
302 gen_serializers(c_fp, h_fp);
303 gen_deserializers(c_fp);
306 size_t msgs_len = split(&msgs, data, "\n");
310 for (size_t i = 0; i < msgs_len; ++i) {
311 if (msgs[i][0] != '\t') {
313 fprintf(h_fp, "} %s;\n\n", msg);
316 fprintf(h_fp, "typedef struct {\n");
319 size_t tokens_len = split(&tokens, msgs[i], " ");
321 fprintf(h_fp, "\t%s %s;\n", &tokens[0][1], tokens[1]);
322 free_split(tokens, tokens_len);
327 fprintf(h_fp, "} %s;\n\n", msg);
330 // Create (de)serialization functions
331 for (size_t i = 0; i < msgs_len; ++i) {
332 if (msgs[i][0] != '\t') {
334 fprintf(c_fp, "}\n\n");
337 fprintf(c_fp, "__attribute__((unused)) static void send_%s(DragonnetPeer *p, %s type)\n{\n", msg, msg);
340 size_t tokens_len = split(&tokens, msgs[i], " ");
342 fprintf(c_fp, "\tsend_%s(p, false, type.%s);\n", &tokens[0][1], tokens[1]);
344 free_split(tokens, tokens_len);
349 fprintf(c_fp, "}\n\n");
352 for (size_t i = 0; i < msgs_len; ++i) {
353 if (msgs[i][0] != '\t') {
355 fprintf(c_fp, "}\n\n");
358 fprintf(h_fp, "void dragonnet_peer_send_%s(DragonnetPeer *p, %s type);\n", msg, msg);
359 fprintf(c_fp, "void dragonnet_peer_send_%s(DragonnetPeer *p, %s type)\n{\n", msg, msg);
361 char upper[1 + strlen(msgs[i])];
365 while ((*ptr = *ptr ? toupper(*ptr) : '\0'))
368 fprintf(c_fp, "\tsend_u16(p, false, DRAGONNET_TYPE_%s);\n", upper);
371 size_t tokens_len = split(&tokens, msgs[i], " ");
373 if (i >= msgs_len-1 || msgs[1+i][0] != '\t')
374 fprintf(c_fp, "\tsend_%s(p, true, type.%s);\n", &tokens[0][1], tokens[1]);
376 fprintf(c_fp, "\tsend_%s(p, false, type.%s);\n", &tokens[0][1], tokens[1]);
378 free_split(tokens, tokens_len);
383 fprintf(c_fp, "}\n\n");
386 for (size_t i = 0; i < msgs_len; ++i) {
387 if (msgs[i][0] != '\t') {
389 fprintf(c_fp, "\treturn type;\n");
390 fprintf(c_fp, "}\n\n");
394 fprintf(h_fp, "%s dragonnet_peer_recv_%s(DragonnetPeer *p);\n", msg, msg);
395 fprintf(c_fp, "%s dragonnet_peer_recv_%s(DragonnetPeer *p)\n{\n", msg, msg);
396 fprintf(c_fp, "\t%s type = {0};\n", msg);
399 size_t tokens_len = split(&tokens, msgs[i], " ");
401 fprintf(c_fp, "\ttype.%s = recv_%s(p);\n", tokens[1], &tokens[0][1]);
402 free_split(tokens, tokens_len);
408 fprintf(c_fp, "\treturn type;\n");
409 fprintf(c_fp, "}\n");
414 for (size_t i = 0; i < msgs_len; ++i)
415 if (msgs[i][0] != '\t')
418 fprintf(h_fp, "typedef enum {\n");
419 for (size_t i = 0; i < msgs_len; ++i) {
420 if (msgs[i][0] == '\t')
423 char upper[1 + strlen(msgs[i])];
425 strcpy(upper, msgs[i]);
427 while ((*ptr = *ptr ? toupper(*ptr) : '\0'))
431 fprintf(h_fp, "\tDRAGONNET_TYPE_%s\n", upper);
433 fprintf(h_fp, "\tDRAGONNET_TYPE_%s,\n", upper);
436 fprintf(h_fp, "} DragonnetType;\n");
438 free_split(msgs, msgs_len);