ruby-debug 0.2-mswin32 → 0.3-mswin32

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.
@@ -0,0 +1,25 @@
1
+ module Debugger
2
+ if RUBY_PLATFORM =~ /darwin/
3
+ class TextMateCommand < Command
4
+ def regexp
5
+ /^\s*tm(?:ate)?$/
6
+ end
7
+
8
+ def execute
9
+ %x|open 'txmt://open?url=file://#{File.expand_path(@state.file)}&line=#{@state.line}'|
10
+ end
11
+
12
+ class << self
13
+ def help_command
14
+ 'tmate'
15
+ end
16
+
17
+ def help(cmd)
18
+ %{
19
+ tm[ate]\topens a current file in TextMate
20
+ }
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,33 @@
1
+ module Debugger
2
+ class TraceCommand < Command
3
+ def regexp
4
+ /^\s*tr(?:ace)?(?:\s+(on|off))?(?:\s+(all))?$/
5
+ end
6
+
7
+ def execute
8
+ if @match[2]
9
+ Debugger.tracing = @match[1] == 'on'
10
+ elsif @match[1]
11
+ @state.context.tracing = @match[1] == 'on'
12
+ end
13
+ if Debugger.tracing || @state.context.tracing
14
+ print "Trace on.\n"
15
+ else
16
+ print "Trace off.\n"
17
+ end
18
+ end
19
+
20
+ class << self
21
+ def help_command
22
+ 'trace'
23
+ end
24
+
25
+ def help(cmd)
26
+ %{
27
+ tr[ace] (on|off)\tset trace mode of current thread
28
+ tr[ace] (on|off) all\tset trace mode of all threads
29
+ }
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,113 @@
1
+ module Debugger
2
+ module VarFunctions
3
+ def var_list(ary, bind = nil)
4
+ bind ||= @state.binding
5
+ ary.sort!
6
+ for v in ary
7
+ print " %s => %s\n", v, eval(v, bind).inspect
8
+ end
9
+ end
10
+ end
11
+
12
+ class VarConstantCommand < Command
13
+ include VarFunctions
14
+
15
+ def regexp
16
+ /^\s*v(?:ar)?\s+c(?:onst(?:ant)?)?\s+/
17
+ end
18
+
19
+ def execute
20
+ obj = debug_eval(@match.post_match)
21
+ unless obj.kind_of? Module
22
+ print "Should be Class/Module: %s\n", @match.post_match
23
+ else
24
+ var_list(obj.constants, obj.module_eval{binding()})
25
+ end
26
+ end
27
+
28
+ class << self
29
+ def help_command
30
+ 'var'
31
+ end
32
+
33
+ def help(cmd)
34
+ %{
35
+ v[ar] c[onst] <object>\t\tshow constants of object
36
+ }
37
+ end
38
+ end
39
+ end
40
+
41
+ class VarGlobalCommand < Command
42
+ include VarFunctions
43
+
44
+ def regexp
45
+ /^\s*v(?:ar)?\s+g(?:lobal)?\s*$/
46
+ end
47
+
48
+ def execute
49
+ var_list(global_variables)
50
+ end
51
+
52
+ class << self
53
+ def help_command
54
+ 'var'
55
+ end
56
+
57
+ def help(cmd)
58
+ %{
59
+ v[ar] g[lobal]\t\t\tshow global variables
60
+ }
61
+ end
62
+ end
63
+ end
64
+
65
+ class VarInstanceCommand < Command
66
+ include VarFunctions
67
+
68
+ def regexp
69
+ /^\s*v(?:ar)?\s+i(?:nstance)?\s+/
70
+ end
71
+
72
+ def execute
73
+ obj = debug_eval(@match.post_match)
74
+ var_list(obj.instance_variables, obj.instance_eval{binding()})
75
+ end
76
+
77
+ class << self
78
+ def help_command
79
+ 'var'
80
+ end
81
+
82
+ def help(cmd)
83
+ %{
84
+ v[ar] i[nstance] <object>\tshow instance variables of object
85
+ }
86
+ end
87
+ end
88
+ end
89
+
90
+ class VarLocalCommand < Command
91
+ include VarFunctions
92
+
93
+ def regexp
94
+ /^\s*v(?:ar)?\s+l(?:ocal)?\s*$/
95
+ end
96
+
97
+ def execute
98
+ var_list(eval("local_variables", @state.binding))
99
+ end
100
+
101
+ class << self
102
+ def help_command
103
+ 'var'
104
+ end
105
+
106
+ def help(cmd)
107
+ %{
108
+ v[ar] l[ocal]\t\t\tshow local variables
109
+ }
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,41 @@
1
+ module Debugger
2
+ class Lock
3
+ def initialize
4
+ @locker = nil
5
+ @waiting = []
6
+ @locked = false;
7
+ end
8
+
9
+ def locked?
10
+ @locked
11
+ end
12
+
13
+ def lock
14
+ return if Thread.critical
15
+ return if @locker == Thread.current
16
+ while (Thread.critical = true; @locked)
17
+ @waiting.push Thread.current
18
+ Thread.stop
19
+ end
20
+ @locked = true
21
+ @locker = Thread.current
22
+ Thread.critical = false
23
+ self
24
+ end
25
+
26
+ def unlock
27
+ return if Thread.critical
28
+ return unless @locked
29
+ unless @locker == Thread.current
30
+ raise RuntimeError, "unlocked by other"
31
+ end
32
+ Thread.critical = true
33
+ t = @waiting.shift
34
+ @locked = false
35
+ @locker = nil
36
+ Thread.critical = false
37
+ t.run if t
38
+ self
39
+ end
40
+ end
41
+ end
@@ -1,66 +1,71 @@
1
1
  require 'ruby-debug/interface'
