ToZerobraneStudioHook.lua 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. --
  2. -- Copyright (c) 2008-2014 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. file:write(param_str)
  100. end
  101. if i ~= count then
  102. file:write(", ")
  103. end
  104. end
  105. end
  106. function writeFunctionReturn(file, func)
  107. local return_str = ""
  108. if func.type ~= "" and func.type ~= "void" then
  109. return_str = return_str .. func.type
  110. end
  111. if func.ptr ~= "" then
  112. if func.type == "" and classname ~= nil then
  113. return_str = return_str .. classname
  114. end
  115. return_str = return_str .. func.ptr
  116. end
  117. file:write(return_str)
  118. end
  119. function writeInheritances(file, classname)
  120. for i, inheritance in ipairs(classes) do
  121. if inheritance.name == classname then
  122. if inheritance.functions ~= nil then
  123. for j, func in ipairs(inheritance.functions) do
  124. writeFunction(file, func, classname, true)
  125. end
  126. end
  127. if inheritance.properties ~= nil then
  128. for j, property in ipairs(inheritance.properties) do
  129. writeProperty(file, property)
  130. end
  131. end
  132. -- append inheritance functions & properties
  133. if inheritance.base ~= "" then
  134. writeInheritances(file, inheritance.base)
  135. end
  136. end
  137. end
  138. end
  139. function writeClasses(file)
  140. sortByName(classes)
  141. adjustClassesOverloadFuncs()
  142. file:write("\n\n -- Classes")
  143. for i, class in ipairs(classes) do
  144. file:write("\n " .. class.name .. " = {")
  145. if class.functions ~= nil or class.properties ~= nil then
  146. file:write("\n childs = {")
  147. end
  148. if class.functions ~= nil then
  149. for i, func in ipairs(class.functions) do
  150. writeFunction(file, func, class.name)
  151. end
  152. end
  153. if class.properties ~= nil then
  154. for i, property in ipairs(class.properties) do
  155. writeProperty(file, property)
  156. end
  157. end
  158. -- append inheritance functions & properties
  159. if class.base ~= "" then
  160. writeInheritances(file, class.base)
  161. end
  162. if class.functions ~= nil or class.properties ~= nil then
  163. file:write("\n },")
  164. end
  165. file:write("\n type = \"class\"")
  166. file:write("\n },")
  167. end
  168. end
  169. function writeEnumerates(file)
  170. sortByName(enumerates)
  171. file:write("\n\n -- Enumerations\n")
  172. for i, enumerate in ipairs(enumerates) do
  173. for i, value in ipairs(enumerate.values) do
  174. file:write("\n " .. value .. " = {")
  175. file:write("\n description = \"(Readonly) int for '" .. enumerate.name .. "'\",")
  176. file:write("\n type = \"value\"")
  177. file:write("\n },")
  178. end
  179. end
  180. end
  181. function writeFunction(file, func, classname, isInheritance, asFunc)
  182. -- ignore operators
  183. if func.name:find("^operator[=%+%-%*%(%)\\</]") == nil then
  184. -- ignore new/delete object if from inheritance
  185. if not ((func.name == classname or func.name == "new" or func.name == "delete") and isInheritance == true) then
  186. -- write function begin
  187. file:write("\n " .. func.name .. " = {")
  188. -- write parameters
  189. file:write("\n args = \"(")
  190. if func.declarations ~= nil then
  191. writeFunctionArgs(file, func.declarations)
  192. end
  193. file:write(")\",")
  194. -- write description preparation
  195. local isFirstDescription = true
  196. if func.overloads ~= nil or func.descriptions ~= nil then
  197. file:write("\n description = \"")
  198. end
  199. -- write overloaded parameters in description, if any
  200. if func.overloads ~= nil then
  201. for i, overload in ipairs(func.overloads) do
  202. if isFirstDescription == false then
  203. file:write(",\\n")
  204. else
  205. isFirstDescription = false
  206. end
  207. file:write("(")
  208. writeFunctionReturn(file, overload)
  209. file:write(") "..overload.name.." (")
  210. writeFunctionArgs(file, overload.declarations)
  211. file:write(")")
  212. end
  213. end
  214. -- write description
  215. if func.descriptions ~= nil then
  216. for i, description in ipairs(func.descriptions) do
  217. if isFirstDescription == false then
  218. file:write("\\n")
  219. else
  220. isFirstDescription = false
  221. end
  222. local fixedDescription = description:gsub([[(")]], [[\%1]])
  223. file:write(fixedDescription)
  224. end
  225. end
  226. -- write description end
  227. if func.overloads ~= nil or func.descriptions ~= nil then
  228. file:write("\",")
  229. end
  230. -- write returns
  231. if func.type ~= "" or func.ptr ~= "" then
  232. file:write("\n returns = \"(")
  233. writeFunctionReturn(file, func)
  234. file:write(")\",")
  235. end
  236. -- write valuetype
  237. if func.ptr ~= "" then
  238. if func.type ~= "" then
  239. file:write("\n valuetype = \"" .. func.type:gsub("(const%s+)","") .. "\",")
  240. elseif classname ~= nil then
  241. file:write("\n valuetype = \"" .. classname .. "\",")
  242. end
  243. end
  244. -- write function end
  245. if asFunc == true then
  246. file:write("\n type = \"function\"") -- accepts auto-completion with ".", ":" and global
  247. else
  248. file:write("\n type = \"method\"") -- accepts auto-completion only with ":"
  249. end
  250. file:write("\n },")
  251. end
  252. end
  253. end
  254. function writeGlobalConstants(file)
  255. sortByName(globalConstants)
  256. file:write("\n\n -- Global Constants\n")
  257. for i, constant in ipairs(globalConstants) do
  258. file:write("\n " .. constant.name .. " = {")
  259. -- write valuetype
  260. if constant.ptr ~= "" then
  261. if constant.type ~= "" then
  262. file:write("\n valuetype = \"" .. constant.type:gsub("(const%s+)","") .. "\",")
  263. end
  264. end
  265. -- write description (type)
  266. file:write("\n description = \"" .. constant.type .. constant.ptr .. "\",")
  267. -- write constant end
  268. file:write("\n type = \"value\"")
  269. file:write("\n },")
  270. end
  271. end
  272. function writeGlobalConstants(file)
  273. sortByName(globalConstants)
  274. file:write("\n\n -- Global Constants\n")
  275. for i, constant in ipairs(globalConstants) do
  276. file:write("\n " .. constant.name .. " = {")
  277. -- write valuetype
  278. if constant.ptr ~= "" then
  279. if constant.type ~= "" then
  280. file:write("\n valuetype = \"" .. constant.type:gsub("(const%s+)","") .. "\",")
  281. end
  282. end
  283. -- write description (type)
  284. file:write("\n description = \"" .. constant.type .. constant.ptr .. "\",")
  285. -- write constant end
  286. file:write("\n type = \"value\"")
  287. file:write("\n },")
  288. end
  289. end
  290. function writeGlobalFunctions(file)
  291. sortByName(globalFunctions)
  292. file:write("\n\n -- Global Functions\n")
  293. for i, func in ipairs(globalFunctions) do
  294. writeFunction(file, func, nil, nil, true)
  295. end
  296. end
  297. function writeGlobalProperties(file)
  298. file:write("\n")
  299. for i, property in ipairs(globalProperties) do
  300. writeProperty(file, property)
  301. end
  302. end
  303. function writeProperty(file, property)
  304. file:write("\n " .. property.name .. " = {")
  305. -- write valuetype
  306. if property.ptr ~= "" then
  307. if property.type ~= "" then
  308. file:write("\n valuetype = \"" .. property.type:gsub("(const%s+)","") .. "\",")
  309. end
  310. end
  311. -- write description (type)
  312. if property.mod:find("tolua_readonly") == nil then
  313. file:write("\n description = \"" .. property.type .. property.ptr .. "")
  314. else
  315. file:write("\n description = \"(Readonly) " .. property.type .. property.ptr .. "")
  316. end
  317. -- write description
  318. if property.descriptions ~= nil then
  319. for i, description in ipairs(property.descriptions) do
  320. local fixedDescription = description:gsub([[(")]], [[\%1]])
  321. file:write("\\n" .. fixedDescription)
  322. end
  323. end
  324. file:write("\",")
  325. -- write property end
  326. file:write("\n type = \"value\"")
  327. file:write("\n },")
  328. end
  329. function classPackage:print()
  330. curDir = getCurrentDirectory()
  331. if flags.o == nil then
  332. print("Invalid output filename");
  333. return
  334. end
  335. local filename = flags.o
  336. local file = io.open(filename, "wt")
  337. file:write("-- Urho3D API generated on "..os.date('%Y-%m-%d'))
  338. file:write("\n\nlocal api = {")
  339. local i = 1
  340. while self[i] do
  341. self[i]:print("","")
  342. i = i + 1
  343. end
  344. printDescriptionsFromPackageFile(flags.f)
  345. writeClasses(file)
  346. writeEnumerates(file)
  347. writeGlobalFunctions(file)
  348. writeGlobalProperties(file)
  349. writeGlobalConstants(file)
  350. file:write("\n}\nreturn api\n")
  351. file:close()
  352. end