]> git.lizzy.rs Git - dragonnet.git/commitdiff
Implement deallocators
authorElias Fleckenstein <eliasfleckenstein@web.de>
Sun, 30 Jan 2022 20:13:45 +0000 (21:13 +0100)
committerElias Fleckenstein <eliasfleckenstein@web.de>
Sun, 30 Jan 2022 20:13:45 +0000 (21:13 +0100)
typegen/main.c

index f1eabf1b138e6933c1406a03f0fc422c98925b1a..e7e72ec3c66363a31648777d0eec85057a78a592 100644 (file)
@@ -73,7 +73,7 @@ static char *process_array(FILE *fp, char *src)
 
 static void gen_serializers(FILE *c_fp)
 {
-       fprintf(c_fp, "void raw_buf_read(Blob blob, void *data, size_t len)\n");
+       fprintf(c_fp, FUNC "void raw_buf_read(Blob blob, void *data, size_t len)\n");
        fprintf(c_fp, "{\n");
        fprintf(c_fp, "\tmemcpy(data, blob->data, len);\n");
        fprintf(c_fp, "\tmemcpy(blob->data, &blob->data[len], -len + blob->siz);\n");
@@ -81,7 +81,7 @@ static void gen_serializers(FILE *c_fp)
        fprintf(c_fp, "\tblob->siz -= len;\n");
        fprintf(c_fp, "\t}\n\n");
 
-       fprintf(c_fp, "void raw_buf_write(Blob blob, const void *data, size_t len)\n");
+       fprintf(c_fp, FUNC "void raw_buf_write(Blob blob, const void *data, size_t len)\n");
        fprintf(c_fp, "{\n");
        fprintf(c_fp, "\tblob->data = realloc(blob->data, len + blob->siz);\n");
        fprintf(c_fp, "\tmemcpy(&blob->data[blob->siz], data, len);\n");
@@ -583,6 +583,32 @@ static void gen_buffer_deserializers(FILE *c_fp)
        fprintf(c_fp, "}\n\n");
 }
 
