rufus-lua-win 5.1.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (459) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +69 -0
  6. data/Rakefile +1 -0
  7. data/lib/rufus/lua/win.rb +18 -0
  8. data/lib/rufus/lua/win/version.rb +7 -0
  9. data/rufus-lua-win.gemspec +23 -0
  10. data/vendor/lua/bin/liblua.dll +0 -0
  11. data/vendor/lua/lib/lua/LuaXml.lua +119 -0
  12. data/vendor/lua/lib/lua/alien.lua +250 -0
  13. data/vendor/lua/lib/lua/alien/core.dll +0 -0
  14. data/vendor/lua/lib/lua/alien/struct.dll +0 -0
  15. data/vendor/lua/lib/lua/base.lua +536 -0
  16. data/vendor/lua/lib/lua/bin.lua +20 -0
  17. data/vendor/lua/lib/lua/bit.dll +0 -0
  18. data/vendor/lua/lib/lua/cdlua.dll +0 -0
  19. data/vendor/lua/lib/lua/cdluacontextplus.dll +0 -0
  20. data/vendor/lua/lib/lua/cdluagl.dll +0 -0
  21. data/vendor/lua/lib/lua/cdluaim.dll +0 -0
  22. data/vendor/lua/lib/lua/cdluapdf.dll +0 -0
  23. data/vendor/lua/lib/lua/copas.lua +543 -0
  24. data/vendor/lua/lib/lua/coxpcall.lua +57 -0
  25. data/vendor/lua/lib/lua/date.lua +745 -0
  26. data/vendor/lua/lib/lua/debug_ext.lua +84 -0
  27. data/vendor/lua/lib/lua/debug_init.lua +2 -0
  28. data/vendor/lua/lib/lua/des56.dll +0 -0
  29. data/vendor/lua/lib/lua/dist/config.lua +109 -0
  30. data/vendor/lua/lib/lua/dist/constraints.lua +271 -0
  31. data/vendor/lua/lib/lua/dist/depends.lua +601 -0
  32. data/vendor/lua/lib/lua/dist/git.lua +307 -0
  33. data/vendor/lua/lib/lua/dist/init.lua +278 -0
  34. data/vendor/lua/lib/lua/dist/manifest.lua +225 -0
  35. data/vendor/lua/lib/lua/dist/package.lua +583 -0
  36. data/vendor/lua/lib/lua/dist/sys.lua +367 -0
  37. data/vendor/lua/lib/lua/dist/utils.lua +130 -0
  38. data/vendor/lua/lib/lua/ex.dll +0 -0
  39. data/vendor/lua/lib/lua/fstable.lua +116 -0
  40. data/vendor/lua/lib/lua/getopt.lua +273 -0
  41. data/vendor/lua/lib/lua/git.lua +5 -0
  42. data/vendor/lua/lib/lua/git/core.dll +0 -0
  43. data/vendor/lua/lib/lua/git/objects.lua +121 -0
  44. data/vendor/lua/lib/lua/git/pack.lua +316 -0
  45. data/vendor/lua/lib/lua/git/protocol.lua +188 -0
  46. data/vendor/lua/lib/lua/git/repo.lua +283 -0
  47. data/vendor/lua/lib/lua/git/util.lua +233 -0
  48. data/vendor/lua/lib/lua/gzio.dll +0 -0
  49. data/vendor/lua/lib/lua/gzip.lua +81 -0
  50. data/vendor/lua/lib/lua/iconv.dll +0 -0
  51. data/vendor/lua/lib/lua/imlua.dll +0 -0
  52. data/vendor/lua/lib/lua/imlua_fftw.dll +0 -0
  53. data/vendor/lua/lib/lua/imlua_jp2.dll +0 -0
  54. data/vendor/lua/lib/lua/imlua_process.dll +0 -0
  55. data/vendor/lua/lib/lua/imlua_process_omp.dll +0 -0
  56. data/vendor/lua/lib/lua/io_ext.lua +115 -0
  57. data/vendor/lua/lib/lua/iuplua.dll +0 -0
  58. data/vendor/lua/lib/lua/iuplua_mglplot.dll +0 -0
  59. data/vendor/lua/lib/lua/iuplua_pplot.dll +0 -0
  60. data/vendor/lua/lib/lua/iupluacd.dll +0 -0
  61. data/vendor/lua/lib/lua/iupluacontrols.dll +0 -0
  62. data/vendor/lua/lib/lua/iupluagl.dll +0 -0
  63. data/vendor/lua/lib/lua/iupluaim.dll +0 -0
  64. data/vendor/lua/lib/lua/iupluaimglib.dll +0 -0
  65. data/vendor/lua/lib/lua/iupluatuio.dll +0 -0
  66. data/vendor/lua/lib/lua/lanes-keeper.lua +302 -0
  67. data/vendor/lua/lib/lua/lanes.lua +591 -0
  68. data/vendor/lua/lib/lua/lanes/core.dll +0 -0
  69. data/vendor/lua/lib/lua/lcs.lua +55 -0
  70. data/vendor/lua/lib/lua/lemock.lua +659 -0
  71. data/vendor/lua/lib/lua/lfs.dll +0 -0
  72. data/vendor/lua/lib/lua/list.lua +375 -0
  73. data/vendor/lua/lib/lua/logging.lua +189 -0
  74. data/vendor/lua/lib/lua/logging/console.lua +22 -0
  75. data/vendor/lua/lib/lua/logging/email.lua +44 -0
  76. data/vendor/lua/lib/lua/logging/file.lua +55 -0
  77. data/vendor/lua/lib/lua/logging/rolling_file.lua +81 -0
  78. data/vendor/lua/lib/lua/logging/socket.lua +35 -0
  79. data/vendor/lua/lib/lua/logging/sql.lua +64 -0
  80. data/vendor/lua/lib/lua/loop/base.lua +68 -0
  81. data/vendor/lua/lib/lua/loop/cached.lua +312 -0
  82. data/vendor/lua/lib/lua/loop/collection/MapWithArrayOfKeys.lua +64 -0
  83. data/vendor/lua/lib/lua/loop/collection/ObjectCache.lua +39 -0
  84. data/vendor/lua/lib/lua/loop/collection/OrderedSet.lua +164 -0
  85. data/vendor/lua/lib/lua/loop/collection/PriorityQueue.lua +86 -0
  86. data/vendor/lua/lib/lua/loop/collection/UnorderedArray.lua +32 -0
  87. data/vendor/lua/lib/lua/loop/collection/UnorderedArraySet.lua +56 -0
  88. data/vendor/lua/lib/lua/loop/compiler/Arguments.lua +108 -0
  89. data/vendor/lua/lib/lua/loop/compiler/Conditional.lua +50 -0
  90. data/vendor/lua/lib/lua/loop/compiler/Expression.lua +215 -0
  91. data/vendor/lua/lib/lua/loop/component/base.lua +221 -0
  92. data/vendor/lua/lib/lua/loop/component/contained.lua +71 -0
  93. data/vendor/lua/lib/lua/loop/component/dynamic.lua +223 -0
  94. data/vendor/lua/lib/lua/loop/component/intercepted.lua +354 -0
  95. data/vendor/lua/lib/lua/loop/component/wrapped.lua +195 -0
  96. data/vendor/lua/lib/lua/loop/debug/Inspector.lua +521 -0
  97. data/vendor/lua/lib/lua/loop/debug/Matcher.lua +192 -0
  98. data/vendor/lua/lib/lua/loop/debug/Verbose.lua +266 -0
  99. data/vendor/lua/lib/lua/loop/debug/Viewer.lua +200 -0
  100. data/vendor/lua/lib/lua/loop/multiple.lua +105 -0
  101. data/vendor/lua/lib/lua/loop/object/Exception.lua +57 -0
  102. data/vendor/lua/lib/lua/loop/object/Publisher.lua +43 -0
  103. data/vendor/lua/lib/lua/loop/object/Wrapper.lua +39 -0
  104. data/vendor/lua/lib/lua/loop/scoped.lua +585 -0
  105. data/vendor/lua/lib/lua/loop/serial/FileStream.lua +48 -0
  106. data/vendor/lua/lib/lua/loop/serial/Serializer.lua +291 -0
  107. data/vendor/lua/lib/lua/loop/serial/SocketStream.lua +51 -0
  108. data/vendor/lua/lib/lua/loop/serial/StringStream.lua +47 -0
  109. data/vendor/lua/lib/lua/loop/simple.lua +75 -0
  110. data/vendor/lua/lib/lua/loop/table.lua +71 -0
  111. data/vendor/lua/lib/lua/loop/thread/CoSocket.lua +416 -0
  112. data/vendor/lua/lib/lua/loop/thread/IOScheduler.lua +170 -0
  113. data/vendor/lua/lib/lua/loop/thread/Scheduler.lua +327 -0
  114. data/vendor/lua/lib/lua/loop/thread/SocketScheduler.lua +88 -0
  115. data/vendor/lua/lib/lua/loop/thread/Timer.lua +54 -0
  116. data/vendor/lua/lib/lua/lpeg.dll +0 -0
  117. data/vendor/lua/lib/lua/ltn12.lua +292 -0
  118. data/vendor/lua/lib/lua/luaXML_lib.dll +0 -0
  119. data/vendor/lua/lib/lua/luacurl.dll +0 -0
  120. data/vendor/lua/lib/lua/luadoc/config.lua +34 -0
  121. data/vendor/lua/lib/lua/luadoc/doclet/debug.lua +46 -0
  122. data/vendor/lua/lib/lua/luadoc/doclet/formatter.lua +84 -0
  123. data/vendor/lua/lib/lua/luadoc/doclet/html.lua +289 -0
  124. data/vendor/lua/lib/lua/luadoc/doclet/html/file.lp +113 -0
  125. data/vendor/lua/lib/lua/luadoc/doclet/html/function.lp +64 -0
  126. data/vendor/lua/lib/lua/luadoc/doclet/html/index.lp +70 -0
  127. data/vendor/lua/lib/lua/luadoc/doclet/html/luadoc.css +286 -0
  128. data/vendor/lua/lib/lua/luadoc/doclet/html/menu.lp +55 -0
  129. data/vendor/lua/lib/lua/luadoc/doclet/html/module.lp +109 -0
  130. data/vendor/lua/lib/lua/luadoc/doclet/html/table.lp +15 -0
  131. data/vendor/lua/lib/lua/luadoc/doclet/raw.lua +12 -0
  132. data/vendor/lua/lib/lua/luadoc/init.lua +58 -0
  133. data/vendor/lua/lib/lua/luadoc/lp.lua +130 -0
  134. data/vendor/lua/lib/lua/luadoc/taglet/standard.lua +495 -0
  135. data/vendor/lua/lib/lua/luadoc/taglet/standard/tags.lua +171 -0
  136. data/vendor/lua/lib/lua/luadoc/util.lua +233 -0
  137. data/vendor/lua/lib/lua/luagl.dll +0 -0
  138. data/vendor/lua/lib/lua/luaglu.dll +0 -0
  139. data/vendor/lua/lib/lua/luaidl.lua +113 -0
  140. data/vendor/lua/lib/lua/luaidl/lex.lua +793 -0
  141. data/vendor/lua/lib/lua/luaidl/pre.lua +149 -0
  142. data/vendor/lua/lib/lua/luaidl/sin.lua +3631 -0
  143. data/vendor/lua/lib/lua/luarocks/add.lua +108 -0
  144. data/vendor/lua/lib/lua/luarocks/admin_remove.lua +87 -0
  145. data/vendor/lua/lib/lua/luarocks/build.lua +330 -0
  146. data/vendor/lua/lib/lua/luarocks/build/builtin.lua +253 -0
  147. data/vendor/lua/lib/lua/luarocks/build/cmake.lua +54 -0
  148. data/vendor/lua/lib/lua/luarocks/build/command.lua +32 -0
  149. data/vendor/lua/lib/lua/luarocks/build/make.lua +92 -0
  150. data/vendor/lua/lib/lua/luarocks/cache.lua +85 -0
  151. data/vendor/lua/lib/lua/luarocks/cfg.lua +449 -0
  152. data/vendor/lua/lib/lua/luarocks/command_line.lua +163 -0
  153. data/vendor/lua/lib/lua/luarocks/deps.lua +654 -0
  154. data/vendor/lua/lib/lua/luarocks/dir.lua +69 -0
  155. data/vendor/lua/lib/lua/luarocks/download.lua +90 -0
  156. data/vendor/lua/lib/lua/luarocks/fetch.lua +321 -0
  157. data/vendor/lua/lib/lua/luarocks/fetch/cvs.lua +44 -0
  158. data/vendor/lua/lib/lua/luarocks/fetch/git.lua +81 -0
  159. data/vendor/lua/lib/lua/luarocks/fetch/git_file.lua +17 -0
  160. data/vendor/lua/lib/lua/luarocks/fetch/hg.lua +54 -0
  161. data/vendor/lua/lib/lua/luarocks/fetch/sscm.lua +42 -0
  162. data/vendor/lua/lib/lua/luarocks/fetch/svn.lua +53 -0
  163. data/vendor/lua/lib/lua/luarocks/fs.lua +40 -0
  164. data/vendor/lua/lib/lua/luarocks/fs/lua.lua +676 -0
  165. data/vendor/lua/lib/lua/luarocks/fs/unix.lua +88 -0
  166. data/vendor/lua/lib/lua/luarocks/fs/unix/tools.lua +325 -0
  167. data/vendor/lua/lib/lua/luarocks/fs/win32.lua +107 -0
  168. data/vendor/lua/lib/lua/luarocks/fs/win32/tools.lua +334 -0
  169. data/vendor/lua/lib/lua/luarocks/help.lua +101 -0
  170. data/vendor/lua/lib/lua/luarocks/index.lua +172 -0
  171. data/vendor/lua/lib/lua/luarocks/install.lua +151 -0
  172. data/vendor/lua/lib/lua/luarocks/list.lua +35 -0
  173. data/vendor/lua/lib/lua/luarocks/loader.lua +228 -0
  174. data/vendor/lua/lib/lua/luarocks/make.lua +71 -0
  175. data/vendor/lua/lib/lua/luarocks/make_manifest.lua +34 -0
  176. data/vendor/lua/lib/lua/luarocks/manif.lua +360 -0
  177. data/vendor/lua/lib/lua/luarocks/manif_core.lua +75 -0
  178. data/vendor/lua/lib/lua/luarocks/new_version.lua +141 -0
  179. data/vendor/lua/lib/lua/luarocks/pack.lua +205 -0
  180. data/vendor/lua/lib/lua/luarocks/path.lua +315 -0
  181. data/vendor/lua/lib/lua/luarocks/persist.lua +173 -0
  182. data/vendor/lua/lib/lua/luarocks/refresh_cache.lua +30 -0
  183. data/vendor/lua/lib/lua/luarocks/remove.lua +135 -0
  184. data/vendor/lua/lib/lua/luarocks/rep.lua +313 -0
  185. data/vendor/lua/lib/lua/luarocks/require.lua +6 -0
  186. data/vendor/lua/lib/lua/luarocks/search.lua +399 -0
  187. data/vendor/lua/lib/lua/luarocks/show.lua +138 -0
  188. data/vendor/lua/lib/lua/luarocks/site_config.lua +23 -0
  189. data/vendor/lua/lib/lua/luarocks/tools/patch.lua +712 -0
  190. data/vendor/lua/lib/lua/luarocks/tools/tar.lua +144 -0
  191. data/vendor/lua/lib/lua/luarocks/tools/zip.lua +245 -0
  192. data/vendor/lua/lib/lua/luarocks/type_check.lua +267 -0
  193. data/vendor/lua/lib/lua/luarocks/unpack.lua +151 -0
  194. data/vendor/lua/lib/lua/luarocks/util.lua +420 -0
  195. data/vendor/lua/lib/lua/luarocks/validate.lua +164 -0
  196. data/vendor/lua/lib/lua/luars232.dll +0 -0
  197. data/vendor/lua/lib/lua/luasql/mysql.dll +0 -0
  198. data/vendor/lua/lib/lua/luasql/postgres.dll +0 -0
  199. data/vendor/lua/lib/lua/luasql/sqlite3.dll +0 -0
  200. data/vendor/lua/lib/lua/luaunit.lua +601 -0
  201. data/vendor/lua/lib/lua/lxp.dll +0 -0
  202. data/vendor/lua/lib/lua/lxp/lom.lua +60 -0
  203. data/vendor/lua/lib/lua/math_ext.lua +27 -0
  204. data/vendor/lua/lib/lua/mbox.lua +53 -0
  205. data/vendor/lua/lib/lua/md5.lua +19 -0
  206. data/vendor/lua/lib/lua/md5/core.dll +0 -0
  207. data/vendor/lua/lib/lua/metalua.lua +0 -0
  208. data/vendor/lua/lib/lua/metalua/ast_to_string.mlua +553 -0
  209. data/vendor/lua/lib/lua/metalua/base.lua +104 -0
  210. data/vendor/lua/lib/lua/metalua/bytecode.lua +0 -0
  211. data/vendor/lua/lib/lua/metalua/clopts.mlua +204 -0
  212. data/vendor/lua/lib/lua/metalua/compiler.lua +3 -0
  213. data/vendor/lua/lib/lua/metalua/dollar.mlua +24 -0
  214. data/vendor/lua/lib/lua/metalua/extension/H-runtime.mlua +216 -0
  215. data/vendor/lua/lib/lua/metalua/extension/H.mlua +22 -0
  216. data/vendor/lua/lib/lua/metalua/extension/anaphoric.mlua +54 -0
  217. data/vendor/lua/lib/lua/metalua/extension/clist.mlua +149 -0
  218. data/vendor/lua/lib/lua/metalua/extension/continue.mlua +53 -0
  219. data/vendor/lua/lib/lua/metalua/extension/localin.mlua +2 -0
  220. data/vendor/lua/lib/lua/metalua/extension/log.mlua +39 -0
  221. data/vendor/lua/lib/lua/metalua/extension/match.mlua +374 -0
  222. data/vendor/lua/lib/lua/metalua/extension/ternary.mlua +10 -0
  223. data/vendor/lua/lib/lua/metalua/extension/trycatch.mlua +189 -0
  224. data/vendor/lua/lib/lua/metalua/extension/types-runtime.mlua +159 -0
  225. data/vendor/lua/lib/lua/metalua/extension/types.mlua +352 -0
  226. data/vendor/lua/lib/lua/metalua/extension/withdo.mlua +30 -0
  227. data/vendor/lua/lib/lua/metalua/extension/xglobal-runtime.lua +41 -0
  228. data/vendor/lua/lib/lua/metalua/extension/xglobal.mlua +20 -0
  229. data/vendor/lua/lib/lua/metalua/extension/xloop.mlua +100 -0
  230. data/vendor/lua/lib/lua/metalua/extension/xmatch.mlua +216 -0
  231. data/vendor/lua/lib/lua/metalua/metaloop.mlua +76 -0
  232. data/vendor/lua/lib/lua/metalua/mlc.lua +0 -0
  233. data/vendor/lua/lib/lua/metalua/mlc_xcall.lua +119 -0
  234. data/vendor/lua/lib/lua/metalua/mlp.lua +0 -0
  235. data/vendor/lua/lib/lua/metalua/package2.lua +101 -0
  236. data/vendor/lua/lib/lua/metalua/runtime.lua +3 -0
  237. data/vendor/lua/lib/lua/metalua/string2.lua +44 -0
  238. data/vendor/lua/lib/lua/metalua/table2.lua +372 -0
  239. data/vendor/lua/lib/lua/metalua/walk.mlua +304 -0
  240. data/vendor/lua/lib/lua/metalua/walk/bindings.mlua +41 -0
  241. data/vendor/lua/lib/lua/metalua/walk/id.mlua +186 -0
  242. data/vendor/lua/lib/lua/metalua/walk/scope.lua +54 -0
  243. data/vendor/lua/lib/lua/mime.lua +87 -0
  244. data/vendor/lua/lib/lua/mime/core.dll +0 -0
  245. data/vendor/lua/lib/lua/mobdebug.lua +1484 -0
  246. data/vendor/lua/lib/lua/modules.lua +16 -0
  247. data/vendor/lua/lib/lua/object.lua +56 -0
  248. data/vendor/lua/lib/lua/oil/Exception.lua +26 -0
  249. data/vendor/lua/lib/lua/oil/arch.lua +27 -0
  250. data/vendor/lua/lib/lua/oil/arch/basic/client.lua +29 -0
  251. data/vendor/lua/lib/lua/oil/arch/basic/common.lua +13 -0
  252. data/vendor/lua/lib/lua/oil/arch/basic/server.lua +27 -0
  253. data/vendor/lua/lib/lua/oil/arch/cooperative/common.lua +10 -0
  254. data/vendor/lua/lib/lua/oil/arch/cooperative/server.lua +16 -0
  255. data/vendor/lua/lib/lua/oil/arch/corba/client.lua +39 -0
  256. data/vendor/lua/lib/lua/oil/arch/corba/common.lua +58 -0
  257. data/vendor/lua/lib/lua/oil/arch/corba/intercepted/client.lua +9 -0
  258. data/vendor/lua/lib/lua/oil/arch/corba/intercepted/server.lua +9 -0
  259. data/vendor/lua/lib/lua/oil/arch/corba/server.lua +35 -0
  260. data/vendor/lua/lib/lua/oil/arch/ludo/byref.lua +18 -0
  261. data/vendor/lua/lib/lua/oil/arch/ludo/client.lua +19 -0
  262. data/vendor/lua/lib/lua/oil/arch/ludo/common.lua +18 -0
  263. data/vendor/lua/lib/lua/oil/arch/ludo/server.lua +19 -0
  264. data/vendor/lua/lib/lua/oil/arch/typed/client.lua +27 -0
  265. data/vendor/lua/lib/lua/oil/arch/typed/common.lua +9 -0
  266. data/vendor/lua/lib/lua/oil/arch/typed/server.lua +18 -0
  267. data/vendor/lua/lib/lua/oil/assert.lua +87 -0
  268. data/vendor/lua/lib/lua/oil/builder.lua +45 -0
  269. data/vendor/lua/lib/lua/oil/builder/basic/client.lua +31 -0
  270. data/vendor/lua/lib/lua/oil/builder/basic/common.lua +11 -0
  271. data/vendor/lua/lib/lua/oil/builder/basic/server.lua +13 -0
  272. data/vendor/lua/lib/lua/oil/builder/cooperative/common.lua +11 -0
  273. data/vendor/lua/lib/lua/oil/builder/cooperative/server.lua +11 -0
  274. data/vendor/lua/lib/lua/oil/builder/corba/client.lua +13 -0
  275. data/vendor/lua/lib/lua/oil/builder/corba/common.lua +24 -0
  276. data/vendor/lua/lib/lua/oil/builder/corba/gencode.lua +13 -0
  277. data/vendor/lua/lib/lua/oil/builder/corba/intercepted/client.lua +11 -0
  278. data/vendor/lua/lib/lua/oil/builder/corba/intercepted/server.lua +11 -0
  279. data/vendor/lua/lib/lua/oil/builder/corba/server.lua +13 -0
  280. data/vendor/lua/lib/lua/oil/builder/lua/client.lua +11 -0
  281. data/vendor/lua/lib/lua/oil/builder/lua/server.lua +12 -0
  282. data/vendor/lua/lib/lua/oil/builder/ludo/byref.lua +13 -0
  283. data/vendor/lua/lib/lua/oil/builder/ludo/client.lua +13 -0
  284. data/vendor/lua/lib/lua/oil/builder/ludo/common.lua +14 -0
  285. data/vendor/lua/lib/lua/oil/builder/ludo/server.lua +13 -0
  286. data/vendor/lua/lib/lua/oil/builder/typed/client.lua +16 -0
  287. data/vendor/lua/lib/lua/oil/builder/typed/server.lua +12 -0
  288. data/vendor/lua/lib/lua/oil/compat.lua +846 -0
  289. data/vendor/lua/lib/lua/oil/component.lua +1 -0
  290. data/vendor/lua/lib/lua/oil/corba/giop.lua +301 -0
  291. data/vendor/lua/lib/lua/oil/corba/giop/Codec.lua +1568 -0
  292. data/vendor/lua/lib/lua/oil/corba/giop/CodecGen.lua +589 -0
  293. data/vendor/lua/lib/lua/oil/corba/giop/Exception.lua +25 -0
  294. data/vendor/lua/lib/lua/oil/corba/giop/Indexer.lua +63 -0
  295. data/vendor/lua/lib/lua/oil/corba/giop/Listener.lua +343 -0
  296. data/vendor/lua/lib/lua/oil/corba/giop/Messenger.lua +228 -0
  297. data/vendor/lua/lib/lua/oil/corba/giop/Referrer.lua +180 -0
  298. data/vendor/lua/lib/lua/oil/corba/giop/Requester.lua +462 -0
  299. data/vendor/lua/lib/lua/oil/corba/idl.lua +597 -0
  300. data/vendor/lua/lib/lua/oil/corba/idl/Compiler.lua +133 -0
  301. data/vendor/lua/lib/lua/oil/corba/idl/Importer.lua +235 -0
  302. data/vendor/lua/lib/lua/oil/corba/idl/Indexer.lua +95 -0
  303. data/vendor/lua/lib/lua/oil/corba/idl/Registry.lua +1821 -0
  304. data/vendor/lua/lib/lua/oil/corba/idl/ir.lua +847 -0
  305. data/vendor/lua/lib/lua/oil/corba/idl/sysex.lua +21 -0
  306. data/vendor/lua/lib/lua/oil/corba/iiop/Profiler.lua +200 -0
  307. data/vendor/lua/lib/lua/oil/corba/intercepted/Listener.lua +158 -0
  308. data/vendor/lua/lib/lua/oil/corba/intercepted/Requester.lua +181 -0
  309. data/vendor/lua/lib/lua/oil/corba/services/event.lua +126 -0
  310. data/vendor/lua/lib/lua/oil/corba/services/event/ConsumerAdmin.lua +50 -0
  311. data/vendor/lua/lib/lua/oil/corba/services/event/EventFactory.lua +15 -0
  312. data/vendor/lua/lib/lua/oil/corba/services/event/EventQueue.lua +37 -0
  313. data/vendor/lua/lib/lua/oil/corba/services/event/ProxyPushConsumer.lua +75 -0
  314. data/vendor/lua/lib/lua/oil/corba/services/event/ProxyPushSupplier.lua +62 -0
  315. data/vendor/lua/lib/lua/oil/corba/services/event/SingleDeferredDispatcher.lua +60 -0
  316. data/vendor/lua/lib/lua/oil/corba/services/event/SingleSynchronousDispatcher.lua +39 -0
  317. data/vendor/lua/lib/lua/oil/corba/services/event/SupplierAdmin.lua +50 -0
  318. data/vendor/lua/lib/lua/oil/corba/services/naming.lua +436 -0
  319. data/vendor/lua/lib/lua/oil/kernel/base/Acceptor.lua +268 -0
  320. data/vendor/lua/lib/lua/oil/kernel/base/Channels.lua +121 -0
  321. data/vendor/lua/lib/lua/oil/kernel/base/Connector.lua +147 -0
  322. data/vendor/lua/lib/lua/oil/kernel/base/Dispatcher.lua +99 -0
  323. data/vendor/lua/lib/lua/oil/kernel/base/Proxies.lua +86 -0
  324. data/vendor/lua/lib/lua/oil/kernel/base/Proxies/asynchronous.lua +56 -0
  325. data/vendor/lua/lib/lua/oil/kernel/base/Proxies/protected.lua +17 -0
  326. data/vendor/lua/lib/lua/oil/kernel/base/Proxies/synchronous.lua +17 -0
  327. data/vendor/lua/lib/lua/oil/kernel/base/Proxies/utils.lua +29 -0
  328. data/vendor/lua/lib/lua/oil/kernel/base/Receiver.lua +110 -0
  329. data/vendor/lua/lib/lua/oil/kernel/base/Servants.lua +207 -0
  330. data/vendor/lua/lib/lua/oil/kernel/base/Sockets.lua +44 -0
  331. data/vendor/lua/lib/lua/oil/kernel/cooperative/Receiver.lua +139 -0
  332. data/vendor/lua/lib/lua/oil/kernel/intercepted/Listener.lua +47 -0
  333. data/vendor/lua/lib/lua/oil/kernel/intercepted/Requester.lua +58 -0
  334. data/vendor/lua/lib/lua/oil/kernel/lua/Dispatcher.lua +76 -0
  335. data/vendor/lua/lib/lua/oil/kernel/lua/Proxies.lua +69 -0
  336. data/vendor/lua/lib/lua/oil/kernel/typed/Dispatcher.lua +91 -0
  337. data/vendor/lua/lib/lua/oil/kernel/typed/Proxies.lua +153 -0
  338. data/vendor/lua/lib/lua/oil/kernel/typed/Servants.lua +137 -0
  339. data/vendor/lua/lib/lua/oil/ludo/Codec.lua +66 -0
  340. data/vendor/lua/lib/lua/oil/ludo/CodecByRef.lua +103 -0
  341. data/vendor/lua/lib/lua/oil/ludo/Listener.lua +151 -0
  342. data/vendor/lua/lib/lua/oil/ludo/Referrer.lua +72 -0
  343. data/vendor/lua/lib/lua/oil/ludo/Requester.lua +107 -0
  344. data/vendor/lua/lib/lua/oil/oo.lua +1 -0
  345. data/vendor/lua/lib/lua/oil/port.lua +1 -0
  346. data/vendor/lua/lib/lua/oil/properties.lua +57 -0
  347. data/vendor/lua/lib/lua/oil/verbose.lua +133 -0
  348. data/vendor/lua/lib/lua/package_ext.lua +15 -0
  349. data/vendor/lua/lib/lua/parser.lua +268 -0
  350. data/vendor/lua/lib/lua/pl/Date.lua +555 -0
  351. data/vendor/lua/lib/lua/pl/List.lua +613 -0
  352. data/vendor/lua/lib/lua/pl/Map.lua +113 -0
  353. data/vendor/lua/lib/lua/pl/MultiMap.lua +62 -0
  354. data/vendor/lua/lib/lua/pl/OrderedMap.lua +151 -0
  355. data/vendor/lua/lib/lua/pl/Set.lua +153 -0
  356. data/vendor/lua/lib/lua/pl/app.lua +165 -0
  357. data/vendor/lua/lib/lua/pl/array2d.lua +501 -0
  358. data/vendor/lua/lib/lua/pl/class.lua +180 -0
  359. data/vendor/lua/lib/lua/pl/comprehension.lua +286 -0
  360. data/vendor/lua/lib/lua/pl/config.lua +176 -0
  361. data/vendor/lua/lib/lua/pl/data.lua +606 -0
  362. data/vendor/lua/lib/lua/pl/dir.lua +475 -0
  363. data/vendor/lua/lib/lua/pl/file.lua +70 -0
  364. data/vendor/lua/lib/lua/pl/func.lua +376 -0
  365. data/vendor/lua/lib/lua/pl/init.lua +68 -0
  366. data/vendor/lua/lib/lua/pl/input.lua +173 -0
  367. data/vendor/lua/lib/lua/pl/lapp.lua +407 -0
  368. data/vendor/lua/lib/lua/pl/lexer.lua +456 -0
  369. data/vendor/lua/lib/lua/pl/luabalanced.lua +264 -0
  370. data/vendor/lua/lib/lua/pl/operator.lua +201 -0
  371. data/vendor/lua/lib/lua/pl/path.lua +398 -0
  372. data/vendor/lua/lib/lua/pl/permute.lua +63 -0
  373. data/vendor/lua/lib/lua/pl/platf/luajava.lua +101 -0
  374. data/vendor/lua/lib/lua/pl/pretty.lua +285 -0
  375. data/vendor/lua/lib/lua/pl/seq.lua +551 -0
  376. data/vendor/lua/lib/lua/pl/sip.lua +344 -0
  377. data/vendor/lua/lib/lua/pl/strict.lua +70 -0
  378. data/vendor/lua/lib/lua/pl/stringio.lua +158 -0
  379. data/vendor/lua/lib/lua/pl/stringx.lua +440 -0
  380. data/vendor/lua/lib/lua/pl/tablex.lua +817 -0
  381. data/vendor/lua/lib/lua/pl/template.lua +103 -0
  382. data/vendor/lua/lib/lua/pl/test.lua +135 -0
  383. data/vendor/lua/lib/lua/pl/text.lua +243 -0
  384. data/vendor/lua/lib/lua/pl/utils.lua +550 -0
  385. data/vendor/lua/lib/lua/pl/xml.lua +689 -0
  386. data/vendor/lua/lib/lua/profiler.dll +0 -0
  387. data/vendor/lua/lib/lua/re.lua +248 -0
  388. data/vendor/lua/lib/lua/rex_onig.dll +0 -0
  389. data/vendor/lua/lib/lua/rex_pcre.dll +0 -0
  390. data/vendor/lua/lib/lua/rex_posix.dll +0 -0
  391. data/vendor/lua/lib/lua/rings.dll +0 -0
  392. data/vendor/lua/lib/lua/serialize.lua +193 -0
  393. data/vendor/lua/lib/lua/set.lua +149 -0
  394. data/vendor/lua/lib/lua/socket.lua +133 -0
  395. data/vendor/lua/lib/lua/socket/core.dll +0 -0
  396. data/vendor/lua/lib/lua/socket/ftp.lua +281 -0
  397. data/vendor/lua/lib/lua/socket/http.lua +350 -0
  398. data/vendor/lua/lib/lua/socket/smtp.lua +251 -0
  399. data/vendor/lua/lib/lua/socket/tp.lua +123 -0
  400. data/vendor/lua/lib/lua/socket/url.lua +297 -0
  401. data/vendor/lua/lib/lua/ssl.dll +0 -0
  402. data/vendor/lua/lib/lua/ssl.lua +93 -0
  403. data/vendor/lua/lib/lua/ssl/https.lua +138 -0
  404. data/vendor/lua/lib/lua/stable.lua +28 -0
  405. data/vendor/lua/lib/lua/std.lua +16 -0
  406. data/vendor/lua/lib/lua/strbuf.lua +32 -0
  407. data/vendor/lua/lib/lua/strict.lua +45 -0
  408. data/vendor/lua/lib/lua/string_ext.lua +274 -0
  409. data/vendor/lua/lib/lua/table_ext.lua +117 -0
  410. data/vendor/lua/lib/lua/tar.lua +262 -0
  411. data/vendor/lua/lib/lua/task.dll +0 -0
  412. data/vendor/lua/lib/lua/tree.lua +81 -0
  413. data/vendor/lua/lib/lua/unicode.dll +0 -0
  414. data/vendor/lua/lib/lua/verbose_require.lua +11 -0
  415. data/vendor/lua/lib/lua/vstruct.lua +86 -0
  416. data/vendor/lua/lib/lua/vstruct/ast.lua +192 -0
  417. data/vendor/lua/lib/lua/vstruct/ast/Bitpack.lua +33 -0
  418. data/vendor/lua/lib/lua/vstruct/ast/Generator.lua +174 -0
  419. data/vendor/lua/lib/lua/vstruct/ast/IO.lua +45 -0
  420. data/vendor/lua/lib/lua/vstruct/ast/List.lua +56 -0
  421. data/vendor/lua/lib/lua/vstruct/ast/Name.lua +20 -0
  422. data/vendor/lua/lib/lua/vstruct/ast/Repeat.lua +23 -0
  423. data/vendor/lua/lib/lua/vstruct/ast/Root.lua +19 -0
  424. data/vendor/lua/lib/lua/vstruct/ast/Table.lua +65 -0
  425. data/vendor/lua/lib/lua/vstruct/cursor.lua +81 -0
  426. data/vendor/lua/lib/lua/vstruct/io.lua +45 -0
  427. data/vendor/lua/lib/lua/vstruct/io/a.lua +24 -0
  428. data/vendor/lua/lib/lua/vstruct/io/b.lua +28 -0
  429. data/vendor/lua/lib/lua/vstruct/io/bigendian.lua +21 -0
  430. data/vendor/lua/lib/lua/vstruct/io/c.lua +25 -0
  431. data/vendor/lua/lib/lua/vstruct/io/defaults.lua +24 -0
  432. data/vendor/lua/lib/lua/vstruct/io/endianness.lua +41 -0
  433. data/vendor/lua/lib/lua/vstruct/io/f.lua +129 -0
  434. data/vendor/lua/lib/lua/vstruct/io/hostendian.lua +21 -0
  435. data/vendor/lua/lib/lua/vstruct/io/i.lua +42 -0
  436. data/vendor/lua/lib/lua/vstruct/io/littleendian.lua +21 -0
  437. data/vendor/lua/lib/lua/vstruct/io/m.lua +62 -0
  438. data/vendor/lua/lib/lua/vstruct/io/p.lua +23 -0
  439. data/vendor/lua/lib/lua/vstruct/io/s.lua +27 -0
  440. data/vendor/lua/lib/lua/vstruct/io/seekb.lua +18 -0
  441. data/vendor/lua/lib/lua/vstruct/io/seekf.lua +18 -0
  442. data/vendor/lua/lib/lua/vstruct/io/seekto.lua +18 -0
  443. data/vendor/lua/lib/lua/vstruct/io/u.lua +54 -0
  444. data/vendor/lua/lib/lua/vstruct/io/x.lua +34 -0
  445. data/vendor/lua/lib/lua/vstruct/io/z.lua +63 -0
  446. data/vendor/lua/lib/lua/vstruct/lexer.lua +100 -0
  447. data/vendor/lua/lib/lua/vstruct/pack.lua +142 -0
  448. data/vendor/lua/lib/lua/vstruct/test.lua +47 -0
  449. data/vendor/lua/lib/lua/vstruct/test/basic.lua +73 -0
  450. data/vendor/lua/lib/lua/vstruct/test/common.lua +100 -0
  451. data/vendor/lua/lib/lua/vstruct/test/fp-bigendian.lua +56 -0
  452. data/vendor/lua/lib/lua/vstruct/test/fp-littleendian.lua +56 -0
  453. data/vendor/lua/lib/lua/vstruct/test/struct-test-gen.lua +1230 -0
  454. data/vendor/lua/lib/lua/vstruct/unpack.lua +126 -0
  455. data/vendor/lua/lib/lua/wx.dll +0 -0
  456. data/vendor/lua/lib/lua/xml.lua +75 -0
  457. data/vendor/lua/lib/lua/zip.dll +0 -0
  458. data/vendor/lua/lib/lua/zlib.dll +0 -0
  459. metadata +529 -0