2
+ require 'ruby-debug/command'
2
3
 
3
4
  module Debugger
4
5
  class CommandProcessor
5
- DEBUG_LAST_CMD = []
6
-
7
6
  attr_accessor :interface
7
+ attr_reader :display
8
8
 
9
9
  def initialize(interface = LocalInterface.new)
10
10
  @interface = interface
11
11
  @display = []
12
12
  @mutex = Mutex.new
13
+ @last_cmd = nil
13
14
  end
14
15
 
15
16
  def interface=(interface)
16
17
  @mutex.synchronize do
17
- @interface.close
18
- @interface = interface
18
+ @interface.close if @interface
19
+ @interface = interface
19
20
  end
20
21
  end
21
-
22
+
23
+ def self.protect(mname)
24
+ alias_method "__#{mname}", mname
25
+ module_eval %{
26
+ def #{mname}(*args)
27
+ @mutex.synchronize do
28
+ return unless @interface
29
+ __#{mname}(*args)
30
+ end
31
+ rescue IOError
32
+ self.interface = nil
33
+ rescue Exception
34
+ print "INTERNAL ERROR!!! #\{$!\}\n"
35
+ print $!.backtrace.map{|l| "\t#\{l\}"}.join("\n")
36
+ end
37
+ }
38
+ end
39
+
22
40
  def at_breakpoint(context, breakpoint)
23
- @mutex.synchronize do
24
- return unless @interface
25
- n = Debugger.breakpoints.index(breakpoint) + 1
26
- print "Breakpoint %d at %s:%s\n", n, breakpoint.source, breakpoint.pos
27
- end
28
- rescue IOError
29
- self.interface = nil
41
+ n = Debugger.breakpoints.index(breakpoint) + 1
42
+ print "Breakpoint %d at %s:%s\n", n, breakpoint.source, breakpoint.pos
30
43
  end
44
+ protect :at_breakpoint
31
45
 
32
46
  def at_catchpoint(context, excpt)