+static void gen_deallocators(FILE *c_fp)
+{
+       for (u8 bits = 8; bits <= 64; bits *= 2) {
+               fprintf(c_fp, FUNC "void free_u%d(__attribute__((unused)) u%d v) {}\n", bits, bits);
+               fprintf(c_fp, FUNC "void free_s%d(__attribute__((unused)) s%d v) {}\n", bits, bits);
+               if (bits >= 32)
+                       fprintf(c_fp, FUNC "void free_f%d(__attribute__((unused)) f%d v) {}\n", bits, bits);
+
+               for (u8 elems = 2; elems <= 4; ++elems) {
+                       fprintf(c_fp, FUNC "void free_v%du%d(__attribute__((unused)) v%du%d v) {}\n", elems, bits, elems, bits);
+                       fprintf(c_fp, FUNC "void free_v%ds%d(__attribute__((unused)) v%ds%d v) {}\n", elems, bits, elems, bits);
+                       if (bits >= 32)
+                               fprintf(c_fp, FUNC "void free_v%df%d(__attribute__((unused)) v%df%d v) {}\n", elems, bits, elems, bits);
+
+                       fprintf(c_fp, FUNC "void free_aabb%du%d(__attribute__((unused)) aabb%du%d v) {}\n", elems, bits, elems, bits);
+                       fprintf(c_fp, FUNC "void free_aabb%ds%d(__attribute__((unused)) aabb%ds%d v) {}\n", elems, bits, elems, bits);
+                       if (bits >= 32)
+                               fprintf(c_fp, FUNC "void free_aabb%df%d(__attribute__((unused)) aabb%df%d v) {}\n", elems, bits, elems, bits);
+               }
+       }
+
+       fprintf(c_fp, FUNC "\nvoid free_string(string str)\n{\n\tfree(str);\n}\n\n");
+       fprintf(c_fp, FUNC "void free_Blob(Blob blob)\n{\n\tdragonnet_free_Blob(blob);\n}\n\n");
+       fprintf(c_fp, FUNC "void free_CompressedBlob(CompressedBlob comp)\n{\n\tdragonnet_free_CompressedBlob(comp);\n}\n\n");
+}
+
 int main(__attribute((unused)) int argc, __attribute((unused)) char **argv)
 {
        FILE *fp = fopen("types.dnet", "r");
@@ -618,6 +644,8 @@ int main(__attribute((unused)) int argc, __attribute((unused)) char **argv)
        fprintf(h_fp, "\tThis file was automatically generated by Dragonnet.\n");
        fprintf(h_fp, "\tDo NOT edit it manually. Instead, edit types.dnet and re-run DragonnetTypegen.\n");
        fprintf(h_fp, "*/\n\n");
+       fprintf(h_fp, "#ifndef _DRAGONNET_TYPES_H_\n");
+       fprintf(h_fp, "#define _DRAGONNET_TYPES_H_\n");
        fprintf(h_fp, "#include <dragonnet/peer.h>\n");
        fprintf(h_fp, "#include <dragontype/number.h>\n");
        fprintf(h_fp, "#include <stddef.h>\n");
@@ -628,12 +656,49 @@ int main(__attribute((unused)) int argc, __attribute((unused)) char **argv)
        fprintf(h_fp, "\tBlob blob;\n");
        fprintf(h_fp, "} *CompressedBlob;\n\n");
 
+       // buffer allocation
+       fprintf(h_fp, "Blob dragonnet_create_Blob();\n");
+       fprintf(h_fp, "void dragonnet_free_Blob(Blob blob);\n\n");
+       fprintf(h_fp, "CompressedBlob dragonnet_create_CompressedBlob();\n");
+       fprintf(h_fp, "void dragonnet_free_CompressedBlob(CompressedBlob comp);\n\n");
+
+       fprintf(c_fp, "Blob dragonnet_create_Blob()\n");
+       fprintf(c_fp, "{\n");
+       fprintf(c_fp, "\tBlob blob = malloc(sizeof *blob);\n");
+       fprintf(c_fp, "\tblob->data = NULL;\n");
+       fprintf(c_fp, "\tblob->siz = 0;\n");
+       fprintf(c_fp, "\treturn blob;\n");
+       fprintf(c_fp, "}\n\n");
+
+       fprintf(c_fp, "void dragonnet_free_Blob(Blob blob)\n");
+       fprintf(c_fp, "{\n");
+       fprintf(c_fp, "\tif (blob->data)\n");
+       fprintf(c_fp, "\t\tfree(blob->data);\n");
+       fprintf(c_fp, "\tfree(blob);\n");
+       fprintf(c_fp, "}\n\n");
+
+       fprintf(c_fp, "CompressedBlob dragonnet_create_CompressedBlob()\n");
+       fprintf(c_fp, "{\n");
+       fprintf(c_fp, "\tCompressedBlob comp = malloc(sizeof *comp);\n");
+       fprintf(c_fp, "\tcomp->blob = dragonnet_create_Blob();\n");
+       fprintf(c_fp, "\tcomp->siz = 0;\n");
+       fprintf(c_fp, "\treturn comp;\n");
+       fprintf(c_fp, "}\n\n");
+
+       fprintf(c_fp, "void dragonnet_free_CompressedBlob(CompressedBlob comp)\n");
+       fprintf(c_fp, "{\n");
+       fprintf(c_fp, "\tdragonnet_free_Blob(comp->blob);\n");
+       fprintf(c_fp, "\tfree(comp);\n");
+       fprintf(c_fp, "}\n\n");
+
        gen_serializers(c_fp);
        gen_deserializers(c_fp);
 
        gen_buffer_serializers(c_fp);
        gen_buffer_deserializers(c_fp);
 
+       gen_deallocators(c_fp);
+
        char **msgs;
        size_t msgs_len = split(&msgs, data, "\n");
 
@@ -824,6 +889,33 @@ int main(__attribute((unused)) int argc, __attribute((unused)) char **argv)
        fprintf(c_fp, "}\n\n");
        msg = NULL;
 
+       // Deallocators
+       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(h_fp, "void dragonnet_free_%s(%s type);", msg, msg);
+                       fprintf(c_fp, "void free_%s(%s type)\n{\n", msg, msg);
+                       fprintf(c_fp, "\tdragonnet_free_%s(type);\n}\n\n", msg);
+                       fprintf(c_fp, "void dragonnet_free_%s(%s type)\n{\n", msg, msg);
+               } else {
+                       char **tokens;
+                       size_t tokens_len = split(&tokens, msgs[i], " ");
+
+                       char *arr = process_array(c_fp, tokens[1]);
+                       fprintf(c_fp, "free_%s(type.%s%s);\n", &tokens[0][1], tokens[1], arr);
+                       free(arr);
+
+                       free_split(tokens, tokens_len);
+                       tokens = NULL;
+               }
+       }
+
+       fprintf(c_fp, "}\n\n");
+       msg = NULL;
+
        // Create type enum
        fprintf(h_fp, "typedef enum {\n");
        for (size_t i = 0; i < msgs_len; ++i) {
@@ -842,6 +934,7 @@ int main(__attribute((unused)) int argc, __attribute((unused)) char **argv)
 
        fprintf(h_fp, "\tDRAGONNET_NUM_TYPES\n");
        fprintf(h_fp, "} DragonnetTypeNum;\n");
+       fprintf(h_fp, "\n#endif\n");
 
        // ABI
        fprintf(c_fp, "u16 dragonnet_num_types = DRAGONNET_NUM_TYPES;\n");