rb8-trepanning 0.1.3-universal-ruby-1.9.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (274) hide show
  1. data/.gitignore +3 -0
  2. data/CHANGES +34 -0
  3. data/ChangeLog +875 -0
  4. data/README.textile +59 -0
  5. data/Rakefile +215 -0
  6. data/app/.gitignore +1 -0
  7. data/app/cmd_parse.kpeg +241 -0
  8. data/app/cmd_parse.rb +212 -0
  9. data/app/cmd_parser.rb +1948 -0
  10. data/app/complete.rb +79 -0
  11. data/app/default.rb +90 -0
  12. data/app/display.rb +148 -0
  13. data/app/eventbuffer.rb +147 -0
  14. data/app/frame.rb +166 -0
  15. data/app/irb.rb +114 -0
  16. data/app/options.rb +200 -0
  17. data/app/run.rb +74 -0
  18. data/app/util.rb +65 -0
  19. data/bin/.gitignore +1 -0
  20. data/bin/trepan8 +115 -0
  21. data/data/.gitignore +1 -0
  22. data/data/irbrc +41 -0
  23. data/interface/.gitignore +1 -0
  24. data/interface/base_intf.rb +109 -0
  25. data/interface/client.rb +82 -0
  26. data/interface/comcodes.rb +20 -0
  27. data/interface/script.rb +110 -0
  28. data/interface/server.rb +147 -0
  29. data/interface/user.rb +165 -0
  30. data/io/base_io.rb +148 -0
  31. data/io/input.rb +158 -0
  32. data/io/null_output.rb +46 -0
  33. data/io/string_array.rb +156 -0
  34. data/io/tcpclient.rb +129 -0
  35. data/io/tcpfns.rb +33 -0
  36. data/io/tcpserver.rb +141 -0
  37. data/lib/debugger.rb +8 -0
  38. data/lib/trepanning.rb +283 -0
  39. data/processor/.gitignore +1 -0
  40. data/processor/command-ruby-debug/breakpoints.rb +155 -0
  41. data/processor/command-ruby-debug/catchpoint.rb +55 -0
  42. data/processor/command-ruby-debug/condition.rb +49 -0
  43. data/processor/command-ruby-debug/control.rb +31 -0
  44. data/processor/command-ruby-debug/display.rb +120 -0
  45. data/processor/command-ruby-debug/enable.rb +202 -0
  46. data/processor/command-ruby-debug/frame.rb +199 -0
  47. data/processor/command-ruby-debug/help.rb +63 -0
  48. data/processor/command-ruby-debug/info.rb +359 -0
  49. data/processor/command-ruby-debug/method.rb +84 -0
  50. data/processor/command-ruby-debug/reload.rb +40 -0
  51. data/processor/command-ruby-debug/save.rb +90 -0
  52. data/processor/command-ruby-debug/set.rb +237 -0
  53. data/processor/command-ruby-debug/show.rb +251 -0
  54. data/processor/command-ruby-debug/source.rb +36 -0
  55. data/processor/command-ruby-debug/threads.rb +189 -0
  56. data/processor/command-ruby-debug/trace.rb +57 -0
  57. data/processor/command-ruby-debug/variables.rb +199 -0
  58. data/processor/command.rb +270 -0
  59. data/processor/command/.gitignore +1 -0
  60. data/processor/command/alias.rb +54 -0
  61. data/processor/command/backtrace.rb +123 -0
  62. data/processor/command/base/cmd.rb +177 -0
  63. data/processor/command/base/subcmd.rb +230 -0
  64. data/processor/command/base/submgr.rb +188 -0
  65. data/processor/command/base/subsubcmd.rb +128 -0
  66. data/processor/command/base/subsubmgr.rb +199 -0
  67. data/processor/command/break.rb +114 -0
  68. data/processor/command/catch.rb +71 -0
  69. data/processor/command/complete.rb +39 -0
  70. data/processor/command/continue.rb +57 -0
  71. data/processor/command/directory.rb +50 -0
  72. data/processor/command/disable.rb +85 -0
  73. data/processor/command/display.rb +78 -0
  74. data/processor/command/down.rb +54 -0
  75. data/processor/command/edit.rb +79 -0
  76. data/processor/command/enable.rb +48 -0
  77. data/processor/command/eval.rb +90 -0
  78. data/processor/command/exit.rb +66 -0
  79. data/processor/command/finish.rb +59 -0
  80. data/processor/command/frame.rb +97 -0
  81. data/processor/command/help.rb +230 -0
  82. data/processor/command/help/.gitignore +1 -0
  83. data/processor/command/help/README +10 -0
  84. data/processor/command/help/command.txt +58 -0
  85. data/processor/command/help/examples.txt +16 -0
  86. data/processor/command/help/filename.txt +40 -0
  87. data/processor/command/help/location.txt +37 -0
  88. data/processor/command/help/suffixes.txt +17 -0
  89. data/processor/command/info.rb +28 -0
  90. data/processor/command/info_subcmd/.gitignore +1 -0
  91. data/processor/command/info_subcmd/args.rb +39 -0
  92. data/processor/command/info_subcmd/breakpoints.rb +80 -0
  93. data/processor/command/info_subcmd/catch.rb +36 -0
  94. data/processor/command/info_subcmd/files.rb +39 -0
  95. data/processor/command/info_subcmd/globals.rb +64 -0
  96. data/processor/command/info_subcmd/line.rb +30 -0
  97. data/processor/command/info_subcmd/locals.rb +69 -0
  98. data/processor/command/info_subcmd/macro.rb +62 -0
  99. data/processor/command/info_subcmd/program.rb +51 -0
  100. data/processor/command/info_subcmd/ruby.rb +57 -0
  101. data/processor/command/info_subcmd/source.rb +74 -0
  102. data/processor/command/info_subcmd/stack.rb +25 -0
  103. data/processor/command/info_subcmd/threads.rb +75 -0
  104. data/processor/command/kill.rb +78 -0
  105. data/processor/command/list.rb +117 -0
  106. data/processor/command/macro.rb +68 -0
  107. data/processor/command/next.rb +79 -0
  108. data/processor/command/parsetree.rb +56 -0
  109. data/processor/command/pp.rb +40 -0
  110. data/processor/command/pr.rb +37 -0
  111. data/processor/command/ps.rb +40 -0
  112. data/processor/command/restart.rb +86 -0
  113. data/processor/command/save.rb +58 -0
  114. data/processor/command/set.rb +47 -0
  115. data/processor/command/set_subcmd/.gitignore +1 -0
  116. data/processor/command/set_subcmd/abbrev.rb +25 -0
  117. data/processor/command/set_subcmd/auto.rb +27 -0
  118. data/processor/command/set_subcmd/auto_subcmd/.gitignore +1 -0
  119. data/processor/command/set_subcmd/auto_subcmd/eval.rb +53 -0
  120. data/processor/command/set_subcmd/auto_subcmd/irb.rb +33 -0
  121. data/processor/command/set_subcmd/auto_subcmd/list.rb +33 -0
  122. data/processor/command/set_subcmd/basename.rb +25 -0
  123. data/processor/command/set_subcmd/callstyle.rb +46 -0
  124. data/processor/command/set_subcmd/confirm.rb +24 -0
  125. data/processor/command/set_subcmd/debug.rb +47 -0
  126. data/processor/command/set_subcmd/different.rb +61 -0
  127. data/processor/command/set_subcmd/highlight.rb +43 -0
  128. data/processor/command/set_subcmd/max.rb +26 -0
  129. data/processor/command/set_subcmd/max_subcmd/list.rb +49 -0
  130. data/processor/command/set_subcmd/max_subcmd/stack.rb +50 -0
  131. data/processor/command/set_subcmd/max_subcmd/string.rb +76 -0
  132. data/processor/command/set_subcmd/max_subcmd/width.rb +49 -0
  133. data/processor/command/set_subcmd/reload.rb +42 -0
  134. data/processor/command/set_subcmd/timer.rb +58 -0
  135. data/processor/command/set_subcmd/trace.rb +37 -0
  136. data/processor/command/set_subcmd/trace_subcmd/buffer.rb +42 -0
  137. data/processor/command/set_subcmd/trace_subcmd/print.rb +41 -0
  138. data/processor/command/shell.rb +139 -0
  139. data/processor/command/show.rb +39 -0
  140. data/processor/command/show_subcmd/.gitignore +1 -0
  141. data/processor/command/show_subcmd/abbrev.rb +20 -0
  142. data/processor/command/show_subcmd/alias.rb +46 -0
  143. data/processor/command/show_subcmd/args.rb +34 -0
  144. data/processor/command/show_subcmd/auto.rb +28 -0
  145. data/processor/command/show_subcmd/auto_subcmd/eval.rb +27 -0
  146. data/processor/command/show_subcmd/auto_subcmd/irb.rb +23 -0
  147. data/processor/command/show_subcmd/auto_subcmd/list.rb +22 -0
  148. data/processor/command/show_subcmd/basename.rb +20 -0
  149. data/processor/command/show_subcmd/callstyle.rb +22 -0
  150. data/processor/command/show_subcmd/confirm.rb +18 -0
  151. data/processor/command/show_subcmd/debug.rb +26 -0
  152. data/processor/command/show_subcmd/debug_subcmd/dbgr.rb +21 -0
  153. data/processor/command/show_subcmd/debug_subcmd/skip.rb +22 -0
  154. data/processor/command/show_subcmd/debug_subcmd/step.rb +22 -0
  155. data/processor/command/show_subcmd/different.rb +26 -0
  156. data/processor/command/show_subcmd/directories.rb +22 -0
  157. data/processor/command/show_subcmd/highlight.rb +24 -0
  158. data/processor/command/show_subcmd/max.rb +27 -0
  159. data/processor/command/show_subcmd/max_subcmd/list.rb +38 -0
  160. data/processor/command/show_subcmd/max_subcmd/stack.rb +36 -0
  161. data/processor/command/show_subcmd/max_subcmd/string.rb +42 -0
  162. data/processor/command/show_subcmd/max_subcmd/width.rb +37 -0
  163. data/processor/command/show_subcmd/reload.rb +18 -0
  164. data/processor/command/show_subcmd/timer.rb +18 -0
  165. data/processor/command/show_subcmd/trace.rb +29 -0
  166. data/processor/command/show_subcmd/trace_subcmd/buffer.rb +65 -0
  167. data/processor/command/show_subcmd/trace_subcmd/print.rb +23 -0
  168. data/processor/command/show_subcmd/version.rb +23 -0
  169. data/processor/command/source.rb +134 -0
  170. data/processor/command/step.rb +81 -0
  171. data/processor/command/tbreak.rb +19 -0
  172. data/processor/command/unalias.rb +44 -0
  173. data/processor/command/undisplay.rb +59 -0
  174. data/processor/command/up.rb +72 -0
  175. data/processor/default.rb +56 -0
  176. data/processor/display.rb +17 -0
  177. data/processor/eval.rb +113 -0
  178. data/processor/eventbuf.rb +105 -0
  179. data/processor/frame.rb +172 -0
  180. data/processor/help.rb +92 -0
  181. data/processor/helper.rb +76 -0
  182. data/processor/hook.rb +134 -0
  183. data/processor/load_cmds.rb +258 -0
  184. data/processor/location.rb +174 -0
  185. data/processor/main.rb +455 -0
  186. data/processor/mock.rb +136 -0
  187. data/processor/msg.rb +61 -0
  188. data/processor/processor.rb +674 -0
  189. data/processor/running.rb +168 -0
  190. data/processor/stepping.rb +18 -0
  191. data/processor/subcmd.rb +161 -0
  192. data/processor/validate.rb +355 -0
  193. data/processor/virtual.rb +34 -0
  194. data/test/data/.gitignore +1 -0
  195. data/test/data/break_bad.cmd +19 -0
  196. data/test/data/break_bad.right +29 -0
  197. data/test/data/break_loop_bug.cmd +5 -0
  198. data/test/data/break_loop_bug.right +15 -0
  199. data/test/data/dollar-0.right +2 -0
  200. data/test/data/dollar-0a.right +2 -0
  201. data/test/data/dollar-0b.right +2 -0
  202. data/test/data/edit.cmd +14 -0
  203. data/test/data/edit.right +24 -0
  204. data/test/data/file-with-space.cmd +6 -0
  205. data/test/data/file-with-space.right +4 -0
  206. data/test/data/printvar.cmd +17 -0
  207. data/test/data/printvar.right +31 -0
  208. data/test/data/raise.cmd +11 -0
  209. data/test/data/raise.right +19 -0
  210. data/test/data/source.cmd +5 -0
  211. data/test/data/source.right +18 -0
  212. data/test/data/stepping-1.9.right +50 -0
  213. data/test/data/stepping.cmd +21 -0
  214. data/test/data/stepping.right +48 -0
  215. data/test/data/trepan8-save.1 +6 -0
  216. data/test/example/bp_loop_issue.rb +3 -0
  217. data/test/example/break-bug.rb +7 -0
  218. data/test/example/brkpt-class-bug.rb +8 -0
  219. data/test/example/classes.rb +11 -0
  220. data/test/example/dollar-0.rb +5 -0
  221. data/test/example/except-bug1.rb +4 -0
  222. data/test/example/except-bug2.rb +7 -0
  223. data/test/example/file with space.rb +1 -0
  224. data/test/example/gcd.rb +18 -0
  225. data/test/example/info-var-bug.rb +47 -0
  226. data/test/example/info-var-bug2.rb +2 -0
  227. data/test/example/null.rb +1 -0
  228. data/test/example/pm-bug.rb +3 -0
  229. data/test/example/pm.rb +11 -0
  230. data/test/example/raise.rb +3 -0
  231. data/test/integration/.gitignore +4 -0
  232. data/test/integration/config.yaml +8 -0
  233. data/test/integration/helper.rb +154 -0
  234. data/test/integration/test-break_bad.rb +26 -0
  235. data/test/integration/test-dollar-0.rb +31 -0
  236. data/test/integration/test-edit.rb +17 -0
  237. data/test/integration/test-file-with-space.rb +26 -0
  238. data/test/integration/test-printvar.rb +17 -0
  239. data/test/integration/test-raise.rb +21 -0
  240. data/test/integration/test-source.rb +16 -0
  241. data/test/integration/test-stepping.rb +24 -0
  242. data/test/unit/.gitignore +1 -0
  243. data/test/unit/cmd-helper.rb +52 -0
  244. data/test/unit/mock-helper.rb +12 -0
  245. data/test/unit/test-app-cmd_parse.rb +97 -0
  246. data/test/unit/test-app-cmd_parser.rb +23 -0
  247. data/test/unit/test-app-complete.rb +39 -0
  248. data/test/unit/test-app-frame.rb +32 -0
  249. data/test/unit/test-app-options.rb +92 -0
  250. data/test/unit/test-app-run.rb +14 -0
  251. data/test/unit/test-app-util.rb +44 -0
  252. data/test/unit/test-base-cmd.rb +45 -0
  253. data/test/unit/test-base-subcmd.rb +57 -0
  254. data/test/unit/test-base-submgr.rb +23 -0
  255. data/test/unit/test-base-subsubcmd.rb +17 -0
  256. data/test/unit/test-cmd-alias.rb +48 -0
  257. data/test/unit/test-cmd-exit.rb +27 -0
  258. data/test/unit/test-cmd-help.rb +104 -0
  259. data/test/unit/test-cmd-kill.rb +46 -0
  260. data/test/unit/test-cmd-source.rb +34 -0
  261. data/test/unit/test-completion.rb +42 -0
  262. data/test/unit/test-intf-user.rb +46 -0
  263. data/test/unit/test-io-input.rb +27 -0
  264. data/test/unit/test-io-tcp.rb +33 -0
  265. data/test/unit/test-io-tcpclient.rb +54 -0
  266. data/test/unit/test-io-tcpfns.rb +17 -0
  267. data/test/unit/test-io-tcpserver.rb +50 -0
  268. data/test/unit/test-proc-eval.rb +36 -0
  269. data/test/unit/test-proc-hook.rb +30 -0
  270. data/test/unit/test-proc-load_cmds.rb +50 -0
  271. data/test/unit/test-proc-location.rb +79 -0
  272. data/test/unit/test-subcmd-help.rb +44 -0
  273. data/trepan8.gemspec +58 -0
  274. metadata +388 -0
