rufus-lua-win 5.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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