Files
cimgui/cimgui/gen_imgui_structs.lua
2018-04-29 16:49:47 +02:00

167 lines
5.4 KiB
Lua

--script for imgui_structs.h generation
function strip(cad)
return cad:gsub("^%s*(.-)%s*$","%1")
end
cdefs = {}
location_re = '^# %d+ "([^"]*)"'
cimpath_re = '^(.*[\\/])(imgui)%.h$'
define_re = "^#define%s+([^%s]+)%s+([^%s]+)$"
function_re = "%b()"
function_closed_re = "[;}]$"
function_closing_re = "}"
number_re = "^-?[0-9]+$"
hex_re = "0x[0-9a-fA-F]+$"
local in_imgui = false
local in_function = false
for line in io.lines() do
repeat -- simulate continue with break
--print(line)
--line = strip(line)
if #line == 0 then break end
-- Is this a preprocessor statement?
if line:sub(1,1) == "#" then
-- Is this a location pragma?
local location_match = line:match(location_re)
if location_match then
--print("location_match",line)
-- If we are transitioning to a header we need to parse, set the flag
local cimpath_match,aaa = location_match:match(cimpath_re)
in_imgui = (cimpath_match ~= nil)
--if in_gl then print(aaa) end
break
end
elseif in_imgui then
--if in_function discard
if in_function then
if line:match(function_closing_re) then
in_function = false
end
break
end
if line:match(function_re) and not line:match("typedef.*%b().*%b().*") then
-- function and functypedef
if not line:match(function_closed_re) then
in_function = true
end
elseif line:match("template") then
--nothing
elseif line:match("public") then
--nothing
else
--line = line:gsub("class","struct")
--line = line:gsub("mutable","")
line = line:gsub("%S+",{class="struct",mutable=""})
line = line:gsub("(%b<>)","/%*%1%*/") --comment template parameters
table.insert(cdefs,line)
end
end
until true
end
local namespace_re = "namespace"
local in_namespace = false
local struct_re = "^%s*struct%s+([^%s;]+)$"
local struct_closed_re = "^%s*struct%s+([^%s]+);$"
local struct_closing_re = "};"
local struct_op_close_re = "%b{}"
local structnames = {}
local innerstructs = {}
-- Output the file
print("/////////////// BEGIN AUTOGENERATED SEGMENT")
print("#ifndef IMGUI_STRUCTS_INCLUDED")
print("#define IMGUI_STRUCTS_INCLUDED")
for i,line in ipairs(cdefs) do
repeat -- simulating continue with break
if line:match(namespace_re) then
in_namespace = true
end
local structbegin = line:match(struct_re)
if structbegin then
structnames[#structnames + 1] = structbegin
if #structnames < 2 and structbegin~= "ImVector" then --not inner and not ImVector
io.write(line,"\n")
break
end
end
if structnames[#structnames] == "ImVector" then
if line:match(struct_closing_re) then
io.write[[struct ImVector
{
int Size;
int Capacity;
void* Data;
};
typedef struct ImVector ImVector;]]
structnames[#structnames] = nil
end
break -- dont write
end
if in_namespace then
if line:match(function_closing_re) then
in_namespace = false
end
break -- dont write anything inside
end
if #structnames < 2 then -- not inner
if (#structnames > 0) then
if line:match("typedef") then --dont allow inner typedefs
break
elseif not line:match("^{$") and not line:match(struct_closing_re) then --avoid tab { and };
--line = " "..line
end
end
io.write( line,"\n")
local struct_closed_name = line:match(struct_closed_re)
if struct_closed_name then
io.write("typedef struct ",struct_closed_name," ",struct_closed_name,";\n")
end
end
if #structnames > 0 then
if #structnames > 1 then --inner structs
innerstructs[structnames[#structnames]] = innerstructs[structnames[#structnames]] or {}
local st = innerstructs[structnames[#structnames]]
if not line:match("struct") and not line:match("^{$") and not line:match(struct_closing_re) then --avoid tab in struct { and };
--line = " "..line
end
st[#st + 1] = line
if line:match(struct_closing_re) and not line:match(struct_op_close_re) then
local structname = structnames[#structnames]
st[#st + 1] = string.format("typedef struct %s %s;\n",structname,structname)
structnames[#structnames] = nil
end
elseif line:match(struct_closing_re) and not line:match(struct_op_close_re) then
local structname = structnames[#structnames]
io.write("typedef struct ",structname," ",structname,";\n")
structnames[#structnames] = nil
end
end
until true
end
for k,v in pairs(innerstructs) do
for i,line in ipairs(v) do
print(line)
end
end
print("#endif //IMGUI_STRUCTS_INCLUDED")
print("//////////////// END AUTOGENERATED SEGMENT ")