mirror of
https://github.com/bkaradzic/bgfx.git
synced 2026-02-17 20:52:36 +01:00
Updated IDL scripts.
This commit is contained in:
328
scripts/bgfx-codegen.lua
Normal file
328
scripts/bgfx-codegen.lua
Normal file
@@ -0,0 +1,328 @@
|
||||
-- Copyright 2019 云风 https://github.com/cloudwu . All rights reserved.
|
||||
-- License (the same with bgfx) : https://github.com/bkaradzic/bgfx/blob/master/LICENSE
|
||||
|
||||
local idl = require "idl"
|
||||
local codegen = require "codegen"
|
||||
local doxygen = require "doxygen"
|
||||
|
||||
local func_actions = {
|
||||
c99 = "\n",
|
||||
c99decl = "\n",
|
||||
cppdecl = "\n",
|
||||
interface_struct = "\n\t",
|
||||
interface_import = ",\n\t\t\t",
|
||||
c99_interface = "\n",
|
||||
cpp_interface = "\n",
|
||||
c99_functionid = "\n\t",
|
||||
cpp_functionid = "\n\t\t",
|
||||
}
|
||||
|
||||
local type_actions = {
|
||||
enums = "\n",
|
||||
cenums = "\n",
|
||||
structs = "\n",
|
||||
cstructs = "\n",
|
||||
handles = "\n",
|
||||
chandles = "\n",
|
||||
funcptrs = "\n",
|
||||
cfuncptrs = "\n",
|
||||
}
|
||||
|
||||
do
|
||||
local source = doxygen.load "bgfx.idl"
|
||||
local f = assert(load(source, "bgfx.idl" , "t", idl))
|
||||
f()
|
||||
end
|
||||
|
||||
codegen.nameconversion(idl.types, idl.funcs)
|
||||
|
||||
local function cfunc(f)
|
||||
return function(func)
|
||||
if not func.cpponly then
|
||||
return f(func)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local funcgen = {}
|
||||
|
||||
local functemp = {}
|
||||
|
||||
functemp.interface_struct = "$CRET (*$CFUNCNAME)($CARGS);"
|
||||
functemp.interface_import = "bgfx_$CFUNCNAME"
|
||||
functemp.c99_interface = [[
|
||||
BGFX_C_API $CRET bgfx_$CFUNCNAME($CARGS)
|
||||
{
|
||||
$CONVERSIONCTOC
|
||||
$PRERETCTOCg_interface->$CFUNCNAME($CALLARGS);
|
||||
$POSTRETCTOC
|
||||
}
|
||||
]]
|
||||
functemp.c99_functionid = "BGFX_FUNCTION_ID_$CFUNCNAMEUPPER,"
|
||||
functemp.cpp_functionid = "$CFUNCNAMECAML,"
|
||||
|
||||
for action,temp in pairs(functemp) do
|
||||
funcgen[action] = cfunc(function(func)
|
||||
return codegen.apply_functemp(func, temp)
|
||||
end)
|
||||
end
|
||||
|
||||
funcgen.cpp_interface= cfunc(function(func)
|
||||
if not func.cfunc and not func.conly then
|
||||
return codegen.apply_functemp(func, [[
|
||||
$RET $CLASSNAME$FUNCNAME($CPPARGS)$CONST
|
||||
{
|
||||
$CONVERSIONCTOCPP
|
||||
$PRERETCPPTOCg_interface->$CFUNCNAME($CALLARGSCPPTOC);
|
||||
$POSTRETCPPTOC
|
||||
}
|
||||
]])
|
||||
end
|
||||
end)
|
||||
|
||||
funcgen.c99 = cfunc(function(func)
|
||||
local temp
|
||||
if func.cfunc then
|
||||
temp = "/* BGFX_C_API $CRET bgfx_$CFUNCNAME($CARGS) */\n"
|
||||
else
|
||||
temp = [[
|
||||
BGFX_C_API $CRET bgfx_$CFUNCNAME($CARGS)
|
||||
{
|
||||
$CONVERSION
|
||||
$PRERET$CPPFUNC($CALLARGSCTOCPP);
|
||||
$POSTRET
|
||||
}
|
||||
]]
|
||||
end
|
||||
return codegen.apply_functemp(func, temp)
|
||||
end)
|
||||
|
||||
local function cppdecl(func)
|
||||
local doc = func.comments
|
||||
if not doc and func.comment then
|
||||
doc = { func.comment }
|
||||
end
|
||||
if doc then
|
||||
local cname
|
||||
if not func.cpponly then
|
||||
if func.multicfunc then
|
||||
cname = {}
|
||||
for _, name in ipairs(func.multicfunc) do
|
||||
cname[#cname+1] = "bgfx_" .. name
|
||||
end
|
||||
else
|
||||
cname = "bgfx_" .. func.cname
|
||||
end
|
||||
end
|
||||
doc = codegen.doxygen_type(doc, func, cname)
|
||||
end
|
||||
local funcdecl = codegen.apply_functemp(func, "$RET $FUNCNAME($ARGS)$CONST;\n")
|
||||
if doc then
|
||||
return doc .. "\n" .. funcdecl
|
||||
else
|
||||
return funcdecl
|
||||
end
|
||||
end
|
||||
|
||||
function funcgen.cppdecl(func)
|
||||
-- Don't generate member functions here
|
||||
if not func.class and not func.conly then
|
||||
return cppdecl(func)
|
||||
end
|
||||
end
|
||||
|
||||
funcgen.c99decl = cfunc(function(func)
|
||||
local doc = func.comments
|
||||
if not doc and func.comment then
|
||||
doc = { func.comment }
|
||||
end
|
||||
if doc then
|
||||
doc = codegen.doxygen_ctype(doc, func)
|
||||
end
|
||||
local funcdecl = codegen.apply_functemp(func, "BGFX_C_API $CRET bgfx_$CFUNCNAME($CARGS);")
|
||||
if doc then
|
||||
return "\n" .. doc .. "\n" .. funcdecl
|
||||
else
|
||||
return funcdecl
|
||||
end
|
||||
end)
|
||||
|
||||
local typegen = {}
|
||||
|
||||
local function add_doxygen(typedef, define, cstyle, cname)
|
||||
local func = cstyle and codegen.doxygen_ctype or codegen.doxygen_type
|
||||
local doc = func(typedef.comments, typedef, cname or typedef.cname)
|
||||
if doc then
|
||||
return doc .. "\n" .. define
|
||||
else
|
||||
return define
|
||||
end
|
||||
end
|
||||
|
||||
function typegen.enums(typedef)
|
||||
if typedef.enum then
|
||||
return add_doxygen(typedef, codegen.gen_enum_define(typedef), false, "bgfx_" .. typedef.cname)
|
||||
end
|
||||
end
|
||||
|
||||
function typegen.cenums(typedef)
|
||||
if typedef.enum then
|
||||
return add_doxygen(typedef, codegen.gen_enum_cdefine(typedef), true)
|
||||
end
|
||||
end
|
||||
|
||||
function typegen.structs(typedef)
|
||||
if typedef.struct and not typedef.namespace then
|
||||
local methods = typedef.methods
|
||||
if methods then
|
||||
local m = {}
|
||||
for _, func in ipairs(methods) do
|
||||
m[#m+1] = cppdecl(func)
|
||||
end
|
||||
methods = m
|
||||
end
|
||||
return add_doxygen(typedef, codegen.gen_struct_define(typedef, methods))
|
||||
end
|
||||
end
|
||||
|
||||
function typegen.cstructs(typedef)
|
||||
if typedef.struct then
|
||||
return add_doxygen(typedef, codegen.gen_struct_cdefine(typedef), true)
|
||||
end
|
||||
end
|
||||
|
||||
function typegen.handles(typedef)
|
||||
if typedef.handle then
|
||||
return codegen.gen_handle(typedef)
|
||||
end
|
||||
end
|
||||
|
||||
function typegen.chandles(typedef)
|
||||
if typedef.handle then
|
||||
return codegen.gen_chandle(typedef)
|
||||
end
|
||||
end
|
||||
|
||||
function typegen.funcptrs(typedef)
|
||||
if typedef.args then
|
||||
return add_doxygen(typedef, codegen.gen_funcptr(typedef))
|
||||
end
|
||||
end
|
||||
|
||||
function typegen.cfuncptrs(typedef)
|
||||
if typedef.args then
|
||||
return add_doxygen(typedef, codegen.gen_cfuncptr(typedef), true)
|
||||
end
|
||||
end
|
||||
|
||||
local function codes()
|
||||
local temp = {}
|
||||
for k in pairs(func_actions) do
|
||||
temp[k] = {}
|
||||
end
|
||||
|
||||
for k in pairs(type_actions) do
|
||||
temp[k] = {}
|
||||
end
|
||||
|
||||
-- call actions with func
|
||||
for _, f in ipairs(idl.funcs) do
|
||||
for k in pairs(func_actions) do
|
||||
local funcgen = funcgen[k]
|
||||
if funcgen then
|
||||
table.insert(temp[k], (funcgen(f)))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- call actions with type
|
||||
|
||||
for _, typedef in ipairs(idl.types) do
|
||||
for k in pairs(type_actions) do
|
||||
local typegen = typegen[k]
|
||||
if typegen then
|
||||
table.insert(temp[k], (typegen(typedef)))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for k, indent in pairs(func_actions) do
|
||||
temp[k] = table.concat(temp[k], indent)
|
||||
end
|
||||
for k, indent in pairs(type_actions) do
|
||||
temp[k] = table.concat(temp[k], indent)
|
||||
end
|
||||
|
||||
return temp
|
||||
end
|
||||
|
||||
local codes_tbl = codes()
|
||||
|
||||
local function add_path(filename)
|
||||
local path
|
||||
if type(paths) == "string" then
|
||||
path = paths
|
||||
else
|
||||
path = assert(paths[filename])
|
||||
end
|
||||
return path .. "/" .. filename
|
||||
end
|
||||
|
||||
local function change_indent(str, indent)
|
||||
if indent == "\t" then
|
||||
-- strip trailing space only
|
||||
return (str:gsub("(.-)\n", function (line)
|
||||
return line:gsub("([ \t]*)$","\n") end))
|
||||
else
|
||||
return (str:gsub("(.-)\n", function (line)
|
||||
return line:gsub("^(\t*)(.-)[ \t]*$",
|
||||
function (tabs, content)
|
||||
return indent:rep(#tabs) .. content .. "\n"
|
||||
end)
|
||||
end))
|
||||
end
|
||||
end
|
||||
|
||||
local gen = {}
|
||||
|
||||
function gen.apply(tempfile)
|
||||
local f = assert(io.open(tempfile, "rb"))
|
||||
local temp = f:read "a"
|
||||
f:close()
|
||||
codes_tbl.source = tempfile
|
||||
return (temp:gsub("$([%l%d_]+)", codes_tbl))
|
||||
end
|
||||
|
||||
function gen.format(codes, f)
|
||||
return change_indent(codes, f.indent)
|
||||
end
|
||||
|
||||
function gen.changed(codes, outputfile)
|
||||
local out = io.open(outputfile, "rb")
|
||||
if out then
|
||||
local origin = out:read "a"
|
||||
out:close()
|
||||
return origin ~= codes
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function gen.write(codes, outputfile)
|
||||
local out = assert(io.open(outputfile, "wb"))
|
||||
out:write(codes)
|
||||
out:close()
|
||||
end
|
||||
|
||||
function gen.gen(tempfile, outputfile, indent)
|
||||
print ("Generate", outputfile, "from", tempfile)
|
||||
local codes = gen.apply(tempfile)
|
||||
codes = change_indent(codes, indent)
|
||||
|
||||
if not gen.changed(codes, outputfile) then
|
||||
print("No change")
|
||||
end
|
||||
|
||||
gen.write(codes, outputfile)
|
||||
end
|
||||
|
||||
return gen
|
||||
@@ -1,305 +0,0 @@
|
||||
-- Copyright 2019 云风 https://github.com/cloudwu . All rights reserved.
|
||||
-- License (the same with bgfx) : https://github.com/bkaradzic/bgfx/blob/master/LICENSE
|
||||
|
||||
function doIdl()
|
||||
|
||||
local idl = require "idl"
|
||||
local codegen = require "codegen"
|
||||
local doxygen = require "doxygen"
|
||||
|
||||
local func_actions = {
|
||||
c99 = "\n",
|
||||
c99decl = "\n",
|
||||
cppdecl = "\n",
|
||||
interface_struct = "\n\t",
|
||||
interface_import = ",\n\t\t\t",
|
||||
c99_interface = "\n",
|
||||
cpp_interface = "\n",
|
||||
c99_functionid = "\n\t",
|
||||
cpp_functionid = "\n\t\t",
|
||||
}
|
||||
|
||||
local type_actions = {
|
||||
enums = "\n",
|
||||
cenums = "\n",
|
||||
structs = "\n",
|
||||
cstructs = "\n",
|
||||
handles = "\n",
|
||||
chandles = "\n",
|
||||
funcptrs = "\n",
|
||||
cfuncptrs = "\n",
|
||||
}
|
||||
|
||||
do
|
||||
local source = doxygen.load "bgfx.idl"
|
||||
local f = assert(load(source, "bgfx.idl" , "t", idl))
|
||||
f()
|
||||
end
|
||||
|
||||
codegen.nameconversion(idl.types, idl.funcs)
|
||||
|
||||
local function cfunc(f)
|
||||
return function(func)
|
||||
if not func.cpponly then
|
||||
return f(func)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local funcgen = {}
|
||||
|
||||
local functemp = {}
|
||||
|
||||
functemp.interface_struct = "$CRET (*$CFUNCNAME)($CARGS);"
|
||||
functemp.interface_import = "bgfx_$CFUNCNAME"
|
||||
functemp.c99_interface = [[
|
||||
BGFX_C_API $CRET bgfx_$CFUNCNAME($CARGS)
|
||||
{
|
||||
$CONVERSIONCTOC
|
||||
$PRERETCTOCg_interface->$CFUNCNAME($CALLARGS);
|
||||
$POSTRETCTOC
|
||||
}
|
||||
]]
|
||||
functemp.c99_functionid = "BGFX_FUNCTION_ID_$CFUNCNAMEUPPER,"
|
||||
functemp.cpp_functionid = "$CFUNCNAMECAML,"
|
||||
|
||||
for action,temp in pairs(functemp) do
|
||||
funcgen[action] = cfunc(function(func)
|
||||
return codegen.apply_functemp(func, temp)
|
||||
end)
|
||||
end
|
||||
|
||||
funcgen.cpp_interface= cfunc(function(func)
|
||||
if not func.cfunc and not func.conly then
|
||||
return codegen.apply_functemp(func, [[
|
||||
$RET $CLASSNAME$FUNCNAME($CPPARGS)$CONST
|
||||
{
|
||||
$CONVERSIONCTOCPP
|
||||
$PRERETCPPTOCg_interface->$CFUNCNAME($CALLARGSCPPTOC);
|
||||
$POSTRETCPPTOC
|
||||
}
|
||||
]])
|
||||
end
|
||||
end)
|
||||
|
||||
funcgen.c99 = cfunc(function(func)
|
||||
local temp
|
||||
if func.cfunc then
|
||||
temp = "/* BGFX_C_API $CRET bgfx_$CFUNCNAME($CARGS) */\n"
|
||||
else
|
||||
temp = [[
|
||||
BGFX_C_API $CRET bgfx_$CFUNCNAME($CARGS)
|
||||
{
|
||||
$CONVERSION
|
||||
$PRERET$CPPFUNC($CALLARGSCTOCPP);
|
||||
$POSTRET
|
||||
}
|
||||
]]
|
||||
end
|
||||
return codegen.apply_functemp(func, temp)
|
||||
end)
|
||||
|
||||
local function cppdecl(func)
|
||||
local doc = func.comments
|
||||
if not doc and func.comment then
|
||||
doc = { func.comment }
|
||||
end
|
||||
if doc then
|
||||
local cname
|
||||
if not func.cpponly then
|
||||
if func.multicfunc then
|
||||
cname = {}
|
||||
for _, name in ipairs(func.multicfunc) do
|
||||
cname[#cname+1] = "bgfx_" .. name
|
||||
end
|
||||
else
|
||||
cname = "bgfx_" .. func.cname
|
||||
end
|
||||
end
|
||||
doc = codegen.doxygen_type(doc, func, cname)
|
||||
end
|
||||
local funcdecl = codegen.apply_functemp(func, "$RET $FUNCNAME($ARGS)$CONST;\n")
|
||||
if doc then
|
||||
return doc .. "\n" .. funcdecl
|
||||
else
|
||||
return funcdecl
|
||||
end
|
||||
end
|
||||
|
||||
function funcgen.cppdecl(func)
|
||||
-- Don't generate member functions here
|
||||
if not func.class and not func.conly then
|
||||
return cppdecl(func)
|
||||
end
|
||||
end
|
||||
|
||||
funcgen.c99decl = cfunc(function(func)
|
||||
local doc = func.comments
|
||||
if not doc and func.comment then
|
||||
doc = { func.comment }
|
||||
end
|
||||
if doc then
|
||||
doc = codegen.doxygen_ctype(doc, func)
|
||||
end
|
||||
local funcdecl = codegen.apply_functemp(func, "BGFX_C_API $CRET bgfx_$CFUNCNAME($CARGS);")
|
||||
if doc then
|
||||
return "\n" .. doc .. "\n" .. funcdecl
|
||||
else
|
||||
return funcdecl
|
||||
end
|
||||
end)
|
||||
|
||||
local typegen = {}
|
||||
|
||||
local function add_doxygen(typedef, define, cstyle, cname)
|
||||
local func = cstyle and codegen.doxygen_ctype or codegen.doxygen_type
|
||||
local doc = func(typedef.comments, typedef, cname or typedef.cname)
|
||||
if doc then
|
||||
return doc .. "\n" .. define
|
||||
else
|
||||
return define
|
||||
end
|
||||
end
|
||||
|
||||
function typegen.enums(typedef)
|
||||
if typedef.enum then
|
||||
return add_doxygen(typedef, codegen.gen_enum_define(typedef), false, "bgfx_" .. typedef.cname)
|
||||
end
|
||||
end
|
||||
|
||||
function typegen.cenums(typedef)
|
||||
if typedef.enum then
|
||||
return add_doxygen(typedef, codegen.gen_enum_cdefine(typedef), true)
|
||||
end
|
||||
end
|
||||
|
||||
function typegen.structs(typedef)
|
||||
if typedef.struct and not typedef.namespace then
|
||||
local methods = typedef.methods
|
||||
if methods then
|
||||
local m = {}
|
||||
for _, func in ipairs(methods) do
|
||||
m[#m+1] = cppdecl(func)
|
||||
end
|
||||
methods = m
|
||||
end
|
||||
return add_doxygen(typedef, codegen.gen_struct_define(typedef, methods))
|
||||
end
|
||||
end
|
||||
|
||||
function typegen.cstructs(typedef)
|
||||
if typedef.struct then
|
||||
return add_doxygen(typedef, codegen.gen_struct_cdefine(typedef), true)
|
||||
end
|
||||
end
|
||||
|
||||
function typegen.handles(typedef)
|
||||
if typedef.handle then
|
||||
return codegen.gen_handle(typedef)
|
||||
end
|
||||
end
|
||||
|
||||
function typegen.chandles(typedef)
|
||||
if typedef.handle then
|
||||
return codegen.gen_chandle(typedef)
|
||||
end
|
||||
end
|
||||
|
||||
function typegen.funcptrs(typedef)
|
||||
if typedef.args then
|
||||
return add_doxygen(typedef, codegen.gen_funcptr(typedef))
|
||||
end
|
||||
end
|
||||
|
||||
function typegen.cfuncptrs(typedef)
|
||||
if typedef.args then
|
||||
return add_doxygen(typedef, codegen.gen_cfuncptr(typedef), true)
|
||||
end
|
||||
end
|
||||
|
||||
local function codes()
|
||||
local temp = {}
|
||||
for k in pairs(func_actions) do
|
||||
temp[k] = {}
|
||||
end
|
||||
|
||||
for k in pairs(type_actions) do
|
||||
temp[k] = {}
|
||||
end
|
||||
|
||||
-- call actions with func
|
||||
for _, f in ipairs(idl.funcs) do
|
||||
for k in pairs(func_actions) do
|
||||
local funcgen = funcgen[k]
|
||||
if funcgen then
|
||||
table.insert(temp[k], (funcgen(f)))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- call actions with type
|
||||
|
||||
for _, typedef in ipairs(idl.types) do
|
||||
for k in pairs(type_actions) do
|
||||
local typegen = typegen[k]
|
||||
if typegen then
|
||||
table.insert(temp[k], (typegen(typedef)))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for k, indent in pairs(func_actions) do
|
||||
temp[k] = table.concat(temp[k], indent)
|
||||
end
|
||||
for k, indent in pairs(type_actions) do
|
||||
temp[k] = table.concat(temp[k], indent)
|
||||
end
|
||||
|
||||
return temp
|
||||
end
|
||||
|
||||
local codes_tbl = codes()
|
||||
|
||||
local function add_path(filename)
|
||||
local path
|
||||
if type(paths) == "string" then
|
||||
path = paths
|
||||
else
|
||||
path = assert(paths[filename])
|
||||
end
|
||||
return path .. "/" .. filename
|
||||
end
|
||||
|
||||
local function change_indent(str, indent)
|
||||
return (str:gsub("(.-)\n", function (line)
|
||||
return line:gsub("^(\t*)(.-)[ \t]*$",
|
||||
function (tabs, content)
|
||||
return indent:rep(#tabs) .. content .. "\n"
|
||||
end)
|
||||
end))
|
||||
end
|
||||
|
||||
local function genidl(filename, outputfile, indent)
|
||||
local tempfile = "temp." .. filename
|
||||
print ("Generate", outputfile, "from", tempfile)
|
||||
local f = assert(io.open(tempfile, "rb"))
|
||||
local temp = f:read "a"
|
||||
f:close()
|
||||
local out = assert(io.open(outputfile, "wb"))
|
||||
codes_tbl.source = tempfile
|
||||
local codes = temp:gsub("$([%l%d_]+)", codes_tbl)
|
||||
out:write(change_indent(codes, indent))
|
||||
out:close()
|
||||
end
|
||||
|
||||
|
||||
genidl("bgfx.h", "../include/bgfx/c99/bgfx.h", " ")
|
||||
genidl("bgfx.idl.inl", "../src/bgfx.idl.inl", "\t")
|
||||
--genidl("bgfx.h", "../include/bgfx/bgfx.h", "\t")
|
||||
--genidl("bgfx.shim.cpp", "../src/bgfx.shim.cpp", "\t")
|
||||
|
||||
os.exit()
|
||||
|
||||
end
|
||||
|
||||
|
||||
@@ -53,12 +53,25 @@ newoption {
|
||||
description = "Enable building examples.",
|
||||
}
|
||||
|
||||
dofile "bgfx-idl.lua"
|
||||
|
||||
newaction {
|
||||
trigger = "idl",
|
||||
description = "Generate bgfx interface source code",
|
||||
execute = doIdl
|
||||
execute = function ()
|
||||
|
||||
local gen = require "bgfx-codegen"
|
||||
|
||||
local function generate(tempfile, outputfile, indent)
|
||||
local codes = gen.apply(tempfile)
|
||||
codes = gen.format(codes, {indent = indent})
|
||||
gen.write(codes, outputfile)
|
||||
print("Generating: " .. outputfile)
|
||||
end
|
||||
|
||||
generate("temp.bgfx.h" , "../include/bgfx/c99/bgfx.h", " ")
|
||||
generate("temp.bgfx.idl.inl", "../src/bgfx.idl.inl", "\t")
|
||||
|
||||
os.exit()
|
||||
end
|
||||
}
|
||||
|
||||
solution "bgfx"
|
||||
|
||||
Reference in New Issue
Block a user