ToZerobraneStudioHook.lua 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. --
  2. -- Copyright (c) 2008-2015 the Urho3D project.
  3. --
  4. -- Permission is hereby granted, free of charge, to any person obtaining a copy
  5. -- of this software and associated documentation files (the "Software"), to deal
  6. -- in the Software without restriction, including without limitation the rights
  7. -- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. -- copies of the Software, and to permit persons to whom the Software is
  9. -- furnished to do so, subject to the following conditions:
  10. --
  11. -- The above copyright notice and this permission notice shall be included in
  12. -- all copies or substantial portions of the Software.
  13. --
  14. -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. -- THE SOFTWARE.
  21. --
  22. -- Highly based on "ToDoxHook.lua", adjusted for Zerobrane Studio API format.
  23. -- Compatible with Zerobrane Studio 0.41+ (Zerobrane Studio 0.40 and below may have issues)
  24. --[[ Copy result in your Zerobrane Studio's folder "api/lua" and set it in your
  25. "interpreters" file with the filename (excluding it's lua extension) into the
  26. "api" table variable. ]]--
  27. require "ToDoxHook"
  28. function printFunction(self,ident,close,isfunc)
  29. local func = {}
  30. func.mod = self.mod
  31. func.type = self.type
  32. func.ptr = self.ptr
  33. func.name = self.name
  34. func.lname = self.lname
  35. func.const = self.const
  36. func.cname = self.cname
  37. func.lname = self.lname
  38. if isfunc then
  39. func.name = func.lname
  40. end
  41. currentFunction = func
  42. local i = 1
  43. while self.args[i] do
  44. self.args[i]:print(ident.." ",",")
  45. i = i + 1
  46. end
  47. currentFunction = nil
  48. if currentClass == nil then
  49. table.insert(globalFunctions, func)
  50. else
  51. if func.name == "delete" then
  52. func.type = "void"
  53. end
  54. if currentClass.functions == nil then
  55. currentClass.functions = { func }
  56. else
  57. table.insert(currentClass.functions, func)
  58. end
  59. end
  60. end
  61. -- Workaround for Zerobrane Studio's tool-tip with overloaded functions
  62. function adjustClassesOverloadFuncs()
  63. for i, class in ipairs(classes) do
  64. if classes[i].functions ~= nil then
  65. for j, func in ipairs(classes[i].functions) do
  66. for k, searchfunc in ipairs(classes[i].functions) do
  67. -- don't apply on same
  68. if k ~= j and func.name == searchfunc.name then
  69. if classes[i].functions[j].overloads == nil then
  70. classes[i].functions[j].overloads = {}
  71. end
  72. table.insert(classes[i].functions[j].overloads, searchfunc)
  73. table.remove(classes[i].functions, k)
  74. adjustClassesOverloadFuncs()
  75. return
  76. end
  77. end
  78. end
  79. end
  80. end
  81. end
  82. function writeFunctionArgs(file, declarations)
  83. local count = table.maxn(declarations)
  84. for i = 1, count do
  85. local declaration = declarations[i]
  86. if declaration.type ~= "void" then
  87. -- add paramter type
  88. local param_str = declaration.type
  89. -- add pointer or reference
  90. if declaration.ptr ~= "" then
  91. param_str = param_str .. declaration.ptr
  92. end
  93. -- add paramter name
  94. param_str = param_str .. " " .. declaration.name
  95. -- add paramter default value
  96. if declaration.def ~= "" then
  97. param_str = param_str .. " = " .. declaration.def
  98. end
  99. local fixedParamStr = param_str:gsub([[(")]], [[\%1]])
  100. file:write(fixedParamStr)
  101. end
  102. if i ~= count then
  103. file:write(", ")
  104. end
  105. end
  106. end
  107. function writeFunctionReturn(file, func)
  108. local return_str = ""
  109. if func.type ~= "" and func.type ~= "void" then
  110. return_str = return_str .. func.type
  111. end
  112. if func.ptr ~= "" then
  113. if func.type == "" and classname ~= nil then
  114. return_str = return_str .. classname
  115. end
  116. return_str = return_str .. func.ptr
  117. end
  118. file:write(return_str)
  119. end
  120. function writeInheritances(file, classname)
  121. for i, inheritance in ipairs(classes) do
  122. if inheritance.name == classname then
  123. if inheritance.functions ~= nil then
  124. for j, func in ipairs(inheritance.functions) do
  125. writeFunction(file, func, classname, true)
  126. end
  127. end
  128. if inheritance.properties ~= nil then
  129. for j, property in ipairs(inheritance.properties) do
  130. writeProperty(file, property)
  131. end
  132. end
  133. -- append inheritance functions & properties
  134. if inheritance.base ~= "" then
  135. writeInheritances(file, inheritance.base)
  136. end
  137. end
  138. end
  139. end
  140. function writeClasses(file)
  141. sortByName(classes)
  142. adjustClassesOverloadFuncs()
  143. file:write("\n\n -- Classes")
  144. for i, class in ipairs(classes) do
  145. file:write("\n " .. class.name .. " = {")
  146. if class.functions ~= nil or class.properties ~= nil then
  147. file:write("\n childs = {")
  148. end
  149. if class.functions ~= nil then
  150. for i, func in ipairs(class.functions) do
  151. writeFunction(file, func, class.name)
  152. end
  153. end
  154. if class.properties ~= nil then
  155. for i, property in ipairs(class.properties) do
  156. writeProperty(file, property)
  157. end
  158. end
  159. -- append inheritance functions & properties
  160. if class.base ~= "" then
  161. writeInheritances(file, class.base)
  162. end
  163. if class.functions ~= nil or class.properties ~= nil then
  164. file:write("\n },")
  165. end
  166. file:write("\n type = \"class\"")
  167. file:write("\n },")
  168. end
  169. end
  170. function writeEnumerates(file)
  171. sortByName(enumerates)
  172. file:write("\n\n -- Enumerations\n")
  173. for i, enumerate in ipairs(enumerates) do
  174. for i, value in ipairs(enumerate.values) do
  175. file:write("\n " .. value .. " = {")
  176. file:write("\n description = \"(Readonly) int for '" .. enumerate.name .. "'\",")
  177. file:write("\n type = \"value\"")
  178. file:write("\n },")
  179. end
  180. end
  181. end
  182. function writeFunction(file, func, classname, isInheritance, asFunc)
  183. -- ignore operators
  184. if func.name:find("^operator[=%+%-%*%(%)\\</]") == nil then
  185. -- ignore new/delete object if from inheritance
  186. if not ((func.name == classname or func.name == "new" or func.name == "delete") and isInheritance == true) then
  187. -- write function begin
  188. file:write("\n " .. func.name .. " = {")
  189. -- write parameters
  190. file:write("\n args = \"(")
  191. if func.declarations ~= nil then
  192. writeFunctionArgs(file, func.declarations)
  193. end
  194. file:write(")\",")
  195. -- write description preparation
  196. local isFirstDescription = true
  197. if func.overloads ~= nil or func.descriptions ~= nil then
  198. file:write("\n description = \"")
  199. end
  200. -- write overloaded parameters in description, if any
  201. if func.overloads ~= nil then
  202. for i, overload in ipairs(func.overloads) do
  203. if isFirstDescription == false then
  204. file:write(",\\n")
  205. else
  206. isFirstDescription = false
  207. end
  208. file:write("(")
  209. writeFunctionReturn(file, overload)
  210. file:write(") "..overload.name.." (")
  211. writeFunctionArgs(file, overload.declarations)
  212. file:write(")")
  213. end
  214. end
  215. -- write description
  216. if func.descriptions ~= nil then
  217. for i, description in ipairs(func.descriptions) do
  218. if isFirstDescription == false then
  219. file:write("\\n")
  220. else
  221. isFirstDescription = false
  222. end
  223. local fixedDescription = description:gsub([[(")]], [[\%1]])
  224. file:write(fixedDescription)
  225. end
  226. end
  227. -- write description end
  228. if func.overloads ~= nil or func.descriptions ~= nil then
  229. file:write("\",")
  230. end
  231. -- write returns
  232. if func.type ~= "" or func.ptr ~= "" then
  233. file:write("\n returns = \"(")
  234. writeFunctionReturn(file, func)
  235. file:write(")\",")
  236. end
  237. -- write valuetype
  238. if func.ptr ~= "" then
  239. if func.type ~= "" then
  240. file:write("\n valuetype = \"" .. func.type:gsub("(const%s+)","") .. "\",")
  241. elseif classname ~= nil then
  242. file:write("\n valuetype = \"" .. classname .. "\",")
  243. end
  244. end
  245. -- write function end
  246. if asFunc == true then
  247. file:write("\n type = \"function\"") -- accepts auto-completion with ".", ":" and global
  248. else
  249. file:write("\n type = \"method\"") -- accepts auto-completion only with ":"
  250. end
  251. file:write("\n },")
  252. end
  253. end
  254. end
  255. function writeGlobalConstants(file)
  256. sortByName(globalConstants)
  257. file:write("\n\n -- Global Constants\n")
  258. for i, constant in ipairs(globalConstants) do
  259. file:write("\n " .. constant.name .. " = {")
  260. -- write valuetype
  261. if constant.ptr ~= "" then
  262. if constant.type ~= "" then
  263. file:write("\n valuetype = \"" .. constant.type:gsub("(const%s+)","") .. "\",")
  264. end
  265. end
  266. -- write description (type)
  267. file:write("\n description = \"" .. constant.type .. constant.ptr .. "\",")
  268. -- write constant end
  269. file:write("\n type = \"value\"")
  270. file:write("\n },")
  271. end
  272. end
  273. function writeGlobalConstants(file)
  274. sortByName(globalConstants)
  275. file:write("\n\n -- Global Constants\n")
  276. for i, constant in ipairs(globalConstants) do
  277. file:write("\n " .. constant.name .. " = {")
  278. -- write valuetype
  279. if constant.ptr ~= "" then
  280. if constant.type ~= "" then
  281. file:write("\n valuetype = \"" .. constant.type:gsub("(const%s+)","") .. "\",")
  282. end
  283. end
  284. -- write description (type)
  285. file:write("\n description = \"" .. constant.type .. constant.ptr .. "\",")
  286. -- write constant end
  287. file:write("\n type = \"value\"")
  288. file:write("\n },")
  289. end
  290. end
  291. function writeGlobalFunctions(file)
  292. sortByName(globalFunctions)
  293. file:write("\n\n -- Global Functions\n")
  294. for i, func in ipairs(globalFunctions) do
  295. writeFunction(file, func, nil, nil, true)
  296. end
  297. end
  298. function writeGlobalProperties(file)
  299. file:write("\n")
  300. for i, property in ipairs(globalProperties) do
  301. writeProperty(file, property)
  302. end
  303. end
  304. function writeProperty(file, property)
  305. file:write("\n " .. property.name .. " = {")
  306. -- write valuetype
  307. if property.ptr ~= "" then
  308. if property.type ~= "" then
  309. file:write("\n valuetype = \"" .. property.type:gsub("(const%s+)","") .. "\",")
  310. end
  311. end
  312. -- write description (type)
  313. if property.mod:find("tolua_readonly") == nil then
  314. file:write("\n description = \"" .. property.type .. property.ptr .. "")
  315. else
  316. file:write("\n description = \"(Readonly) " .. property.type .. property.ptr .. "")
  317. end
  318. -- write description
  319. if property.descriptions ~= nil then
  320. for i, description in ipairs(property.descriptions) do
  321. local fixedDescription = description:gsub([[(")]], [[\%1]])
  322. file:write("\\n" .. fixedDescription)
  323. end
  324. end
  325. file:write("\",")
  326. -- write property end
  327. file:write("\n type = \"value\"")
  328. file:write("\n },")
  329. end
  330. function classPackage:print()
  331. curDir = getCurrentDirectory()
  332. if flags.o == nil then
  333. print("Invalid output filename");
  334. return
  335. end
  336. local filename = flags.o
  337. local file = io.open(filename, "wt")
  338. file:write("-- Urho3D API generated on "..os.date('%Y-%m-%d'))
  339. file:write("\n\nlocal api = {")
  340. local i = 1
  341. while self[i] do
  342. self[i]:print("","")
  343. i = i + 1
  344. end
  345. printDescriptionsFromPackageFile(flags.f)
  346. writeClasses(file)
  347. writeEnumerates(file)
  348. writeGlobalFunctions(file)
  349. writeGlobalProperties(file)
  350. writeGlobalConstants(file)
  351. file:write("\n}\nreturn api\n")
  352. file:close()
  353. end