@@ -0,0 +1,54 @@
1
+ --------------------------------------------------------------------------------
2
+ --
3
+ -- Scopes: this library helps keeping track of identifier scopes,
4
+ -- typically in code walkers.
5
+ --
6
+ -- * scope:new() returns a new scope instance s
7
+ --
8
+ -- * s:push() bookmarks the current set of variables, so the it can be
9
+ -- retrieved next time a s:pop() is performed.
10
+ --
11
+ -- * s:pop() retrieves the last state saved by s:push(). Calls to
12
+ -- :push() and :pop() can be nested as deep as one wants.
13
+ --
14
+ -- * s:add(var_list, val) adds new variable names (stirng) into the
15
+ -- scope, as keys. val is the (optional) value associated with them:
16
+ -- it allows to attach arbitrary information to variables, e.g. the
17
+ -- statement or expression that created them.
18
+ --
19
+ -- * s:push(var_list, val) is a shortcut for
20
+ -- s:push(); s:add(var_list, val).
21
+ --
22
+ -- * s.current is the current scope, a table with variable names as
23
+ -- keys and their associated value val (or 'true') as value.
24
+ --
25
+ --------------------------------------------------------------------------------
26
+
27
+ scope = { }
28
+ scope.__index = scope
29
+
30
+ function scope:new()
31
+ local ret = { current = { } }
32
+ ret.stack = { ret.current }
33
+ setmetatable (ret, self)
34
+ return ret
35
+ end
36
+
37
+ function scope:push(...)
38
+ table.insert (self.stack, table.shallow_copy (self.current))
39
+ if ... then return self:add(...) end
40
+ end
41
+
42
+ function scope:pop()
43
+ self.current = table.remove (self.stack)
44
+ end
45
+
46
+ function scope:add (vars, val)
47
+ val = val or true
48
+ for i, id in ipairs (vars) do
49
+ assert(id.tag=='Id' or id.tag=='Dots' and i==#vars)
50
+ if id.tag=='Id' then self.current[id[1]] = val end
51
+ end
52
+ end
53
+
54
+ return scope
@@ -0,0 +1,87 @@
1
+ -----------------------------------------------------------------------------
2
+ -- MIME support for the Lua language.
3
+ -- Author: Diego Nehab
4
+ -- Conforming to RFCs 2045-2049
5
+ -- RCS ID: $Id$
6
+ -----------------------------------------------------------------------------
7
+
8
+ -----------------------------------------------------------------------------
9
+ -- Declare module and import dependencies
10
+ -----------------------------------------------------------------------------
11
+ local base = _G
12
+ local ltn12 = require("ltn12")
13
+ local mime = require("mime.core")
14
+ local io = require("io")
15
+ local string = require("string")
16
+ module("mime")
17
+
18
+ -- encode, decode and wrap algorithm tables
19
+ encodet = {}
20
+ decodet = {}
21
+ wrapt = {}
22
+
23
+ -- creates a function that chooses a filter by name from a given table
24
+ local function choose(table)
25
+ return function(name, opt1, opt2)
26
+ if base.type(name) ~= "string" then
27
+ name, opt1, opt2 = "default", name, opt1
28
+ end
29
+ local f = table[name or "nil"]
30
+ if not f then
31
+ base.error("unknown key (" .. base.tostring(name) .. ")", 3)
32
+ else return f(opt1, opt2) end
33
+ end
34
+ end
35
+
36
+ -- define the encoding filters
37
+ encodet['base64'] = function()
38
+ return ltn12.filter.cycle(b64, "")
39
+ end
40
+
41
+ encodet['quoted-printable'] = function(mode)
42
+ return ltn12.filter.cycle(qp, "",
43
+ (mode == "binary") and "=0D=0A" or "\r\n")
44
+ end
45
+
46
+ -- define the decoding filters
47
+ decodet['base64'] = function()
48
+ return ltn12.filter.cycle(unb64, "")
49
+ end
50
+
51
+ decodet['quoted-printable'] = function()
52
+ return ltn12.filter.cycle(unqp, "")
53
+ end
54
+
55
+ local function format(chunk)
56
+ if chunk then
57
+ if chunk == "" then return "''"
58
+ else return string.len(chunk) end
59
+ else return "nil" end
60
+ end
61
+
62
+ -- define the line-wrap filters
63
+ wrapt['text'] = function(length)
64
+ length = length or 76
65
+ return ltn12.filter.cycle(wrp, length, length)
66
+ end
67
+ wrapt['base64'] = wrapt['text']
68
+ wrapt['default'] = wrapt['text']
69
+
70
+ wrapt['quoted-printable'] = function()
71
+ return ltn12.filter.cycle(qpwrp, 76, 76)
72
+ end
73
+
74
+ -- function that choose the encoding, decoding or wrap algorithm
75
+ encode = choose(encodet)
76
+ decode = choose(decodet)
77
+ wrap = choose(wrapt)
78
+
79
+ -- define the end-of-line normalization filter
80
+ function normalize(marker)
81
+ return ltn12.filter.cycle(eol, 0, marker)
82
+ end
83
+
84
+ -- high level stuffing filter
85
+ function stuff()
86
+ return ltn12.filter.cycle(dot, 2)
87
+ end
@@ -0,0 +1,1484 @@
1
+ --
2
+ -- MobDebug 0.515
3
+ -- Copyright 2011-12 Paul Kulchenko
4
+ -- Based on RemDebug 1.0 Copyright Kepler Project 2005
5
+ --
6
+
7
+ local mobdebug = {
8
+ _NAME = "mobdebug",
9
+ _VERSION = 0.515,
10
+ _COPYRIGHT = "Paul Kulchenko",
11
+ _DESCRIPTION = "Mobile Remote Debugger for the Lua programming language",
12
+ port = os and os.getenv and os.getenv("MOBDEBUG_PORT") or 8172,
13
+ yieldtimeout = 0.02,
14
+ }
15
+
16
+ local coroutine = coroutine
17
+ local error = error
18
+ local getfenv = getfenv
19
+ local setfenv = setfenv
20
+ local loadstring = loadstring or load -- "load" replaced "loadstring" in Lua 5.2
21
+ local io = io
22
+ local os = os
23
+ local pairs = pairs
24
+ local require = require
25
+ local setmetatable = setmetatable
26
+ local string = string
27
+ local tonumber = tonumber
28
+
29
+ -- if strict.lua is used, then need to avoid referencing some global
30
+ -- variables, as they can be undefined;
31
+ -- use rawget to to avoid complaints from strict.lua at run-time.
32
+ -- it's safe to do the initialization here as all these variables
33
+ -- should get defined values (of any) before the debugging starts.
34
+ -- there is also global 'wx' variable, which is checked as part of
35
+ -- the debug loop as 'wx' can be loaded at any time during debugging.
36
+ local genv = _G or _ENV
37
+ local jit = rawget(genv, "jit")
38
+ local mosync = rawget(genv, "mosync")
39
+ local MOAICoroutine = rawget(genv, "MOAICoroutine")
40
+
41
+ if not setfenv then -- Lua 5.2
42
+ -- based on http://lua-users.org/lists/lua-l/2010-06/msg00314.html
43
+ -- this assumes f is a function
44
+ local function findenv(f)
45
+ local level = 1
46
+ repeat
47
+ local name, value = debug.getupvalue(f, level)
48
+ if name == '_ENV' then return level, value end
49
+ level = level + 1
50
+ until name == nil
51
+ return nil end
52
+ getfenv = function (f) return(select(2, findenv(f)) or _G) end
53
+ setfenv = function (f, t)
54
+ local level = findenv(f)
55
+ if level then debug.setupvalue(f, level, t) end
56
+ return f end
57
+ end
58
+
59
+ -- check for OS and convert file names to lower case on windows
60
+ -- (its file system is case insensitive, but case preserving), as setting a
61
+ -- breakpoint on x:\Foo.lua will not work if the file was loaded as X:\foo.lua.
62
+ local iswindows = os and os.getenv and (os.getenv('WINDIR')
63
+ or (os.getenv('OS') or ''):match('[Ww]indows'))
64
+ or pcall(require, "winapi")
65
+
66
+ -- this is a socket class that implements maConnect interface
67
+ local function socketMobileLua()
68
+ local self = {}
69
+ self.select = function(readfrom) -- writeto and timeout parameters are ignored
70
+ local canread = {}
71
+ for _,s in ipairs(readfrom) do
72
+ if s:receive(0) then canread[s] = true end
73
+ end
74
+ return canread
75
+ end
76
+ self.connect = coroutine.wrap(function(host, port)
77
+ while true do
78
+ local connection = mosync.maConnect("socket://" .. host .. ":" .. port)
79
+
80
+ if connection > 0 then
81
+ local event = mosync.SysEventCreate()
82
+ while true do
83
+ mosync.maWait(0)
84
+ mosync.maGetEvent(event)
85
+ local eventType = mosync.SysEventGetType(event)
86
+ if (mosync.EVENT_TYPE_CONN == eventType and
87
+ mosync.SysEventGetConnHandle(event) == connection and
88
+ mosync.SysEventGetConnOpType(event) == mosync.CONNOP_CONNECT) then
89
+ -- result > 0 ? success : error
90
+ if not (mosync.SysEventGetConnResult(event) > 0) then connection = nil end
91
+ break
92
+ elseif mosync.EventMonitor and mosync.EventMonitor.HandleEvent then
93
+ mosync.EventMonitor:HandleEvent(event)
94
+ end
95
+ end
96
+ mosync.SysFree(event)
97
+ end
98
+
99
+ host, port = coroutine.yield(connection and (function ()
100
+ local self = {}
101
+ local outBuffer = mosync.SysAlloc(1000)
102
+ local inBuffer = mosync.SysAlloc(1000)
103
+ local event = mosync.SysEventCreate()
104
+ local recvBuffer = ""
105
+ function stringToBuffer(s, buffer)
106
+ local i = 0
107
+ for c in s:gmatch(".") do
108
+ i = i + 1
109
+ local b = s:byte(i)
110
+ mosync.SysBufferSetByte(buffer, i - 1, b)
111
+ end
112
+ return i
113
+ end
114
+ function bufferToString(buffer, len)
115
+ local s = ""
116
+ for i = 0, len - 1 do
117
+ local c = mosync.SysBufferGetByte(buffer, i)
118
+ s = s .. string.char(c)
119
+ end
120
+ return s
121
+ end
122
+ self.send = coroutine.wrap(function(self, msg)
123
+ while true do
124
+ local numberOfBytes = stringToBuffer(msg, outBuffer)
125
+ mosync.maConnWrite(connection, outBuffer, numberOfBytes)
126
+ while true do
127
+ mosync.maWait(0)
128
+ mosync.maGetEvent(event)
129
+ local eventType = mosync.SysEventGetType(event)
130
+ if (mosync.EVENT_TYPE_CONN == eventType and
131
+ mosync.SysEventGetConnHandle(event) == connection and
132
+ mosync.SysEventGetConnOpType(event) == mosync.CONNOP_WRITE) then
133
+ break
134
+ elseif mosync.EventMonitor and mosync.EventMonitor.HandleEvent then
135
+ mosync.EventMonitor:HandleEvent(event)
136
+ end
137
+ end
138
+ self, msg = coroutine.yield()
139
+ end
140
+ end)
141
+ self.receive = coroutine.wrap(function(self, len)
142
+ while true do
143
+ local line = recvBuffer
144
+ while (len and string.len(line) < len) -- either we need len bytes
145
+ or (not len and not line:find("\n")) -- or one line (if no len specified)
146
+ or (len == 0) do -- only check for new data (select-like)
147
+ mosync.maConnRead(connection, inBuffer, 1000)
148
+ while true do
149
+ if len ~= 0 then mosync.maWait(0) end
150
+ mosync.maGetEvent(event)
151
+ local eventType = mosync.SysEventGetType(event)
152
+ if (mosync.EVENT_TYPE_CONN == eventType and
153
+ mosync.SysEventGetConnHandle(event) == connection and
154
+ mosync.SysEventGetConnOpType(event) == mosync.CONNOP_READ) then
155
+ local result = mosync.SysEventGetConnResult(event)
156
+ if result > 0 then line = line .. bufferToString(inBuffer, result) end
157
+ if len == 0 then self, len = coroutine.yield("") end
158
+ break -- got the event we wanted; now check if we have all we need
159
+ elseif len == 0 then
160
+ self, len = coroutine.yield(nil)
161
+ elseif mosync.EventMonitor and mosync.EventMonitor.HandleEvent then
162
+ mosync.EventMonitor:HandleEvent(event)
163
+ end
164
+ end
165
+ end
166
+
167
+ if not len then
168
+ len = string.find(line, "\n") or string.len(line)
169
+ end
170
+
171
+ recvBuffer = string.sub(line, len+1)
172
+ line = string.sub(line, 1, len)
173
+
174
+ self, len = coroutine.yield(line)
175
+ end
176
+ end)
177
+ self.close = coroutine.wrap(function(self)
178
+ while true do
179
+ mosync.SysFree(inBuffer)
180
+ mosync.SysFree(outBuffer)
181
+ mosync.SysFree(event)
182
+ mosync.maConnClose(connection)
183
+ coroutine.yield(self)
184
+ end
185
+ end)
186
+ return self
187
+ end)())
188
+ end
189
+ end)
190
+
191
+ return self
192
+ end
193
+
194
+ -- overwrite RunEventLoop in MobileLua as it conflicts with the event
195
+ -- loop that needs to run to process debugger events (socket read/write).
196
+ -- event loop functionality is implemented by calling HandleEvent
197
+ -- while waiting for debugger events.
198
+ if mosync and mosync.EventMonitor then
199
+ mosync.EventMonitor.RunEventLoop = function(self) end
200
+ end
201
+
202
+ -- turn jit off based on Mike Pall's comment in this discussion:
203
+ -- http://www.freelists.org/post/luajit/Debug-hooks-and-JIT,2
204
+ -- "You need to turn it off at the start if you plan to receive
205
+ -- reliable hook calls at any later point in time."
206
+ if jit and jit.off then jit.off() end
207
+
208
+ local socket = mosync and socketMobileLua() or (require "socket")
209
+
210
+ local debug = require "debug"
211
+ local coro_debugger
212
+ local coro_debugee
213
+ local coroutines = {}; setmetatable(coroutines, {__mode = "k"}) -- "weak" keys
214
+ local events = { BREAK = 1, WATCH = 2, RESTART = 3, STACK = 4 }
215
+ local breakpoints = {}
216
+ local watches = {}
217
+ local lastsource
218
+ local lastfile
219
+ local watchescnt = 0
220
+ local abort -- default value is nil; this is used in start/loop distinction
221
+ local seen_hook = false
222
+ local skip
223
+ local skipcount = 0
224
+ local step_into = false
225
+ local step_over = false
226
+ local step_level = 0
227
+ local stack_level = 0
228
+ local server
229
+ local rset
230
+ local outputs = {}
231
+ local iobase = {print = print}
232
+ local basedir = ""
233
+ local deferror = "execution aborted at default debugee"
234
+ local debugee = function ()
235
+ local a = 1
236
+ for _ = 1, 10 do a = a + 1 end
237
+ error(deferror)
238
+ end
239
+ local function q(s) return s:gsub('([%(%)%.%%%+%-%*%?%[%^%$%]])','%%%1') end
240
+
241
+ local serpent = (function() ---- include Serpent module for serialization
242
+ local n, v = "serpent", 0.22 -- (C) 2012 Paul Kulchenko; MIT License
243
+ local c, d = "Paul Kulchenko", "Serializer and pretty printer of Lua data types"
244
+ local snum = {[tostring(1/0)]='1/0 --[[math.huge]]',[tostring(-1/0)]='-1/0 --[[-math.huge]]',[tostring(0/0)]='0/0'}
245
+ local badtype = {thread = true, userdata = true}
246
+ local keyword, globals, G = {}, {}, (_G or _ENV)
247
+ for _,k in ipairs({'and', 'break', 'do', 'else', 'elseif', 'end', 'false',
248
+ 'for', 'function', 'goto', 'if', 'in', 'local', 'nil', 'not', 'or', 'repeat',
249
+ 'return', 'then', 'true', 'until', 'while'}) do keyword[k] = true end
250
+ for k,v in pairs(G) do globals[v] = k end -- build func to name mapping
251
+ for _,g in ipairs({'coroutine', 'debug', 'io', 'math', 'string', 'table', 'os'}) do
252
+ for k,v in pairs(G[g]) do globals[v] = g..'.'..k end end
253
+
254
+ local function s(t, opts)
255
+ local name, indent, fatal = opts.name, opts.indent, opts.fatal
256
+ local sparse, custom, huge = opts.sparse, opts.custom, not opts.nohuge
257
+ local space, maxl = (opts.compact and '' or ' '), (opts.maxlevel or math.huge)
258
+ local comm = opts.comment and (tonumber(opts.comment) or math.huge)
259
+ local seen, sref, syms, symn = {}, {}, {}, 0
260
+ local function gensym(val) return (tostring(val):gsub("[^%w]",""):gsub("(%d%w+)",
261
+ function(s) if not syms[s] then symn = symn+1; syms[s] = symn end return syms[s] end)) end
262
+ local function safestr(s) return type(s) == "number" and (huge and snum[tostring(s)] or s)
263
+ or type(s) ~= "string" and tostring(s) -- escape NEWLINE/010 and EOF/026
264
+ or ("%q"):format(s):gsub("\010","n"):gsub("\026","\\026") end
265
+ local function comment(s,l) return comm and (l or 0) < comm and ' --[['..tostring(s)..']]' or '' end
266
+ local function globerr(s,l) return globals[s] and globals[s]..comment(s,l) or not fatal
267
+ and safestr(select(2, pcall(tostring, s))) or error("Can't serialize "..tostring(s)) end
268
+ local function safename(path, name) -- generates foo.bar, foo[3], or foo['b a r']
269
+ local n = name == nil and '' or name
270
+ local plain = type(n) == "string" and n:match("^[%l%u_][%w_]*$") and not keyword[n]
271
+ local safe = plain and n or '['..safestr(n)..']'
272
+ return (path or '')..(plain and path and '.' or '')..safe, safe end
273
+ local alphanumsort = type(opts.sortkeys) == 'function' and opts.sortkeys or function(o, n)
274
+ local maxn, to = tonumber(n) or 12, {number = 'a', string = 'b'}
275
+ local function padnum(d) return ("%0"..maxn.."d"):format(d) end
276
+ table.sort(o, function(a,b)
277
+ return (o[a] and 0 or to[type(a)] or 'z')..(tostring(a):gsub("%d+",padnum))
278
+ < (o[b] and 0 or to[type(b)] or 'z')..(tostring(b):gsub("%d+",padnum)) end) end
279
+ local function val2str(t, name, indent, insref, path, plainindex, level)
280
+ local ttype, level = type(t), (level or 0)
281
+ local spath, sname = safename(path, name)
282
+ local tag = plainindex and
283
+ ((type(name) == "number") and '' or name..space..'='..space) or
284
+ (name ~= nil and sname..space..'='..space or '')
285
+ if seen[t] then -- if already seen and in sref processing,
286
+ if insref then return tag..seen[t] end -- then emit right away
287
+ table.insert(sref, spath..space..'='..space..seen[t])
288
+ return tag..'nil'..comment('ref', level)
289
+ elseif badtype[ttype] then
290
+ seen[t] = spath
291
+ return tag..globerr(t, level)
292
+ elseif ttype == 'function' then
293
+ seen[t] = insref or spath
294
+ local ok, res = pcall(string.dump, t)
295
+ local func = ok and ((opts.nocode and "function() --[[..skipped..]] end" or
296
+ "loadstring("..safestr(res)..",'@serialized')")..comment(t, level))
297
+ return tag..(func or globerr(t, level))
298
+ elseif ttype == "table" then
299
+ if level >= maxl then return tag..'{}'..comment('max', level) end
300
+ seen[t] = insref or spath -- set path to use as reference
301
+ if getmetatable(t) and getmetatable(t).__tostring
302
+ then return tag..val2str(tostring(t),nil,indent,false,nil,nil,level+1)..comment("meta", level) end
303
+ if next(t) == nil then return tag..'{}'..comment(t, level) end -- table empty
304
+ local maxn, o, out = #t, {}, {}
305
+ for key = 1, maxn do table.insert(o, key) end
306
+ for key in pairs(t) do if not o[key] then table.insert(o, key) end end
307
+ if opts.sortkeys then alphanumsort(o, opts.sortkeys) end
308
+ for n, key in ipairs(o) do
309
+ local value, ktype, plainindex = t[key], type(key), n <= maxn and not sparse
310
+ if opts.valignore and opts.valignore[value] -- skip ignored values; do nothing
311
+ or opts.keyallow and not opts.keyallow[key]
312
+ or opts.valtypeignore and opts.valtypeignore[type(value)] -- skipping ignored value types
313
+ or sparse and value == nil then -- skipping nils; do nothing
314
+ elseif ktype == 'table' or ktype == 'function' or badtype[ktype] then
315
+ if not seen[key] and not globals[key] then
316
+ table.insert(sref, 'placeholder')
317
+ sref[#sref] = 'local '..val2str(key,gensym(key),indent,gensym(key)) end
318
+ table.insert(sref, 'placeholder')
319
+ local path = seen[t]..'['..(seen[key] or globals[key] or gensym(key))..']'
320
+ sref[#sref] = path..space..'='..space..(seen[value] or val2str(value,nil,indent,path))
321
+ else
322
+ table.insert(out,val2str(value,key,indent,insref,seen[t],plainindex,level+1))
323
+ end
324
+ end
325
+ local prefix = string.rep(indent or '', level)
326
+ local head = indent and '{\n'..prefix..indent or '{'
327
+ local body = table.concat(out, ','..(indent and '\n'..prefix..indent or space))
328
+ local tail = indent and "\n"..prefix..'}' or '}'
329
+ return (custom and custom(tag,head,body,tail) or tag..head..body..tail)..comment(t, level)
330
+ else return tag..safestr(t) end -- handle all other types
331
+ end
332
+ local sepr = indent and "\n" or ";"..space
333
+ local body = val2str(t, name, indent) -- this call also populates sref
334
+ local tail = #sref>0 and table.concat(sref, sepr)..sepr or ''
335
+ return not name and body or "do local "..body..sepr..tail.."return "..name..sepr.."end"
336
+ end
337
+
338
+ local function merge(a, b) if b then for k,v in pairs(b) do a[k] = v end end; return a; end
339
+ return { _NAME = n, _COPYRIGHT = c, _DESCRIPTION = d, _VERSION = v, serialize = s,
340
+ dump = function(a, opts) return s(a, merge({name = '_', compact = true, sparse = true}, opts)) end,
341
+ line = function(a, opts) return s(a, merge({sortkeys = true, comment = true}, opts)) end,
342
+ block = function(a, opts) return s(a, merge({indent = ' ', sortkeys = true, comment = true}, opts)) end }
343
+ end)() ---- end of Serpent module
344
+
345
+ local function removebasedir(path, basedir)
346
+ if iswindows then
347
+ -- check if the lowercased path matches the basedir
348
+ -- if so, return substring of the original path (to not lowercase it)
349
+ return path:lower():find('^'..q(basedir:lower()))
350
+ and path:sub(#basedir+1) or path
351
+ else
352
+ return string.gsub(path, '^'..q(basedir), '')
353
+ end
354
+ end
355
+
356
+ local function stack(start)
357
+ local function vars(f)
358
+ local func = debug.getinfo(f, "f").func
359
+ local i = 1
360
+ local locals = {}
361
+ while true do
362
+ local name, value = debug.getlocal(f, i)
363
+ if not name then break end
364
+ if string.sub(name, 1, 1) ~= '(' then locals[name] = {value, tostring(value)} end
365
+ i = i + 1
366
+ end
367
+ i = 1
368
+ local ups = {}
369
+ while func and true do -- check for func as it may be nil for tail calls
370
+ local name, value = debug.getupvalue(func, i)
371
+ if not name then break end
372
+ ups[name] = {value, tostring(value)}
373
+ i = i + 1
374
+ end
375
+ return locals, ups
376
+ end
377
+
378
+ local stack = {}
379
+ for i = (start or 0), 100 do
380
+ local source = debug.getinfo(i, "Snl")
381
+ if not source then break end
382
+
383
+ -- remove basedir from source
384
+ local src = source.source
385
+ if src:find("@") == 1 then
386
+ src = src:sub(2):gsub("\\", "/")
387
+ if src:find("%./") == 1 then src = src:sub(3) end
388
+ end
389
+
390
+ table.insert(stack, {
391
+ {source.name, removebasedir(src, basedir), source.linedefined,
392
+ source.currentline, source.what, source.namewhat, source.short_src},
393
+ vars(i+1)})
394
+ if source.what == 'main' then break end
395
+ end
396
+ return stack
397
+ end
398
+
399
+ local function set_breakpoint(file, line)
400
+ if file == '-' and lastfile then file = lastfile
401
+ elseif iswindows then file = string.lower(file) end
402
+ if not breakpoints[file] then breakpoints[file] = {} end
403
+ breakpoints[file][line] = true
404
+ end
405
+
406
+ local function remove_breakpoint(file, line)
407
+ if file == '-' and lastfile then file = lastfile
408
+ elseif iswindows then file = string.lower(file) end
409
+ if breakpoints[file] then breakpoints[file][line] = nil end
410
+ end
411
+
412
+ -- this file name is already converted to lower case on windows.
413
+ local function has_breakpoint(file, line)
414
+ return breakpoints[file] and breakpoints[file][line]
415
+ end
416
+
417
+ local function restore_vars(vars)
418
+ if type(vars) ~= 'table' then return end
419
+
420
+ -- locals need to be processed in the reverse order, starting from
421
+ -- the inner block out, to make sure that the localized variables
422
+ -- are correctly updated with only the closest variable with
423
+ -- the same name being changed
424
+ -- first loop find how many local variables there is, while
425
+ -- the second loop processes them from i to 1
426
+ local i = 1
427
+ while true do
428
+ local name = debug.getlocal(3, i)
429
+ if not name then break end
430
+ i = i + 1
431
+ end
432
+ i = i - 1
433
+ local written_vars = {}
434
+ while i > 0 do
435
+ local name = debug.getlocal(3, i)
436
+ if not written_vars[name] then
437
+ if string.sub(name, 1, 1) ~= '(' then debug.setlocal(3, i, vars[name]) end
438
+ written_vars[name] = true
439
+ end
440
+ i = i - 1
441
+ end
442
+
443
+ i = 1
444
+ local func = debug.getinfo(3, "f").func
445
+ while true do
446
+ local name = debug.getupvalue(func, i)
447
+ if not name then break end
448
+ if not written_vars[name] then
449
+ if string.sub(name, 1, 1) ~= '(' then debug.setupvalue(func, i, vars[name]) end
450
+ written_vars[name] = true
451
+ end
452
+ i = i + 1
453
+ end
454
+ end
455
+
456
+ local function capture_vars(level)
457
+ local vars = {}
458
+ local func = debug.getinfo(level or 3, "f").func
459
+ local i = 1
460
+ while true do
461
+ local name, value = debug.getupvalue(func, i)
462
+ if not name then break end
463
+ if string.sub(name, 1, 1) ~= '(' then vars[name] = value end
464
+ i = i + 1
465
+ end
466
+ i = 1
467
+ while true do
468
+ local name, value = debug.getlocal(level or 3, i)
469
+ if not name then break end
470
+ if string.sub(name, 1, 1) ~= '(' then vars[name] = value end
471
+ i = i + 1
472
+ end
473
+ setmetatable(vars, { __index = getfenv(func), __newindex = getfenv(func) })
474
+ return vars
475
+ end
476
+
477
+ local function stack_depth(start_depth)
478
+ for i = start_depth, 0, -1 do
479
+ if debug.getinfo(i, "l") then return i+1 end
480
+ end
481
+ return start_depth
482
+ end
483
+
484
+ local function is_safe(stack_level)
485
+ -- the stack grows up: 0 is getinfo, 1 is is_safe, 2 is debug_hook, 3 is user function
486
+ if stack_level == 3 then return true end
487
+ for i = 3, stack_level do
488
+ -- return if it is not safe to abort
489
+ local info = debug.getinfo(i, "S")
490
+ if not info then return true end
491
+ if info.what == "C" then return false end
492
+ end
493
+ return true
494
+ end
495
+
496
+ local function in_debugger()
497
+ local this = debug.getinfo(1, "S").source
498
+ -- only need to check few frames as mobdebug frames should be close
499
+ for i = 3, 7 do
500
+ local info = debug.getinfo(i, "S")
501
+ if not info then return false end
502
+ if info.source == this then return true end
503
+ end
504
+ return false
505
+ end
506
+
507
+ local function debug_hook(event, line)
508
+ -- (1) LuaJIT needs special treatment. Because debug_hook is set for
509
+ -- *all* coroutines, and not just the one being debugged as in regular Lua
510
+ -- (http://lua-users.org/lists/lua-l/2011-06/msg00513.html),
511
+ -- need to avoid debugging mobdebug's own code as LuaJIT doesn't
512
+ -- always correctly generate call/return hook events (there are more
513
+ -- calls than returns, which breaks stack depth calculation and
514
+ -- 'step' and 'step over' commands stop working; possibly because
515
+ -- 'tail return' events are not generated by LuaJIT).
516
+ -- the next line checks if the debugger is run under LuaJIT and if
517
+ -- one of debugger methods is present in the stack, it simply returns.
518
+ if jit then
519
+ local coro = coroutine.running()
520
+ if coro_debugee and coro ~= coro_debugee and not coroutines[coro]
521
+ or not coro_debugee and (in_debugger() or coro and not coroutines[coro])
522
+ then return end
523
+ end
524
+
525
+ -- (2) check if abort has been requested and it's safe to abort
526
+ if abort and is_safe(stack_level) then error(abort) end
527
+
528
+ -- (3) also check if this debug hook has not been visited for any reason.
529
+ -- this check is needed to avoid stepping in too early
530
+ -- (for example, when coroutine.resume() is executed inside start()).
531
+ if not seen_hook and in_debugger() then return end
532
+
533
+ if event == "call" then
534
+ stack_level = stack_level + 1
535
+ elseif event == "return" or event == "tail return" then
536
+ stack_level = stack_level - 1
537
+ elseif event == "line" then
538
+
539
+ -- check if we need to skip some callbacks (to save time)
540
+ if skip then
541
+ skipcount = skipcount + 1
542
+ if skipcount < skip or not is_safe(stack_level) then return end
543
+ skipcount = 0
544
+ end
545
+
546
+ -- this is needed to check if the stack got shorter or longer.
547
+ -- unfortunately counting call/return calls is not reliable.
548
+ -- the discrepancy may happen when "pcall(load, '')" call is made
549
+ -- or when "error()" is called in a function.
550
+ -- in either case there are more "call" than "return" events reported.
551
+ -- this validation is done for every "line" event, but should be "cheap"
552
+ -- as it checks for the stack to get shorter (or longer by one call).
553
+ -- start from one level higher just in case we need to grow the stack.
554
+ -- this may happen after coroutine.resume call to a function that doesn't
555
+ -- have any other instructions to execute. it triggers three returns:
556
+ -- "return, tail return, return", which needs to be accounted for.
557
+ stack_level = stack_depth(stack_level+1)
558
+ local caller = debug.getinfo(2, "S")
559
+
560
+ -- grab the filename and fix it if needed
561
+ local file = lastfile
562
+ if (lastsource ~= caller.source) then
563
+ lastsource = caller.source
564
+ file = lastsource
565
+ if file:find("@") == 1 then
566
+ file = file:sub(2):gsub("\\", "/")
567
+ -- need this conversion to be applied to relative and absolute
568
+ -- file names as you may write "require 'Foo'" on Windows to
569
+ -- load "foo.lua" (as it's case insensitive) and breakpoints
570
+ -- set on foo.lua will not work if not converted to the same case.
571
+ if iswindows then file = string.lower(file) end
572
+ if file:find("%./") == 1 then file = file:sub(3)
573
+ else file = file:gsub('^'..q(basedir), '') end
574
+ end
575
+
576
+ -- fix filenames for loaded strings that may contain scripts with newlines;
577
+ -- some filesystems may allow "\n" in filenames, which is not supported here.
578
+ if file:find("\n") then
579
+ file = file:gsub("\n", ' '):sub(1, 32) -- limit to 32 chars
580
+ end
581
+
582
+ -- set to true if we got here; this only needs to be done once per
583
+ -- session, so do it here to at least avoid setting it for every line.
584
+ seen_hook = true
585
+ lastfile = file
586
+ end
587
+
588
+ local vars, status, res
589
+ if (watchescnt > 0) then
590
+ vars = capture_vars()
591
+ for index, value in pairs(watches) do
592
+ setfenv(value, vars)
593
+ local ok, fired = pcall(value)
594
+ if ok and fired then
595
+ status, res = coroutine.resume(coro_debugger, events.WATCH, vars, file, line, index)
596
+ break -- any one watch is enough; don't check multiple times
597
+ end
598
+ end
599
+ end
600
+
601
+ -- need to get into the "regular" debug handler, but only if there was
602
+ -- no watch that was fired. If there was a watch, handle its result.
603
+ local getin = (status == nil) and
604
+ (step_into
605
+ or (step_over and stack_level <= step_level)
606
+ or has_breakpoint(file, line)
607
+ or (socket.select(rset, nil, 0))[server])
608
+
609
+ if getin then
610
+ vars = vars or capture_vars()
611
+ step_into = false
612
+ step_over = false
613
+ status, res = coroutine.resume(coro_debugger, events.BREAK, vars, file, line)
614
+ end
615
+
616
+ -- handle 'stack' command that provides stack() information to the debugger
617
+ if status and res == 'stack' then
618
+ while status and res == 'stack' do
619
+ -- resume with the stack trace and variables
620
+ if vars then restore_vars(vars) end -- restore vars so they are reflected in stack values
621
+ -- this may fail if __tostring method fails at run-time
622
+ local ok, snapshot = pcall(stack, 4)
623
+ status, res = coroutine.resume(coro_debugger, ok and events.STACK or events.BREAK, snapshot, file, line)
624
+ end
625
+ end
626
+
627
+ -- need to recheck once more as resume after 'stack' command may
628
+ -- return something else (for example, 'exit'), which needs to be handled
629
+ if status and res and res ~= 'stack' then
630
+ if abort == nil and res == "exit" then os.exit(1) end
631
+ abort = res
632
+ -- only abort if safe; if not, there is another (earlier) check inside
633
+ -- debug_hook, which will abort execution at the first safe opportunity
634
+ if is_safe(stack_level) then error(abort) end
635
+ elseif not status and res then
636
+ error(res, 2) -- report any other (internal) errors back to the application
637
+ end
638
+
639
+ if vars then restore_vars(vars) end
640
+ end
641
+ end
642
+
643
+ local function stringify_results(status, ...)
644
+ if not status then return status, ... end -- on error report as it
645
+
646
+ local t = {...}
647
+ for i,v in pairs(t) do -- stringify each of the returned values
648
+ local ok, res = pcall(serpent.line, v, {nocode = true, comment = 1})
649
+ t[i] = ok and res or ("%q"):format(res):gsub("\010","n"):gsub("\026","\\026")
650
+ end
651
+ -- stringify table with all returned values
652
+ -- this is done to allow each returned value to be used (serialized or not)
653
+ -- intependently and to preserve "original" comments
654
+ return pcall(serpent.dump, t, {sparse = false})
655
+ end
656
+
657
+ local function debugger_loop(sfile, sline)
658
+ local command
659
+ local app, osname
660
+ local eval_env = {}
661
+ local function emptyWatch () return false end
662
+ local loaded = {}
663
+ for k in pairs(package.loaded) do loaded[k] = true end
664
+
665
+ while true do
666
+ local line, err
667
+ local wx = rawget(genv, "wx") -- use rawread to make strict.lua happy
668
+ if (wx or mobdebug.yield) and server.settimeout then server:settimeout(mobdebug.yieldtimeout) end
669
+ while true do
670
+ line, err = server:receive()
671
+ if not line and err == "timeout" then
672
+ -- yield for wx GUI applications if possible to avoid "busyness"
673
+ app = app or (wx and wx.wxGetApp and wx.wxGetApp())
674
+ if app then
675
+ local win = app:GetTopWindow()
676
+ local inloop = app:IsMainLoopRunning()
677
+ osname = osname or wx.wxPlatformInfo.Get():GetOperatingSystemFamilyName()
678
+ if win and not inloop then
679
+ -- process messages in a regular way
680
+ -- and exit as soon as the event loop is idle
681
+ if osname == 'Unix' then wx.wxTimer(app):Start(10, true) end
682
+ local exitLoop = function()
683
+ win:Disconnect(wx.wxID_ANY, wx.wxID_ANY, wx.wxEVT_IDLE)
684
+ win:Disconnect(wx.wxID_ANY, wx.wxID_ANY, wx.wxEVT_TIMER)
685
+ app:ExitMainLoop()
686
+ end
687
+ win:Connect(wx.wxEVT_IDLE, exitLoop)
688
+ win:Connect(wx.wxEVT_TIMER, exitLoop)
689
+ app:MainLoop()
690
+ end
691
+ elseif mobdebug.yield then mobdebug.yield()
692
+ end
693
+ elseif not line and err == "closed" then
694
+ error("Debugger connection unexpectedly closed", 0)
695
+ else
696
+ break
697
+ end
698
+ end
699
+ if server.settimeout then server:settimeout() end -- back to blocking
700
+ command = string.sub(line, string.find(line, "^[A-Z]+"))
701
+ if command == "SETB" then
702
+ local _, _, _, file, line = string.find(line, "^([A-Z]+)%s+(.-)%s+(%d+)%s*$")
703
+ if file and line then
704
+ set_breakpoint(file, tonumber(line))
705
+ server:send("200 OK\n")
706
+ else
707
+ server:send("400 Bad Request\n")
708
+ end
709
+ elseif command == "DELB" then
710
+ local _, _, _, file, line = string.find(line, "^([A-Z]+)%s+(.-)%s+(%d+)%s*$")
711
+ if file and line then
712
+ remove_breakpoint(file, tonumber(line))
713
+ server:send("200 OK\n")
714
+ else
715
+ server:send("400 Bad Request\n")
716
+ end
717
+ elseif command == "EXEC" then
718
+ local _, _, chunk = string.find(line, "^[A-Z]+%s+(.+)$")
719
+ if chunk then
720
+ local func, res = loadstring(chunk)
721
+ local status
722
+ if func then
723
+ setfenv(func, eval_env)
724
+ status, res = stringify_results(pcall(func))
725
+ end
726
+ if status then
727
+ server:send("200 OK " .. #res .. "\n")
728
+ server:send(res)
729
+ else
730
+ server:send("401 Error in Expression " .. #res .. "\n")
731
+ server:send(res)
732
+ end
733
+ else
734
+ server:send("400 Bad Request\n")
735
+ end
736
+ elseif command == "LOAD" then
737
+ local _, _, size, name = string.find(line, "^[A-Z]+%s+(%d+)%s+(%S.-)%s*$")
738
+ size = tonumber(size)
739
+
740
+ if abort == nil then -- no LOAD/RELOAD allowed inside start()
741
+ if size > 0 then server:receive(size) end
742
+ if sfile and sline then
743
+ server:send("201 Started " .. sfile .. " " .. sline .. "\n")
744
+ else
745
+ server:send("200 OK 0\n")
746
+ end
747
+ else
748
+ -- reset environment to allow required modules to load again
749
+ -- remove those packages that weren't loaded when debugger started
750
+ for k in pairs(package.loaded) do
751
+ if not loaded[k] then package.loaded[k] = nil end
752
+ end
753
+
754
+ if size == 0 then -- RELOAD the current script being debugged
755
+ server:send("200 OK 0\n")
756
+ coroutine.yield("load")
757
+ else
758
+ local chunk = server:receive(size)
759
+ if chunk then -- LOAD a new script for debugging
760
+ local func, res = loadstring(chunk, name)
761
+ if func then
762
+ server:send("200 OK 0\n")
763
+ debugee = func
764
+ coroutine.yield("load")
765
+ else
766
+ server:send("401 Error in Expression " .. #res .. "\n")
767
+ server:send(res)
768
+ end
769
+ else
770
+ server:send("400 Bad Request\n")
771
+ end
772
+ end
773
+ end
774
+ elseif command == "SETW" then
775
+ local _, _, exp = string.find(line, "^[A-Z]+%s+(.+)%s*$")
776
+ if exp then
777
+ local func, res = loadstring("return(" .. exp .. ")")
778
+ if func then
779
+ watchescnt = watchescnt + 1
780
+ local newidx = #watches + 1
781
+ watches[newidx] = func
782
+ server:send("200 OK " .. newidx .. "\n")
783
+ else
784
+ server:send("401 Error in Expression " .. #res .. "\n")
785
+ server:send(res)
786
+ end
787
+ else
788
+ server:send("400 Bad Request\n")
789
+ end
790
+ elseif command == "DELW" then
791
+ local _, _, index = string.find(line, "^[A-Z]+%s+(%d+)%s*$")
792
+ index = tonumber(index)
793
+ if index > 0 and index <= #watches then
794
+ watchescnt = watchescnt - (watches[index] ~= emptyWatch and 1 or 0)
795
+ watches[index] = emptyWatch
796
+ server:send("200 OK\n")
797
+ else
798
+ server:send("400 Bad Request\n")
799
+ end
800
+ elseif command == "RUN" then
801
+ server:send("200 OK\n")
802
+
803
+ local ev, vars, file, line, idx_watch = coroutine.yield()
804
+ eval_env = vars
805
+ if ev == events.BREAK then
806
+ server:send("202 Paused " .. file .. " " .. line .. "\n")
807
+ elseif ev == events.WATCH then
808
+ server:send("203 Paused " .. file .. " " .. line .. " " .. idx_watch .. "\n")
809
+ elseif ev == events.RESTART then
810
+ -- nothing to do
811
+ else
812
+ server:send("401 Error in Execution " .. #file .. "\n")
813
+ server:send(file)
814
+ end
815
+ elseif command == "STEP" then
816
+ server:send("200 OK\n")
817
+ step_into = true
818
+
819
+ local ev, vars, file, line, idx_watch = coroutine.yield()
820
+ eval_env = vars
821
+ if ev == events.BREAK then
822
+ server:send("202 Paused " .. file .. " " .. line .. "\n")
823
+ elseif ev == events.WATCH then
824
+ server:send("203 Paused " .. file .. " " .. line .. " " .. idx_watch .. "\n")
825
+ elseif ev == events.RESTART then
826
+ -- nothing to do
827
+ else
828
+ server:send("401 Error in Execution " .. #file .. "\n")
829
+ server:send(file)
830
+ end
831
+ elseif command == "OVER" or command == "OUT" then
832
+ server:send("200 OK\n")
833
+ step_over = true
834
+
835
+ -- OVER and OUT are very similar except for
836
+ -- the stack level value at which to stop
837
+ if command == "OUT" then step_level = stack_level - 1
838
+ else step_level = stack_level end
839
+
840
+ local ev, vars, file, line, idx_watch = coroutine.yield()
841
+ eval_env = vars
842
+ if ev == events.BREAK then
843
+ server:send("202 Paused " .. file .. " " .. line .. "\n")
844
+ elseif ev == events.WATCH then
845
+ server:send("203 Paused " .. file .. " " .. line .. " " .. idx_watch .. "\n")
846
+ elseif ev == events.RESTART then
847
+ -- nothing to do
848
+ else
849
+ server:send("401 Error in Execution " .. #file .. "\n")
850
+ server:send(file)
851
+ end
852
+ elseif command == "BASEDIR" then
853
+ local _, _, dir = string.find(line, "^[A-Z]+%s+(.+)%s*$")
854
+ if dir then
855
+ basedir = iswindows and string.lower(dir) or dir
856
+ server:send("200 OK\n")
857
+ else
858
+ server:send("400 Bad Request\n")
859
+ end
860
+ elseif command == "SUSPEND" then
861
+ -- do nothing; it already fulfilled its role
862
+ elseif command == "STACK" then
863
+ -- first check if we can execute the stack command
864
+ -- as it requires yielding back to debug_hook it cannot be executed
865
+ -- if we have not seen the hook yet as happens after start().
866
+ -- in this case we simply return an empty result
867
+ local vars, ev = {}
868
+ if seen_hook then
869
+ ev, vars = coroutine.yield("stack")
870
+ end
871
+ if ev and ev ~= events.STACK then
872
+ server:send("401 Error in Execution " .. #vars .. "\n")
873
+ server:send(vars)
874
+ else
875
+ local ok, res = pcall(serpent.dump, vars, {nocode = true, sparse = false})
876
+ if ok then
877
+ server:send("200 OK " .. res .. "\n")
878
+ else
879
+ server:send("401 Error in Execution " .. #res .. "\n")
880
+ server:send(res)
881
+ end
882
+ end
883
+ elseif command == "OUTPUT" then
884
+ local _, _, stream, mode = string.find(line, "^[A-Z]+%s+(%w+)%s+([dcr])%s*$")
885
+ if stream and mode and stream == "stdout" then
886
+ -- assign "print" in the global environment
887
+ genv.print = mode == 'd' and iobase.print or coroutine.wrap(function(...)
888
+ -- wrapping into coroutine.wrap protects this function from
889
+ -- being stepped through in the debugger
890
+ local tbl = {...}
891
+ while true do
892
+ if mode == 'c' then iobase.print(unpack(tbl)) end
893
+ for n = 1, #tbl do
894
+ tbl[n] = select(2, pcall(serpent.line, tbl[n], {nocode = true, comment = false})) end
895
+ local file = table.concat(tbl, "\t").."\n"
896
+ server:send("204 Output " .. stream .. " " .. #file .. "\n" .. file)
897
+ tbl = {coroutine.yield()}
898
+ end
899
+ end)
900
+ server:send("200 OK\n")
901
+ else
902
+ server:send("400 Bad Request\n")
903
+ end
904
+ elseif command == "EXIT" then
905
+ server:send("200 OK\n")
906
+ coroutine.yield("exit")
907
+ else
908
+ server:send("400 Bad Request\n")
909
+ end
910
+ end
911
+ end
912
+
913
+ local function connect(controller_host, controller_port)
914
+ return (socket.connect4 or socket.connect)(controller_host, controller_port)
915
+ end
916
+
917
+ local function isrunning()
918
+ return coro_debugger and coroutine.status(coro_debugger) == 'suspended'
919
+ end
920
+
921
+ -- Starts a debug session by connecting to a controller
922
+ local function start(controller_host, controller_port)
923
+ -- only one debugging session can be run (as there is only one debug hook)
924
+ if isrunning() then return end
925
+
926
+ controller_host = controller_host or "localhost"
927
+ controller_port = controller_port or mobdebug.port
928
+
929
+ server = (socket.connect4 or socket.connect)(controller_host, controller_port)
930
+ if server then
931
+ rset = {server} -- store hash to avoid recreating it later
932
+ -- check if we are called from the debugger as this may happen
933
+ -- when another debugger function calls start(); only check one level deep
934
+ local this = debug.getinfo(1, "S").source
935
+ local info = debug.getinfo(2, "Sl")
936
+ if info.source == this then info = debug.getinfo(3, "Sl") end
937
+
938
+ local file = info.source
939
+ if string.find(file, "@") == 1 then file = string.sub(file, 2) end
940
+ if string.find(file, "%.[/\\]") == 1 then file = string.sub(file, 3) end
941
+
942
+ -- correct stack depth which already has some calls on it
943
+ -- so it doesn't go into negative when those calls return
944
+ -- as this breaks subsequence checks in stack_depth().
945
+ -- start from 16th frame, which is sufficiently large for this check.
946
+ stack_level = stack_depth(16)
947
+
948
+ -- provide our own traceback function to report the error remotely
949
+ do
950
+ local dtraceback = debug.traceback
951
+ debug.traceback = function (err) genv.print(dtraceback(err, 3)) end
952
+ end
953
+ coro_debugger = coroutine.create(debugger_loop)
954
+ debug.sethook(debug_hook, "lcr")
955
+ local ok, res = coroutine.resume(coro_debugger, file, info.currentline)
956
+ if not ok and res then error(res, 2) end
957
+ return true
958
+ else
959
+ print("Could not connect to " .. controller_host .. ":" .. controller_port)
960
+ end
961
+ end
962
+
963
+ local function controller(controller_host, controller_port)
964
+ -- only one debugging session can be run (as there is only one debug hook)
965
+ if isrunning() then return end
966
+
967
+ controller_host = controller_host or "localhost"
968
+ controller_port = controller_port or mobdebug.port
969
+
970
+ local exitonerror = not skip -- exit if not running a scratchpad
971
+ server = (socket.connect4 or socket.connect)(controller_host, controller_port)
972
+ if server then
973
+ rset = {server} -- store hash to avoid recreating it later
974
+
975
+ local function report(trace, err)
976
+ local msg = err .. "\n" .. trace
977
+ server:send("401 Error in Execution " .. #msg .. "\n")
978
+ server:send(msg)
979
+ return err
980
+ end
981
+
982
+ seen_hook = true -- allow to accept all commands
983
+ coro_debugger = coroutine.create(debugger_loop)
984
+
985
+ while true do
986
+ step_into = true -- start with step command
987
+ abort = false -- reset abort flag from the previous loop
988
+ if skip then skipcount = skip end -- force suspend right away
989
+
990
+ coro_debugee = coroutine.create(debugee)
991
+ debug.sethook(coro_debugee, debug_hook, "lcr")
992
+ local status, err = coroutine.resume(coro_debugee)
993
+
994
+ -- was there an error or is the script done?
995
+ -- 'abort' state is allowed here; ignore it
996
+ if abort then
997
+ if tostring(abort) == 'exit' then break end
998
+ else
999
+ if status then -- normal execution is done
1000
+ break
1001
+ elseif err and not tostring(err):find(deferror) then
1002
+ -- report the error back
1003
+ -- err is not necessarily a string, so convert to string to report
1004
+ report(debug.traceback(coro_debugee), tostring(err))
1005
+ if exitonerror then break end
1006
+ -- resume once more to clear the response the debugger wants to send
1007
+ local status, err = coroutine.resume(coro_debugger, events.RESTART, capture_vars(2))
1008
+ if not status or status and err == "exit" then break end
1009
+ end
1010
+ end
1011
+ end
1012
+ else
1013
+ print("Could not connect to " .. controller_host .. ":" .. controller_port)
1014
+ return false
1015
+ end
1016
+ return true
1017
+ end
1018
+
1019
+ local function scratchpad(controller_host, controller_port, frequency)
1020
+ skip = frequency or 100
1021
+ return controller(controller_host, controller_port)
1022
+ end
1023
+
1024
+ local function loop(controller_host, controller_port)
1025
+ skip = nil -- just in case if loop() is called after scratchpad()
1026
+ return controller(controller_host, controller_port)
1027
+ end
1028
+
1029
+ local function on()
1030
+ if not (isrunning() and server) then return end
1031
+
1032
+ local co = coroutine.running()
1033
+ if co then
1034
+ if not coroutines[co] then
1035
+ coroutines[co] = true
1036
+ debug.sethook(co, debug_hook, "lcr")
1037
+ end
1038
+ else
1039
+ debug.sethook(debug_hook, "lcr")
1040
+ end
1041
+ end
1042
+
1043
+ local function off()
1044
+ if not (isrunning() and server) then return end
1045
+
1046
+ local co = coroutine.running()
1047
+ if co then
1048
+ if coroutines[co] then coroutines[co] = false end
1049
+ -- don't remove coroutine hook under LuaJIT as there is only one (global) hook
1050
+ if not jit then debug.sethook(co) end
1051
+ else
1052
+ debug.sethook()
1053
+ end
1054
+ end
1055
+
1056
+ -- Handles server debugging commands
1057
+ local function handle(params, client, options)
1058
+ local _, _, command = string.find(params, "^([a-z]+)")
1059
+ local file, line, watch_idx
1060
+ if command == "run" or command == "step" or command == "out"
1061
+ or command == "over" or command == "exit" then
1062
+ client:send(string.upper(command) .. "\n")
1063
+ client:receive() -- this should consume the first '200 OK' response
1064
+ while true do
1065
+ local done = true
1066
+ local breakpoint = client:receive()
1067
+ if not breakpoint then
1068
+ print("Program finished")
1069
+ os.exit()
1070
+ return -- use return here for those cases where os.exit() is not wanted
1071
+ end
1072
+ local _, _, status = string.find(breakpoint, "^(%d+)")
1073
+ if status == "200" then
1074
+ -- don't need to do anything
1075
+ elseif status == "202" then
1076
+ _, _, file, line = string.find(breakpoint, "^202 Paused%s+(.-)%s+(%d+)%s*$")
1077
+ if file and line then
1078
+ print("Paused at file " .. file .. " line " .. line)
1079
+ end
1080
+ elseif status == "203" then
1081
+ _, _, file, line, watch_idx = string.find(breakpoint, "^203 Paused%s+(.-)%s+(%d+)%s+(%d+)%s*$")
1082
+ if file and line and watch_idx then
1083
+ print("Paused at file " .. file .. " line " .. line .. " (watch expression " .. watch_idx .. ": [" .. watches[watch_idx] .. "])")
1084
+ end
1085
+ elseif status == "204" then
1086
+ local _, _, stream, size = string.find(breakpoint, "^204 Output (%w+) (%d+)$")
1087
+ if stream and size then
1088
+ local msg = client:receive(tonumber(size))
1089
+ print(msg)
1090
+ if outputs[stream] then outputs[stream](msg) end
1091
+ -- this was just the output, so go back reading the response
1092
+ done = false
1093
+ end
1094
+ elseif status == "401" then
1095
+ local _, _, size = string.find(breakpoint, "^401 Error in Execution (%d+)$")
1096
+ if size then
1097
+ local msg = client:receive(tonumber(size))
1098
+ print("Error in remote application: " .. msg)
1099
+ os.exit(1)
1100
+ return nil, nil, msg -- use return here for those cases where os.exit() is not wanted
1101
+ end
1102
+ else
1103
+ print("Unknown error")
1104
+ os.exit(1)
1105
+ -- use return here for those cases where os.exit() is not wanted
1106
+ return nil, nil, "Debugger error: unexpected response '" .. breakpoint .. "'"
1107
+ end
1108
+ if done then break end
1109
+ end
1110
+ elseif command == "setb" then
1111
+ _, _, _, file, line = string.find(params, "^([a-z]+)%s+(.-)%s+(%d+)%s*$")
1112
+ if file and line then
1113
+ file = string.gsub(file, "\\", "/") -- convert slash
1114
+ file = removebasedir(file, basedir)
1115
+ client:send("SETB " .. file .. " " .. line .. "\n")
1116
+ if client:receive() == "200 OK" then
1117
+ if not breakpoints[file] then breakpoints[file] = {} end
1118
+ breakpoints[file][line] = true
1119
+ else
1120
+ print("Error: breakpoint not inserted")
1121
+ end
1122
+ else
1123
+ print("Invalid command")
1124
+ end
1125
+ elseif command == "setw" then
1126
+ local _, _, exp = string.find(params, "^[a-z]+%s+(.+)$")
1127
+ if exp then
1128
+ client:send("SETW " .. exp .. "\n")
1129
+ local answer = client:receive()
1130
+ local _, _, watch_idx = string.find(answer, "^200 OK (%d+)%s*$")
1131
+ if watch_idx then
1132
+ watches[watch_idx] = exp
1133
+ print("Inserted watch exp no. " .. watch_idx)
1134
+ else
1135
+ local _, _, size = string.find(answer, "^401 Error in Expression (%d+)$")
1136
+ if size then
1137
+ local err = client:receive(tonumber(size)):gsub(".-:%d+:%s*","")
1138
+ print("Error: watch expression not set: " .. err)
1139
+ else
1140
+ print("Error: watch expression not set")
1141
+ end
1142
+ end
1143
+ else
1144
+ print("Invalid command")
1145
+ end
1146
+ elseif command == "delb" then
1147
+ _, _, _, file, line = string.find(params, "^([a-z]+)%s+(.-)%s+(%d+)%s*$")
1148
+ if file and line then
1149
+ file = string.gsub(file, "\\", "/") -- convert slash
1150
+ file = removebasedir(file, basedir)
1151
+ client:send("DELB " .. file .. " " .. line .. "\n")
1152
+ if client:receive() == "200 OK" then
1153
+ if breakpoints[file] then breakpoints[file][line] = nil end
1154
+ else
1155
+ print("Error: breakpoint not removed")
1156
+ end
1157
+ else
1158
+ print("Invalid command")
1159
+ end
1160
+ elseif command == "delallb" then
1161
+ for file, breaks in pairs(breakpoints) do
1162
+ for line, _ in pairs(breaks) do
1163
+ client:send("DELB " .. file .. " " .. line .. "\n")
1164
+ if client:receive() == "200 OK" then
1165
+ breakpoints[file][line] = nil
1166
+ else
1167
+ print("Error: breakpoint at file " .. file .. " line " .. line .. " not removed")
1168
+ end
1169
+ end
1170
+ end
1171
+ elseif command == "delw" then
1172
+ local _, _, index = string.find(params, "^[a-z]+%s+(%d+)%s*$")
1173
+ if index then
1174
+ client:send("DELW " .. index .. "\n")
1175
+ if client:receive() == "200 OK" then
1176
+ watches[index] = nil
1177
+ else
1178
+ print("Error: watch expression not removed")
1179
+ end
1180
+ else
1181
+ print("Invalid command")
1182
+ end
1183
+ elseif command == "delallw" then
1184
+ for index, exp in pairs(watches) do
1185
+ client:send("DELW " .. index .. "\n")
1186
+ if client:receive() == "200 OK" then
1187
+ watches[index] = nil
1188
+ else
1189
+ print("Error: watch expression at index " .. index .. " [" .. exp .. "] not removed")
1190
+ end
1191
+ end
1192
+ elseif command == "eval" or command == "exec"
1193
+ or command == "load" or command == "loadstring"
1194
+ or command == "reload" then
1195
+ local _, _, exp = string.find(params, "^[a-z]+%s+(.+)$")
1196
+ if exp or (command == "reload") then
1197
+ if command == "eval" or command == "exec" then
1198
+ exp = (exp:gsub("%-%-%[(=*)%[.-%]%1%]", "") -- remove comments
1199
+ :gsub("%-%-.-\n", " ") -- remove line comments
1200
+ :gsub("\n", " ")) -- convert new lines
1201
+ if command == "eval" then exp = "return " .. exp end
1202
+ client:send("EXEC " .. exp .. "\n")
1203
+ elseif command == "reload" then
1204
+ client:send("LOAD 0 -\n")
1205
+ elseif command == "loadstring" then
1206
+ local _, _, _, file, lines = string.find(exp, "^([\"'])(.-)%1%s+(.+)")
1207
+ if not file then
1208
+ _, _, file, lines = string.find(exp, "^(%S+)%s+(.+)")
1209
+ end
1210
+ client:send("LOAD " .. #lines .. " " .. file .. "\n")
1211
+ client:send(lines)
1212
+ else
1213
+ local file = io.open(exp, "r")
1214
+ if not file and pcall(require, "winapi") then
1215
+ -- if file is not open and winapi is there, try with a short path;
1216
+ -- this may be needed for unicode paths on windows
1217
+ winapi.set_encoding(winapi.CP_UTF8)
1218
+ file = io.open(winapi.short_path(exp), "r")
1219
+ end
1220
+ if not file then error("Cannot open file " .. exp) end
1221
+ -- read the file and remove the shebang line as it causes a compilation error
1222
+ local lines = file:read("*all"):gsub("^#!.-\n", "\n")
1223
+ file:close()
1224
+
1225
+ local file = string.gsub(exp, "\\", "/") -- convert slash
1226
+ file = removebasedir(file, basedir)
1227
+ client:send("LOAD " .. #lines .. " " .. file .. "\n")
1228
+ client:send(lines)
1229
+ end
1230
+ while true do
1231
+ local params, err = client:receive()
1232
+ if not params then
1233
+ return nil, nil, "Debugger connection " .. (err or "error")
1234
+ end
1235
+ local done = true
1236
+ local _, _, status, len = string.find(params, "^(%d+).-%s+(%d+)%s*$")
1237
+ if status == "200" then
1238
+ len = tonumber(len)
1239
+ if len > 0 then
1240
+ local status, res
1241
+ local str = client:receive(len)
1242
+ -- handle serialized table with results
1243
+ local func, err = loadstring(str)
1244
+ if func then
1245
+ status, res = pcall(func)
1246
+ if not status then err = res
1247
+ elseif type(res) ~= "table" then
1248
+ err = "received "..type(res).." instead of expected 'table'"
1249
+ end
1250
+ end
1251
+ if err then
1252
+ print("Error in processing results: " .. err)
1253
+ return nil, nil, "Error in processing results: " .. err
1254
+ end
1255
+ print((table.unpack or unpack)(res))
1256
+ return res[1], res
1257
+ end
1258
+ elseif status == "201" then
1259
+ _, _, file, line = string.find(params, "^201 Started%s+(.-)%s+(%d+)%s*$")
1260
+ elseif status == "202" or params == "200 OK" then
1261
+ -- do nothing; this only happens when RE/LOAD command gets the response
1262
+ -- that was for the original command that was aborted
1263
+ elseif status == "204" then
1264
+ local _, _, stream, size = string.find(params, "^204 Output (%w+) (%d+)$")
1265
+ if stream and size then
1266
+ local msg = client:receive(tonumber(size))
1267
+ print(msg)
1268
+ if outputs[stream] then outputs[stream](msg) end
1269
+ -- this was just the output, so go back reading the response
1270
+ done = false
1271
+ end
1272
+ elseif status == "401" then
1273
+ len = tonumber(len)
1274
+ local res = client:receive(len)
1275
+ print("Error in expression: " .. res)
1276
+ return nil, nil, res
1277
+ else
1278
+ print("Unknown error")
1279
+ return nil, nil, "Debugger error: unexpected response after EXEC/LOAD '" .. params .. "'"
1280
+ end
1281
+ if done then break end
1282
+ end
1283
+ else
1284
+ print("Invalid command")
1285
+ end
1286
+ elseif command == "listb" then
1287
+ for k, v in pairs(breakpoints) do
1288
+ local b = k .. ": " -- get filename
1289
+ for k in pairs(v) do
1290
+ b = b .. k .. " " -- get line numbers
1291
+ end
1292
+ print(b)
1293
+ end
1294
+ elseif command == "listw" then
1295
+ for i, v in pairs(watches) do
1296
+ print("Watch exp. " .. i .. ": " .. v)
1297
+ end
1298
+ elseif command == "suspend" then
1299
+ client:send("SUSPEND\n")
1300
+ elseif command == "stack" then
1301
+ client:send("STACK\n")
1302
+ local resp = client:receive()
1303
+ local _, _, status, res = string.find(resp, "^(%d+)%s+%w+%s+(.+)%s*$")
1304
+ if status == "200" then
1305
+ local func, err = loadstring(res)
1306
+ if func == nil then
1307
+ print("Error in stack information: " .. err)
1308
+ return nil, nil, err
1309
+ end
1310
+ local ok, stack = pcall(func)
1311
+ if not ok then
1312
+ print("Error in stack information: " .. stack)
1313
+ return nil, nil, stack
1314
+ end
1315
+ for _,frame in ipairs(stack) do
1316
+ print(serpent.line(frame[1], {comment = false}))
1317
+ end
1318
+ return stack
1319
+ elseif status == "401" then
1320
+ local _, _, len = string.find(resp, "%s+(%d+)%s*$")
1321
+ len = tonumber(len)
1322
+ local res = len > 0 and client:receive(len) or "Invalid stack information."
1323
+ print("Error in expression: " .. res)
1324
+ return nil, nil, res
1325
+ else
1326
+ print("Unknown error")
1327
+ return nil, nil, "Debugger error: unexpected response after STACK"
1328
+ end
1329
+ elseif command == "output" then
1330
+ local _, _, stream, mode = string.find(params, "^[a-z]+%s+(%w+)%s+([dcr])%s*$")
1331
+ if stream and mode then
1332
+ client:send("OUTPUT "..stream.." "..mode.."\n")
1333
+ local resp = client:receive()
1334
+ local _, _, status = string.find(resp, "^(%d+)%s+%w+%s*$")
1335
+ if status == "200" then
1336
+ print("Stream "..stream.." redirected")
1337
+ outputs[stream] = type(options) == 'table' and options.handler or nil
1338
+ else
1339
+ print("Unknown error")
1340
+ return nil, nil, "Debugger error: can't redirect "..stream
1341
+ end
1342
+ else
1343
+ print("Invalid command")
1344
+ end
1345
+ elseif command == "basedir" then
1346
+ local _, _, dir = string.find(params, "^[a-z]+%s+(.+)$")
1347
+ if dir then
1348
+ dir = string.gsub(dir, "\\", "/") -- convert slash
1349
+ if not string.find(dir, "/$") then dir = dir .. "/" end
1350
+
1351
+ local remdir = dir:match("\t(.+)")
1352
+ if remdir then dir = dir:gsub("/?\t.+", "/") end
1353
+ basedir = dir
1354
+
1355
+ client:send("BASEDIR "..(remdir or dir).."\n")
1356
+ local resp = client:receive()
1357
+ local _, _, status = string.find(resp, "^(%d+)%s+%w+%s*$")
1358
+ if status == "200" then
1359
+ print("New base directory is " .. basedir)
1360
+ else
1361
+ print("Unknown error")
1362
+ return nil, nil, "Debugger error: unexpected response after BASEDIR"
1363
+ end
1364
+ else
1365
+ print(basedir)
1366
+ end
1367
+ elseif command == "help" then
1368
+ print("setb <file> <line> -- sets a breakpoint")
1369
+ print("delb <file> <line> -- removes a breakpoint")
1370
+ print("delallb -- removes all breakpoints")
1371
+ print("setw <exp> -- adds a new watch expression")
1372
+ print("delw <index> -- removes the watch expression at index")
1373
+ print("delallw -- removes all watch expressions")
1374
+ print("run -- runs until next breakpoint")
1375
+ print("step -- runs until next line, stepping into function calls")
1376
+ print("over -- runs until next line, stepping over function calls")
1377
+ print("out -- runs until line after returning from current function")
1378
+ print("listb -- lists breakpoints")
1379
+ print("listw -- lists watch expressions")
1380
+ print("eval <exp> -- evaluates expression on the current context and returns its value")
1381
+ print("exec <stmt> -- executes statement on the current context")
1382
+ print("load <file> -- loads a local file for debugging")
1383
+ print("reload -- restarts the current debugging session")
1384
+ print("stack -- reports stack trace")
1385
+ print("output stdout <d|c|r> -- capture and redirect io stream (default|copy|redirect)")
1386
+ print("basedir [<path>] -- sets the base path of the remote application, or shows the current one")
1387
+ print("exit -- exits debugger")
1388
+ else
1389
+ local _, _, spaces = string.find(params, "^(%s*)$")
1390
+ if not spaces then
1391
+ print("Invalid command")
1392
+ return nil, nil, "Invalid command"
1393
+ end
1394
+ end
1395
+ return file, line
1396
+ end
1397
+
1398
+ -- Starts debugging server
1399
+ local function listen(host, port)
1400
+ host = host or "*"
1401
+ port = port or mobdebug.port
1402
+
1403
+ local socket = require "socket"
1404
+
1405
+ print("Lua Remote Debugger")
1406
+ print("Run the program you wish to debug")
1407
+
1408
+ local server = socket.bind(host, port)
1409
+ local client = server:accept()
1410
+
1411
+ client:send("STEP\n")
1412
+ client:receive()
1413
+
1414
+ local breakpoint = client:receive()
1415
+ local _, _, file, line = string.find(breakpoint, "^202 Paused%s+(.-)%s+(%d+)%s*$")
1416
+ if file and line then
1417
+ print("Paused at file " .. file )
1418
+ print("Type 'help' for commands")
1419
+ else
1420
+ local _, _, size = string.find(breakpoint, "^401 Error in Execution (%d+)%s*$")
1421
+ if size then
1422
+ print("Error in remote application: ")
1423
+ print(client:receive(size))
1424
+ end
1425
+ end
1426
+
1427
+ while true do
1428
+ io.write("> ")
1429
+ local line = io.read("*line")
1430
+ handle(line, client)
1431
+ end
1432
+ end
1433
+
1434
+ local cocreate
1435
+ local function coro()
1436
+ if cocreate then return end -- only set once
1437
+ cocreate = cocreate or coroutine.create
1438
+ coroutine.create = function(f, ...)
1439
+ return cocreate(function(...)
1440
+ require("mobdebug").on()
1441
+ return f(...)
1442
+ end, ...)
1443
+ end
1444
+ end
1445
+
1446
+ local moconew
1447
+ local function moai()
1448
+ if moconew then return end -- only set once
1449
+ moconew = moconew or (MOAICoroutine and MOAICoroutine.new)
1450
+ if not moconew then return end
1451
+ MOAICoroutine.new = function(...)
1452
+ local thread = moconew(...)
1453
+ local mt = getmetatable(thread)
1454
+ local patched = mt.run
1455
+ mt.run = function(self, f, ...)
1456
+ return patched(self, function(...)
1457
+ require("mobdebug").on()
1458
+ return f(...)
1459
+ end, ...)
1460
+ end
1461
+ return thread
1462
+ end
1463
+ end
1464
+
1465
+ -- make public functions available
1466
+ mobdebug.listen = listen
1467
+ mobdebug.loop = loop
1468
+ mobdebug.scratchpad = scratchpad
1469
+ mobdebug.handle = handle
1470
+ mobdebug.connect = connect
1471
+ mobdebug.start = start
1472
+ mobdebug.on = on
1473
+ mobdebug.off = off
1474
+ mobdebug.moai = moai
1475
+ mobdebug.coro = coro
1476
+ mobdebug.line = serpent.line
1477
+ mobdebug.dump = serpent.dump
1478
+ mobdebug.yield = nil -- callback
1479
+
1480
+ -- this is needed to make "require 'modebug'" to work when mobdebug
1481
+ -- module is loaded manually
1482
+ package.loaded.mobdebug = mobdebug
1483
+
1484
+ return mobdebug