bgfx-idl.lua 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. -- Copyright 2019 云风 https://github.com/cloudwu . All rights reserved.
  2. -- License (the same with bgfx) : https://github.com/bkaradzic/bgfx/blob/master/LICENSE
  3. local idl = require "idl"
  4. local codegen = require "codegen"
  5. local doxygen = require "doxygen"
  6. local func_actions = {
  7. c99 = "\n",
  8. c99decl = "\n",
  9. cppdecl = "\n",
  10. interface_struct = "\n\t",
  11. interface_import = ",\n\t\t\t",
  12. c99_interface = "\n",
  13. cpp_interface = "\n",
  14. }
  15. local type_actions = {
  16. enums = "\n",
  17. cenums = "\n",
  18. structs = "\n",
  19. cstructs = "\n",
  20. handles = "\n",
  21. chandles = "\n",
  22. funcptrs = "\n",
  23. cfuncptrs = "\n",
  24. }
  25. do
  26. local source = doxygen.load "bgfx.idl"
  27. local f = assert(load(source, "bgfx.idl" , "t", idl))
  28. f()
  29. end
  30. codegen.nameconversion(idl.types, idl.funcs)
  31. local function cfunc(f)
  32. return function(func)
  33. if not func.cpponly then
  34. return f(func)
  35. end
  36. end
  37. end
  38. local funcgen = {}
  39. local functemp = {}
  40. functemp.interface_struct = "$CRET (*$CFUNCNAME)($CARGS);"
  41. functemp.interface_import = "bgfx_$CFUNCNAME"
  42. functemp.c99_interface = [[
  43. BGFX_C_API $CRET bgfx_$CFUNCNAME($CARGS)
  44. {
  45. $CONVERSIONCTOC
  46. $PRERETCTOCg_interface->$CFUNCNAME($CALLARGS);
  47. $POSTRETCTOC
  48. }
  49. ]]
  50. for action,temp in pairs(functemp) do
  51. funcgen[action] = cfunc(function(func)
  52. return codegen.apply_functemp(func, temp)
  53. end)
  54. end
  55. funcgen.cpp_interface= cfunc(function(func)
  56. if not func.cfunc and not func.conly then
  57. return codegen.apply_functemp(func, [[
  58. $RET $CLASSNAME$FUNCNAME($CPPARGS)$CONST
  59. {
  60. $CONVERSIONCTOCPP
  61. $PRERETCPPTOCg_interface->$CFUNCNAME($CALLARGSCPPTOC);
  62. $POSTRETCPPTOC
  63. }
  64. ]])
  65. end
  66. end)
  67. funcgen.c99 = cfunc(function(func)
  68. local temp
  69. if func.cfunc then
  70. temp = "/* BGFX_C_API $CRET bgfx_$CFUNCNAME($CARGS) */\n"
  71. else
  72. temp = [[
  73. BGFX_C_API $CRET bgfx_$CFUNCNAME($CARGS)
  74. {
  75. $CONVERSION
  76. $PRERET$CPPFUNC($CALLARGSCTOCPP);
  77. $POSTRET
  78. }
  79. ]]
  80. end
  81. return codegen.apply_functemp(func, temp)
  82. end)
  83. local function cppdecl(func)
  84. local doc = func.comments
  85. if not doc and func.comment then
  86. doc = { func.comment }
  87. end
  88. if doc then
  89. local cname
  90. if not func.cpponly then
  91. if func.multicfunc then
  92. cname = {}
  93. for _, name in ipairs(func.multicfunc) do
  94. cname[#cname+1] = "bgfx_" .. name
  95. end
  96. else
  97. cname = "bgfx_" .. func.cname
  98. end
  99. end
  100. doc = codegen.doxygen_type(doc, func, cname)
  101. end
  102. local funcdecl = codegen.apply_functemp(func, "$RET $FUNCNAME($ARGS)$CONST;\n")
  103. if doc then
  104. return doc .. "\n" .. funcdecl
  105. else
  106. return funcdecl
  107. end
  108. end
  109. function funcgen.cppdecl(func)
  110. -- Don't generate member functions here
  111. if not func.class and not func.conly then
  112. return cppdecl(func)
  113. end
  114. end
  115. funcgen.c99decl = cfunc(function(func)
  116. local doc = func.comments
  117. if not doc and func.comment then
  118. doc = { func.comment }
  119. end
  120. if doc then
  121. doc = codegen.doxygen_ctype(doc, func)
  122. end
  123. local funcdecl = codegen.apply_functemp(func, "BGFX_C_API $CRET bgfx_$CFUNCNAME($CARGS);")
  124. if doc then
  125. return "\n" .. doc .. "\n" .. funcdecl
  126. else
  127. return funcdecl
  128. end
  129. end)
  130. local typegen = {}
  131. local function add_doxygen(typedef, define, cstyle, cname)
  132. local func = cstyle and codegen.doxygen_ctype or codegen.doxygen_type
  133. local doc = func(typedef.comments, typedef, cname or typedef.cname)
  134. if doc then
  135. return doc .. "\n" .. define
  136. else
  137. return define
  138. end
  139. end
  140. function typegen.enums(typedef)
  141. if typedef.enum then
  142. return add_doxygen(typedef, codegen.gen_enum_define(typedef), false, "bgfx_" .. typedef.cname)
  143. end
  144. end
  145. function typegen.cenums(typedef)
  146. if typedef.enum then
  147. return add_doxygen(typedef, codegen.gen_enum_cdefine(typedef), true)
  148. end
  149. end
  150. function typegen.structs(typedef)
  151. if typedef.struct and not typedef.namespace then
  152. local methods = typedef.methods
  153. if methods then
  154. local m = {}
  155. for _, func in ipairs(methods) do
  156. m[#m+1] = cppdecl(func)
  157. end
  158. methods = m
  159. end
  160. return add_doxygen(typedef, codegen.gen_struct_define(typedef, methods))
  161. end
  162. end
  163. function typegen.cstructs(typedef)
  164. if typedef.struct then
  165. return add_doxygen(typedef, codegen.gen_struct_cdefine(typedef), true)
  166. end
  167. end
  168. function typegen.handles(typedef)
  169. if typedef.handle then
  170. return codegen.gen_handle(typedef)
  171. end
  172. end
  173. function typegen.chandles(typedef)
  174. if typedef.handle then
  175. return codegen.gen_chandle(typedef)
  176. end
  177. end
  178. function typegen.funcptrs(typedef)
  179. if typedef.args then
  180. return add_doxygen(typedef, codegen.gen_funcptr(typedef))
  181. end
  182. end
  183. function typegen.cfuncptrs(typedef)
  184. if typedef.args then
  185. return add_doxygen(typedef, codegen.gen_cfuncptr(typedef), true)
  186. end
  187. end
  188. local function codes()
  189. local temp = {}
  190. for k in pairs(func_actions) do
  191. temp[k] = {}
  192. end
  193. for k in pairs(type_actions) do
  194. temp[k] = {}
  195. end
  196. -- call actions with func
  197. for _, f in ipairs(idl.funcs) do
  198. for k in pairs(func_actions) do
  199. local funcgen = funcgen[k]
  200. if funcgen then
  201. table.insert(temp[k], (funcgen(f)))
  202. end
  203. end
  204. end
  205. -- call actions with type
  206. for _, typedef in ipairs(idl.types) do
  207. for k in pairs(type_actions) do
  208. local typegen = typegen[k]
  209. if typegen then
  210. table.insert(temp[k], (typegen(typedef)))
  211. end
  212. end
  213. end
  214. for k, ident in pairs(func_actions) do
  215. temp[k] = table.concat(temp[k], ident)
  216. end
  217. for k, ident in pairs(type_actions) do
  218. temp[k] = table.concat(temp[k], ident)
  219. end
  220. return temp
  221. end
  222. local codes_tbl = codes()
  223. local function add_path(filename)
  224. local path
  225. if type(paths) == "string" then
  226. path = paths
  227. else
  228. path = assert(paths[filename])
  229. end
  230. return path .. "/" .. filename
  231. end
  232. local function genidl(filename, outputfile)
  233. local tempfile = "temp." .. filename
  234. print ("Generate", outputfile, "from", tempfile)
  235. local f = assert(io.open(tempfile, "rb"))
  236. local temp = f:read "a"
  237. f:close()
  238. local out = assert(io.open(outputfile, "wb"))
  239. codes_tbl.source = tempfile
  240. out:write((temp:gsub("$([%l%d_]+)", codes_tbl)))
  241. out:close()
  242. end
  243. function doIdl()
  244. local files = {
  245. ["bgfx.h"] = "../include/bgfx/c99",
  246. ["bgfx.idl.inl"] = "../src",
  247. }
  248. for filename, path in pairs (files) do
  249. genidl(filename, path .. "/" .. filename)
  250. end
  251. os.exit()
  252. end