@@ -0,0 +1,20 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2011 Rocky Bernstein <rockyb@rubyforge.net>
3
+
4
+ # Communication status codes
5
+ module Trepanning
6
+ # Most of these go from debugged process to front-end
7
+ # client interface. COMMAND goes the other way.
8
+ module RemoteCommunication
9
+ unless defined?(PRINT)
10
+ PRINT = '.'
11
+ COMMAND = 'C'
12
+ CONFIRM_TRUE = 'Y'
13
+ CONFIRM_FALSE = 'N'
14
+ CONFIRM_REPLY = '?'
15
+ QUIT = 'q'
16
+ PROMPT = 'p'
17
+ RESTART = 'r'
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,110 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
3
+
4
+ # Module for reading debugger scripts
5
+
6
+ # Our local modules
7
+ require 'rubygems'; require 'require_relative'
8
+ require_relative 'base_intf'
9
+ require_relative '../io/input'
10
+ require_relative '../io/string_array'
11
+
12
+ # Interface when reading debugger scripts
13
+ class Trepan::ScriptInterface < Trepan::Interface
14
+ attr_accessor :opts, :output
15
+
16
+ DEFAULT_OPTS = {
17
+ :abort_on_error => true,
18
+ :confirm_val => false,
19
+ :verbose => false
20
+ } unless defined?(DEFAULT_OPTS)
21
+
22
+ def initialize(script_name, out=nil, opts={})
23
+ @opts = DEFAULT_OPTS.merge(opts)
24
+
25
+ at_exit { finalize }
26
+ @script_name = script_name
27
+ @input_lineno = 0
28
+ @input = opts[:input] ||
29
+ Trepan::UserInput.open(script_name, :line_edit => false)
30
+ @buffer_output = []
31
+ unless @opts[:verbose] or out
32
+ out = Trepan::StringArrayOutput.open(@buffer_output)
33
+ end
34
+ super(@input, out, @opts)
35
+ end
36
+
37
+ # Closes input only.
38
+ def close
39
+ @input.close
40
+ end
41
+
42
+ # Called when a dangerous action is about to be done, to make
43
+ # sure it's okay.
44
+ #
45
+ # Could look also look for interactive input and
46
+ # use that. For now, though we'll simplify.
47
+ def confirm(prompt, default)
48
+ @opts[:default_confirm]
49
+ end
50
+
51
+ # Common routine for reporting debugger error messages.
52
+ #
53
+ def errmsg(msg, prefix="*** ")
54
+ # self.verbose shows lines so we don't have to duplicate info
55
+ # here. Perhaps there should be a 'terse' mode to never show
56
+ # position info.
57
+ mess = if not @opts[:verbose]
58
+ location = ("%s:%s: Error in source command file" %
59
+ [@script_name, @input_lineno])
60
+ "%s%s:\n%s%s" % [prefix, location, prefix, msg]
61
+ else
62
+ "%s%s" % [prefix, msg]
63
+ end
64
+ msg(mess)
65
+ # FIXME: should we just set a flag and report eof? to be more
66
+ # consistent with File and IO?
67
+ raise IOError if @opts[:abort_on_error]
68
+ end
69
+
70
+ def interactive? ; false end
71
+
72
+ # Script interface to read a command. `prompt' is a parameter for
73
+ # compatibilty and is ignored.
74
+ def read_command(prompt='')
75
+ @input_lineno += 1
76
+ line = readline
77
+ if @opts[:verbose]
78
+ script_name =
79
+ if @opts[:basename]
80
+ File.basename(@script_name)
81
+ else
82
+ @script_name
83
+ end
84
+ location = "%s line %s" % [script_name, @input_lineno]
85
+ msg('+ %s: %s' % [location, line])
86
+ end
87
+ # Do something with history?
88
+ return line
89
+ end
90
+
91
+ # Script interface to read a line. `prompt' is a parameter for
92
+ # compatibilty and is ignored.
93
+ #
94
+ # Could decide make this look for interactive input?
95
+ def readline(prompt='')
96
+ begin
97
+ return input.readline().chomp
98
+ rescue EOFError
99
+ @eof = true
100
+ raise EOFError
101
+ end
102
+ end
103
+ end
104
+
105
+ # Demo
106
+ if __FILE__ == $0
107
+ intf = Trepan::ScriptInterface.new(__FILE__)
108
+ line = intf.readline()
109
+ print "Line read: ", line
110
+ end
@@ -0,0 +1,147 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2011 Rocky Bernstein <rockyb@rubyforge.net>
3
+
4
+ # Our local modules
5
+ require 'rubygems'; require 'require_relative'
6
+ require_relative 'base_intf'
7
+ require_relative 'comcodes'
8
+ require_relative '../io/input'
9
+ require_relative '../io/tcpserver'
10
+
11
+ # Mfifoserver = import_relative('fifoserver', '..io', 'pydbgr')
12
+
13
+ # Interface for debugging a program but having user control
14
+ # reside outside of the debugged process, possibly on another
15
+ # computer
16
+ class Trepan::ServerInterface < Trepan::Interface
17
+
18
+ include Trepanning::RemoteCommunication
19
+
20
+ DEFAULT_INIT_CONNECTION_OPTS = {
21
+ :io => 'TCP'
22
+ } unless defined?(DEFAULT_INIT_CONNECTION_OPTS)
23
+
24
+ def initialize(inout=nil, out=nil, connection_opts={})
25
+
26
+ @connection_opts = DEFAULT_INIT_CONNECTION_OPTS.merge(connection_opts)
27
+
28
+ at_exit { finalize }
29
+ @inout =
30
+ if inout
31
+ inout
32
+ else
33
+ server_type = @connection_opts[:io]
34
+ # FIXME: complete this.
35
+ # if 'FIFO' == server_type
36
+ # FIFOServer.new
37
+ # else
38
+ Trepan::TCPDbgServer.new(@connection_opts)
39
+ # end
40
+ end
41
+ # For Compatability
42
+ @output = @inout
43
+ @input = @inout
44
+ @interactive = true # Or at least so we think initially
45
+ end
46
+
47
+ # Closes both input and output
48
+ def close
49
+ if @inout && @inout.connected?
50
+ @inout.write(QUIT + 'bye')
51
+ @inout.close
52
+ end
53
+ end
54
+
55
+ def closed?
56
+ @inout.closed?
57
+ end
58
+
59
+ # Called when a dangerous action is about to be done to make sure
60
+ # it's okay. `prompt' is printed; user response is returned.
61
+ # FIXME: make common routine for this and user.rb
62
+ def confirm(prompt, default)
63
+ while true
64
+ begin
65
+ write_confirm(prompt, default)
66
+ reply = readline(nil).strip.downcase
67
+ rescue EOFError
68
+ return default
69
+ end
70
+ if YES.member?(reply)
71
+ return true
72
+ elsif NO.member?(reply)
73
+ return false
74
+ else
75
+ msg "Please answer 'yes' or 'no'. Try again."
76
+ end
77
+ end
78
+ return default
79
+ end
80
+
81
+ # Return true if we are connected
82
+ def connected?
83
+ :connected == @inout.state
84
+ end
85
+
86
+ # print exit annotation
87
+ def finalize(last_wishes=QUIT)
88
+ @inout.writeline(last_wishes) if connected?
89
+ close
90
+ end
91
+
92
+ def input_eof?
93
+ false
94
+ end
95
+
96
+ # used to write to a debugger that is connected to this
97
+ # server; `str' written will have a newline added to it
98
+ def msg(msg)
99
+ @inout.writeline(PRINT + msg)
100
+ end
101
+
102
+ # used to write to a debugger that is connected to this
103
+ # server; `str' written will not have a newline added to it
104
+ def msg_nocr(msg)
105
+ @inout.write(PRINT + msg)
106
+ end
107
+
108
+ def read_command(prompt)
109
+ readline(prompt)
110
+ end
111
+
112
+ def read_data
113
+ @inout.read_dat
114
+ end
115
+
116
+ def readline(prompt, add_to_history=true)
117
+ if prompt
118
+ write_prompt(prompt)
119
+ end
120
+ coded_line = @inout.read_msg()
121
+ @read_ctrl = coded_line[0..0]
122
+ coded_line[1..-1]
123
+ end
124
+
125
+ # Return connected
126
+ def state
127
+ @inout.state
128
+ end
129
+
130
+ def write_prompt(prompt)
131
+ @inout.write(PROMPT + prompt)
132
+ end
133
+
134
+ def write_confirm(prompt, default)
135
+ if default
136
+ code = CONFIRM_TRUE
137
+ else
138
+ code = CONFIRM_FALSE
139
+ end
140
+ @inout.write(code + prompt)
141
+ end
142
+ end
143
+
144
+ # Demo
145
+ if __FILE__ == $0
146
+ intf = Trepan::ServerInterface.new(nil, nil, :open => false)
147
+ end
data/interface/user.rb ADDED
@@ -0,0 +1,165 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
3
+
4
+ # Interface when communicating with the user.
5
+
6
+ # Our local modules
7
+
8
+ require 'rubygems'; require 'require_relative'
9
+ require_relative 'base_intf'
10
+ require_relative '../io/input'
11
+
12
+ # Interface when communicating with the user.
13
+ class Trepan::UserInterface < Trepan::Interface
14
+
15
+ DEFAULT_USER_OPTS = {
16
+ :readline => true, # Try to use GNU Readline?
17
+
18
+ # The below are only used if we want and have readline support.
19
+ # See method Trepan::GNU_readline? below.
20
+ :histsize => 256, # Use gdb's default setting
21
+ :file_history => '.trepan8_hist', # where history file lives
22
+ # Note a directory will
23
+ # be appended
24
+ :history_save => true # do we save the history?
25
+ } unless defined?(DEFAULT_USER_OPTS)
26
+
27
+ def initialize(inp=nil, out=nil, opts={})
28
+ super(inp, out, opts)
29
+ @opts = DEFAULT_USER_OPTS.merge(opts)
30
+ @input = if inp.class.ancestors.member?(Trepan::InputBase)
31
+ inp
32
+ else
33
+ Trepan::UserInput.open(inp, {:readline => opts[:readline]})
34
+ end
35
+ if Trepan::GNU_readline? && @opts[:complete]
36
+ Readline.completion_proc = @opts[:complete]
37
+ read_history
38
+ end
39
+ ## at_exit { finalize }
40
+ end
41
+
42
+ def closed?
43
+ @input.closed? && @output.closed?
44
+ end
45
+
46
+ # Called when a dangerous action is about to be done, to make
47
+ # sure it's okay. Expect a yes/no answer to `prompt' which is printed,
48
+ # suffixed with a question mark and the default value. The user
49
+ # response converted to a boolean is returned.
50
+ # FIXME: make common routine for this and server.rb
51
+ def confirm(prompt, default)
52
+ default_str = default ? 'Y/n' : 'N/y'
53
+ while true do
54
+ begin
55
+ response = readline('%s (%s) ' % [prompt, default_str])
56
+ rescue EOFError
57
+ return default
58
+ end
59
+ response = response.strip.downcase
60
+
61
+ # We don't catch "Yes, I'm sure" or "NO!", but I leave that
62
+ # as an exercise for the reader.
63
+ break if YES_OR_NO.member?(response)
64
+ msg "Please answer 'yes' or 'no'. Try again."
65
+ end
66
+ return YES.member?(response)
67
+ end
68
+
69
+ # Read a saved Readline history file into Readline. The history
70
+ # file will be created if it doesn't already exist.
71
+ # Much of this code follows what's done in ruby-debug.
72
+ def read_history
73
+ unless @histfile
74
+ dirname = ENV['HOME'] || ENV['HOMEPATH'] || File.expand_path('~')
75
+ @histfile = File.join(dirname, @opts[:file_history])
76
+ end
77
+ @histsize ||= (ENV['HISTSIZE'] ? ENV['HISTSIZE'].to_i : @opts[:histsize])
78
+ Readline.completion_proc = @opts[:complete]
79
+ if File.exists?(@histfile)
80
+ lines = IO::readlines(@histfile).last(@histsize).collect do
81
+ |line| line.chomp
82
+ end
83
+ Readline::HISTORY.push(*lines)
84
+ @history_io = File.new(@histfile, "a")
85
+ else
86
+ @history_io = File.new(@histfile, "w")
87
+ end
88
+ @history_io.sync = true
89
+ @history_save = @opts[:history_save]
90
+ end
91
+
92
+ def save_history
93
+ if @histfile
94
+ lines = Readline::HISTORY.to_a
95
+ lines = lines[-@histsize, @histsize] if lines.size > @histsize
96
+ begin
97
+ open(@histfile, 'w') do |file|
98
+ Readline::HISTORY.to_a.last(@histsize).each do |line|
99
+ file.puts line
100
+ end
101
+ end if defined?(@history_save) and @history_save
102
+ rescue
103
+ end
104
+ end
105
+ end
106
+
107
+ def finalize(last_wishes=nil)
108
+ # ?? print gdb-style exit annotation if annotate = 2?
109
+ if Trepan::GNU_readline? && @history_save
110
+ save_history
111
+ end
112
+ super
113
+ end
114
+
115
+ def interactive? ; @input.interactive? end
116
+
117
+ def read_command(prompt='')
118
+ readline(prompt)
119
+ end
120
+
121
+ def readline(prompt='')
122
+ @output.flush
123
+ if @input.line_edit && @opts[:readline]
124
+ if Trepan::GNU_readline? && @opts[:complete]
125
+ Readline.completion_proc = @opts[:complete]
126
+ end
127
+ # rb-readline 0.4.0 has bugs
128
+ begin
129
+ @input.readline(prompt)
130
+ rescue Exception => e
131
+ @output.write("Exception: #{e} in readline\n")
132
+ ''
133
+ end
134
+ else
135
+ @output.write(prompt) if prompt and prompt.size > 0
136
+ @input.readline
137
+ end
138
+ end
139
+
140
+ end
141
+
142
+ # Demo
143
+ if __FILE__ == $0
144
+ intf = Trepan::UserInterface.new
145
+ intf.errmsg("Houston, we have a problem here!")
146
+ if ARGV.size > 0
147
+ begin
148
+ line = intf.readline("Type something: ")
149
+ rescue EOFError
150
+ puts "No input, got EOF"
151
+ else
152
+ puts "You typed: #{line}"
153
+ end
154
+ puts "EOF is now: %s" % intf.input.eof?.inspect
155
+ unless intf.input.eof?
156
+ line = intf.confirm("Are you sure", false)
157
+ puts "You typed: #{line}"
158
+ puts "EOF is now: %s" % intf.input.eof?.inspect
159
+ line = intf.confirm("Are you not sure", true)
160
+ puts "You typed: #{line}"
161
+ puts "EOF is now: %s" % intf.input.eof?.inspect
162
+ end
163
+ end
164
+ puts "User interface closed?: #{intf.closed?}"
165
+ end
data/io/base_io.rb ADDED
@@ -0,0 +1,148 @@
1
+ # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
2
+ # classes to support communication to and from the debugger. This
3
+ # communcation might be to/from another process or another computer.
4
+ # And reading may be from a debugger command script.
5
+ #
6
+ # For example, we'd like to support Sockets, and serial lines and file
7
+ # reading, as well a readline-type input. Encryption and Authentication
8
+ # methods might decorate some of the communication channels.
9
+ #
10
+ # Some ideas originiated as part of Matt Fleming's 2006 Google Summer of
11
+ # Code project.
12
+
13
+ module Trepan
14
+
15
+ NotImplementedMessage = 'This method must be overriden in a subclass' unless
16
+ defined?(NotImplementedMessage)
17
+
18
+ class InputBase
19
+ attr_reader :input
20
+ attr_reader :line_edit
21
+
22
+ DEFAULT_OPTS = {
23
+ :line_edit => false,
24
+ } unless defined?(DEFAULT_OPTS)
25
+
26
+ def initialize(inp, opts={})
27
+ @opts = DEFAULT_OPTS.merge(opts)
28
+ @input = inp
29
+ @line_edit = opts[:line_edit]
30
+ end
31
+
32
+ def close
33
+ @input.close unless @input.closed?
34
+ end
35
+
36
+ def eof?
37
+ begin
38
+ @input.eof?
39
+ rescue IOError
40
+ true
41
+ end
42
+ end
43
+
44
+ # Read a line of input. EOFError will be raised on EOF.
45
+ #
46
+ # Note that we don't support prompting first. Instead, arrange
47
+ # to call Trepan::Output.write() first with the prompt. If
48
+ # `use_raw' is set raw_input() will be used in that is supported
49
+ # by the specific input input. If this option is left None as is
50
+ # normally expected the value from the class initialization is
51
+ # used.
52
+ def readline
53
+ @input.readline
54
+ end
55
+ end
56
+
57
+ # This is an abstract class that specifies debugger output.
58
+ class OutputBase
59
+ attr_accessor :flush_after_write
60
+ attr_reader :output
61
+ def initialize(out, opts={})
62
+ @output = out
63
+ @flush_after_write = false
64
+ @eof = false
65
+ end
66
+
67
+ def close
68
+ @output.close if @output
69
+ @eof = true
70
+ end
71
+
72
+ def eof?
73
+ @eof
74
+ end
75
+
76
+ def flush
77
+ @output.flush
78
+ end
79
+
80
+ # Use this to set where to write to. output can be a
81
+ # file object or a string. This code raises IOError on error.
82
+ def write(*args)
83
+ @output.print(*args)
84
+ end
85
+
86
+ # used to write to a debugger that is connected to this
87
+ # `str' written will have a newline added to it
88
+ #
89
+ def writeline(msg)
90
+ @output.write("%s\n" % msg)
91
+ end
92
+ end
93
+
94
+ # This is an abstract class that specifies debugger input output when
95
+ # handled by the same channel, e.g. a socket or tty.
96
+ #
97
+ class InOutBase
98
+
99
+ def initialize(inout, opts={})
100
+ @opts = DEFAULT_OPTS.merge(opts)
101
+ @inout = inout
102
+ end
103
+
104
+ def close
105
+ @inout.close() if @inout
106
+ end
107
+
108
+ def eof?
109
+ begin
110
+ @input.eof?
111
+ rescue IOError
112
+ true
113
+ end
114
+ end
115
+
116
+ def flush
117
+ @inout.flush
118
+ end
119
+
120
+ # Read a line of input. EOFError will be raised on EOF.
121
+ #
122
+ # Note that we don't support prompting first. Instead, arrange to
123
+ # call DebuggerOutput.write() first with the prompt. If `use_raw'
124
+ # is set raw_input() will be used in that is supported by the
125
+ # specific input input. If this option is left nil as is normally
126
+ # expected the value from the class initialization is used.
127
+ def readline(use_raw=nil)
128
+ @input.readline
129
+ end
130
+
131
+ # Use this to set where to write to. output can be a
132
+ # file object or a string. This code raises IOError on error.
133
+ #
134
+ # Use this to set where to write to. output can be a
135
+ # file object or a string. This code raises IOError on error.
136
+ def write(*args)
137
+ @inout.write(*args)
138
+ end
139
+
140
+ # used to write to a debugger that is connected to this
141
+ # server; `str' written will have a newline added to it
142
+ def writeline( msg)
143
+ @inout.write("%s\n" % msg)
144
+ end
145
+ end
146
+
147
+ end
148
+