Compare commits

..

2 Commits

Author SHA1 Message Date
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 1294 additions and 34 deletions

View File

@@ -195,6 +195,11 @@ local function check_template(code)
te = te:gsub("%s","_") te = te:gsub("%s","_")
te = te:gsub("%*","Ptr") te = te:gsub("%*","Ptr")
te = te:gsub("::","_") 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 = code:gsub("(<[%w_%*%s]+>)([^%s%*])","%1 %2")
code2 = code2:gsub("<([^<>]-)>","_"..te) 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: -- 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%(%)_]*;)", operator_re = "^([^;{}]+operator[^;{}]+%b()[\n%s%w%(%)_]*;)",
struct_re = "^([^;{}]-struct[^;{}]-%b{}[%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_%(%)]*;)", enum_re = "^([^;{}]-enum[^;{}]-%b{}[%s%w_%(%)]*;)",
union_re = "^([^;{}]-union[^;{}]-%b{}[%s%w_%(%)]*;)", union_re = "^([^;{}]-union[^;{}]-%b{}[%s%w_%(%)]*;)",
structenum_re = "^([^;{}]-%b{}[%s%w_%(%)]*;)", structenum_re = "^([^;{}]-%b{}[%s%w_%(%)]*;)",
namespace_re = "^([^;{}]-namespace[^;{}]-%b{})", namespace_re = "^([^;{}]-namespace[^;{}]-%b{})",
class_re = "^([^;{}]-class[^;{}]-%b{}%s*;)",
typedef_re = "^\n*%s*(typedef[^;]+;)", typedef_re = "^\n*%s*(typedef[^;]+;)",
typedef_st_re = "^\n*(typedef%s+struct%s*%b{}.-;)", typedef_st_re = "^\n*(typedef%s+struct%s*%b{}.-;)",
functypedef_re = "^\n*%s*(typedef[%w%s%*_]+%(%s*%*%s*[%w_]+%s*%)%s*%b()%s*;)", 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 end
local ret = line:match("([^%(%):,]+[%*%s])%s?~?[_%w]+%b()") 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 = line:match("(~?[_%w]+)%s*(%b())")
local funcname, args, extraconst = line:match("(~?[_%w]+)%s*(%b())(.*)") local funcname, args, extraconst = line:match("(~?[_%w]+)%s*(%b())(.*)")
extraconst = extraconst:match("const") extraconst = extraconst:match("const")
@@ -819,7 +826,14 @@ local function parseFunction(self,stname,itt,namespace,locat)
else else
reftoptr = nil reftoptr = nil
if ar:match("&") then 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("&","") ar = ar:gsub("&","")
else else
ar = ar:gsub("&","*") ar = ar:gsub("&","*")
@@ -949,6 +963,8 @@ local function parseFunction(self,stname,itt,namespace,locat)
defT.skipped = true defT.skipped = true
end end
if ret then 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.ret = clean_spaces(ret:gsub("&","*"))
defT.retref = ret:match("&") defT.retref = ret:match("&")
-- if defT.ret=="ImVec2" or defT.ret=="ImVec4" or defT.ret=="ImColor" then -- if defT.ret=="ImVec2" or defT.ret=="ImVec4" or defT.ret=="ImColor" then
@@ -1331,6 +1347,7 @@ local function ADDnonUDT(FP)
get_nonPODused(FP) get_nonPODused(FP)
for k,defs in pairs(FP.defsT) do 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 --ret
local rets = (def.ret or ""):gsub("const ","") local rets = (def.ret or ""):gsub("const ","")
rets = rets:gsub("*","") rets = rets:gsub("*","")
@@ -1341,6 +1358,14 @@ local function ADDnonUDT(FP)
elseif FP.nP_ret[rets] then elseif FP.nP_ret[rets] then
def.ret = def.ret:gsub(rets, FP.nP_ret[rets]) def.ret = def.ret:gsub(rets, FP.nP_ret[rets])
def.nonUDT = 2 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 end
--args --args
local caar,asp local caar,asp
@@ -1363,6 +1388,24 @@ local function ADDnonUDT(FP)
local typ3 = v.type:gsub(typ2,typ2.."_c") local typ3 = v.type:gsub(typ2,typ2.."_c")
caar = caar .. "reinterpret_cast<"..v.type..">("..name..")," caar = caar .. "reinterpret_cast<"..v.type..">("..name.."),"
asp = asp .. typ3 .." "..v.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::") 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 else
local siz = v.type:match("(%[%d*%])") or "" local siz = v.type:match("(%[%d*%])") or ""
local typ = v.type:gsub("(%[%d*%])","") local typ = v.type:gsub("(%[%d*%])","")
@@ -1378,9 +1421,14 @@ local function ADDnonUDT(FP)
caar = "()" caar = "()"
asp = "()" asp = "()"
end end
def.call_args_old = def.call_args if skip then
def.call_args = caar def.skipped = skip
def.args = asp 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 end
end end
@@ -1602,6 +1650,7 @@ function M.Parser()
par.manuals = {} par.manuals = {}
par.skipped = {} par.skipped = {}
par.UDTs = {} par.UDTs = {}
par.opaque_structs = {}
par.save_output = save_output par.save_output = save_output
par.genConversors = genConversions par.genConversors = genConversions
@@ -1710,6 +1759,29 @@ function M.Parser()
end end
end 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 --recursive item parsing
function par:parseItemsR2(txt, itparent) function par:parseItemsR2(txt, itparent)
local itsarr,its = parseItems(txt,self.linenumdict,itparent) local itsarr,its = parseItems(txt,self.linenumdict,itparent)
@@ -1718,17 +1790,22 @@ function M.Parser()
if it.re_name == "class_re" then if it.re_name == "class_re" then
it.name = it.item:match("class%s+(%S+)") it.name = it.item:match("class%s+(%S+)")
print("cleaning class",it.name) 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("private:","")
it.item = it.item:gsub("public:","") it.item = it.item:gsub("public:","")
it.item = it.item:gsub("enum%s*class","enum") it.item = it.item:gsub("enum%s*class","enum")
end end
if not isLeaf(it.re_name) then if not isLeaf(it.re_name) then
local inner = strip_end(it.item:match("%b{}"):sub(2,-2)) local inner = strip_end(it.item:match("%b{}"):sub(2,-2))
--print(it.item)
--print(inner)
it.childs = par:parseItemsR2(inner, it) it.childs = par:parseItemsR2(inner, it)
--if it.name == "TextEditor" then M.prtable(it.childs) end
for j,child in ipairs(it.childs) do for j,child in ipairs(it.childs) do
child.parent = it child.parent = it
end end
if it.re_name == "struct_re" then if it.re_name == "struct_re" then
local typename = it.item:match("^%s*template%s*<%s*typename%s*(%S+)%s*>") local typename = it.item:match("^%s*template%s*<%s*typename%s*(%S+)%s*>")
--local stname = it.item:match("struct%s+(%S+)") --local stname = it.item:match("struct%s+(%S+)")
@@ -1747,6 +1824,37 @@ function M.Parser()
it.name = it.item:match("namespace%s+(%S+)") it.name = it.item:match("namespace%s+(%S+)")
elseif it.re_name == "class_re" then elseif it.re_name == "class_re" then
--it.name = it.item:match("class%s+(%S+)") --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 end
end end
@@ -1831,6 +1939,15 @@ function M.Parser()
self.itemsarr = par:parseItemsR2(txt) self.itemsarr = par:parseItemsR2(txt)
--save_data("./itemsarr.lua",ToStr(self.itemsarr)) --save_data("./itemsarr.lua",ToStr(self.itemsarr))
itemsarr = 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 end
function par:printItems() function par:printItems()
@@ -1869,6 +1986,7 @@ function M.Parser()
end) end)
return table.concat(ttd,"") return table.concat(ttd,"")
end end
function par:clean_structR1(itst,doheader) function par:clean_structR1(itst,doheader)
local stru = itst.item local stru = itst.item
local outtab = {} local outtab = {}
@@ -1883,7 +2001,8 @@ function M.Parser()
local stname, derived local stname, derived
if inistruct:match":" then if inistruct:match":" then
stname,derived = inistruct:match"struct%s*([^%s:]+):(.+)" 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+)$" derived = derived:match"(%S+)$"
else else
if itst.re_name == "struct_re" then if itst.re_name == "struct_re" then
@@ -1930,6 +2049,9 @@ function M.Parser()
-- if stname=="StbUndoRecord" then error"dddd" end -- if stname=="StbUndoRecord" then error"dddd" end
return "" return ""
end --here we avoid empty structs end --here we avoid empty structs
if itst.opaque_struct then
return "", stname,nil,nil,""
end
for j,it in ipairs(itlist) do 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 (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 if not (it.re_name == "vardef_re" and it.item:match"static") then --skip static variables
@@ -1938,28 +2060,32 @@ function M.Parser()
--local ttype,template = it.item:match("([^%s,%(%)]+)%s*<(.+)>") --local ttype,template = it.item:match("([^%s,%(%)]+)%s*<(.+)>")
local ttype,template,te,code2 = check_template(it2) --it.item:match"([^%s,%(%)]+)%s*<(.+)>" local ttype,template,te,code2 = check_template(it2) --it.item:match"([^%s,%(%)]+)%s*<(.+)>"
if template then if template then
--print(it2)
--print("not doheader",ttype,template,te, self.typenames[ttype]) --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] = self.templates[ttype] or {}
self.templates[ttype][template] = te self.templates[ttype][template] = te
it2=code2 it2=code2
end end
if doheader then if doheader and self.templates[ttype] then
local templatetypedef = self:gentemplatetypedef(ttype, template,self.templates[ttype][template]) local templatetypedef = self:gentemplatetypedef(ttype, template,self.templates[ttype][template])
predeclare = predeclare .. templatetypedef predeclare = predeclare .. templatetypedef
end end
end end
--clean mutable --clean mutable
it2 = it2:gsub("mutable","") it2 = it2:gsub("mutable","")
--clean namespaces --clean namespaces but not std::
it2 = it2:gsub("%w+::","") --if not it2:match"std::" then
it2 = it2:gsub("%w+::","")
--end
--clean initializations --clean initializations
if it.re_name == "vardef_re" then if it.re_name == "vardef_re" then
it2 = it2:gsub("%s*=.+;",";") it2 = it2:gsub("%s*=.+;",";")
it2 = it2:gsub("%b{}","") it2 = it2:gsub("%b{}","")
end end
table.insert(outtab,it2) table.insert(outtab,it2)
--print("cleanstruct",it2)
table.insert(commtab,{above=it.prevcomments,sameline=it.comments})--it.comments or "") table.insert(commtab,{above=it.prevcomments,sameline=it.comments})--it.comments or "")
end end
elseif it.re_name == "union_re" then elseif it.re_name == "union_re" then
@@ -1971,10 +2097,12 @@ function M.Parser()
table.insert(outtab,item) table.insert(outtab,item)
com = (com ~= "") and com or nil com = (com ~= "") and com or nil
table.insert(commtab,{above=it.prevcomments,sameline=com}) 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) --print("nested struct in",stname,it.name)
--check if has declaration --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) local cleanst,structname,strtab,comstab,predec = self:clean_structR1(it,doheader)
if not structname then --unamed nested struct if not structname then --unamed nested struct
--print("----generate unamed nested struct----",it.name) --print("----generate unamed nested struct----",it.name)
@@ -1989,7 +2117,7 @@ function M.Parser()
table.insert(commtab,{above=it.prevcomments,sameline=it.comments})--it.comments or "") table.insert(commtab,{above=it.prevcomments,sameline=it.comments})--it.comments or "")
end end
if doheader then if doheader and not it.opaque_struct then
local tst = "\ntypedef struct "..structname.." "..structname..";\n" local tst = "\ntypedef struct "..structname.." "..structname..";\n"
if check_unique_typedefs(tst,uniques) then if check_unique_typedefs(tst,uniques) then
--table.insert(outtab,tst) --table.insert(outtab,tst)
@@ -2000,7 +2128,11 @@ function M.Parser()
predeclare = predeclare .. predec .. cleanst predeclare = predeclare .. predec .. cleanst
end end
elseif it.re_name == "enum_re" then 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 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)) print(it.re_name,"not processed clean_struct in",stname,it.item:sub(1,24))
--M.prtable(it) --M.prtable(it)
@@ -2031,6 +2163,7 @@ function M.Parser()
return parnam return parnam
end end
function par:header_text_insert(tab,txt,it) function par:header_text_insert(tab,txt,it)
--print("--header_text_insert",txt)--:sub(1,40))
table.insert(tab, txt) table.insert(tab, txt)
end end
local function function_parse(self,it) local function function_parse(self,it)
@@ -2039,6 +2172,7 @@ function M.Parser()
if it.parent then 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 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 stname = it.parent.name
namespace = get_parents_nameC(it)
elseif it.parent.re_name == "namespace_re" then elseif it.parent.re_name == "namespace_re" then
namespace = get_parents_nameC(it) --it.parent.name namespace = get_parents_nameC(it) --it.parent.name
end end
@@ -2057,6 +2191,48 @@ function M.Parser()
self:parseFunction(stname,it,namespace,it.locat) self:parseFunction(stname,it,namespace,it.locat)
end end
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() function par:gen_structs_and_enums()
print"--------------gen_structs_and_enums" print"--------------gen_structs_and_enums"
--M.prtable(self.typenames) --M.prtable(self.typenames)
@@ -2067,6 +2243,11 @@ function M.Parser()
--local uniques = {} --local uniques = {}
local processer = function(it) 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 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 if not it.parent or it.parent.re_name=="namespace_re" then
local it2 = it.item local it2 = it.item
@@ -2114,6 +2295,8 @@ function M.Parser()
self:header_text_insert(outtab, it2, it) self:header_text_insert(outtab, it2, it)
-- add typedef after struct name -- add typedef after struct name
if it.re_name == "vardef_re" and it.item:match"^%s*struct" then 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*;") local stname = it.item:match("struct%s*(%S+)%s*;")
--table.insert(typedefs_table,"typedef struct "..stname.." "..stname..";\n") --table.insert(typedefs_table,"typedef struct "..stname.." "..stname..";\n")
local tst = "\ntypedef struct "..stname.." "..stname..";" local tst = "\ntypedef struct "..stname.." "..stname..";"
@@ -2129,6 +2312,12 @@ function M.Parser()
end end
end end
elseif it.re_name == "enum_re" then 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, enumbody = it.item:match"^%s*enum%s+([^%s;{}]+)[%s\n\r]*(%b{})"
local enumname = it.item:match"^%s*enum%s+([^%s;{}]+)" local enumname = it.item:match"^%s*enum%s+([^%s;{}]+)"
if enumname then if enumname then
@@ -2169,8 +2358,14 @@ function M.Parser()
self:header_text_insert(outtab, cl_item, it) self:header_text_insert(outtab, cl_item, it)
print("unnamed enum",cl_item) print("unnamed enum",cl_item)
end end
--]]
elseif it.re_name == "struct_re" or it.re_name == "typedef_st_re" or it.re_name == "class_re" then 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) 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 structname then print("NO NAME",cleanst,it.item) end
--if not void stname or templated --if not void stname or templated
if structname and not self.typenames[structname] then if structname and not self.typenames[structname] then
@@ -2185,14 +2380,16 @@ function M.Parser()
end end
self.typedefs_dict[structname]="struct "..structname self.typedefs_dict[structname]="struct "..structname
--dont insert child structs as they are inserted before parent struct --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) --table.insert(outtab,predec .. cleanst)
self:header_text_insert(outtab, predec .. cleanst, it) self:header_text_insert(outtab, predec .. cleanst, it)
end end
end end
if it.parent then --and (it.parent.re_name == "struct_re" or it.parent.re_name == "typedef_st_re" then 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{]+)")) --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*;")) --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 --TODO nesting namespace and class
if embededst then --discards false which can happen with untagged structs if embededst then --discards false which can happen with untagged structs
local parname = get_parents_name(it) local parname = get_parents_name(it)
@@ -2200,10 +2397,12 @@ function M.Parser()
--needed by cimnodes with struct tag name equals member name --needed by cimnodes with struct tag name equals member name
self.embeded_structs[embededst] = "struct "..parname..embededst self.embeded_structs[embededst] = "struct "..parname..embededst
else else
--print("---------embeddd2",parname,embededst)
self.embeded_structs[embededst] = parname..embededst self.embeded_structs[embededst] = parname..embededst
end end
end 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 elseif it.re_name == "namespace_re" or it.re_name == "union_re" or it.re_name == "functype_re" then
--nop --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
@@ -2226,6 +2425,10 @@ function M.Parser()
-- end -- end
--check arg detection failure if no name in function declaration --check arg detection failure if no name in function declaration
check_arg_detection(self.defsT,self.typedefs_dict) 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,"") local outtabprest, outtabst = table.concat(outtabpre,""),table.concat(outtab,"")
outtabprest = M.header_subs_nonPOD(self,outtabprest) outtabprest = M.header_subs_nonPOD(self,outtabprest)
outtabst = M.header_subs_nonPOD(self,outtabst) outtabst = M.header_subs_nonPOD(self,outtabst)
@@ -2248,6 +2451,7 @@ function M.Parser()
table.insert(outtab,{type=t1..t2,name=name,comment=comment}) table.insert(outtab,{type=t1..t2,name=name,comment=comment})
else else
--split type name1,name2; in several lines --split type name1,name2; in several lines
--print(line)
local typen,rest = line:match("%s*([^,]+)%s(%S+[,;])") local typen,rest = line:match("%s*([^,]+)%s(%S+[,;])")
--print(typen,"rest:",rest) --print(typen,"rest:",rest)
if not typen then -- Lets try Type*name if not typen then -- Lets try Type*name
@@ -2345,7 +2549,7 @@ function M.Parser()
par.enums_for_table = enums_for_table par.enums_for_table = enums_for_table
function par:gen_structs_and_enums_table() function par:gen_structs_and_enums_table()
print"--------------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 = {} --self.typedefs_table = {}
local enumsordered = {} local enumsordered = {}
unnamed_enum_counter = 0 unnamed_enum_counter = 0
@@ -2408,6 +2612,7 @@ function M.Parser()
enums_for_table(it, outtab, enumsordered) 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 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) 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 void stname or templated
if not structname then print("NO NAME",cleanst,it.item) end if not structname then print("NO NAME",cleanst,it.item) end
if structname and not self.typenames[structname] then if structname and not self.typenames[structname] then
@@ -2415,17 +2620,25 @@ function M.Parser()
outtab.struct_comments[structname] = {sameline=it.comments,above=it.prevcomments} 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.struct_comments[structname] = next(outtab.struct_comments[structname]) and outtab.struct_comments[structname] or nil
outtab.locations[structname] = it.locat outtab.locations[structname] = it.locat
if strtab then
for j=3,#strtab-1 do for j=3,#strtab-1 do
self:parse_struct_line(strtab[j],outtab.structs[structname],comstab[j]) self:parse_struct_line(strtab[j],outtab.structs[structname],comstab[j])
end end
end
-- if structname == "Change" then
-- print(it.item)
-- M.prtable(outtab.structs[structname])
-- end
else else
--templated struct --templated struct
if structname then if structname then
print("saving templated struct",structname) print("saving templated struct",structname)
self.templated_structs[structname] = {} self.templated_structs[structname] = {}
if strtab then
for j=3,#strtab-1 do for j=3,#strtab-1 do
self:parse_struct_line(strtab[j],self.templated_structs[structname],comstab[j]) self:parse_struct_line(strtab[j],self.templated_structs[structname],comstab[j])
end end
end
--M.prtable(self.templated_structs[structname]) --M.prtable(self.templated_structs[structname])
else else
print("skipped unnamed struct",structname) print("skipped unnamed struct",structname)
@@ -2436,7 +2649,7 @@ function M.Parser()
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) function_parse(self,it)
elseif it.re_name ~= "operator_re" then 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
end end
@@ -2687,7 +2900,11 @@ function M.Parser()
end end
function par:gen_template_typedef_auto(ttype,te,newte) function par:gen_template_typedef_auto(ttype,te,newte)
--M.prtable(self.templated_structs) --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 defi = self.templated_structs[ttype]
local Targ = strsplit(self.typenames[ttype],",") local Targ = strsplit(self.typenames[ttype],",")
local defa = {} local defa = {}
@@ -3009,7 +3226,7 @@ local function ImGui_f_implementation(def)
table.insert(outtab,"CIMGUI_API".." "..def.ret.." "..def.ov_cimguiname..def.args.."\n") table.insert(outtab,"CIMGUI_API".." "..def.ret.." "..def.ov_cimguiname..def.args.."\n")
table.insert(outtab,"{\n") table.insert(outtab,"{\n")
local namespace = def.namespace and def.namespace.."::" or "" 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 if def.isvararg then
local call_args = def.call_args:gsub("%.%.%.","args") local call_args = def.call_args:gsub("%.%.%.","args")
table.insert(outtab," va_list args;\n") table.insert(outtab," va_list args;\n")
@@ -3037,6 +3254,9 @@ local function ImGui_f_implementation(def)
insert(outtab," return ConvertFromCPP_"..def.conv.."("..namespace..def.funcname..def.call_args..");\n") insert(outtab," return ConvertFromCPP_"..def.conv.."("..namespace..def.funcname..def.call_args..");\n")
elseif def.nonUDT == 2 then elseif def.nonUDT == 2 then
insert(outtab," return reinterpret_cast<"..def.ret..">("..ptret..namespace..def.funcname..def.call_args..");\n") 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 end
table.insert(outtab,"}\n") table.insert(outtab,"}\n")
else --standard ImGui else --standard ImGui
@@ -3075,6 +3295,9 @@ local function struct_f_implementation(def)
insert(outtab," return ConvertFromCPP_"..def.conv.."(self->"..def.funcname..def.call_args..");\n") insert(outtab," return ConvertFromCPP_"..def.conv.."(self->"..def.funcname..def.call_args..");\n")
elseif def.nonUDT == 2 then elseif def.nonUDT == 2 then
insert(outtab," return reinterpret_cast<"..def.ret..">("..ptret.."self->"..def.funcname..def.call_args..");\n") 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 end
else --standard struct else --standard struct
table.insert(outtab," return "..ptret.."self->"..def.funcname..def.call_args..";\n") table.insert(outtab," return "..ptret.."self->"..def.funcname..def.call_args..";\n")
@@ -3096,7 +3319,9 @@ local function func_implementation(FP)
custom = FP.custom_implementation(outtab, def, FP) custom = FP.custom_implementation(outtab, def, FP)
end end
local manual = FP.get_manuals(def) 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 if def.constructor then
local tab = {} local tab = {}
assert(def.stname ~= "","constructor without struct") assert(def.stname ~= "","constructor without struct")
@@ -3152,20 +3377,28 @@ M.table_do_sorted = table_do_sorted
local function func_header_generate_structs(FP) 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_do_sorted(FP.embeded_structs,function(k,v)
table.insert(outtab,"typedef "..v.." "..k..";\n") table.insert(outtab,"typedef "..v.." "..k..";\n")
end) end)
table_do_sorted(FP.embeded_enums,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(FP.templates,function(ttype,v)
table_do_sorted(v,function(ttypein,te) --print("func_header_generate_structs",ttype)
local ttype2 = ttype:gsub("::","_") --std::string if not (ttype == "std::function") then
table.insert(outtab,"typedef "..ttype.."<"..ttypein.."> "..ttype2.."_"..te..";\n") table_do_sorted(v,function(ttypein,te)
end) local ttype2 = ttype:gsub("::","_") --std::string
table.insert(outtab,"typedef "..ttype.."<"..ttypein.."> "..ttype2.."_"..te..";\n")
end)
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 return outtab
end end
M.func_header_generate_structs = func_header_generate_structs M.func_header_generate_structs = func_header_generate_structs
@@ -3186,7 +3419,8 @@ local function func_header_generate_funcs(FP)
custom = FP.custom_header(outtab, def) custom = FP.custom_header(outtab, def)
end end
local manual = FP.get_manuals(def) 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 addcoment = "" --def.comment or ""
local empty = def.args:match("^%(%)") --no args 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": {}, "defaults": {},
"funcname": "ImGui_ImplVulkanH_Window", "funcname": "ImGui_ImplVulkanH_Window",
"location": "imgui_impl_vulkan:260", "location": "imgui_impl_vulkan:260",
"namespace": "ImGui_ImplVulkanH_Window",
"ov_cimguiname": "ImGui_ImplVulkanH_Window_ImGui_ImplVulkanH_Window", "ov_cimguiname": "ImGui_ImplVulkanH_Window_ImGui_ImplVulkanH_Window",
"signature": "()", "signature": "()",
"stname": "ImGui_ImplVulkanH_Window" "stname": "ImGui_ImplVulkanH_Window"

View File

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

View File

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

View File

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