|
@@ -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
|