Compare commits

...

3 Commits

Author SHA1 Message Date
sonoro1234
a444aa6c50 cpp2ffi: class work 3 std::function wrapping 2026-04-17 18:15:27 +02:00
sonoro1234
fab34e3855 cpp2ffi: class work 2 2026-04-15 19:36:15 +02:00
sonoro1234
467262ef29 cpp2ffi: class work 1 2026-04-14 10:44:36 +02:00
7 changed files with 1409 additions and 39 deletions

View File

@@ -195,6 +195,11 @@ local function check_template(code)
te = te:gsub("%s","_")
te = te:gsub("%*","Ptr")
te = te:gsub("::","_")
te = te:gsub("%(","_")
te = te:gsub("%)","_")
te = te:gsub("&","amp")
te = te:gsub("<","_")
te = te:gsub(">","_")
code2 = code:gsub("(<[%w_%*%s]+>)([^%s%*])","%1 %2")
code2 = code2:gsub("<([^<>]-)>","_"..te)
@@ -343,11 +348,12 @@ local function getRE()
-- but we don want operator== to appear as a var and as we should skip this kind of function solution is:
operator_re = "^([^;{}]+operator[^;{}]+%b()[\n%s%w%(%)_]*;)",
struct_re = "^([^;{}]-struct[^;{}]-%b{}[%s%w_%(%)]*;)",
class_re = "^([^;{}]-class[^;{}]-%b{}[%s%w_%(%)]*;)",
--class_re = "^([^;{}]-class[^;{}]-%b{}%s*;)",
enum_re = "^([^;{}]-enum[^;{}]-%b{}[%s%w_%(%)]*;)",
union_re = "^([^;{}]-union[^;{}]-%b{}[%s%w_%(%)]*;)",
structenum_re = "^([^;{}]-%b{}[%s%w_%(%)]*;)",
namespace_re = "^([^;{}]-namespace[^;{}]-%b{})",
class_re = "^([^;{}]-class[^;{}]-%b{}%s*;)",
typedef_re = "^\n*%s*(typedef[^;]+;)",
typedef_st_re = "^\n*(typedef%s+struct%s*%b{}.-;)",
functypedef_re = "^\n*%s*(typedef[%w%s%*_]+%(%s*%*%s*[%w_]+%s*%)%s*%b()%s*;)",
@@ -740,6 +746,7 @@ local function parseFunction(self,stname,itt,namespace,locat)
end
local ret = line:match("([^%(%):,]+[%*%s])%s?~?[_%w]+%b()")
--local ret = line:match("(.+[%*%s])%s?~?[_%w]+%b()")
--local funcname, args = line:match("(~?[_%w]+)%s*(%b())")
local funcname, args, extraconst = line:match("(~?[_%w]+)%s*(%b())(.*)")
extraconst = extraconst:match("const")
@@ -782,7 +789,7 @@ local function parseFunction(self,stname,itt,namespace,locat)
end
end
--[[
--- templates in args
for i,ar in ipairs(argsTa) do
--TODO several diferent templates
@@ -796,13 +803,23 @@ local function parseFunction(self,stname,itt,namespace,locat)
end
argsTa[i] = te and code2 or ar --ar:gsub("<([%w_%*%s]+)>",te) --ImVector
end
--]]
--get typ, name and defaults
local functype_re = "^%s*[%w%s%*]+%(%*%s*[%w_]+%)%([^%(%)]*%)"
local functype_reex = "^(%s*[%w%s%*]+)%(%*%s*([%w_]+)%)(%([^%(%)]*%))"
local argsTa2 = {}
local noname_counter = 0
for i,ar in ipairs(argsTa) do
local ttype,template,te,code2 = check_template(ar) --ar:match("([^%s,%(%)]+)%s*<(.-)>")
if template then
if self.typenames[stname] ~= template then --rule out template typename
self.templates[ttype] = self.templates[ttype] or {}
self.templates[ttype][template] = te
end
end
argsTa[i] = te and code2 or ar
local template_orig = te and ar or nil
ar = argsTa[i]
--avoid var name without space type&name -> type& name
-- also do type &name -> type& name
--ar = ar:gsub("(%S)&(%S)","%1& %2")
@@ -819,7 +836,14 @@ local function parseFunction(self,stname,itt,namespace,locat)
else
reftoptr = nil
if ar:match("&") then
if ar:match("const") then
ar1,defa = ar:match"([^=]+)=([^=]+)"
ar1 = ar1 or ar
local typ11,name11 = ar1:match("(.+)%s([^%s]+)")
typ11 = typ11:gsub("const ","")
typ11 = typ11:gsub("&","")
if ar:match("const") and not self.opaque_structs[typ11] then
--if ar:match"Palette" then print("--w---w--w",ar,typ11,name11) end
--print("--w---w--w",ar,cname)
ar = ar:gsub("&","")
else
ar = ar:gsub("&","*")
@@ -848,7 +872,7 @@ local function parseFunction(self,stname,itt,namespace,locat)
name = name:gsub("(%[%d*%])","")
end
end
argsTa2[i] = {type=typ,name=name,default=defa,reftoptr=reftoptr,ret=retf,signature=sigf,has_cdecl=has_cdecl}
argsTa2[i] = {type=typ,name=name,default=defa,reftoptr=reftoptr,ret=retf,signature=sigf,has_cdecl=has_cdecl,template_orig=template_orig}
if ar:match("&") and not ar:match("const") then
--only post error if not manual
local cname = self.getCname(stname,funcname, namespace) --cimguiname
@@ -949,6 +973,8 @@ local function parseFunction(self,stname,itt,namespace,locat)
defT.skipped = true
end
if ret then
defT.stdret = line:match("^\n*%s*std::")
--if ret:match"string" then print("parsefunction",defT.cimguiname, ret, line) end
defT.ret = clean_spaces(ret:gsub("&","*"))
defT.retref = ret:match("&")
-- if defT.ret=="ImVec2" or defT.ret=="ImVec4" or defT.ret=="ImColor" then
@@ -1326,11 +1352,88 @@ local function header_subs_nonPOD(FP,txt)
return txt
end
M.header_subs_nonPOD = header_subs_nonPOD
local function get_std_function(ar)
local skip = false
local ty=ar.template_orig:gsub(ar.name,"")
ty = ty:match("std::function(%b<>)")
ty = ty:sub(2,-2)
local ret, args = ty:match("([^%(%)]+)(%b())")
local ret2
if ret:match"std::string_view" then
ret2 = "const char*"
elseif ret:match"std::string" then
ret2 = "const char*"
end
args = args:sub(2,-2)
local argsT = strsplit(args,",")
--get noname args
local argsT2 = {}
local noname_counter = 0
for i,v in ipairs(argsT) do
local typ, name = v:match("(.+)%s+(%w+)")
if not name then
typ = v
noname_counter = noname_counter + 1
name = "noname" .. noname_counter
end
argsT2[i] = {type=typ,name=name}
end
--get conversions
local argsT3 = {}
for i,v in ipairs(argsT2) do
local typ,name,conv
if v.type:match("std::string_view") then
typ = "const char*"
conv = v.name..".data()"
elseif v.type:match("std::string") then
typ = "const char*"
conv = v.name..".c_str()"
elseif v.type:match("std::") then
skip = true
else
end
argsT3[i] = {type=typ or v.type,conv=conv,name=v.name}
end
local asp = ""
local caar1 = ""
local caar2 = ""
for i,v in ipairs(argsT3) do
asp = asp..v.type..","
caar1 = caar1 .. argsT2[i].type.." "..argsT2[i].name..","
caar2 = caar2..(argsT3[i].conv or argsT3[i].name)..","
end
caar1 = caar1:sub(1,-2)
caar1 = "[cb]("..caar1..")"
caar2 = caar2:sub(1,-2)
caar2 = "cb("..caar2..")"
if ret ~= "void" then
if ret:match"std::string$" then
caar2 = "return std::string("..caar2..")"
-- elseif ret:match"std::string_view" then
-- caar2 = "return "..caar2..".data()"
else
caar2 = "return "..caar2
end
end
local caar = caar1 .."{"..caar2..";}"
asp = asp:sub(1,-2)
asp = (ret2 or ret).."(*cb)("..asp..")"
-- print(ty,ret,args)
-- M.prtable(argsT3)
-- print("ret",ret)
-- print("asp",asp)
-- print("caar1",caar1)
-- print("caar2",caar2)
-- print("caar",caar)
-- print("skip",skip)
return caar,asp,skip
end
local function ADDnonUDT(FP)
local nonPOD = get_nonPOD(FP)
get_nonPODused(FP)
for k,defs in pairs(FP.defsT) do
for i, def in ipairs(defs) do
for i, def in ipairs(defs) do
local skip = nil
--ret
local rets = (def.ret or ""):gsub("const ","")
rets = rets:gsub("*","")
@@ -1341,6 +1444,14 @@ local function ADDnonUDT(FP)
elseif FP.nP_ret[rets] then
def.ret = def.ret:gsub(rets, FP.nP_ret[rets])
def.nonUDT = 2
elseif def.ret=="string" then
def.ret = "const char*"
def.nonUDT = "string"
elseif FP.opaque_structs[rets] then
assert(def.ret:match"%*","opaque struct without pointer")
def.ret = def.ret:gsub(rets.."%s*%*",rets.."_opq")
elseif def.stdret then -- not std::string
skip = true
end
--args
local caar,asp
@@ -1363,6 +1474,30 @@ local function ADDnonUDT(FP)
local typ3 = v.type:gsub(typ2,typ2.."_c")
caar = caar .. "reinterpret_cast<"..v.type..">("..name.."),"
asp = asp .. typ3 .." "..v.name..","
elseif v.type:match("std::string_view") then
caar = caar ..name..","
asp = asp .. "const char* "..v.name..","
elseif v.type:match("std::string") then
caar = caar .. "std::string("..name.."),"
asp = asp .. "const char* "..v.name..","
elseif v.type:match"std::function" then
local ca2,asp2,skip2 = get_std_function(v)
caar = caar .. ca2..","
asp = asp .. asp2..","
if skip2 then skip = true end
--skip = true
elseif v.type:match("std::") then
skip = true
elseif FP.opaque_structs[typ2] then
--assert(v.type:match"%*","opaque struct arg without pointer")
if not v.type:match"%*" then
M.prtable(def)
error"opaque struct arg without pointer"
end
local newt = v.type:gsub(typ2.."%s*%*",typ2.."_opq")
local callname = v.reftoptr and "*"..name or name
caar = caar .. callname .. ","
asp = asp .. newt.." "..name .. ","
else
local siz = v.type:match("(%[%d*%])") or ""
local typ = v.type:gsub("(%[%d*%])","")
@@ -1378,9 +1513,14 @@ local function ADDnonUDT(FP)
caar = "()"
asp = "()"
end
def.call_args_old = def.call_args
def.call_args = caar
def.args = asp
if skip then
def.skipped = skip
FP.skipped[def.ov_cimguiname] = true
else
def.call_args_old = def.call_args
def.call_args = caar
def.args = asp
end
end
end
end
@@ -1602,6 +1742,7 @@ function M.Parser()
par.manuals = {}
par.skipped = {}
par.UDTs = {}
par.opaque_structs = {}
par.save_output = save_output
par.genConversors = genConversions
@@ -1710,6 +1851,29 @@ function M.Parser()
end
end
end
local function derived_check(it)
--print("checks",it.name)
--expects struct or class
assert(it.re_name=="struct_re" or it.re_name=="class_re",it.re_name)
local inistruct = clean_spaces(it.item:match("(.-)%b{}"))
--clean final:
inistruct = inistruct:gsub("%s*final%s*:",":")
local stname, derived
if inistruct:match":" then
stname,derived = inistruct:match"struct%s*([^%s:]+):(.+)"
if not stname then stname,derived = inistruct:match"class%s*([^%s:]+):(.+)" end
if derived then
derived = derived:match"(%S+)$"
else assert(inistruct:match"private" or inistruct:match"protected",inistruct) end
else
if it.re_name == "struct_re" then
stname = inistruct:match"struct%s(%S+)"
elseif it.re_name == "class_re" then
stname = inistruct:match"class%s(%S+)"
end
end
return stname, derived
end
--recursive item parsing
function par:parseItemsR2(txt, itparent)
local itsarr,its = parseItems(txt,self.linenumdict,itparent)
@@ -1718,17 +1882,22 @@ function M.Parser()
if it.re_name == "class_re" then
it.name = it.item:match("class%s+(%S+)")
print("cleaning class",it.name)
it.item = it.item:gsub("private:.+};$","};")
--it.item = it.item:gsub("private:.+};$","};")
--it.item = it.item:gsub("private:","")
it.item = it.item:gsub("public:","")
it.item = it.item:gsub("enum%s*class","enum")
end
if not isLeaf(it.re_name) then
local inner = strip_end(it.item:match("%b{}"):sub(2,-2))
--print(it.item)
--print(inner)
it.childs = par:parseItemsR2(inner, it)
--if it.name == "TextEditor" then M.prtable(it.childs) end
for j,child in ipairs(it.childs) do
child.parent = it
end
if it.re_name == "struct_re" then
local typename = it.item:match("^%s*template%s*<%s*typename%s*(%S+)%s*>")
--local stname = it.item:match("struct%s+(%S+)")
@@ -1747,6 +1916,37 @@ function M.Parser()
it.name = it.item:match("namespace%s+(%S+)")
elseif it.re_name == "class_re" then
--it.name = it.item:match("class%s+(%S+)")
local first_private
for j,child in ipairs(it.childs) do
if child.item:match("^\n*%s*private:") or child.item:match("^\n*%s*protected:") then
first_private = j
break
end
end
if first_private then
for j=first_private,#it.childs do
--print("private discards",it.childs[j].re_name,it.childs[j].name)
it.childs[j] = nil
end
end
end
--create opaque_struct
if it.re_name == "struct_re" or it.re_name == "class_re" then
local stname,derived = derived_check(it)
if derived and derived:match"std::" then
print("--make opaque std::derived",it.name,derived)
it.opaque_struct = (itparent and itparent.name .."::" or "")..it.name
end
for j,child in ipairs(it.childs) do
if child.re_name == "vardef_re" and child.item:match"std::" then
print("--make opaque",it.name,child.item)
it.opaque_struct = (itparent and itparent.name .."::" or "")..it.name
--cant do that as function is recursive
--self.opaque_structs[it.name] = (itparent and itparent.name .."::" or "")..it.name
break
end
end
end
end
end
@@ -1829,8 +2029,17 @@ function M.Parser()
--save_data("./preparse"..tostring(self):gsub("table: ","")..".c",txt)
--]]
self.itemsarr = par:parseItemsR2(txt)
--save_data("./itemsarr.lua",ToStr(self.itemsarr))
save_data("./itemsarr.lua",ToStr(self.itemsarr))
itemsarr = self.itemsarr
---find opaque_structs
self:Listing(itemsarr,function(it)
if it.re_name == "struct_re" or it.re_name == "class_re" then
if it.opaque_struct then
self.opaque_structs[it.name] = it.opaque_struct
end
end
end)
if next(self.opaque_structs) then M.prtable("opaque_structs:",self.opaque_structs) end
end
function par:printItems()
@@ -1869,6 +2078,7 @@ function M.Parser()
end)
return table.concat(ttd,"")
end
function par:clean_structR1(itst,doheader)
local stru = itst.item
local outtab = {}
@@ -1883,7 +2093,8 @@ function M.Parser()
local stname, derived
if inistruct:match":" then
stname,derived = inistruct:match"struct%s*([^%s:]+):(.+)"
--print(inistruct,stname,derived)
if not stname then stname,derived = inistruct:match"class%s*([^%s:]+):(.+)" end
print("derived------",inistruct,stname,derived, derived:match"(%S+)$")
derived = derived:match"(%S+)$"
else
if itst.re_name == "struct_re" then
@@ -1928,8 +2139,11 @@ function M.Parser()
print("clean_struct with empty struc",stname);
-- M.prtable(itst)
-- if stname=="StbUndoRecord" then error"dddd" end
return ""
return ""
end --here we avoid empty structs
if itst.opaque_struct then
return "", stname,nil,nil,""
end
for j,it in ipairs(itlist) do
if (it.re_name == "vardef_re" or it.re_name == "functype_re") then -- or it.re_name == "union_re") then
if not (it.re_name == "vardef_re" and it.item:match"static") then --skip static variables
@@ -1938,28 +2152,32 @@ function M.Parser()
--local ttype,template = it.item:match("([^%s,%(%)]+)%s*<(.+)>")
local ttype,template,te,code2 = check_template(it2) --it.item:match"([^%s,%(%)]+)%s*<(.+)>"
if template then
--print(it2)
--print("not doheader",ttype,template,te, self.typenames[ttype])
if self.typenames[ttype] ~= template and self.typenames[ttype].."*" ~= template then --rule out T (template typename)
--M.prtable(self.typenames)
if self.typenames[ttype] and self.typenames[ttype] ~= template and self.typenames[ttype].."*" ~= template then --rule out T (template typename)
self.templates[ttype] = self.templates[ttype] or {}
self.templates[ttype][template] = te
it2=code2
end
if doheader then
if doheader and self.templates[ttype] then
local templatetypedef = self:gentemplatetypedef(ttype, template,self.templates[ttype][template])
predeclare = predeclare .. templatetypedef
end
end
--clean mutable
it2 = it2:gsub("mutable","")
--clean namespaces
it2 = it2:gsub("%w+::","")
--clean namespaces but not std::
--if not it2:match"std::" then
it2 = it2:gsub("%w+::","")
--end
--clean initializations
if it.re_name == "vardef_re" then
it2 = it2:gsub("%s*=.+;",";")
it2 = it2:gsub("%b{}","")
end
table.insert(outtab,it2)
--print("cleanstruct",it2)
table.insert(commtab,{above=it.prevcomments,sameline=it.comments})--it.comments or "")
end
elseif it.re_name == "union_re" then
@@ -1971,10 +2189,12 @@ function M.Parser()
table.insert(outtab,item)
com = (com ~= "") and com or nil
table.insert(commtab,{above=it.prevcomments,sameline=com})
elseif it.re_name == "struct_re" then
elseif it.re_name == "struct_re" or it.re_name == "class_re" then
--print("nested struct in",stname,it.name)
--check if has declaration
local decl = it.item:match"%b{}%s*([^%s}{]+)%s*;"
--local decl = it.item:match"%b{}%s*([^%s}{]+)%s*;"
local decl = it.item:match"^[^{}]+%b{}%s*([^%s}{]+)%s*;"
--local decl1,decl2,decl3 = it.item:match"^([^{}]+%b{})(%s*[^%s}{]+%s*;)(.*)$"
local cleanst,structname,strtab,comstab,predec = self:clean_structR1(it,doheader)
if not structname then --unamed nested struct
--print("----generate unamed nested struct----",it.name)
@@ -1989,7 +2209,7 @@ function M.Parser()
table.insert(commtab,{above=it.prevcomments,sameline=it.comments})--it.comments or "")
end
if doheader then
if doheader and not it.opaque_struct then
local tst = "\ntypedef struct "..structname.." "..structname..";\n"
if check_unique_typedefs(tst,uniques) then
--table.insert(outtab,tst)
@@ -2000,7 +2220,11 @@ function M.Parser()
predeclare = predeclare .. predec .. cleanst
end
elseif it.re_name == "enum_re" then
--nop
if doheader then
local outtab1 = {}
self:enum_for_header( it, outtab1)
predeclare = predeclare .. table.concat(outtab1)
end
elseif it.re_name ~= "functionD_re" and it.re_name ~= "function_re" and it.re_name ~= "operator_re" then
print(it.re_name,"not processed clean_struct in",stname,it.item:sub(1,24))
--M.prtable(it)
@@ -2031,6 +2255,7 @@ function M.Parser()
return parnam
end
function par:header_text_insert(tab,txt,it)
--print("--header_text_insert",txt)--:sub(1,40))
table.insert(tab, txt)
end
local function function_parse(self,it)
@@ -2039,6 +2264,7 @@ function M.Parser()
if it.parent then
if it.parent.re_name == "struct_re" or it.parent.re_name == "typedef_st_re" or it.parent.re_name == "class_re" then
stname = it.parent.name
namespace = get_parents_nameC(it)
elseif it.parent.re_name == "namespace_re" then
namespace = get_parents_nameC(it) --it.parent.name
end
@@ -2057,6 +2283,48 @@ function M.Parser()
self:parseFunction(stname,it,namespace,it.locat)
end
end
function par:enum_for_header( it,outtab)
--local enumname, enumbody = it.item:match"^%s*enum%s+([^%s;{}]+)[%s\n\r]*(%b{})"
local enumname = it.item:match"^%s*enum%s+([^%s;{}]+)"
if enumname then
--if it's an enum with int type changed
if self.structs_and_enums_table.enumtypes[enumname] then
local enumtype = self.structs_and_enums_table.enumtypes[enumname]
local enumbody = ""
local extraenums = ""
for i,v in ipairs(self.structs_and_enums_table.enums[enumname]) do
if type(v.calc_value)=="string" then
extraenums = extraenums .."\nstatic const "..enumtype.." "..v.name.." = "..v.calc_value..";"
else
enumbody = enumbody .. "\n" ..v.name .."="..v.value..","
end
end
enumbody = "{"..enumbody.."\n}"
--table.insert(outtab,"\ntypedef enum ".. enumbody..enumname..";"..extraenums)
local it2 = "\ntypedef enum ".. enumbody..enumname..";"..extraenums
self:header_text_insert(outtab, it2, it)
else
local enumbody = it.item:match"(%b{})"
enumbody = clean_comments(enumbody)
--table.insert(outtab,"\ntypedef enum ".. enumbody..enumname..";")
local it2 = "\ntypedef enum ".. enumbody..enumname..";"
self:header_text_insert(outtab, it2, it)
end
if it.parent then
if it.parent.re_name == "namespace_re" then
local namespace = it.parent.item:match("namespace%s+(%S+)")
self.embeded_enums[enumname] = namespace.."::"..enumname
else
self.embeded_enums[enumname] = it.parent.name.."::"..enumname
end
end
else --unamed enum just repeat declaration
local cl_item = clean_comments(it.item)
--table.insert(outtab,cl_item)
self:header_text_insert(outtab, cl_item, it)
print("unnamed enum",cl_item)
end
end
function par:gen_structs_and_enums()
print"--------------gen_structs_and_enums"
--M.prtable(self.typenames)
@@ -2064,9 +2332,14 @@ function M.Parser()
local outtabpre = {}
local typedefs_table = {}
self.embeded_enums = {}
--local uniques = {}
--local uniques = {}
local processer = function(it)
-- if it.re_name == "enum_re" then
-- it.name = it.item:match"^%s*enum%s+([^%s;{}]+)"
-- end
-- print("gen_structs_and_enums",it.re_name, it.name)
--table.insert(outtab,it.re_name.." "..(it.name or "unkn "))
if it.re_name == "typedef_re" or it.re_name == "functypedef_re" or it.re_name == "vardef_re" then
if not it.parent or it.parent.re_name=="namespace_re" then
local it2 = it.item
@@ -2114,6 +2387,8 @@ function M.Parser()
self:header_text_insert(outtab, it2, it)
-- add typedef after struct name
if it.re_name == "vardef_re" and it.item:match"^%s*struct" then
--print("---------emmbed")
--M.prtable(it)
local stname = it.item:match("struct%s*(%S+)%s*;")
--table.insert(typedefs_table,"typedef struct "..stname.." "..stname..";\n")
local tst = "\ntypedef struct "..stname.." "..stname..";"
@@ -2129,6 +2404,12 @@ function M.Parser()
end
end
elseif it.re_name == "enum_re" then
--dont insert child enums as they are inserted before parent struct
if not (it.parent and (it.parent.re_name == "struct_re" or it.parent.re_name == "class_re")) then
--self:header_text_insert(outtab, predec .. cleanst, it)
self:enum_for_header(it,outtab)
end
--[[
--local enumname, enumbody = it.item:match"^%s*enum%s+([^%s;{}]+)[%s\n\r]*(%b{})"
local enumname = it.item:match"^%s*enum%s+([^%s;{}]+)"
if enumname then
@@ -2169,8 +2450,14 @@ function M.Parser()
self:header_text_insert(outtab, cl_item, it)
print("unnamed enum",cl_item)
end
--]]
elseif it.re_name == "struct_re" or it.re_name == "typedef_st_re" or it.re_name == "class_re" then
if it.opaque_struct then
self:header_text_insert(outtab, "\ntypedef struct "..it.name.."* "..it.name.."_opq;\n",it)
else
--self:header_text_insert(outtab,"\n///inittt "..it.name.."\n", it)
local cleanst,structname,strtab,comstab,predec = self:clean_structR1(it,true)
--self:header_text_insert(outtab,"\n///endttt "..it.name.."\n", it)
if not structname then print("NO NAME",cleanst,it.item) end
--if not void stname or templated
if structname and not self.typenames[structname] then
@@ -2185,14 +2472,16 @@ function M.Parser()
end
self.typedefs_dict[structname]="struct "..structname
--dont insert child structs as they are inserted before parent struct
if not (it.parent and it.parent.re_name == "struct_re") then
if not (it.parent and (it.parent.re_name == "struct_re" or it.parent.re_name == "class_re")) then
--table.insert(outtab,predec .. cleanst)
self:header_text_insert(outtab, predec .. cleanst, it)
end
end
if it.parent then --and (it.parent.re_name == "struct_re" or it.parent.re_name == "typedef_st_re" then
local embededst = (it.re_name == "struct_re" and it.item:match("struct%s+([^%s{]+)"))
or (it.re_name == "typedef_st_re" and it.item:match("%b{}%s*(%S+)%s*;"))
--local embededst = (it.re_name == "struct_re" and it.item:match("struct%s+([^%s{]+)"))
--or (it.re_name == "typedef_st_re" and it.item:match("%b{}%s*(%S+)%s*;"))
local embededst = (it.re_name == "struct_re" or it.re_name == "class_re") and it.name
--print("--------embedd1",it.re_name, it.name, embededst)
--TODO nesting namespace and class
if embededst then --discards false which can happen with untagged structs
local parname = get_parents_name(it)
@@ -2200,10 +2489,12 @@ function M.Parser()
--needed by cimnodes with struct tag name equals member name
self.embeded_structs[embededst] = "struct "..parname..embededst
else
--print("---------embeddd2",parname,embededst)
self.embeded_structs[embededst] = parname..embededst
end
end
end
end --opaque_struct
elseif it.re_name == "namespace_re" or it.re_name == "union_re" or it.re_name == "functype_re" then
--nop
elseif it.re_name == "functionD_re" or it.re_name == "function_re" then
@@ -2226,6 +2517,10 @@ function M.Parser()
-- end
--check arg detection failure if no name in function declaration
check_arg_detection(self.defsT,self.typedefs_dict)
--table.insert(outtabpre,1,"\n/////outtabpre start\n")
--table.insert(outtabpre,"\n/////outtabpre end\n")
--table.insert(outtab,1,"\n/////outtab start\n")
--table.insert(outtab,"\n/////outtab end\n")
local outtabprest, outtabst = table.concat(outtabpre,""),table.concat(outtab,"")
outtabprest = M.header_subs_nonPOD(self,outtabprest)
outtabst = M.header_subs_nonPOD(self,outtabst)
@@ -2248,6 +2543,7 @@ function M.Parser()
table.insert(outtab,{type=t1..t2,name=name,comment=comment})
else
--split type name1,name2; in several lines
--print(line)
local typen,rest = line:match("%s*([^,]+)%s(%S+[,;])")
--print(typen,"rest:",rest)
if not typen then -- Lets try Type*name
@@ -2345,7 +2641,7 @@ function M.Parser()
par.enums_for_table = enums_for_table
function par:gen_structs_and_enums_table()
print"--------------gen_structs_and_enums_table"
local outtab = {enums={},structs={},locations={},enumtypes={},struct_comments={},enum_comments={}}
local outtab = {enums={},structs={},locations={},enumtypes={},struct_comments={},enum_comments={},opaque_structs={}}
--self.typedefs_table = {}
local enumsordered = {}
unnamed_enum_counter = 0
@@ -2408,6 +2704,7 @@ function M.Parser()
enums_for_table(it, outtab, enumsordered)
elseif it.re_name == "struct_re" or it.re_name == "typedef_st_re" or it.re_name == "class_re" then
local cleanst,structname,strtab,comstab = self:clean_structR1(it)
if it.name then outtab.opaque_structs[it.name] = it.opaque_struct end
--if not void stname or templated
if not structname then print("NO NAME",cleanst,it.item) end
if structname and not self.typenames[structname] then
@@ -2415,17 +2712,25 @@ function M.Parser()
outtab.struct_comments[structname] = {sameline=it.comments,above=it.prevcomments}
outtab.struct_comments[structname] = next(outtab.struct_comments[structname]) and outtab.struct_comments[structname] or nil
outtab.locations[structname] = it.locat
if strtab then
for j=3,#strtab-1 do
self:parse_struct_line(strtab[j],outtab.structs[structname],comstab[j])
end
end
-- if structname == "Change" then
-- print(it.item)
-- M.prtable(outtab.structs[structname])
-- end
else
--templated struct
if structname then
print("saving templated struct",structname)
self.templated_structs[structname] = {}
if strtab then
for j=3,#strtab-1 do
self:parse_struct_line(strtab[j],self.templated_structs[structname],comstab[j])
end
end
--M.prtable(self.templated_structs[structname])
else
print("skipped unnamed struct",structname)
@@ -2433,10 +2738,10 @@ function M.Parser()
end
elseif it.re_name == "namespace_re" or it.re_name == "union_re" or it.re_name == "functype_re" then
--nop
elseif it.re_name ~= "functionD_re" or it.re_name ~= "function_re" then
elseif it.re_name == "functionD_re" or it.re_name == "function_re" then
function_parse(self,it)
elseif it.re_name ~= "operator_re" then
print("not processed gen table",it.re_name)
print("---not processed gen table",it.re_name)
end
end
@@ -2687,7 +2992,11 @@ function M.Parser()
end
function par:gen_template_typedef_auto(ttype,te,newte)
--M.prtable(self.templated_structs)
assert(self.templated_structs[ttype],ttype)
--assert(self.templated_structs[ttype],ttype)
if not self.templated_structs[ttype] then
print("----gentemplatetypedef failed for", ttype)
return ""
end
local defi = self.templated_structs[ttype]
local Targ = strsplit(self.typenames[ttype],",")
local defa = {}
@@ -3009,7 +3318,7 @@ local function ImGui_f_implementation(def)
table.insert(outtab,"CIMGUI_API".." "..def.ret.." "..def.ov_cimguiname..def.args.."\n")
table.insert(outtab,"{\n")
local namespace = def.namespace and def.namespace.."::" or ""
namespace = def.is_static_function and namespace..def.stname.."::" or namespace
--namespace = def.is_static_function and namespace..def.stname.."::" or namespace
if def.isvararg then
local call_args = def.call_args:gsub("%.%.%.","args")
table.insert(outtab," va_list args;\n")
@@ -3037,6 +3346,9 @@ local function ImGui_f_implementation(def)
insert(outtab," return ConvertFromCPP_"..def.conv.."("..namespace..def.funcname..def.call_args..");\n")
elseif def.nonUDT == 2 then
insert(outtab," return reinterpret_cast<"..def.ret..">("..ptret..namespace..def.funcname..def.call_args..");\n")
elseif def.nonUDT == "string" then
insert(outtab," static std::string str = "..ptret..namespace..def.funcname..def.call_args..";\n")
insert(outtab," return str.c_str();\n")
end
table.insert(outtab,"}\n")
else --standard ImGui
@@ -3075,6 +3387,9 @@ local function struct_f_implementation(def)
insert(outtab," return ConvertFromCPP_"..def.conv.."(self->"..def.funcname..def.call_args..");\n")
elseif def.nonUDT == 2 then
insert(outtab," return reinterpret_cast<"..def.ret..">("..ptret.."self->"..def.funcname..def.call_args..");\n")
elseif def.nonUDT == "string" then
insert(outtab," static std::string str = "..ptret.."self->"..def.funcname..def.call_args..";\n")
insert(outtab," return str.c_str();\n")
end
else --standard struct
table.insert(outtab," return "..ptret.."self->"..def.funcname..def.call_args..";\n")
@@ -3096,7 +3411,9 @@ local function func_implementation(FP)
custom = FP.custom_implementation(outtab, def, FP)
end
local manual = FP.get_manuals(def)
if not custom and not manual and not def.templated and not FP.get_skipped(def) then
if not custom and not manual and not def.templated and not FP.get_skipped(def)
and not (FP.opaque_structs[def.stname] and not def.is_static_function)
then
if def.constructor then
local tab = {}
assert(def.stname ~= "","constructor without struct")
@@ -3152,20 +3469,28 @@ M.table_do_sorted = table_do_sorted
local function func_header_generate_structs(FP)
local outtab = {}--"\n/////func_header_generate_structs\n"}
local outtab = {} --"\n/////func_header_generate_structs\n"}
table_do_sorted(FP.embeded_structs,function(k,v)
table.insert(outtab,"typedef "..v.." "..k..";\n")
end)
table_do_sorted(FP.embeded_enums,function(k,v) table.insert(outtab,"typedef "..v.." "..k..";\n") end)
--table.insert(outtab, "\n//////////templates\n")
table_do_sorted(FP.templates,function(ttype,v)
table_do_sorted(v,function(ttypein,te)
local ttype2 = ttype:gsub("::","_") --std::string
table.insert(outtab,"typedef "..ttype.."<"..ttypein.."> "..ttype2.."_"..te..";\n")
end)
--print("func_header_generate_structs",ttype)
if not (ttype == "std::function") then
table_do_sorted(v,function(ttypein,te)
local ttype2 = ttype:gsub("::","_") --std::string
table.insert(outtab,"typedef "..ttype.."<"..ttypein.."> "..ttype2.."_"..te..";\n")
end)
end
end)
table_do_sorted(FP.opaque_structs,function(k,v)
table.insert(outtab,"typedef const "..v.."* "..k.."_opq;\n")
end)
--table.insert(outtab, "\n//////////end func header\n")
return outtab
end
M.func_header_generate_structs = func_header_generate_structs
@@ -3186,7 +3511,8 @@ local function func_header_generate_funcs(FP)
custom = FP.custom_header(outtab, def)
end
local manual = FP.get_manuals(def)
if not custom and not manual and not def.templated and not FP.get_skipped(def) then
if not custom and not manual and not def.templated and not FP.get_skipped(def) and
not (FP.opaque_structs[def.stname] and not def.is_static_function) then
local addcoment = "" --def.comment or ""
local empty = def.args:match("^%(%)") --no args

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1576,6 +1576,7 @@
"defaults": {},
"funcname": "ImGui_ImplVulkanH_Window",
"location": "imgui_impl_vulkan:260",
"namespace": "ImGui_ImplVulkanH_Window",
"ov_cimguiname": "ImGui_ImplVulkanH_Window_ImGui_ImplVulkanH_Window",
"signature": "()",
"stname": "ImGui_ImplVulkanH_Window"

View File

@@ -1360,6 +1360,7 @@ local t={
defaults={},
funcname="ImGui_ImplVulkanH_Window",
location="imgui_impl_vulkan:260",
namespace="ImGui_ImplVulkanH_Window",
ov_cimguiname="ImGui_ImplVulkanH_Window_ImGui_ImplVulkanH_Window",
signature="()",
stname="ImGui_ImplVulkanH_Window"},

View File

@@ -5762,6 +5762,7 @@
"ImVec2i": true,
"ImVec4": true
},
"opaque_structs": [],
"structs": {
"ImBitVector": [
{

View File

@@ -4617,6 +4617,7 @@ local t={
ImVec2=true,
ImVec2i=true,
ImVec4=true},
opaque_structs={},
structs={
ImBitVector={
[1]={