]> git.lizzy.rs Git - protogen.git/blobdiff - protogen.lua
Update endian include
[protogen.git] / protogen.lua
index 130859de31eae28eccafc12be6aa1545ec21b4a6..1139a9da846149e80e71041d53f01554a3afea29 100755 (executable)
@@ -3,7 +3,7 @@ require "luax"
 
 local h   = io.open("types.h",   "w")
 local c   = io.open("types.c",   "w")
-local def = io.open("types.def", "r")
+local def = io.open(arg[1] or "types.def", "r")
 
 local function emit_h(str)
        h:write(str)
@@ -49,7 +49,7 @@ emit_h([[
 typedef char *String;
 
 typedef struct {
-       size_t siz;
+       uint64_t siz;
        unsigned char *data;
 } ]] .. struct_prefix .. [[Blob;
 
@@ -63,7 +63,8 @@ emit_c([[
 #include <dragonnet/recv.h>
 #endif
 
-#include <endian.h/endian.h>
+#include <endian.h>
+#include <inttypes.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdlib.h>
@@ -88,7 +89,7 @@ emit_c([[
                return true;
 
        if (buffer->siz < len) {
-               fprintf(stderr, "[warning] buffer exhausted (requested bytes: %lu, remaining bytes: %lu)\n", len, buffer->siz);
+               fprintf(stderr, "[warning] buffer exhausted (requested bytes: %zu, remaining bytes: %" PRIu64 ")\n", len, buffer->siz);
                return false;
        }
 
@@ -122,6 +123,8 @@ end
 
 -- numeric types
 
+local numeric_types = {}
+
 local function emit_vector(type, l)
        local name = "v" .. l .. type
        local box = "aabb" .. l .. type
@@ -132,16 +135,8 @@ local function emit_vector(type, l)
        existing_types[box] = true
        has_deallocator[box] = false
 
-       local typedef, equals, add, clamp, cmp, scale, mix, write, read, send, recv =
-                  "",     "",  "",    "",  "",    "",  "",    "",   "",   "",   ""
-
-       typedef = typedef .. "\t" .. type .. " "
-       equals  = equals  .. "\treturn "
-       add     = add     .. "\treturn (" .. name .. ") {"
-       clamp   = clamp   .. "\treturn (" .. name .. ") {"
-       cmp     = cmp     .. "\tint i;\n"
-       scale   = scale   .. "\treturn (" .. name .. ") {"
-       mix     = mix     .. "\treturn (" .. name .. ") {"
+       local typedef, equals, add, sub, clamp, cmp, scale, mix, write, read, send, recv =
+                  "",     "",  "",  "",    "",  "",    "",  "",    "",   "",   "",   ""
 
        for i, c in ipairs(vector_components[l]) do
                local last = i == l
@@ -169,6 +164,14 @@ local function emit_vector(type, l)
                                or ", "
                        )
 
+               sub = sub
+                       .. "a." .. c .. " - "
+                       .. "b." .. c ..
+                       (last
+                               and "};\n"
+                               or ", "
+                       )
+
                clamp = clamp
                        .. type .. "_clamp("
                        .. "val." .. c .. ", "
@@ -215,16 +218,17 @@ local function emit_vector(type, l)
                        .. "\tif (!" .. type .. "_recv(peer, &val->" .. c .. "))\n\t\treturn false;\n"
        end
 
-       emit_h("typedef struct {\n" .. typedef ..  "} " .. struct_prefix .. name .. ";\n")
+       emit_h("typedef struct {\n\t" .. type .. " " .. typedef ..  "} " .. struct_prefix .. name .. ";\n")
 
-       emit(export_prefix .. "bool " .. name .. "_equals(" .. name .. " a, " .. name .. " b)", "{\n" .. equals .. "}\n\n")
-       emit(export_prefix .. name .. " " .. name .. "_add(" .. name .. " a, " .. name .. " b)", "{\n" .. add .. "}\n\n")
-       emit(export_prefix .. name .. " " .. name .. "_clamp(" .. name .. " val, " .. name .. " min, " .. name .. " max)", "{\n" .. clamp .. "}\n\n")
-       emit(export_prefix .. "int " .. name .. "_cmp(const void *a, const void *b)", "{\n" .. cmp .. "\treturn 0;\n}\n\n")
-       emit(export_prefix .. name .. " " .. name .. "_scale(" .. name .. " v, " .. type .. " s)", "{\n" .. scale .. "}\n\n")
+       emit(export_prefix .. "bool " .. name .. "_equals(" .. name .. " a, " .. name .. " b)", "{\n\treturn " .. equals .. "}\n\n")
+       emit(export_prefix .. name .. " " .. name .. "_add(" .. name .. " a, " .. name .. " b)", "{\n\treturn (" .. name .. ") {" .. add .. "}\n\n")
+       emit(export_prefix .. name .. " " .. name .. "_sub(" .. name .. " a, " .. name .. " b)", "{\n\treturn (" .. name .. ") {" .. sub .. "}\n\n")
+       emit(export_prefix .. name .. " " .. name .. "_clamp(" .. name .. " val, " .. name .. " min, " .. name .. " max)", "{\n\treturn (" .. name .. ") {" .. clamp .. "}\n\n")
+       emit(export_prefix .. "int " .. name .. "_cmp(const void *a, const void *b)", "{\n\tint i;\n" .. cmp .. "\treturn 0;\n}\n\n")
+       emit(export_prefix .. name .. " " .. name .. "_scale(" .. name .. " v, " .. type .. " s)", "{\n\treturn (" .. name .. ") {" .. scale .. "}\n\n")
 
        if type:sub(1, 1) == "f" then
-               emit(export_prefix .. name .. " " .. name .. "_mix(" .. name .. " a, " .. name .. " b, " .. type .. " f)", "{\n" .. mix .. "}\n\n")
+               emit(export_prefix .. name .. " " .. name .. "_mix(" .. name .. " a, " .. name .. " b, " .. type .. " f)", "{\n\treturn (" .. name .. ") {" .. mix .. "}\n\n")
        end
 
        emit(export_prefix .. "void " .. name .. "_write(Blob *buffer, " .. name .. " *val)", "{\n" .. write .. "}\n\n")
@@ -252,6 +256,7 @@ end
 
 local function emit_numeric(class, bits, alias)
        local name = class .. bits
+       table.insert(numeric_types, name)
 
        existing_types[name] = true
        has_deallocator[name] = false
@@ -306,6 +311,36 @@ for i = 0, 3 do
        end
 end
 
+local converters = {}
+
+for l = 2, 4 do
+       converters[l] = ""
+
+       for i, c in ipairs(vector_components[l]) do
+               converters[l] = converters[l]
+                       .. "v." .. c ..
+                       ((i == l)
+                               and "};\n"
+                               or ", "
+                       )
+       end
+end
+
+for _, from in ipairs(numeric_types) do
+       for _, to in ipairs(numeric_types) do
+               if from ~= to then
+                       for i = 2, 4 do
+                               local v_from = "v" .. i .. from
+                               local v_to   = "v" .. i .. to
+
+                               emit(export_prefix .. v_to .. " " .. v_from .. "_to_" .. to  .. "(" .. v_from .. " v)", "{\n\treturn (" .. v_to .. ") {" .. converters[i] .. "}\n\n")
+                       end
+               end
+       end
+end
+
+emit_h("\n")
+
 -- string
 
 existing_types.String = true
@@ -727,16 +762,28 @@ for _, t in ipairs(custom_types) do
                   "",   "",    "",   "",   "",   ""
 
        for ic, c in ipairs(t.components) do
-               typedef = typedef
-                       .. "\t" .. c.type .. " " .. c.name
+               local type = c.type
+               local type_end = ""
 
                if c.array then
-                       typedef = typedef
-                               .. "[" .. table.concat(c.array, "][") .. "]"
+                       local indices = {}
+
+                       for _, a in ipairs(c.array) do
+                               table.insert(indices, 1, a)
+                       end
+
+                       for _, a in ipairs(indices) do
+                               if a == "" then
+                                       type = "struct { size_t siz; " .. type .. " (*ptr)" .. type_end .. "; }"
+                                       type_end = ""
+                               else
+                                       type_end = "[" .. a .. "]" .. type_end
+                               end
+                       end
                end
 
                typedef = typedef
-                       .. ";\n"
+                       .. "\t" .. type .. " " .. c.name .. type_end .. ";\n"
 
                local compressed = false
 
@@ -748,21 +795,69 @@ for _, t in ipairs(custom_types) do
                        end
                end
 
-               local indent = "\t"
-               local loop = ""
+               local indent = {
+                       free = "\t",
+                       write = "\t",
+                       read = "\t",
+                       send = "\t",
+                       recv = "\t",
+               }
+               local loop = {
+                       free = "",
+                       write = "",
+                       read = "",
+                       send = "",
+                       recv = ""
+               }
+               local loop_end = {
+                       free = "",
+                       write = "",
+                       read = "",
+                       send = "",
+                       recv = ""
+               }
                local index = ""
                local array_submit = ""
 
                if c.array then
                        for ia, a in ipairs(c.array) do
                                local it = "i" .. ia
+                               local siz = a
 
-                               loop = loop .. indent .. "for (int " .. it .. " = 0; " .. it .. " < " .. a .. "; " .. it .. "++)\n"
-                               indent = indent .. "\t"
+                               if a == "" then
+                                       local var = "val->" .. c.name .. index
+                                       local ptr = var .. ".ptr"
+                                       siz = var .. ".siz"
 
-                               index = index .. "[" .. it .. "]"
+                                       loop.free = loop.free .. indent.free .. "if (" .. ptr .. ") {\n"
+                                       loop_end.free = indent.free .. "}\n" .. loop_end.free
+                                       indent.free = indent.free .. "\t"
+                                       loop_end.free = indent.free .. "free(" .. ptr .. ");\n" .. loop_end.free
+
+                                       loop.write = loop.write .. indent.write .. "u64_write(buffer, &" .. siz .. ");\n"
+
+                                       loop.send = loop.send .. indent.send .. "if (!u64_send(peer, &" .. siz .. ", false))\n"
+                                               .. indent.send .. "\treturn false;\n"
 
-                               array_submit = array_submit .. " && " .. it .. " == " .. a
+                                       loop.read = loop.read .. indent.read .. "if (!u64_read(buffer, &" .. siz .. "))\n"
+                                               .. indent.read .. "\treturn false;\n"
+                                               .. indent.read .. ptr .. " = calloc(" .. siz .. ", sizeof *" .. ptr .. ");\n"
+
+                                       loop.recv = loop.recv .. indent.recv .. "if (!u64_recv(peer, &" .. siz .. "))\n"
+                                               .. indent.recv .. "\treturn false;\n"
+                                               .. indent.recv .. ptr .. " = calloc(" .. siz .. ", sizeof *" .. ptr .. ");\n"
+
+                                       index = index .. ".ptr"
+                               end
+
+                               for f in pairs(loop) do
+                                       loop[f] = loop[f] .. indent[f] .. "for (size_t " .. it .. " = 0; " .. it .. " < " .. siz .. "; " .. it .. "++) {\n"
+                                       loop_end[f] = indent[f] .. "}\n" .. loop_end[f]
+                                       indent[f] = indent[f] .. "\t"
+                               end
+       
+                               index = index .. "[" .. it .. "]"
+                               array_submit = array_submit .. " && " .. it .. " == " .. siz .. " - 1"
                        end
                end
 
@@ -770,33 +865,33 @@ for _, t in ipairs(custom_types) do
 
                if has_deallocator[c.type] then
                        free = free
-                               .. loop .. indent .. c.type .. "_free(" .. addr .. ");\n"
+                               .. loop.free .. indent.free .. c.type .. "_free(" .. addr .. ");\n" .. loop_end.free
                end
 
                write = write
-                       .. loop .. indent .. (compressed
+                       .. loop.write .. indent.write .. (compressed
                                and "raw_write_compressed(buffer, " .. addr .. ", (void *) &" .. c.type .. "_write);\n"
                                or      c.type .. "_write(buffer, " .. addr .. ");\n"
-                       )
+                       ) .. loop_end.write
 
                read = read
-                       .. loop .. indent .. "if (!" .. (compressed
+                       .. loop.read .. indent.read .. "if (!" .. (compressed
                                and "raw_read_compressed(buffer, " .. addr .. ", (void *) &" .. c.type .. "_read)"
                                or      c.type .. "_read(buffer, " .. addr .. ")"
-                       ) .. ")\n" .. indent .. "\treturn false;\n"
+                       ) .. ")\n" .. indent.read .. "\treturn false;\n" .. loop_end.read
 
                local submit = ic == #t.components and "submit" .. array_submit or "false"
                send = send
-                       .. loop .. indent .. "if (!" .. (compressed
+                       .. loop.send .. indent.send .. "if (!" .. (compressed
                                and "raw_send_compressed(peer, " .. submit .. ", " .. addr .. ", (void *) &" .. c.type .. "_write)"
                                or      c.type .. "_send(peer, " .. submit .. ", " .. addr .. ")"
-                       ) .. ")\n" .. indent .. "\treturn false;\n"
+                       ) .. ")\n" .. indent.send .. "\treturn false;\n" .. loop_end.send
 
                recv = recv
-                       .. loop .. indent .. "if (!" .. (compressed
+                       .. loop.recv .. indent.recv .. "if (!" .. (compressed
                                and "raw_recv_compressed(peer, " .. addr .. ", (void *) &" .. c.type .. "_read)"
                                or      c.type .. "_recv(peer, " .. addr .. ")"
-                       ) .. ")\n" .. indent .. "\treturn false;\n"
+                       ) .. ")\n" .. indent.recv .. "\treturn false;\n" .. loop_end.recv
        end
 
        emit_h("typedef struct {\n" .. typedef .. "} " .. struct_prefix .. t.name .. ";\n")