]> git.lizzy.rs Git - dragonnet.git/commitdiff
Add socket (de)serialization generator
authorHimbeerserverDE <himbeerserverde@gmail.com>
Tue, 5 Oct 2021 18:34:01 +0000 (20:34 +0200)
committerHimbeerserverDE <himbeerserverde@gmail.com>
Tue, 5 Oct 2021 18:34:01 +0000 (20:34 +0200)
typegen/main.c

index 6a1b9044ca12d059cc9f16860bbde71a77029484..c778026e7f2fc34d42241eeca7d7ec67fc37e07b 100644 (file)
@@ -9,101 +9,124 @@ static size_t split(char ***strs, char *s, const char *delim)
        size_t i = 0;
        *strs = malloc((1+i) * sizeof(char *));
 
-       char *tok = strtok(s, delim);
+       // Can't be allocated on the stack for some reason
+       char *str = malloc(1+strlen(s));
+       strcpy(str, s);
+
+       char *tok = strtok(str, delim);
        while (tok != NULL) {
                *strs = realloc(*strs, (1+i) * sizeof(char *));
-               (*strs)[i++] = tok;
+               (*strs)[i++] = strdup(tok);
                tok = strtok(NULL, delim);
        }
 
+       free(str);
        return i;
 }
 
+static void free_split(char **strs, size_t n)
+{
+       for (size_t i = 0; i < n; ++i)
+               free(strs[i]);
+
+       free(strs);
+}
+
 int main(__attribute((unused)) int argc, __attribute((unused)) char **argv)
 {
        FILE *fp = fopen("types.dnet", "r");
 
        char data[1 << 16];
-       memset(data, 0, sizeof data);
+       memset(data, '\0', sizeof data);
        fread(data, sizeof *data, sizeof data, fp);
 
        fclose(fp);
-       fp = fopen("dnet-types.h", "w");
-       fprintf(fp, "#include <dragontype/number.h>\n\n");
+       fp = NULL;
+
+       FILE *c_fp = fopen("dnet-types.c", "w");
+       fprintf(c_fp, "#include \"dnet-types.h\"\n");
+       fprintf(c_fp, "#include <dragonnet/send.h>\n\n");
+
+       FILE *h_fp = fopen("dnet-types.h", "w");
+       fprintf(h_fp, "#include <dragontype/number.h>\n\n");
 
        char **msgs;
        size_t msgs_len = split(&msgs, data, "\n");
 
+       // Create data types
        char *msg = NULL;
        for (size_t i = 0; i < msgs_len; ++i) {
                if (msgs[i][0] != '\t') {
                        if (msg != NULL)
-                               fprintf(fp, "} %s;\n\n", msg);
+                               fprintf(h_fp, "} %s;\n\n", msg);
 
                        msg = msgs[i];
-                       fprintf(fp, "typedef struct {\n");
+                       fprintf(h_fp, "typedef struct {\n");
                } else {
                        char **tokens;
-                       split(&tokens, msgs[i], " ");
-
-                       char type[15];
-                       if (    // Numeric types
-                                       strcmp(&tokens[0][1], "u8") == 0 || strcmp(&tokens[0][1], "s8")
-                                       || strcmp(&tokens[0][1], "u16") || strcmp(&tokens[0][1], "s16")
-                                       || strcmp(&tokens[0][1], "u32") || strcmp(&tokens[0][1], "s32")
-                                       || strcmp(&tokens[0][1], "u64") || strcmp(&tokens[0][1], "s64")
-                                       || strcmp(&tokens[0][1], "f32") || strcmp(&tokens[0][1], "f64")
-                                       // Vectors (2 elements)
-                                       || strcmp(&tokens[0][1], "v2u8") || strcmp(&tokens[0][1], "v2s8")
-                                       || strcmp(&tokens[0][1], "v2u16") || strcmp(&tokens[0][1], "v2s16")
-                                       || strcmp(&tokens[0][1], "v2u32") || strcmp(&tokens[0][1], "v2s32")
-                                       || strcmp(&tokens[0][1], "v2u64") || strcmp(&tokens[0][1], "v2s64")
-                                       || strcmp(&tokens[0][1], "v2f32") || strcmp(&tokens[0][1], "v2f32")
-                                       || strcmp(&tokens[0][1], "v2f64") || strcmp(&tokens[0][1], "v2f64")
-                                       // Vectors (3 elements)
-                                       || strcmp(&tokens[0][1], "v3u8") || strcmp(&tokens[0][1], "v3s8")
-                                       || strcmp(&tokens[0][1], "v3u16") || strcmp(&tokens[0][1], "v3s16")
-                                       || strcmp(&tokens[0][1], "v3u32") || strcmp(&tokens[0][1], "v3s32")
-                                       || strcmp(&tokens[0][1], "v3u64") || strcmp(&tokens[0][1], "v3s64")
-                                       || strcmp(&tokens[0][1], "v3f32") || strcmp(&tokens[0][1], "v3f64")
-                                       // Vectors (4 elements)
-                                       || strcmp(&tokens[0][1], "v4u8") || strcmp(&tokens[0][1], "v4s8")
-                                       || strcmp(&tokens[0][1], "v4u16") || strcmp(&tokens[0][1], "v4s16")
-                                       || strcmp(&tokens[0][1], "v4u32") || strcmp(&tokens[0][1], "v4s32")
-                                       || strcmp(&tokens[0][1], "v4u64") || strcmp(&tokens[0][1], "v4s64")
-                                       || strcmp(&tokens[0][1], "v4f32") || strcmp(&tokens[0][1], "v4f64")
-                                       // AABB2
-                                       || strcmp(&tokens[0][1], "aabb2u8") || strcmp(&tokens[0][1], "aabb2s8")
-                                       || strcmp(&tokens[0][1], "aabb2u16") || strcmp(&tokens[0][1], "aabb2s16")
-                                       || strcmp(&tokens[0][1], "aabb2u32") || strcmp(&tokens[0][1], "aabb2s32")
-                                       || strcmp(&tokens[0][1], "aabb2u64") || strcmp(&tokens[0][1], "aabb2s64")
-                                       || strcmp(&tokens[0][1], "aabb2f32") || strcmp(&tokens[0][1], "aabb2f64")
-                                       // AABB3
-                                       || strcmp(&tokens[0][1], "aabb3u8") || strcmp(&tokens[0][1], "aabb3s8")
-                                       || strcmp(&tokens[0][1], "aabb3u16") || strcmp(&tokens[0][1], "aabb3s16")
-                                       || strcmp(&tokens[0][1], "aabb3u32") || strcmp(&tokens[0][1], "aabb3s32")
-                                       || strcmp(&tokens[0][1], "aabb3u64") || strcmp(&tokens[0][1], "aabb3s64")
-                                       || strcmp(&tokens[0][1], "aabb3f32") || strcmp(&tokens[0][1], "aabb3f64")
-                                       // AABB4
-                                       || strcmp(&tokens[0][1], "aabb4u8") || strcmp(&tokens[0][1], "aabb4s8")
-                                       || strcmp(&tokens[0][1], "aabb4u16") || strcmp(&tokens[0][1], "aabb4s16")
-                                       || strcmp(&tokens[0][1], "aabb4u32") || strcmp(&tokens[0][1], "aabb4s32")
-                                       || strcmp(&tokens[0][1], "aabb4u64") || strcmp(&tokens[0][1], "aabb4s64")
-                                       || strcmp(&tokens[0][1], "aabb4f32") || strcmp(&tokens[0][1], "aabb4f64"))
-                               sprintf(type, "%s ", &tokens[0][1]);
-                       else if (strcmp(&tokens[0][1], "string"))
-                               // String
-                               strcpy(type, "char *");
-                       else if (strcmp(&tokens[0][1], "blob"))
-                               // Blob
-                               strcpy(type, "DragonnetBlob ");
-
-                       fprintf(fp, "\t%s%s;\n", type, tokens[1]);
-                       free(tokens);
+                       size_t tokens_len = split(&tokens, msgs[i], " ");
+
+                       fprintf(h_fp, "\t%s %s;\n", &tokens[0][1], tokens[1]);
+                       free_split(tokens, tokens_len);
+                       tokens = NULL;
                }
        }
 
-       fprintf(fp, "} %s;\n\ntypedef enum {\n", msg);
+       fprintf(h_fp, "} %s;\n\n", msg);
+       msg = NULL;
+
+       // Create (de)serialization functions
+       for (size_t i = 0; i < msgs_len; ++i) {
+               if (msgs[i][0] != '\t') {
+                       if (msg != NULL)
+                               fprintf(c_fp, "}\n\n");
+
+                       msg = msgs[i];
+                       fprintf(c_fp, "void dragonnet_send_%s(DragonnetPeer *p, %s type)\n{\n", msg, msg);
+               } else {
+                       char **tokens;
+                       size_t tokens_len = split(&tokens, msgs[i], " ");
+
+                       fprintf(c_fp, "\tsend_%s(p, type.%s);\n", &tokens[0][1], tokens[1]);
+                       free_split(tokens, tokens_len);
+                       tokens = NULL;
+               }
+       }
+
+       fprintf(c_fp, "}\n\n");
+       msg = NULL;
+
+       for (size_t i = 0; i < msgs_len; ++i) {
+               if (msgs[i][0] != '\t') {
+                       if (msg != NULL) {
+                               fprintf(c_fp, "\treturn type;\n");
+                               fprintf(c_fp, "}\n\n");
+                       }
+
+                       msg = msgs[i];
+                       fprintf(c_fp, "%s dragonnet_recv_%s(DragonnetPeer *p)\n{\n", msg, msg);
+                       fprintf(c_fp, "\t%s type = {0};\n", msg);
+               } else {
+                       char **tokens;
+                       size_t tokens_len = split(&tokens, msgs[i], " ");
+
+                       fprintf(c_fp, "\ttype.%s = recv_%s(p);\n", tokens[1], &tokens[0][1]);
+                       free_split(tokens, tokens_len);
+                       tokens = NULL;
+               }
+       }
+
+       fprintf(c_fp, "\treturn type;\n");
+       fprintf(c_fp, "}\n");
+       msg = NULL;
+
+       // Create type enum
+       size_t last_msg = 0;
+       for (size_t i = 0; i < msgs_len; ++i)
+               if (msgs[i][0] != '\t')
+                       last_msg = i;
+
+       fprintf(h_fp, "typedef enum {\n");
        for (size_t i = 0; i < msgs_len; ++i) {
                if (msgs[i][0] == '\t')
                        continue;
@@ -115,14 +138,19 @@ int main(__attribute((unused)) int argc, __attribute((unused)) char **argv)
                while ((*ptr = *ptr ? toupper(*ptr) : '\0'))
                        ++ptr;
 
-               if (i == msgs_len-1)
-                       fprintf(fp, "\tDRAGONNET_TYPE_%s\n", upper);
+               if (i == last_msg)
+                       fprintf(h_fp, "\tDRAGONNET_TYPE_%s\n", upper);
                else
-                       fprintf(fp, "\tDRAGONNET_TYPE_%s,\n", upper);
+                       fprintf(h_fp, "\tDRAGONNET_TYPE_%s,\n", upper);
        }
 
-       fprintf(fp, "} DragonnetType;\n");
+       fprintf(h_fp, "} DragonnetType;\n");
 
-       free(msgs);
-       fclose(fp);
+       free_split(msgs, msgs_len);
+       msgs = NULL;
+
+       fclose(c_fp);
+       fclose(h_fp);
+       c_fp = NULL;
+       h_fp = NULL;
 }