rbx-trepanning 0.0.1-universal-rubinius

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 (205) hide show
  1. data/ChangeLog +376 -0
  2. data/LICENSE +25 -0
  3. data/NEWS +2 -0
  4. data/README.textile +28 -0
  5. data/Rakefile +165 -0
  6. data/THANKS +14 -0
  7. data/app/breakpoint.rb +218 -0
  8. data/app/breakpoint.rbc +3564 -0
  9. data/app/brkptmgr.rb +138 -0
  10. data/app/brkptmgr.rbc +2827 -0
  11. data/app/default.rb +61 -0
  12. data/app/default.rbc +1011 -0
  13. data/app/display.rb +35 -0
  14. data/app/display.rbc +968 -0
  15. data/app/frame.rb +98 -0
  16. data/app/frame.rbc +1808 -0
  17. data/app/irb.rb +112 -0
  18. data/app/irb.rbc +2111 -0
  19. data/app/iseq.rb +95 -0
  20. data/app/iseq.rbc +1801 -0
  21. data/app/method.rb +173 -0
  22. data/app/method.rbc +2492 -0
  23. data/app/mock.rb +13 -0
  24. data/app/mock.rbc +398 -0
  25. data/app/options.rb +123 -0
  26. data/app/options.rbc +2183 -0
  27. data/app/run.rb +86 -0
  28. data/app/run.rbc +1244 -0
  29. data/app/util.rb +49 -0
  30. data/app/util.rbc +1144 -0
  31. data/app/validate.rb +30 -0
  32. data/app/validate.rbc +676 -0
  33. data/bin/trepan.compiled.rbc +1043 -0
  34. data/bin/trepanx +63 -0
  35. data/bin/trepanx.compiled.rbc +985 -0
  36. data/interface/base_intf.rb +95 -0
  37. data/interface/base_intf.rbc +1742 -0
  38. data/interface/script.rb +104 -0
  39. data/interface/script.rbc +1642 -0
  40. data/interface/user.rb +91 -0
  41. data/interface/user.rbc +1418 -0
  42. data/io/base_io.rb +94 -0
  43. data/io/base_io.rbc +1404 -0
  44. data/io/input.rb +112 -0
  45. data/io/input.rbc +1979 -0
  46. data/io/null_output.rb +42 -0
  47. data/io/null_output.rbc +730 -0
  48. data/io/string_array.rb +156 -0
  49. data/io/string_array.rbc +2466 -0
  50. data/lib/trepanning.rb +398 -0
  51. data/lib/trepanning.rbc +6661 -0
  52. data/processor/breakpoint.rb +161 -0
  53. data/processor/command/alias.rb +55 -0
  54. data/processor/command/backtrace.rb +46 -0
  55. data/processor/command/base/cmd.rb +124 -0
  56. data/processor/command/base/subcmd.rb +213 -0
  57. data/processor/command/base/submgr.rb +179 -0
  58. data/processor/command/base/subsubcmd.rb +103 -0
  59. data/processor/command/base/subsubmgr.rb +184 -0
  60. data/processor/command/break.rb +100 -0
  61. data/processor/command/continue.rb +82 -0
  62. data/processor/command/delete.rb +30 -0
  63. data/processor/command/directory.rb +43 -0
  64. data/processor/command/disassemble.rb +103 -0
  65. data/processor/command/down.rb +54 -0
  66. data/processor/command/eval.rb +31 -0
  67. data/processor/command/exit.rb +58 -0
  68. data/processor/command/finish.rb +78 -0
  69. data/processor/command/frame.rb +89 -0
  70. data/processor/command/help.rb +146 -0
  71. data/processor/command/info.rb +28 -0
  72. data/processor/command/info_subcmd/breakpoints.rb +75 -0
  73. data/processor/command/info_subcmd/file.rb +153 -0
  74. data/processor/command/info_subcmd/method.rb +71 -0
  75. data/processor/command/info_subcmd/program.rb +59 -0
  76. data/processor/command/info_subcmd/variables.rb +40 -0
  77. data/processor/command/irb.rb +96 -0
  78. data/processor/command/kill.rb +70 -0
  79. data/processor/command/list.rb +296 -0
  80. data/processor/command/next.rb +66 -0
  81. data/processor/command/nexti.rb +59 -0
  82. data/processor/command/pr.rb +38 -0
  83. data/processor/command/ps.rb +40 -0
  84. data/processor/command/restart.rb +60 -0
  85. data/processor/command/set.rb +47 -0
  86. data/processor/command/set_subcmd/auto.rb +28 -0
  87. data/processor/command/set_subcmd/auto_subcmd/dis.rb +33 -0
  88. data/processor/command/set_subcmd/auto_subcmd/eval.rb +54 -0
  89. data/processor/command/set_subcmd/auto_subcmd/irb.rb +34 -0
  90. data/processor/command/set_subcmd/auto_subcmd/list.rb +34 -0
  91. data/processor/command/set_subcmd/basename.rb +26 -0
  92. data/processor/command/set_subcmd/debug.rb +27 -0
  93. data/processor/command/set_subcmd/debug_subcmd/dbgr.rb +36 -0
  94. data/processor/command/set_subcmd/debug_subcmd/skip.rb +23 -0
  95. data/processor/command/set_subcmd/debug_subcmd/step.rb +23 -0
  96. data/processor/command/set_subcmd/different.rb +60 -0
  97. data/processor/command/set_subcmd/hidelevel.rb +63 -0
  98. data/processor/command/set_subcmd/kernelstep.rb +61 -0
  99. data/processor/command/set_subcmd/max.rb +29 -0
  100. data/processor/command/set_subcmd/max_subcmd/list.rb +49 -0
  101. data/processor/command/set_subcmd/max_subcmd/stack.rb +50 -0
  102. data/processor/command/set_subcmd/max_subcmd/string.rb +54 -0
  103. data/processor/command/set_subcmd/max_subcmd/width.rb +49 -0
  104. data/processor/command/set_subcmd/substitute.rb +25 -0
  105. data/processor/command/set_subcmd/substitute_subcmd/path.rb +56 -0
  106. data/processor/command/set_subcmd/trace.rb +37 -0
  107. data/processor/command/set_subcmd/trace_subcmd/print.rb +57 -0
  108. data/processor/command/show.rb +27 -0
  109. data/processor/command/show_subcmd/alias.rb +43 -0
  110. data/processor/command/show_subcmd/args.rb +26 -0
  111. data/processor/command/show_subcmd/auto.rb +28 -0
  112. data/processor/command/show_subcmd/auto_subcmd/dis.rb +37 -0
  113. data/processor/command/show_subcmd/auto_subcmd/eval.rb +28 -0
  114. data/processor/command/show_subcmd/auto_subcmd/irb.rb +23 -0
  115. data/processor/command/show_subcmd/auto_subcmd/list.rb +22 -0
  116. data/processor/command/show_subcmd/basename.rb +22 -0
  117. data/processor/command/show_subcmd/debug.rb +27 -0
  118. data/processor/command/show_subcmd/debug_subcmd/dbgr.rb +21 -0
  119. data/processor/command/show_subcmd/debug_subcmd/skip.rb +22 -0
  120. data/processor/command/show_subcmd/debug_subcmd/step.rb +22 -0
  121. data/processor/command/show_subcmd/different.rb +27 -0
  122. data/processor/command/show_subcmd/hidelevel.rb +42 -0
  123. data/processor/command/show_subcmd/kernelstep.rb +37 -0
  124. data/processor/command/show_subcmd/max.rb +30 -0
  125. data/processor/command/show_subcmd/max_subcmd/list.rb +38 -0
  126. data/processor/command/show_subcmd/max_subcmd/stack.rb +36 -0
  127. data/processor/command/show_subcmd/max_subcmd/string.rb +42 -0
  128. data/processor/command/show_subcmd/max_subcmd/width.rb +37 -0
  129. data/processor/command/show_subcmd/trace.rb +29 -0
  130. data/processor/command/show_subcmd/trace_subcmd/print.rb +38 -0
  131. data/processor/command/source.rb +83 -0
  132. data/processor/command/step.rb +41 -0
  133. data/processor/command/tbreak.rb +19 -0
  134. data/processor/command/unalias.rb +44 -0
  135. data/processor/command/up.rb +87 -0
  136. data/processor/default.rb +56 -0
  137. data/processor/disassemble.rb +32 -0
  138. data/processor/eval.rb +96 -0
  139. data/processor/frame.rb +211 -0
  140. data/processor/help.rb +72 -0
  141. data/processor/hook.rb +133 -0
  142. data/processor/load_cmds.rb +101 -0
  143. data/processor/location.rb +128 -0
  144. data/processor/main.rb +394 -0
  145. data/processor/mock.rb +137 -0
  146. data/processor/msg.rb +28 -0
  147. data/processor/running.rb +230 -0
  148. data/processor/stepping.rb +115 -0
  149. data/processor/subcmd.rb +160 -0
  150. data/processor/validate.rb +355 -0
  151. data/test/data/enable.right +36 -0
  152. data/test/data/fname-with-blank.cmd +6 -0
  153. data/test/data/fname-with-blank.right +1 -0
  154. data/test/data/quit-Xdebug.right +3 -0
  155. data/test/data/quit.cmd +5 -0
  156. data/test/data/quit.right +0 -0
  157. data/test/example/fname with blank.rb +1 -0
  158. data/test/example/gcd-xx.rb +18 -0
  159. data/test/example/gcd.rb +19 -0
  160. data/test/example/gcd1.rb +24 -0
  161. data/test/example/null.rb +1 -0
  162. data/test/example/thread1.rb +3 -0
  163. data/test/functional/fn_helper.rb +112 -0
  164. data/test/functional/test-break-name.rb +52 -0
  165. data/test/functional/test-break.rb +51 -0
  166. data/test/functional/test-finish.rb +70 -0
  167. data/test/functional/test-fn_helper.rb +43 -0
  168. data/test/functional/test-list.rb +55 -0
  169. data/test/functional/test-next-bug.rb +49 -0
  170. data/test/functional/test-next.rb +101 -0
  171. data/test/functional/test-step.rb +272 -0
  172. data/test/functional/test-step2.rb +35 -0
  173. data/test/functional/test-tbreak.rb +41 -0
  174. data/test/integration/file-diff.rb +89 -0
  175. data/test/integration/helper.rb +78 -0
  176. data/test/integration/test-fname-with-blank.rb +12 -0
  177. data/test/integration/test-quit.rb +25 -0
  178. data/test/unit/cmd-helper.rb +46 -0
  179. data/test/unit/test-app-brkpt.rb +30 -0
  180. data/test/unit/test-app-brkptmgr.rb +51 -0
  181. data/test/unit/test-app-iseq.rb +49 -0
  182. data/test/unit/test-app-method.rb +54 -0
  183. data/test/unit/test-app-options.rb +61 -0
  184. data/test/unit/test-app-run.rb +16 -0
  185. data/test/unit/test-app-util.rb +28 -0
  186. data/test/unit/test-app-validate.rb +18 -0
  187. data/test/unit/test-base-subcmd.rb +61 -0
  188. data/test/unit/test-bin-trepanx.rb +48 -0
  189. data/test/unit/test-cmd-alias.rb +49 -0
  190. data/test/unit/test-cmd-break.rb +23 -0
  191. data/test/unit/test-cmd-exit.rb +27 -0
  192. data/test/unit/test-cmd-help.rb +101 -0
  193. data/test/unit/test-cmd-kill.rb +48 -0
  194. data/test/unit/test-intf-user.rb +46 -0
  195. data/test/unit/test-io-input.rb +27 -0
  196. data/test/unit/test-proc-eval.rb +37 -0
  197. data/test/unit/test-proc-frame.rb +79 -0
  198. data/test/unit/test-proc-help.rb +16 -0
  199. data/test/unit/test-proc-hook.rb +30 -0
  200. data/test/unit/test-proc-load_cmds.rb +41 -0
  201. data/test/unit/test-proc-location.rb +48 -0
  202. data/test/unit/test-proc-main.rb +96 -0
  203. data/test/unit/test-proc-validate.rb +91 -0
  204. data/test/unit/test-subcmd-help.rb +51 -0
  205. metadata +337 -0
