From af684b6cb18ba77b6c70dc91edbadcd9b9d2bc9e Mon Sep 17 00:00:00 2001 From: sonoro1234 Date: Mon, 3 Aug 2026 19:29:35 +0200 Subject: [PATCH] cpp2ffi: manuals not in module go to definitions --- generator/cpp2ffi.lua | 246 +++++++++++++++++++++++++++++- generator/output/definitions.json | 8 +- generator/output/definitions.lua | 12 +- 3 files changed, 254 insertions(+), 12 deletions(-) diff --git a/generator/cpp2ffi.lua b/generator/cpp2ffi.lua index 9124059..48bb555 100644 --- a/generator/cpp2ffi.lua +++ b/generator/cpp2ffi.lua @@ -998,7 +998,8 @@ local function parseFunction(self,stname,itt,namespace,locat) end end - --if ismanual then M.prtable(argsArr) end + -- print(cimguiname) + -- if ismanual then M.prtable("===================================\n",argsArr) end defT.templated = self.typenames[stname] and true defT.namespace = namespace @@ -1813,6 +1814,16 @@ end local function save_output(self) + --add manual not present in module + for k,v in pairs(self.manuals) do + if not self.defsT[k] then + print("add manual",k) + self.defsT[k] = {v} + else + print("skipped manual",k) + end + end + ---------------------- save_data("./output/overloads.txt",self.overloadstxt) save_data("./output/definitions.lua",M.serializeTableF(self.defsT)) save_data("./output/structs_and_enums.lua",M.serializeTableF(self.structs_and_enums_table)) @@ -2318,6 +2329,235 @@ function M.Parser() function par:printItems() printItems(items) end + -- for manuals not present in original module + -- copied from parseFuncion + local function split_args(self, funcname, stname, args, ret) + print("split args",funcname, stname, args, ret) + args = clean_spaces(args) + args = moveptr(args) + ret = clean_spaces(ret) + ret = moveptr(ret) + if stname==true then stname="" end + local constructor = ret:match(stname) and true or nil + + local argsp = args:sub(2,-2).."," + local argsTa = {} + for tynam in argsp:gmatch("([^,]+),") do + if tynam:match("%)") and not tynam:match("%b()") then + error"split_args" + --patenthesis not closed are merged in previous (happens in some defaults) + argsTa[#argsTa] = argsTa[#argsTa]..","..tynam + while argsTa[#argsTa]:match("%)") and not argsTa[#argsTa]:match("%b()") do + argsTa[#argsTa-1] = argsTa[#argsTa-1] .. "," .. argsTa[#argsTa] + argsTa[#argsTa] = nil + end + else + argsTa[#argsTa+1] = tynam + end + 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") + ar = ar:gsub("(%S)%s*&(%S)","%1& %2") + local typ,name,retf,sigf,reftoptr,defa,ar1 + local has_cdecl = ar:match"__cdecl" + if has_cdecl then ar = ar:gsub("__cdecl","") end + if ar:match(functype_re) then + local t1,namef,t2 = ar:match(functype_reex) + local f_ = has_cdecl and "(__cdecl*)" or "(*)" + typ, name = t1..f_..t2, namef + retf = t1 + sigf = t2 + else + reftoptr = nil + if ar:match("&") 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("&","*") + reftoptr = true + end + end + if ar:match("%.%.%.") then + typ, name = "...", "..." + else + ar1,defa = ar:match"([^=]+)=([^=]+)" + ar1 = ar1 or ar + typ,name = ar1:match("(.+)%s([^%s]+)") + end + if not typ or not name or name:match"%*" or M.c_types[name] or self.typedefs_dict[name] then + print("argument without name",funcname,typ,name,ar) + ar1,defa = ar:match"([^=]+)=([^=]+)" + ar1 = ar1 or ar + typ = ar1 + noname_counter = noname_counter + 1 + name = "noname"..noname_counter + end + --float name[2] to float[2] name + local siz = name:match("(%[%d*%])") + if siz then + typ = typ..siz + name = name:gsub("(%[%d*%])","") + end + end + + if typ:match"::" then + local const,typsimp,ptr = typ:match("(const )([^%*&]+)([%*&]*)") + print("= = = = 0 = =typ",typ,const,typsimp,ptr) + if self.opaque_structs_inv and self.opaque_structs_inv[typsimp] then + print("(((())))))=======self.opaque",const,typsimp,ptr); + typ = (const or "")..self.opaque_structs_inv[typsimp]..(ptr or "") + end + end + 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 + if not self.manuals[cname] then + print("reference to no const arg in",funcname,argscsinpars,ar) + end + end + end + + local argsArr = argsTa2 + + --recreate argscsinpars, call_args and signature from argsArr + local asp, caar,signat + if #argsArr > 0 then + asp = "(" + caar = "(" + signat = "(" + for i,v in ipairs(argsArr) do + if v.ret then --function pointer + local f_ = v.has_cdecl and "(__cdecl*" or "(*" + asp = asp .. v.ret .. f_ .. v.name .. ")" .. v.signature .. "," + caar = caar .. v.name .. "," + signat = signat .. v.ret .. f_..")" .. clean_names_from_signature(self,v.signature) .. "," + else + local siz = v.type:match("(%[%d*%])") or "" + local typ = v.type:gsub("(%[%d*%])","") + asp = asp .. typ .. (v.name~="..." and " "..v.name or "") .. siz .. "," + local callname = v.reftoptr and "*"..v.name or v.name + caar = caar .. callname .. "," + signat = signat .. typ .. siz .. "," + end + end + asp = asp:sub(1,-2)..")" + caar = caar:sub(1,-2)..")" + signat = signat:sub(1,-2)..")" .. (extraconst or "") + else + asp = "()" + caar = "()" + signat = "()" .. (extraconst or "") + end + --if ismanual then print("manual",asp, caar, signat) end + ---------------------------- + --[[ + if not ret and stname then --must be constructors + if not (stname == funcname or "~"..stname==funcname) then --break end + print("false constructor:",line); + print("b2:",ret,stname,funcname,args) + return --are function defs + end + end + --]] + local cimguiname = funcname --self.getCname(stname,funcname, namespace) + -- table.insert(self.funcdefs,{stname=stname,funcname=funcname,args=args,signature=signat,cimguiname=cimguiname,call_args=caar,ret =ret}) + local funcdef = {stname=stname,funcname=funcname,args=args,signature=signat,cimguiname=cimguiname,call_args=caar,ret =ret} + -- local defsT = self.defsT + -- defsT[cimguiname] = defsT[cimguiname] or {} + -- table.insert(defsT[cimguiname],{}) + -- local defT = defsT[cimguiname][#defsT[cimguiname]] + local defT = {constructor = constructor} + defT.defaults = {} + for i,ar in ipairs(argsArr) do + if ar.default then + --clean defaults + --do only if not a c string + local is_cstring = ar.default:sub(1,1)=='"' and ar.default:sub(-1,-1) =='"' + if not is_cstring then + ar.default = ar.default:gsub("%(%(void%s*%*%)0%)","NULL") + if ar.default:match"%(ImU32%)" and not ar.default:match"sizeof" then + ar.default = tostring(CleanImU32(ar.default)) + end + end + defT.defaults[ar.name] = ar.default + ar.default = nil + end + end + + -- print(cimguiname) + -- if ismanual then M.prtable("===================================\n",argsArr) end + + defT.templated = self.typenames[stname] and true + defT.namespace = namespace + defT.cimguiname = cimguiname + defT.ov_cimguiname = cimguiname + defT.stname = stname + defT.is_static_function = is_static_function + defT.funcname = funcname + defT.argsoriginal = args + defT.args= asp + defT.signature = signat --signature + defT.call_args = caar --call_args + defT.isvararg = signat:match("%.%.%.%)$") + defT.location = locat + --local comentario = (itt.prevcomments or "")..(itt.comments or "")..(comment or "") + --if comentario=="" then comentario=nil end + --defT.comment = comentario + defT.argsT = argsArr + if self.get_manuals(defT) then + defT.manual = true + end + if self.get_skipped(defT) then + 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("&","*")) + --name_conversion + local rr = defT.ret:gsub("*","") + rr = rr:gsub("const ","") + if self.name_conversion and self.name_conversion[rr] then + defT.ret = defT.ret:gsub(rr,self.name_conversion[rr]) + end + defT.retref = ret:match("&") + -- if defT.ret=="ImVec2" or defT.ret=="ImVec4" or defT.ret=="ImColor" then + -- defT.ret = defT.ret.."_Simple" + -- end + end + --]] + --defsT[cimguiname][signat] = defT + --M.prtable(defT) + defT.call_args_old = defT.call_args + return defT --, funcdef + end function par:set_manuals(manuals, modulen, erase) erase = erase or {"CIMGUI_API"} local moddata = read_data("./"..modulen.."_template.h") @@ -2327,10 +2567,12 @@ function M.Parser() ret = ret:gsub(ww,"") end local args = moddata:match(k.."%s*(%b())") - manuals[k] = {args = args, ret = ret} + manuals[k] = split_args(self,k,v,args,ret) + --manuals[k] = {args = args, ret = ret, argsT = split_args(self,args), manual = true, stname = ""} --print(k,args,ret) end self.manuals = manuals + M.prtable("manuals",manuals) end par.parseFunction = parseFunction local uniques = {} diff --git a/generator/output/definitions.json b/generator/output/definitions.json index 04a6aeb..999a7d6 100644 --- a/generator/output/definitions.json +++ b/generator/output/definitions.json @@ -10800,7 +10800,7 @@ ], "ImGuiTextBuffer_appendf": [ { - "args": "(ImGuiTextBuffer* self, const char* fmt,...)", + "args": "(ImGuiTextBuffer* self,const char* fmt,...)", "argsT": [ { "name": "self", @@ -10808,14 +10808,14 @@ }, { "name": "fmt", - "type": " const char*" + "type": "const char*" }, { "name": "...", "type": "..." } ], - "argsoriginal": "(ImGuiTextBuffer* self, const char* fmt, ...)", + "argsoriginal": "(ImGuiTextBuffer* self,const char* fmt,...)", "call_args": "(self,fmt,...)", "call_args_old": "(self,fmt,...)", "cimguiname": "ImGuiTextBuffer_appendf", @@ -10827,7 +10827,7 @@ "namespace": "ImGuiTextBuffer", "ov_cimguiname": "ImGuiTextBuffer_appendf", "ret": "void", - "signature": "(ImGuiTextBuffer*, const char*,...)", + "signature": "(ImGuiTextBuffer*,const char*,...)", "stname": "ImGuiTextBuffer" } ], diff --git a/generator/output/definitions.lua b/generator/output/definitions.lua index c092206..1f8f187 100644 --- a/generator/output/definitions.lua +++ b/generator/output/definitions.lua @@ -9224,18 +9224,18 @@ local t={ ["(const char*,const char*)"]=nil}, ImGuiTextBuffer_appendf={ [1]={ - args="(ImGuiTextBuffer* self, const char* fmt,...)", + args="(ImGuiTextBuffer* self,const char* fmt,...)", argsT={ [1]={ name="self", type="ImGuiTextBuffer*"}, [2]={ name="fmt", - type=" const char*"}, + type="const char*"}, [3]={ name="...", type="..."}}, - argsoriginal="(ImGuiTextBuffer* self, const char* fmt, ...)", + argsoriginal="(ImGuiTextBuffer* self,const char* fmt,...)", call_args="(self,fmt,...)", call_args_old="(self,fmt,...)", cimguiname="ImGuiTextBuffer_appendf", @@ -9247,9 +9247,9 @@ local t={ namespace="ImGuiTextBuffer", ov_cimguiname="ImGuiTextBuffer_appendf", ret="void", - signature="(ImGuiTextBuffer*, const char*,...)", + signature="(ImGuiTextBuffer*,const char*,...)", stname="ImGuiTextBuffer"}, - ["(ImGuiTextBuffer*, const char*,...)"]=nil}, + ["(ImGuiTextBuffer*,const char*,...)"]=nil}, ImGuiTextBuffer_appendfv={ [1]={ args="(ImGuiTextBuffer* self,const char* fmt,va_list args)", @@ -39324,7 +39324,7 @@ t.ImGuiTable_ImGuiTable["()"]=t.ImGuiTable_ImGuiTable[1] t.ImGuiTable_destroy["(ImGuiTable*)"]=t.ImGuiTable_destroy[1] t.ImGuiTextBuffer_ImGuiTextBuffer["()"]=t.ImGuiTextBuffer_ImGuiTextBuffer[1] t.ImGuiTextBuffer_append["(const char*,const char*)"]=t.ImGuiTextBuffer_append[1] -t.ImGuiTextBuffer_appendf["(ImGuiTextBuffer*, const char*,...)"]=t.ImGuiTextBuffer_appendf[1] +t.ImGuiTextBuffer_appendf["(ImGuiTextBuffer*,const char*,...)"]=t.ImGuiTextBuffer_appendf[1] t.ImGuiTextBuffer_appendfv["(const char*,va_list)"]=t.ImGuiTextBuffer_appendfv[1] t.ImGuiTextBuffer_begin["()const"]=t.ImGuiTextBuffer_begin[1] t.ImGuiTextBuffer_c_str["()const"]=t.ImGuiTextBuffer_c_str[1]