33
- @mutex.synchronize do
34
- frames = Debugger.current_context.frames
35
- print "%s:%d: `%s' (%s)\n", frames[0].file, frames[0].line, excpt, excpt.class
36
- fs = frames.size
37
- tb = caller(0)[-fs..-1]
38
- if tb
39
- for i in tb
40
- print "\tfrom %s\n", i
41
- end
47
+ frames = context.frames
48
+ print "Catchpoint at %s:%d: `%s' (%s)\n", frames[0].file, frames[0].line, excpt, excpt.class
49
+ fs = frames.size
50
+ tb = caller(0)[-fs..-1]
51
+ if tb
52
+ for i in tb
53
+ print "\tfrom %s\n", i
42
54
  end
43
55
  end
44
- rescue IOError
45
- self.interface = nil
46
56
  end
57
+ protect :at_catchpoint
47
58
 
48
59
  def at_tracing(context, file, line)
49
- @mutex.synchronize do
50
- print "Tracing(%d):%s:%s %s", context.thnum, file, line, line_at(file, line)
51
- end
52
- rescue IOError
53
- self.interface = nil
60
+ print "Tracing(%d):%s:%s %s", context.thnum, file, line, Debugger.line_at(file, line)
54
61
  end
62
+ protect :at_tracing
55
63
 
56
- def at_line(*args)
57
- @mutex.synchronize do
58
- process_commands(*args)
59
- end
60
- rescue IOError
61
- puts 'error'
62
- self.interface = nil
64
+ def at_line(context, file, line, binding)
65
+ print "%s:%d: %s", file, line, Debugger.line_at(file, line)
66
+ process_commands(context, file, line, binding)
63
67
  end
68
+ protect :at_line
64
69
 
65
70
  private
66
71
 
@@ -69,559 +74,117 @@ module Debugger
69
74
  end
70
75
 
71
76
  def process_commands(context, file, line, binding)
72
- frame_pos = 0
73
- binding_file = file
74
- binding_line = line
75
- previous_line = nil
76
- print "%s:%d: %s", binding_file, binding_line, line_at(binding_file, binding_line)
77
- display_expressions(binding)
78
- prompt = true
79
- while prompt and input = @interface.read_command("(rdb:%d) " % context.thnum)
77
+ event_cmds = Command.commands.select{|cmd| cmd.event }
78
+ state = State.new do |s|
79
+ s.context = context
80
+ s.file = file
81
+ s.line = line
82
+ s.binding = binding
83
+ s.display = display
84
+ s.interface = interface
85
+ s.commands = event_cmds
86
+ end
87
+ commands = event_cmds.map{|cmd| cmd.new(state) }
88
+ commands.find{ |cmd| cmd.kind_of?(DisplayCommand) }.execute
89
+
90
+ while !state.proceed? and input = @interface.read_command("(rdb:%d) " % context.thnum)
80
91
  catch(:debug_error) do
81
92
  if input == ""
82
- next unless DEBUG_LAST_CMD[0]
83
- input = DEBUG_LAST_CMD[0]
93
+ next unless @last_cmd
94
+ input = @last_cmd
84
95
  else
85
- DEBUG_LAST_CMD[0] = input
96
+ @last_cmd = input
86
97
  end