@@ -0,0 +1,355 @@
1
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
2
+
3
+ # Trepan command input validation routines. A String type is
4
+ # usually passed in as the argument to validation routines.
5
+
6
+ require 'rubygems'
7
+ require 'require_relative'
8
+ require 'linecache'
9
+ require_relative '../app/method'
10
+ require_relative '../app/validate'
11
+ ## require_relative '../app/condition'
12
+ ## require_relative '../app/file'
13
+ class Trepan
14
+ class CmdProcessor
15
+
16
+ attr_reader :dbgr_script_iseqs
17
+ attr_reader :dbgr_iseqs
18
+
19
+ include Trepanning::Method
20
+ include Trepan::Validate
21
+ ## include Trepan::ThreadHelper
22
+ ## include Trepan::Condition
23
+
24
+ def confirm(msg, default)
25
+ @dbgr.intf[-1].confirm(msg, default)
26
+ end
27
+
28
+ # Like cmdfns.get_an_int(), but if there's a stack frame use that
29
+ # in evaluation.
30
+ def get_an_int(arg, opts={})
31
+ ret_value = get_int_noerr(arg)
32
+ if !ret_value
33
+ if opts[:msg_on_error]
34
+ errmsg(opts[:msg_on_error])
35
+ else
36
+ errmsg("Expecting an integer, got: #{arg}.")
37
+ end
38
+ return nil
39
+ end
40
+ if opts[:min_value] and ret_value < opts[:min_value]
41
+ errmsg("Expecting integer value to be at least %d; got %d." %
42
+ [opts[:min_value], ret_value])
43
+ return nil
44
+ elsif opts[:max_value] and ret_value > opts[:max_value]
45
+ errmsg("Expecting integer value to be at most %d; got %d." %
46
+ [opts[:max_value], ret_value])
47
+ return nil
48
+ end
49
+ return ret_value
50
+ end
51
+
52
+ unless defined?(DEFAULT_GET_INT_OPTS)
53
+ DEFAULT_GET_INT_OPTS = {
54
+ :min_value => 0, :default => 1, :cmdname => nil, :max_value => nil}
55
+ end
56
+
57
+ # If argument parameter 'arg' is not given, then use what is in
58
+ # opts[:default]. If String 'arg' evaluates to an integer between
59
+ # least min_value and at_most, use that. Otherwise report an
60
+ # error. If there's a stack frame use that for bindings in
61
+ # evaluation.
62
+ def get_int(arg, opts={})
63
+
64
+ return default unless arg
65
+ opts = DEFAULT_GET_INT_OPTS.merge(opts)
66
+ val = arg ? get_int_noerr(arg) : opts[:default]
67
+ unless val
68
+ if opts[:cmdname]
69
+ errmsg(("Command '%s' expects an integer; " +
70
+ "got: %s.") % [opts[:cmdname], arg])
71
+ else
72
+ errmsg('Expecting a positive integer, got: %s' % arg)
73
+ end
74
+ return nil
75
+ end
76
+
77
+ if val < opts[:min_value]
78
+ if cmdname
79
+ errmsg(("Command '%s' expects an integer at least" +
80
+ ' %d; got: %d.') %
81
+ [cmdname, opts[:min_value], opts[:default]])
82
+ else
83
+ errmsg(("Expecting a positive integer at least" +
84
+ ' %d; got: %d') %
85
+ [opts[:min_value], opts[:default]])
86
+ end
87
+ return nil
88
+ elsif opts[:max_value] and val > opts[:max_value]
89
+ if opts[:cmdname]
90
+ errmsg(("Command '%s' expects an integer at most" +
91
+ ' %d; got: %d.') %
92
+ [opts[:cmdname], opts[:max_value], val])
93
+ else
94
+ errmsg(("Expecting an integer at most %d; got: %d") %
95
+ [opts[:max_value], val])
96
+ end
97
+ return nil
98
+ end
99
+ return val
100
+ end
101
+
102
+ def get_int_list(args, opts={})
103
+ args.map{|arg| get_an_int(arg, opts)}.compact
104
+ end
105
+
106
+ # Eval arg and it is an integer return the value. Otherwise
107
+ # return nil
108
+ def get_int_noerr(arg)
109
+ b = @frame ? @frame.binding : nil
110
+ val = Integer(eval(arg, b))
111
+ rescue SyntaxError
112
+ nil
113
+ rescue
114
+ nil
115
+ end
116
+
117
+ def get_thread_from_string(id_or_num_str)
118
+ if id_or_num_str == '.'
119
+ Thread.current
120
+ elsif id_or_num_str.downcase == 'm'
121
+ Thread.main
122
+ else
123
+ num = get_int_noerr(id_or_num_str)
124
+ if num
125
+ get_thread(num)
126
+ else
127
+ nil
128
+ end
129
+ end
130
+ end
131
+
132
+ # Parse a breakpoint position. On success return
133
+ # - a string "description"
134
+ # - the method the position is in - a CompiledMethod or a String
135
+ # - the line - a Fixnum
136
+ # - whether the position is an instance or not
137
+ # On failure, an error message is shown and we return nil.
138
+ def breakpoint_position(args)
139
+ ip = nil
140
+ if args.size == 0
141
+ args = [frame.line.to_s]
142
+ end
143
+ if args[0] == 'main.__script__'
144
+ if args.size > 2
145
+ errmsg 'Expecting only a line number'
146
+ return nil
147
+ elsif args.size == 2
148
+ ip, line = line_or_ip(args[1])
149
+ unless line || ip
150
+ errmsg ("Expecting a line or an IP offset number")
151
+ return nil
152
+ end
153
+ else
154
+ ip, line = nil, nil
155
+ end
156
+ return [args.join(' '), '.', '__script__', line, ip]
157
+ elsif args.size == 1
158
+ meth = parse_method(args[0])
159
+ if meth
160
+ cm = meth.executable
161
+ return [args[0], nil, true, cm, cm.lines[1], cm.lines[0]]
162
+ else
163
+ m = /([A-Z]\w*(?:::[A-Z]\w*)*)([.#])(\w+[!?=]?)(?:[:]([oO])?(\d+))?/.match(args[0])
164
+ if m
165
+ if m[4]
166
+ return [m[0], m[1], m[2], m[3], nil, m[5] ? m[5].to_i : nil]
167
+ else
168
+ return [m[0], m[1], m[2], m[3], (m[4] ? m[4].to_i : nil), nil]
169
+ end
170
+ else
171
+ ip, line = line_or_ip(args[0])
172
+ unless line || ip
173
+ errmsg ("Expecting a line or an IP offset number")
174
+ return nil
175
+ end
176
+ if line
177
+ meth = find_method_with_line(frame.method, line)
178
+ unless meth
179
+ errmsg "Cannot find method location for line #{line}"
180
+ return nil
181
+ end
182
+ elsif valid_ip?(frame.method, ip)
183
+ return [args.join(' '), meth.class, '#', frame.method, nil, ip]
184
+ else
185
+ errmsg 'Cannot parse breakpoint location'
186
+ return nil
187
+ end
188
+
189
+ return ["#{meth.describe}", nil, '#', meth, line, nil]
190
+ end
191
+ end
192
+ end
193
+ errmsg 'Cannot parse breakpoint location'
194
+ return nil
195
+ end
196
+
197
+ # Return true if arg is 'on' or 1 and false arg is 'off' or 0.
198
+ # Any other value is raises TypeError.
199
+ def get_onoff(arg, default=nil, print_error=true)
200
+ unless arg
201
+ if !default
202
+ if print_error
203
+ errmsg("Expecting 'on', 1, 'off', or 0. Got nothing.")
204
+ end
205
+ raise TypeError
206
+ end
207
+ return default
208
+ end
209
+ darg = arg.downcase
210
+ return true if arg == '1' || darg == 'on'
211
+ return false if arg == '0' || darg =='off'
212
+
213
+ errmsg("Expecting 'on', 1, 'off', or 0. Got: %s." % arg.to_s) if
214
+ print_error
215
+ raise TypeError
216
+ end
217
+
218
+ def method?(method_string)
219
+ obj, type, meth =
220
+ if method_string =~ /(.+)(#|::|\.)(.+)/
221
+ [$1, $2, $3]
222
+ else
223
+ ['self', '.', method_string]
224
+ end
225
+ ret = debug_eval_no_errmsg("#{obj}.method(#{meth.inspect})")
226
+ return true if ret
227
+ return debug_eval_no_errmsg("#{obj}.is_a?(Class)") &&
228
+ debug_eval_no_errmsg("#{obj}.method_defined?(#{meth.inspect})")
229
+ end
230
+
231
+ # parse_position(self, arg)->(fn, container, lineno)
232
+ #
233
+ # Parse arg as [filename:]lineno | function | module
234
+ # Make sure it works for C:\foo\bar.py:12
235
+ def parse_position(arg, old_mod=nil, allow_offset = false)
236
+ colon = arg.rindex(':')
237
+ if colon
238
+ # First handle part before the colon
239
+ arg1 = arg[0...colon].rstrip
240
+ lineno_str = arg[colon+1..-1].lstrip
241
+ mf, container, lineno = parse_position_one_arg(arg1, old_mod, false, allow_offset)
242
+ return nil, nil, nil unless container
243
+ filename = canonic_file(arg1)
244
+ # Next handle part after the colon
245
+ val = get_an_int(lineno_str)
246
+ lineno = val if val
247
+ else
248
+ mf, container, lineno = parse_position_one_arg(arg, old_mod, true, allow_offset)
249
+ end
250
+
251
+ return mf, container, lineno
252
+ end
253
+
254
+ # parse_position_one_arg(self,arg)->(module/function, container, lineno)
255
+ #
256
+ # See if arg is a line number, function name, or module name.
257
+ # Return what we've found. nil can be returned as a value in
258
+ # the triple.
259
+ def parse_position_one_arg(arg, old_mod=nil, show_errmsg=true, allow_offset=false)
260
+ name, filename = nil, nil, nil
261
+ begin
262
+ # First see if argument is an integer
263
+ lineno = Integer(arg)
264
+ rescue
265
+ else
266
+ filename = @frame.file
267
+ return nil, canonic_file(filename), lineno
268
+ end
269
+
270
+ # Next see if argument is a file name
271
+ if LineCache::cached?(arg)
272
+ return nil, canonic_file(arg), 1
273
+ elsif File.readable?(arg)
274
+ return nil, canonic_file(arg), 1
275
+ end
276
+
277
+ # How about a method name with an instruction sequence?
278
+ meth = parse_method(arg)
279
+ if meth
280
+ cm = meth.executable
281
+ return arg, canonic_file(cm.active_path), cm.lines[1]
282
+ end
283
+
284
+ if show_errmsg
285
+ unless (allow_offset && arg.size > 0 && arg[0].downcase == 'o')
286
+ errmsg("#{arg} is not a line number, filename or method " +
287
+ "we can get location information about")
288
+ end
289
+ end
290
+ return nil, nil, nil
291
+ end
292
+
293
+ def parse_method(meth_str)
294
+ # For meth_str = "foo", try via method("foo".to_sym)
295
+ str = "method(#{meth_str.inspect}.to_sym)"
296
+ meth = debug_eval_no_errmsg(str)
297
+ return meth if meth
298
+ last_dot = meth_str.rindex('.')
299
+ if last_dot
300
+ # For meth_str = "a.b.foo",
301
+ # try via a.b.method("foo".to_sym)
302
+ try_eval = "#{meth_str[0..last_dot]}method" +
303
+ "(#{meth_str[last_dot+1..-1].inspect}.to_sym)"
304
+ meth = debug_eval_no_errmsg(try_eval)
305
+ end
306
+ return meth
307
+ end
308
+
309
+ def validate_initialize
310
+ ## top_srcdir = File.expand_path(File.join(File.dirname(__FILE__), '..'))
311
+ ## @dbgr_script_iseqs, @dbgr_iseqs = filter_scripts(top_srcdir)
312
+ end
313
+ end
314
+ end
315
+
316
+ if __FILE__ == $0
317
+ # Demo it.
318
+ require_relative './mock'
319
+ dbgr, cmd = MockDebugger::setup('exit', false)
320
+ proc = cmd.proc
321
+ onoff = %w(1 0 on off)
322
+ onoff.each { |val| puts "onoff(#{val}) = #{proc.get_onoff(val)}" }
323
+ %w(1 1E bad 1+1 -5).each do |val|
324
+ puts "get_int_noerr(#{val}) = #{proc.get_int_noerr(val).inspect}"
325
+ end
326
+ def foo; 5 end
327
+ def proc.errmsg(msg)
328
+ puts msg
329
+ end
330
+ puts proc.parse_position_one_arg('tmpdir.rb').inspect
331
+
332
+ puts '=' * 40
333
+ ['Array#map', 'Trepan::CmdProcessor.new',
334
+ 'foo', 'proc.errmsg'].each do |str|
335
+ puts "#{str} should be true: #{proc.method?(str).inspect}"
336
+ end
337
+ puts '=' * 40
338
+
339
+ # FIXME:
340
+ # Array#foo should be false: true
341
+ # Trepan::CmdProcessor.allocate should be false: true
342
+
343
+ ['food', '.errmsg'].each do |str|
344
+ puts "#{str} should be false: #{proc.method?(str).inspect}"
345
+ end
346
+ puts '-' * 20
347
+ # require_relative '../lib/trepanning'
348
+ # Trepan.start
349
+ p proc.breakpoint_position(%w(O0))
350
+ p proc.breakpoint_position(%w(1))
351
+ p proc.breakpoint_position(%w(__LINE__))
352
+ # p proc.breakpoint_position(%w(2 if a > b))
353
+ p proc.get_int_list(%w(1+0 3-1 3))
354
+ p proc.get_int_list(%w(a 2 3))
355
+ end
@@ -0,0 +1,36 @@
1
+ gcd.rb:4
2
+ def gcd(a, b)
3
+ # # ********************************************************
4
+ # # This tests the enable command.
5
+ # # ********************************************************
6
+ # set debuggertesting on
7
+ Currently testing the debugger is on.
8
+ # set callstyle last
9
+ Frame call-display style is last.
10
+ # set autoeval off
11
+ autoeval is off.
12
+ # break Object.gcd
13
+ Breakpoint 1 at Object::gcd
14
+ # # Should have a breakpoint 1
15
+ # enable br 1
16
+ # # Get help on enable
17
+ # help enable
18
+ Enable some things.
19
+ This is used to cancel the effect of the "disable" command.
20
+ --
21
+ List of enable subcommands:
22
+ --
23
+ enable breakpoints -- Enable specified breakpoints
24
+ enable display -- Enable some expressions to be displayed when program stops
25
+ # # Get help on just enable break
26
+ # help enable break
27
+ Enable specified breakpoints.
28
+ Give breakpoint numbers (separated by spaces) as arguments.
29
+ This is used to cancel the effect of the "disable" command.
30
+ # # Plain enable should work
31
+ # enable
32
+ *** "enable" must be followed "display", "breakpoints" or breakpoint numbers.
33
+ # # An invalid enable command
34
+ # enable foo
35
+ Enable breakpoints argument 'foo' needs to be a number.
36
+ # quit
@@ -0,0 +1,6 @@
1
+ # *******************************************************************
2
+ # Just to see that we can load a filename with an blank in it
3
+ # *******************************************************************
4
+ set basename off
5
+ continue
6
+
@@ -0,0 +1 @@
1
+ Ha!
@@ -0,0 +1,3 @@
1
+ -> (/home/rocky-rvm/.rvm/src/rbx-trepanning/test/example/null.rb:1 @0)
2
+ # Nothing here. Move along.
3
+ (trepanx): (trepanx): (trepanx): (trepanx): (trepanx):
@@ -0,0 +1,5 @@
1
+ # ***************************************************
2
+ # This tests the quit.
3
+ # ***************************************************
4
+ # FIXME need to test --no-quit.
5
+ quit!
File without changes
@@ -0,0 +1 @@
1
+ puts "Ha!"
@@ -0,0 +1,18 @@
1
+
2
+ # GCD. We assume positive numbers
3
+ def gcd(a, b)
4
+ # Make: a <= b
5
+ if a > b
6
+ a, b = [b, a]
7
+ end
8
+
9
+ return nil if a <= 0
10
+ addline
11
+
12
+ if a == 1 or b-a == 0
13
+ return a
14
+ end
15
+ end
16
+
17
+ a, b = ARGV[0..1].map {|arg| arg.to_i}
18
+ puts "The GCD of %d and %d is %d" % [a, b, gcd(a, b)]
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # GCD. We assume positive numbers
4
+ def gcd(a, b)
5
+ # Make: a <= b
6
+ if a > b
7
+ a, b = [b, a]
8
+ end
9
+
10
+ return nil if a <= 0
11
+
12
+ if a == 1 or b-a == 0
13
+ return a
14
+ end
15
+ return gcd(b-a, a)
16
+ end
17
+
18
+ a, b = ARGV[0..1].map {|arg| arg.to_i}
19
+ puts "The GCD of %d and %d is %d" % [a, b, gcd(a, b)]
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+ require 'thread_frame'
3
+ tf = RubyVM::ThreadFrame.current
4
+ iseq = tf.iseq
5
+ p iseq.child_iseqs
6
+ puts iseq.disassemble
7
+
8
+ # GCD. We assume positive numbers
9
+ def gcd(a, b)
10
+ # Make: a <= b
11
+ if a > b
12
+ a, b = [b, a]
13
+ end
14
+
15
+ return nil if a <= 0
16
+
17
+ if a == 1 or b-a == 0
18
+ return a
19
+ end
20
+ return gcd(b-a, a)
21
+ end
22
+
23
+ a, b = ARGV[0..1].map {|arg| arg.to_i}
24
+ puts "The GCD of %d and %d is %d" % [a, b, gcd(a, b)]
@@ -0,0 +1 @@
1
+ # Nothing here. Move along.
@@ -0,0 +1,3 @@
1
+ Thread.new do
2
+ x = 1
3
+ end.join
@@ -0,0 +1,112 @@
1
+ ## require 'thread_frame'
2
+ ## require 'trace'
3
+ require 'rubygems'; require 'require_relative'
4
+ require_relative '../../lib/trepanning'
5
+ require_relative '../../io/string_array'
6
+
7
+ module FnTestHelper
8
+ ## include Trace
9
+
10
+ ## # Synchronous events without C frames or instructions
11
+ # Common setup to create a debugger with String Array I/O attached
12
+ def strarray_setup(debugger_cmds, insn_stepping=false)
13
+ stringin = Trepan::StringArrayInput.open(debugger_cmds)
14
+ stringout = Trepan::StringArrayOutput.open
15
+ d_opts = {:input => stringin, :output => stringout,
16
+ :nx => true}
17
+ d = Trepan.new(d_opts)
18
+
19
+ d.settings[:basename] = true
20
+ d.settings[:different] = false
21
+ d.settings[:autoeval] = false
22
+ return d
23
+ end
24
+
25
+ unless defined?(TREPAN_PROMPT)
26
+ TREPAN_PROMPT = /^\(trepanx\): /
27
+ TREPAN_LOC = /.. \(.+:\d+( @\d+)?\)/
28
+ end
29
+
30
+ # Return the caller's line number
31
+ def get_lineno
32
+ Rubinius::VM.backtrace(0)[1].line
33
+ end
34
+
35
+ def compare_output(right, d, debugger_cmds)
36
+ # require_relative '../../lib/trepanning'
37
+ # Trepan.debug(:set_restart => true)
38
+ got = filter_line_cmd(d.intf[-1].output.output)
39
+ if got != right
40
+ got.each_with_index do |got_line, i|
41
+ if i < right.size and got_line != right[i]
42
+ # dbgr.debugger
43
+ puts "! #{got_line}"
44
+ else
45
+ puts " #{got_line}"
46
+ end
47
+ end
48
+ puts '-' * 10
49
+ right.each_with_index do |right_line, i|
50
+ if i < got.size and got[i] != right_line
51
+ # dbgr.debugger
52
+ puts "! #{right_line}"
53
+ else
54
+ puts " #{right_line}"
55
+ end
56
+ end
57
+ end
58
+ assert_equal(right, got, caller[0])
59
+ end
60
+
61
+ # Return output with source lines prompt and command removed
62
+ def filter_line_cmd(a, show_prompt=false)
63
+ # Remove debugger prompt
64
+ a = a.map do |s|
65
+ s =~ TREPAN_PROMPT ? nil : s
66
+ end.compact unless show_prompt
67
+
68
+ # Remove debugger location lines.
69
+ # For example:
70
+ # -- (/src/external-vcs/trepan/tmp/gcd.rb:4 @21)
71
+ # becomes:
72
+ # --
73
+ a2 = a.map do |s|
74
+ s =~ TREPAN_LOC ? s.gsub(/\(.+:\d+( @\d+)?\)\n/, '').chomp : s.chomp
75
+ end
76
+
77
+ # Canonicalize breakpoint messages.
78
+ # For example:
79
+ # Set breakpoint 1: test/functional/test-tbreak.rb:10 (@0)
80
+ # becomes :
81
+ # Set breakpoint 1: foo.rb:55 (@3)
82
+ a3 = a2.map do |s|
83
+ s.gsub(/^Set (temporary )?breakpoint (\d+): .+:(\d+) \(@\d+\)/,
84
+ 'Set \1breakpoint \2: foo.rb:55 (@3)')
85
+ end
86
+ return a3
87
+ end
88
+
89
+ end
90
+
91
+ # Demo it
92
+ if __FILE__ == $0
93
+ include FnTestHelper
94
+ strarray_setup(%w(eh bee see))
95
+ puts get_lineno()
96
+ p '-- (/src/external-vcs/trepan/tmp/gcd.rb:4)' =~ TREPAN_LOC
97
+ p '(trepan): exit' =~ TREPAN_PROMPT
98
+ output='
99
+ -- (/src/external-vcs/trepan/tmp/gcd.rb:4)
100
+ (trepan): s
101
+ -- (/src/external-vcs/trepan/tmp/gcd.rb:18)
102
+ (trepan): s
103
+ -- (/src/external-vcs/trepan/tmp/gcd.rb:19)
104
+ (trepan): s
105
+ .. (/src/external-vcs/trepan/tmp/gcd.rb:0)
106
+ (trepan): s
107
+ -> (/src/external-vcs/trepan/tmp/gcd.rb:4)
108
+ '.split(/\n/)
109
+ puts filter_line_cmd(output)
110
+ puts '-' * 10
111
+ puts filter_line_cmd(output, true)
112
+ end
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env ruby
2
+ require 'test/unit'
3
+ require 'rubygems'; require 'require_relative'
4
+ require_relative 'fn_helper'
5
+
6
+ def five
7
+ 5
8
+ end
9
+
10
+ class TestNameBreak < Test::Unit::TestCase
11
+
12
+ include FnTestHelper
13
+
14
+ def self.six=(val)
15
+ @six = val
16
+ end
17
+
18
+ def five?(num) 5 == num; end
19
+
20
+ def test_basic
21
+ # Check that we can set breakpoints in parent, sibling and children
22
+ # of sibling returns. We have one more 'continue' than we need
23
+ # just in case something goes wrong.
24
+ cmds = ['break Object#five', 'break TestNameBreak#five?',
25
+ 'break TestNameBreak.six=',
26
+ 'continue', 'continue', 'continue', 'continue']
27
+
28
+ d = strarray_setup(cmds)
29
+ ##############################
30
+ d.start
31
+ five
32
+ five?(5)
33
+ TestNameBreak::six=6
34
+ ##############################
35
+ d.stop # ({:remove => true})
36
+ out = ["-- ",
37
+ "five ",
38
+ "Set breakpoint 1: foo.rb:55 (@3)",
39
+ "Set breakpoint 2: foo.rb:55 (@3)",
40
+ "Set breakpoint 3: foo.rb:55 (@3)",
41
+ "xx ",
42
+ "5",
43
+ "xx ",
44
+ "def five?(num) 5 == num; end",
45
+ "xx ",
46
+ "@six = val"]
47
+ compare_output(out, d, cmds)
48
+ end
49
+
50
+ end
51
+
52
+