pkgToDox.lua 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. -- Generate dox from pkg file
  2. if #arg == 0 then
  3. print("Usage: lua pkgToDox.lua <output file name> <input pkg file name> ...")
  4. os.exit(1)
  5. end
  6. pkgFiles = {}
  7. enums = {}
  8. classes = {}
  9. globalConstants = {}
  10. globalFunctions = {}
  11. -- trim string.
  12. function trim(s)
  13. return (s:gsub("^%s*(.-)%s*$", "%1"))
  14. end
  15. -- check is embed code.
  16. inEmbed = false
  17. function isEmbedLine(line)
  18. if string.sub(line, 1, 2) == "$#" then
  19. return true
  20. end
  21. if not inEmbed then
  22. if string.find(line, "${") ~= nil or string.find(line, "$[[]") ~= nil then
  23. inEmbed = true
  24. return true
  25. end
  26. else
  27. if string.find(line, "$}") ~= nil or string.find(line, "$[]]") ~= nil then
  28. inEmbed = false
  29. return true
  30. end
  31. end
  32. return inEmbed
  33. end
  34. -- check is comment.
  35. inComment = false
  36. function isCommentLine(line)
  37. if line:find("//") ~= nil then
  38. return true
  39. end
  40. if inComment then
  41. if line:find("[*]/") ~= nil then
  42. inComment = false
  43. return true
  44. end
  45. else
  46. if line:find("/[*]") ~= nil then
  47. inComment = true
  48. return true
  49. end
  50. end
  51. return inComment
  52. end
  53. -- check is valid line.
  54. function isValidLine(line)
  55. if #line < 2 then
  56. return fasle
  57. end
  58. if isEmbedLine(line) then
  59. return false
  60. end
  61. if isCommentLine(line) then
  62. return false
  63. end
  64. -- Declaration line.
  65. if (string.find(line, "enum ") ~= nil or string.find(line, "class ") ~= nil or
  66. string.find(line, "struct ") ~= nil ) and string.find(line, "}") ~= nil then
  67. return false
  68. end
  69. return true
  70. end
  71. local ENUM = 1 -- line is enum code.
  72. local CLASS = 2 -- line is class code.
  73. local GLOBAL = 3 -- line is global code.
  74. local type = GLOBAL -- current line type.
  75. function handleLine(line)
  76. if type == ENUM then
  77. if line:find("};") ~= nil then -- end of enum.
  78. type = GLOBAL
  79. else
  80. table.insert(enums, line)
  81. end
  82. return
  83. end
  84. if type == CLASS then
  85. if line:find("};") ~= nil then -- end of class or struct.
  86. type = GLOBAL
  87. else
  88. table.insert(classes, line)
  89. end
  90. return
  91. end
  92. if type == GLOBAL then
  93. if line:find("enum ") ~= nil then
  94. type = ENUM
  95. return
  96. end
  97. if line:find("class ") ~= nil or line:find("struct ") ~= nil then -- begin of class or struct.
  98. type = CLASS
  99. table.insert(classes, line)
  100. return
  101. end
  102. if line:find(")") == nil then -- global function.
  103. table.insert(globalConstants, line)
  104. else
  105. table.insert(globalFunctions, line)
  106. end
  107. return
  108. end
  109. end
  110. function gatherPkgFile(apiFile)
  111. local file = io.open(apiFile)
  112. if file == nil then
  113. return
  114. end
  115. local line = file:read()
  116. while line ~= nil do
  117. line = trim(line)
  118. local i, _, pkgFile = line:find("$pfile \"(.+)\"")
  119. if i ~= nil then -- begin of pkg file.
  120. table.insert(pkgFiles, pkgFile)
  121. end
  122. line = file:read()
  123. end
  124. file:close()
  125. end
  126. function handlePkgFile(pkgFile)
  127. local file = io.open(pkgFile)
  128. if file == nil then
  129. return
  130. end
  131. type = GLOBAL
  132. local line = file:read()
  133. while line ~= nil do
  134. line = trim(line)
  135. if isValidLine(line) then
  136. handleLine(line)
  137. end
  138. line = file:read()
  139. end
  140. file:close()
  141. end
  142. for i=2,#arg do
  143. gatherPkgFile(arg[i])
  144. end
  145. for _, pkgFile in ipairs(pkgFiles) do
  146. handlePkgFile(pkgFile)
  147. end
  148. function writeGlobalFunctions(ofile)
  149. ofile:write("\\section LuaScriptAPI_GlobalFunctions Global functions\n")
  150. for _, line in ipairs(globalFunctions) do
  151. line = line:gsub("%w+ @ ", "")
  152. line = line:gsub(";", "")
  153. ofile:write("- " .. line .. "\n")
  154. end
  155. ofile:write("\n")
  156. end
  157. function writeGlobalConstants(ofile)
  158. ofile:write("\\section LuaScriptAPI_GlobalConstants Global constants\n")
  159. for _, line in ipairs(globalConstants) do
  160. line = line:gsub("static ", "")
  161. line = line:gsub("const ", "")
  162. line = line:gsub(";", "")
  163. ofile:write("- " .. line .. "\n")
  164. end
  165. for _, line in ipairs(enums) do
  166. line = line:gsub(",", "")
  167. line = line:gsub(" = .*", "")
  168. ofile:write("- int " .. line .. "\n")
  169. end
  170. ofile:write("\n")
  171. end
  172. function writeClasses(ofile)
  173. ofile:write("\\section LuaScriptAPI_Classes Classes\n")
  174. local firstProperty = true
  175. for _, line in ipairs(classes) do
  176. if line:find("class ") ~= nil or line:find("struct ") ~= nil then
  177. line = line:gsub("class ", "")
  178. line = line:gsub("struct ", "")
  179. line = line:gsub("public ", "")
  180. ofile:write("\n### " .. line .. "\n\nMethods:\n\n")
  181. firstProperty = true
  182. else
  183. line = line:gsub(";", "")
  184. if line:find(")") ~= nil then
  185. line = line:gsub(" %w+ @ ", " ")
  186. line = line:gsub("explicit ", "")
  187. line = line:gsub("tolua_outside ", "")
  188. ofile:write("- " .. line .. "\n")
  189. else
  190. if firstProperty then
  191. firstProperty = false
  192. ofile:write("\nProperties:\n\n")
  193. end
  194. line = line:gsub(" %w+_ @ ", " ")
  195. line = line:gsub("tolua_property__get_set ", "")
  196. line = line:gsub("tolua_property__is_set ", "")
  197. line = line:gsub("tolua_property__has_set ", "")
  198. line = line:gsub("tolua_property__no_prefix ", "")
  199. if line:find("tolua_readonly") == nil then
  200. ofile:write("- " .. line .. "\n")
  201. else
  202. line = line:gsub("tolua_readonly ", "")
  203. ofile:write("- " .. line .. " (readonly)\n")
  204. end
  205. end
  206. end
  207. end
  208. end
  209. ofile = io.open(arg[1], "w")
  210. ofile:write([[
  211. namespace Urho3D
  212. {
  213. /**
  214. \page LuaScriptAPI Lua Scripting API
  215. ]])
  216. ofile:write("\n")
  217. writeClasses(ofile)
  218. writeGlobalFunctions(ofile)
  219. writeGlobalConstants(ofile)
  220. ofile:write([[
  221. */
  222. }
  223. ]])