87
-
88
- case input
89
- when /^\s*s(?:tep)?(?:\s+(\d+))?$/
90
- context.stop_next = $1 ? $1.to_i : 1
91
- prompt = false
92
-
93
- when /^\s*c(?:ont)?$|^\s*r(?:un)?$/
94
- prompt = false
95
-
96
- when /^\s*v(?:ar)?\s+/
97
- debug_variable_info($', binding)
98
-
99
- when /^\s*w(?:here)?$/, /^\s*f(?:rame)?$/
100
- display_frames(context, frame_pos)
101
-
102
- when /^\s*l(?:ist)?(?:\s+(.+))?$/
103
- if not $1
104
- b = previous_line ? previous_line + 10 : binding_line - 5
105
- e = b + 9
106
- elsif $1 == '-'
107
- b = previous_line ? previous_line - 10 : binding_line - 5
108
- e = b + 9
109
- else
110
- b, e = $1.split(/[-,]/)
111
- if e
112
- b = b.to_i
113
- e = e.to_i
114
- else
115
- b = b.to_i - 5
116
- e = b + 9
117
- end
118
- end
119
- previous_line = b
120
- display_list(b, e, binding_file, binding_line)
121
-
122
- when /^\s*n(?:ext)?(?:\s+(\d+))?$/
123
- steps = $1 ? $1.to_i : 1
124
- context.step_over steps, context.frames.size - frame_pos
125
- prompt = false
126
-
127
- when /^\s*up(?:\s+(\d+))?$/
128
- previous_line = nil
129
- frame_pos += $1 ? $1.to_i : 1
130
- if frame_pos >= context.frames.size
131
- frame_pos = context.frames.size - 1
132
- print "At toplevel"
133
- end
134
- frame = context.frames[frame_pos]
135
- binding, binding_file, binding_line = frame.binding, frame.file, frame.line
136
- print format_frame(frame, frame_pos)
137
-
138
- when /^\s*down(?:\s+(\d+))?$/
139
- previous_line = nil
140
- frame_pos -= $1 ? $1.to_i : 1
141
- if frame_pos < 0
142
- frame_pos = 0
143
- print "At stack bottom\n"
144
- end
145
- frame = context.frames[frame_pos]
146
- binding, binding_file, binding_line = frame.binding, frame.file, frame.line
147
- print format_frame(frame, frame_pos)
148
-
149
- when /^\s*fin(?:ish)?$/
150
- if frame_pos == context.frames.size
151
- print "\"finish\" not meaningful in the outermost frame.\n"
152
- else
153
- context.stop_frame = context.frames.size - frame_pos
154
- frame_pos = 0
155
- prompt = false
156
- end
157
-
158
- when /^\s*b(?:reak)?\s+(?:(.+):)?([^.:\s]+)\s*(?:\sif\s+(.+))?$/
159
- pos = $2
160
- expr = $3
161
- b_file = file
162
- if $1
163
- klass = debug_silent_eval($1, binding)
164
- if klass && !klass.kind_of?(Module)
165
- print "Unknown class #$1\n"
166
- throw :debug_error
167
- end
168
- klass = klass.name if klass
169
- b_file = $1
170
- end
171
- if pos =~ /^\d+$/
172
- pname = pos
173
- pos = pos.to_i
174
- else
175
- pname = pos = pos.intern.id2name
176
- end
177
- b_file = File.basename(b_file)
178
- Debugger.add_breakpoint klass || b_file, pos, expr
179
- print "Set breakpoint %d at %s:%s\n", Debugger.breakpoints.size, klass || b_file, pname
180
-
181
- when /^\s*b(?:reak)?\s+(.+)[#.]([^.:\s]+)(?:\s+if\s+(.+))?$/
182
- pos = $2.intern.id2name
183
- expr = $3
184
- klass = debug_eval($1, binding)
185
- if klass.nil? || !klass.kind_of?(Module)
186
- print "Unknown class #$1\n"
187
- throw :debug_error
188
- end
189
- Debugger.add_breakpoint klass.name, pos, expr
190
- print "Set breakpoint %d at %s.%s\n", Debugger.breakpoints.size, klass, pos
191
-
192
- when /^\s*b(?:reak)?$/
193
- unless Debugger.breakpoints.empty?
194
- print "Breakpoints:\n"
195
- Debugger.breakpoints.each_with_index do |b, n|
196
- if b.expr.nil?
197
- print " %d %s:%s\n", n+1, b.source, b.pos
198
- else
199
- print " %d %s:%s if %s\n", n+1, b.source, b.pos, b.expr
200
- end
201
- end
202
- print "\n"
203
- else
204
- print "No breakpoints\n"
205
- end
206
- when /^\s*del(?:ete)?(?:\s+(\d+))?$/
207
- pos = $1
208
- unless pos
209
- input = @interface.confirm("Clear all breakpoints? (y/n) ")
210
- if input == "y"
211
- Debugger.breakpoints.clear
212
- end
213
- else
214
- pos = pos.to_i
215
- unless Debugger.breakpoints.delete_at(pos-1)
216
- print "Breakpoint %d is not defined\n", pos
217
- end
218
- end
219
-
220
- when /^\s*th(?:read)?\s+/
221
- if debug_thread_info($') == :cont
222
- prompt = false
223
- end
224
-
225
- when /^\s*m(?:ethod)?\s+/
226
- debug_method_info($', binding)
227
-
228
- when /^\s*pp\s+/
229
- out = StringIO.new
230
- PP.pp(debug_eval($', binding), out) rescue out.puts $!.message
231
- print out.string
232
-
233
- when /^\s*(\s*p|e(?:val)?)\s+/
234
- print "%s\n", debug_eval($', binding).inspect
235
-
236
- when /^\s*h(?:elp)?(?:\s+(.+))?$/
237
- debug_print_help($1)
238
-
239
- when /^\s*q(?:uit)?$/
240
- input = @interface.confirm("Really quit? (y/n) ")
241
- if input == "y"
242
- exit! # exit -> exit!: No graceful way to stop threads...
243
- end
244
-
245
- when /^\s*disp(?:lay)?\s+(.+)$/
246
- exp = $1
247
- @display.push [true, exp]
248
- print "%d: ", @display.size
249
- display_expression(exp, binding)
250
-
251
- when /^\s*disp(?:lay)?$/
252
- display_expressions(binding)
253
-
254
- when /^\s*undisp(?:lay)?(?:\s+(\d+))?$/
255
- pos = $1
256
- unless pos
257
- input = @interface.confirm("Clear all expressions? (y/n) ")
258
- if input == "y"
259
- for d in @display
260
- d[0] = false
261
- end
262
- end
263
- else
264
- pos = pos.to_i
265
- if @display[pos-1]
266
- @display[pos-1][0] = false
267
- else
268
- print "Display expression %d is not defined\n", pos
269
- end
270
- end
271
-
272
- when /^\s*cat(?:ch)?(?:\s+(.+))?$/
273
- if $1
274
- excn = $1
275
- if excn == 'off'
276
- Debugger.catchpoint = nil
277
- print "Clear catchpoint.\n"
278
- else
279
- Debugger.catchpoint = excn
280
- print "Set catchpoint %s.\n", excn
281
- end
282
- else
283
- if Debugger.catchpoint
284
- print "Catchpoint %s.\n", Debugger.catchpoint
285
- else
286
- print "No catchpoint.\n"
287
- end
288
- end
289
-
290
- when /^\s*tr(?:ace)?(?:\s+(on|off))?(?:\s+(all))?$/
291
- if defined?( $2 )
292
- Debugger.tracing = $1 == 'on'
293
- elsif defined?( $1 )
294
- context.tracing = $1 == 'on'
295
- end
296
- if Debugger.tracing || context.tracing
297
- print "Trace on.\n"
298
- else
299
- print "Trace off.\n"
300
- end
301
-
98
+
99
+ if cmd = commands.find{ |c| c.match(input) }
100
+ cmd.execute
302
101
  else
303
102
  print "Unknown command\n"
304
103
  end
305
104
  end
306
105
  end
307
106
  end
308
-
309
- def display_expressions(binding)
310
- n = 1
311
- for d in @display
312
- if d[0]
313
- print "%d: ", n
314
- display_expression(d[1], binding)
315
- end
316
- n += 1
317
- end
318
- end
319
107
 
320
- def display_expression(exp, binding)
321
- print "%s = %s\n", exp, debug_silent_eval(exp, binding).to_s
322
- end
108
+ class State
109
+ attr_accessor :context, :file, :line, :binding
110
+ attr_accessor :frame_pos, :previous_line, :display
111
+ attr_accessor :interface, :commands
323
112
 
324
- def debug_eval(str, binding)
325
- begin
326
- val = eval(str, binding)
327
- rescue StandardError, ScriptError => e
328
- at = eval("caller(1)", binding)
329
- print "%s:%s\n", at.shift, e.to_s.sub(/\(eval\):1:(in `.*?':)?/, '')
330
- for i in at
331
- print "\tfrom %s\n", i
332
- end
333
- throw :debug_error
113
+ def initialize
114
+ @frame_pos = 0
115
+ @previous_line = nil
116
+ yield self
334
117
  end
335
- end
336
118
 
337
- def debug_silent_eval(str, binding)
338
- begin
339
- eval(str, binding)
340
- rescue StandardError, ScriptError
341
- nil
119
+ def print(*args)
120
+ @interface.print(*args)
342
121
  end
343
- end
344
-
345
- def debug_variable_info(input, binding)
346
- case input
347
- when /^\s*g(?:lobal)?\s*$/
348
- var_list(global_variables, binding)
349
-
350
- when /^\s*l(?:ocal)?\s*$/
351
- var_list(eval("local_variables", binding), binding)
352
-
353
- when /^\s*i(?:nstance)?\s+/
354
- obj = debug_eval($', binding)
355
- var_list(obj.instance_variables, obj.instance_eval{binding()})
356
122
 
357
- when /^\s*c(?:onst(?:ant)?)?\s+/
358
- obj = debug_eval($', binding)
359
- unless obj.kind_of? Module
360
- print "Should be Class/Module: %s\n", $'
361
- else
362
- var_list(obj.constants, obj.module_eval{binding()})
363
- end
123
+ def confirm(*args)
124
+ @interface.confirm(*args)
364
125
  end
365
- end
366
126
 
367
- def display_frames(context, pos)
368
- context.frames.each_with_index do |frame, idx|
369
- if idx == pos
370
- print "--> "
371
- else
372
- print " "
373
- end
374
- print format_frame(frame, idx)
127
+ def proceed?
128
+ @proceed
375
129
  end
376
- end
377
-
378
- def format_frame(frame, pos)
379
- file, line, id = frame.file, frame.line, frame.id
380
- "#%d %s:%s%s\n" % [pos + 1, file, line, (id ? ":in `#{id.id2name}'" : "")]
381
- end
382
130
 
383
- def var_list(ary, binding)
384
- ary.sort!
385
- for v in ary
386
- print " %s => %s\n", v, eval(v, binding).inspect
131
+ def proceed
132
+ @proceed = true
387
133
  end
388
134
  end
389
-
390
- def display_list(b, e, file, line)
391
- print "[%d, %d] in %s\n", b, e, file
392
- if lines = SCRIPT_LINES__[file] and lines != true
393
- n = 0
394
- b.upto(e) do |n|
395
- if n > 0 && lines[n-1]
396
- if n == line
397
- print "=> %d %s\n", n, lines[n-1].chomp
398
- else
399
- print " %d %s\n", n, lines[n-1].chomp
400
- end
401
- end
402
- end
403
- else
404
- print "No sourcefile available for %s\n", file
405
- end
135
+ end
136
+
137
+ class ControlCommandProcessor
138
+ def initialize(interface)
139
+ @interface = interface
406
140
  end
407
-
408
- def debug_method_info(input, binding)
409
- case input
410
- when /^i(:?nstance)?\s+/
411
- obj = debug_eval($', binding)
412
-
413
- len = 0
414
- for v in obj.methods.sort
415
- len += v.size + 1
416
- if len > 70
417
- len = v.size + 1
418
- print "\n"
419
- end
420
- print "%s ", v
421
- end
422
- print "\n"
423
-
424
- else
425
- obj = debug_eval(input, binding)
426
- unless obj.kind_of? Module
427
- print "Should be Class/Module: %s\n", input
428
- else
429
- len = 0
430
- for v in obj.instance_methods(false).sort
431
- len += v.size + 1
432
- if len > 70
433
- len = v.size + 1
434
- print "\n"
435
- end
436
- print "%s ", v
141
+
142
+ def print(*args)
143
+ @interface.print(*args)
144
+ end
145
+
146
+ def process_commands
147
+ control_cmds = Command.commands.select{|cmd| cmd.control }
148
+ state = State.new(@interface, control_cmds)
149
+ commands = control_cmds.map{|cmd| cmd.new(state) }
150
+
151
+ while input = @interface.read_command("(rdb:ctrl) ")
152
+ catch(:debug_error) do
153
+ if cmd = commands.find{|c| c.match(input) }
154
+ cmd.execute
155
+ else
156
+ print "Unknown command\n"
437
157
  end
438
- print "\n"
439
158
  end
440
159
  end
160
+ rescue IOError
161
+ rescue Exception
162
+ print "INTERNAL ERROR!!! #{$!}\n"
163
+ print $!.backtrace.map{|l| "\t#{l}"}.join("\n")
441
164
  end
442
-
443
- def display_context(c)
444
- if c.thread == Thread.current
445
- print "+"
446
- else
447
- print " "
165
+
166
+ class State
167
+ attr_reader :commands
168
+ def initialize(interface, commands)
169
+ @interface = interface
170
+ @commands = commands
448
171
  end
449
- print "%d ", c.thnum
450
- print "%s\t", c.thread.inspect
451
- last_frame = c.frames.first
452
- if last_frame
453
- print "%s:%d", last_frame.file, last_frame.line
172
+
173
+ def proceed
454
174
  end
455
- print "\n"
456
- end
457
-
458
- def display_all_contexts
459
- threads = Debugger.contexts.sort_by{|c| c.thnum}.each do |c|
460
- display_context(c)
175
+
176
+ def print(*args)
177
+ @interface.print(*args)
461
178
  end
462
- end
463
-
464
- def get_context(thnum)
465
- Debugger.contexts.find{|c| c.thnum == thnum}
466
- end
467
-
468
- def debug_thread_info(input)
469
- case input
470
- when /^l(?:ist)?/
471
- display_all_contexts
472
-
473
- when /^c(?:ur(?:rent)?)?$/
474
- display_context(Debugger.current_context)
475
-
476
- when /^(?:sw(?:itch)?\s+)?(\d+)/
477
- c = get_context($1.to_i)
478
- if c == Debugger.current_context
479
- print "It's the current thread.\n"
480
- else
481
- display_context(c)
482
- c.stop_next = 1
483
- c.thread.run
484
- return :cont
485
- end
486
-
487
- when /^stop\s+(\d+)/
488
- c = get_context($1.to_i)
489
- if c == Debugger.current_context
490
- print "It's the current thread.\n"
491
- elsif c.thread.stop?
492
- print "Already stopped.\n"
493
- else
494
- display_context(c)
495
- c.set_suspend
496
- end
497
-
498
- when /^resume\s+(\d+)/
499
- c = get_context($1.to_i)
500
- if c == Debugger.current_context
501
- print "It's the current thread.\n"
502
- elsif !c.thread.stop?
503
- print "Already running."
504
- else
505
- display_context(c)
506
- c.thread.run
507
- end
179
+
180
+ def confirm(*args)
181
+ 'y'
508
182
  end
509
- end
510
183
 
511
- def line_at(file, line)
512
- lines = SCRIPT_LINES__[file]
513
- if lines
514
- return "\n" if lines == true
515
- line = lines[line-1]
516
- return "\n" unless line
517
- return line.gsub(/^\s+/, '')
518
- end
519
- return "\n"
520
- end
521
-
522
- COMMANDS = {
523
- 'break' => %{
524
- b[reak]\tlist breakpoints
525
- b[reak] [file|class(:|.)]<line|method> [if expr] -
526
- set breakpoint to some position, (optionally) if expr == true
527
- },
528
- 'delete' => %{
529
- del[ete][ nnn]\tdelete some or all breakpoints
530
- },
531
- 'catch' => %{
532
- cat[ch]\t\t\tshow catchpoint
533
- cat[ch] <an Exception>\tset catchpoint to an exception
534
- },
535
- 'display' => %{
536
- disp[lay] <expression>\tadd expression into display expression list
537
- },
538
- 'undisplay' => %{
539
- undisp[lay][ nnn]\tdelete one particular or all display expressions
540
- },
541
- 'cont' => %{
542
- c[ont]\trun until program ends or hit breakpoint
543
- },
544
- 'run' => %{
545
- r[un]\talias for cont
546
- },
547
- 'step' => %{
548
- s[tep][ nnn]\tstep (into methods) one line or till line nnn
549
- },
550
- 'next' => %{
551
- n[ext][ nnn]\tgo over one line or till line nnn
552
- },
553
- 'where' => %{
554
- w[here]\tdisplay frames
555
- },
556
- 'frame' => %{
557
- f[rame]\talias for where
558
- },
559
- 'list' => %{
560
- l[ist][ (-|nn-mm)]\tlist program, '-' list backwards, nn-mm list given lines
561
- },
562
- 'up' => %{
563
- up[ nn]\tmove to higher frame
564
- },
565
- 'down' => %{
566
- down[ nn]\tmove to lower frame
567
- },
568
- 'finish' => %{
569
- fin[ish]\treturn to outer frame
570
- },
571
- 'quit' => %{
572
- q[uit]\texit from debugger
573
- },
574
- 'trace' => %{
575
- tr[ace] (on|off)\tset trace mode of current thread
576
- tr[ace] (on|off) all\tset trace mode of all threads
577
- },
578
- 'var' => %{
579
- v[ar] g[lobal]\t\t\tshow global variables
580
- v[ar] l[ocal]\t\t\tshow local variables
581
- v[ar] i[nstance] <object>\tshow instance variables of object
582
- v[ar] c[onst] <object>\t\tshow constants of object
583
- },
584
- 'method' => %{
585
- m[ethod] i[nstance] <obj>\tshow methods of object
586
- m[ethod] <class|module>\t\tshow instance methods of class or module
587
- },
588
- 'thread' => %{
589
- th[read] l[ist]\t\t\tlist all threads
590
- th[read] c[ur[rent]]\t\tshow current thread
591
- th[read] [sw[itch]] <nnn>\tswitch thread context to nnn
592
- th[read] stop <nnn>\t\tstop thread nnn
593
- th[read] resume <nnn>\t\tresume thread nnn
594
- },
595
- 'p' => %{
596
- p expression\tevaluate expression and print its value
597
- },
598
- 'eval' => %{
599
- e[val] expression\tevaluate expression and print its value,
600
- \t\t\talias for p
601
- },
602
- 'pp' => %{
603
- pp expression\tevaluate expression and print its value
604
- },
605
- 'help' => %{
606
- h[elp]\tprint this help
607
- }
608
- }
609
-
610
- def debug_print_help(command)
611
- print "ruby-debug help v.#{Debugger::VERSION}\n"
612
- help = COMMANDS[command]
613
- if help
614
- print help.split("\n").map{|l| l.gsub(/^ +/, '')}.join("\n")
615
- else
616
- print "Available commands:\n"
617
- require 'enumerator'
618
- COMMANDS.keys.sort.enum_slice(12).each do |slice|
619
- print slice.join(' ')
620
- print "\n"
621
- end
184
+ def file
185
+ print "No filename given.\n"
186
+ throw :debug_error
622
187
  end
623
- print "\n"
624
188
  end
625
-
626
189
  end
627
190
  end