/limdebug/controller.lua

https://github.com/AdUki/LimLim · Lua · 382 lines · 287 code · 34 blank · 61 comment · 114 complexity · 9f8dec2d2708b45ca4ebb5982a926c82 MD5 · raw file

  1. #! /usr/bin/lua
  2. -- RemDebug 1.0
  3. -- Copyright Kepler Project 2005-2007 (http://www.keplerproject.org/remdebug)
  4. --
  5. -- Modified 2011-2012 for LuaIDE project by Simon Mikuda to LimDebug
  6. -- Bachelor project on STU Fiit
  7. -- Project manager: Ing. Michal Kottman
  8. -- Copyright Simon Mikuda STU Fiit 2012
  9. --
  10. print "LimDebug controller"
  11. local socket = require "socket"
  12. local server = socket.bind("*", 8172)
  13. if server == nil then
  14. print "Error: Remdebug already running"
  15. os.exit()
  16. else
  17. print "Start program you want to debug:"
  18. end
  19. local client = server:accept()
  20. local breakpoints = {}
  21. local watches = {}
  22. client:send("STEP\n")
  23. client:receive()
  24. local breakpoint = client:receive()
  25. local _, _, file, line = string.find(breakpoint, "^202 Paused%s+([%w%p]+)%s+(%d+)$")
  26. if file and line then
  27. print("Paused:" .. " file " .. file )
  28. else
  29. local _, _, size = string.find(breakpoint, "^401 Error in Execution (%d+)$")
  30. if size then
  31. print("Error in remote application: ")
  32. print(client:receive(size))
  33. end
  34. end
  35. local basedir = ""
  36. while true do
  37. io.write("> ")
  38. --io.flush()
  39. -- Read new command
  40. local line = io.read("*line")
  41. local _, _, command = string.find(line, "^([a-z]+)")
  42. --
  43. -- RUN, STEP, OVER commands
  44. --
  45. if command == "run" or command == "step" or command == "over" then
  46. client:send(string.upper(command) .. "\n")
  47. client:receive()
  48. local breakpoint = client:receive()
  49. if not breakpoint then
  50. os.exit()
  51. end
  52. local _, _, status = string.find(breakpoint, "^(%d+)")
  53. if status == "202" then
  54. local _, _, file, line = string.find(breakpoint, "^202 Paused (.+) (%d+)$")
  55. if file and line then
  56. print("Paused:" .. " line " .. line .. " file " .. file)
  57. end
  58. elseif status == "203" then
  59. local _, _, file, line, watch_idx = string.find(breakpoint, "^203 Paused (.+) (%d+) (%d+)$")
  60. if file and line and watch_idx then
  61. print("Paused:" .. " line " .. line .. " watch " .. watch_idx .. " file " .. file)
  62. end
  63. elseif status == "401" then
  64. local _, _, size = string.find(breakpoint, "^401 Error in Execution (%d+)$")
  65. if size then
  66. print("Error in remote application: ")
  67. print(client:receive(tonumber(size)))
  68. os.exit()
  69. end
  70. else
  71. print("Error: Unknown error")
  72. os.exit()
  73. end
  74. --
  75. -- EXIT command
  76. --
  77. elseif command == "exit" then
  78. client:close()
  79. os.exit()
  80. --
  81. -- SETB command
  82. --
  83. elseif command == "setb" then
  84. local _, _, filename, line = string.find(line, "^.... (.+) (%d+)$")
  85. if filename and line then
  86. filename = basedir .. filename
  87. if not breakpoints[filename] then breakpoints[filename] = {} end
  88. client:send("SETB " .. filename .. " " .. line .. "\n")
  89. if client:receive() == "200 OK" then
  90. breakpoints[filename][line] = true
  91. else
  92. print("Error: breakpoint not inserted")
  93. end
  94. else
  95. print("Error: Invalid command")
  96. end
  97. --
  98. -- SETW command
  99. --
  100. elseif command == "setw" then
  101. local _, _, exp = string.find(line, "^[a-z]+%s+(.+)$")
  102. if exp then
  103. client:send("SETW " .. exp .. "\n")
  104. local answer = client:receive()
  105. local _, _, watch_idx = string.find(answer, "^200 OK (%d+)$")
  106. if watch_idx then
  107. watches[watch_idx] = exp
  108. print("Watch: " .. watch_idx)
  109. else
  110. print("Error: Watch expression not inserted")
  111. end
  112. else
  113. print("Error: Invalid command")
  114. end
  115. --
  116. -- DELB command
  117. --
  118. elseif command == "delb" then
  119. local _, _, filename, line = string.find(line, "^.... (.+) (%d+)$")
  120. if filename and line then
  121. filename = basedir .. filename
  122. if not breakpoints[filename] then breakpoints[filename] = {} end
  123. client:send("DELB " .. filename .. " " .. line .. "\n")
  124. if client:receive() == "200 OK" then
  125. breakpoints[filename][line] = nil
  126. else
  127. print("Error: breakpoint not removed")
  128. end
  129. else
  130. print("Error: Invalid command")
  131. end
  132. --
  133. -- DELALLB command
  134. --
  135. elseif command == "delallb" then
  136. for filename, breaks in pairs(breakpoints) do
  137. for line, _ in pairs(breaks) do
  138. client:send("DELB " .. filename .. " " .. line .. "\n")
  139. if client:receive() == "200 OK" then
  140. breakpoints[filename][line] = nil
  141. else
  142. print("Error: breakpoint at file " .. filename .. " line " .. line .. " not removed")
  143. end
  144. end
  145. end
  146. --
  147. -- DELW command
  148. --
  149. elseif command == "delw" then
  150. local _, _, index = string.find(line, "^[a-z]+%s+(%d+)$")
  151. if index then
  152. client:send("DELW " .. index .. "\n")
  153. if client:receive() == "200 OK" then
  154. watches[index] = nil
  155. else
  156. print("Error: watch expression not removed")
  157. end
  158. else
  159. print("Error: Invalid command")
  160. end
  161. elseif command == "delallw" then
  162. for index, exp in pairs(watches) do
  163. client:send("DELW " .. index .. "\n")
  164. if client:receive() == "200 OK" then
  165. watches[index] = nil
  166. else
  167. print("Error: watch expression at index " .. index .. " [" .. exp .. "] not removed")
  168. end
  169. end
  170. --
  171. -- EVAL command
  172. --
  173. elseif command == "eval" then
  174. local _, _, exp = string.find(line, "^%a+%s+(.+)$")
  175. if exp then
  176. client:send("EVAL return " .. exp .. ", 1\n")
  177. local line = client:receive()
  178. local _, _, status, len = string.find(line, "^(%d+)[a-zA-Z ]+%s*(%d+)$")
  179. if status == "200" then
  180. len = tonumber(len)
  181. local res = client:receive(len)
  182. print("Evaluate: " .. res)
  183. elseif status == "401" then
  184. len = tonumber(len)
  185. local res = client:receive(len)
  186. print("Error: Invalid expression:" .. res)
  187. else
  188. print("Error: Unknown error")
  189. end
  190. else
  191. print("Error: Invalid command")
  192. end
  193. --
  194. -- TABLE command
  195. --
  196. elseif command == "table" then
  197. local _, _, exp = string.find(line, "^[a-z]+%s+(.+)$")
  198. if exp then
  199. client:send("TABLE " .. exp .. "\n")
  200. local line = client:receive()
  201. local _, _, status, len = string.find(line, "^(%d+)[a-zA-Z ]+%s*(%d+)$")
  202. if status == "200" then
  203. len = tonumber(len)
  204. local res = client:receive(len)
  205. io.write("Table: " .. res)
  206. elseif status == "401" then
  207. len = tonumber(len)
  208. local res = client:receive(len)
  209. print("Error: Invalid expression:" .. res)
  210. else
  211. print("Error: Unknown error")
  212. end
  213. else
  214. print("Error: Invalid command")
  215. end
  216. --
  217. -- TRACEBACK command
  218. --
  219. elseif command == "traceback" then
  220. client:send("TRACEBACK\n")
  221. local line = client:receive()
  222. local _, _, status, len = string.find(line, "^(%d+)[a-zA-Z ]+%s*(%d+)$")
  223. if status == "200" then
  224. len = tonumber(len)
  225. local res = client:receive(len)
  226. print(res)
  227. elseif status == "401" then
  228. len = tonumber(len)
  229. local res = client:receive(len)
  230. print("Error: Invalid expression:" .. res)
  231. else
  232. print("Error: Unknown error")
  233. end
  234. --
  235. -- LOCAL command
  236. --
  237. elseif command == "local" then
  238. client:send("LOCAL\n")
  239. local line = client:receive()
  240. local _, _, status, len = string.find(line, "^(%d+)[a-zA-Z ]+%s*(%d+)$")
  241. if status == "200" then
  242. len = tonumber(len)
  243. local res = client:receive(len)
  244. io.write("Local: " .. res)
  245. elseif status == "401" then
  246. len = tonumber(len)
  247. local res = client:receive(len)
  248. print("Error: Invalid expression:" .. res)
  249. else
  250. print("Error: Unknown error")
  251. end
  252. --
  253. -- GLOBAL command
  254. --
  255. elseif command == "global" then
  256. client:send("GLOBAL\n")
  257. local line = client:receive()
  258. local _, _, status, len = string.find(line, "^(%d+)[a-zA-Z ]+%s*(%d+)$")
  259. if status == "200" then
  260. len = tonumber(len)
  261. local res = client:receive(len)
  262. io.write("Global: " .. res)
  263. elseif status == "401" then
  264. len = tonumber(len)
  265. local res = client:receive(len)
  266. print("Error: Invalid expression:" .. res)
  267. else
  268. print("Error: Unknown error")
  269. end
  270. --
  271. -- EXEC command
  272. --
  273. elseif command == "exec" then
  274. local _, _, exp = string.find(line, "^[a-z]+%s+(.+)$")
  275. if exp then
  276. client:send("EXEC " .. exp .. "\n")
  277. local line = client:receive()
  278. local _, _, status, len = string.find(line, "^(%d+)[%s%w]+ (%d+)$")
  279. if status == "200" then
  280. elseif status == "401" then
  281. len = tonumber(len)
  282. local res = client:receive(len)
  283. print("Error: Invalid expression" .. res)
  284. else
  285. print("Error: Unknown error")
  286. end
  287. else
  288. print("Error: Invalid command")
  289. end
  290. --
  291. -- LISTB command
  292. --
  293. elseif command == "listb" then
  294. for k, v in pairs(breakpoints) do
  295. io.write(k .. ": ")
  296. for k, v in pairs(v) do
  297. io.write(k .. " ")
  298. end
  299. io.write("\n")
  300. end
  301. --
  302. -- LISTW command
  303. --
  304. elseif command == "listw" then
  305. for i, v in pairs(watches) do
  306. print("Watch exp. " .. i .. ": " .. v)
  307. end
  308. --
  309. -- BASEDIR command
  310. --
  311. elseif command == "basedir" then
  312. local _, _, dir = string.find(line, "^[a-z]+%s+(.+)$")
  313. if dir then
  314. dir = string.gsub(dir, "\\", "/")
  315. if not string.find(dir, "/$") then dir = dir .. "/" end
  316. basedir = dir
  317. print("New base directory is " .. basedir)
  318. else
  319. print(basedir)
  320. end
  321. --
  322. -- HELP command
  323. --
  324. elseif command == "help" then
  325. print("setb <file> <line> -- sets a breakpoint")
  326. print("delb <file> <line> -- removes a breakpoint")
  327. print("delallb -- removes all breakpoints")
  328. print("setw <exp> -- adds a new watch expression")
  329. print("delw <index> -- removes the watch expression at index")
  330. print("delallw -- removes all watch expressions")
  331. print("run -- run until next breakpoint")
  332. print("step -- run until next line, stepping into function calls")
  333. print("over -- run until next line, stepping over function calls")
  334. print("listb -- lists breakpoints")
  335. print("listw -- lists watch expressions")
  336. print("eval <exp> -- evaluates expression on the current context and returns its value")
  337. print("exec <stmt> -- executes statement on the current context")
  338. print("table <name> -- ")
  339. print("traceback -- ")
  340. print("basedir [<path>] -- sets the base path of the remote application, or shows the current one")
  341. print("exit -- exits debugger")
  342. else
  343. local _, _, spaces = string.find(line, "^(%s*)$")
  344. if not spaces then
  345. print("Error: Invalid command")
  346. end
  347. end
  348. end