浏览代码

Updated IDL scripts.

Бранимир Караџић 6 年之前
父节点
当前提交
218b4b73ea
共有 3 个文件被更改,包括 344 次插入308 次删除
  1. 328 0
      scripts/bgfx-codegen.lua
  2. 0 305
      scripts/bgfx-idl.lua
  3. 16 3
      scripts/genie.lua

+ 328 - 0
scripts/bgfx-codegen.lua

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

+ 0 - 305
scripts/bgfx-idl.lua

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

+ 16 - 3
scripts/genie.lua

@@ -53,12 +53,25 @@ newoption {
 	description = "Enable building examples.",
 	description = "Enable building examples.",
 }
 }
 
 
-dofile "bgfx-idl.lua"
-
 newaction {
 newaction {
 	trigger = "idl",
 	trigger = "idl",
 	description = "Generate bgfx interface source code",
 	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"
 solution "bgfx"