ruby-debug 0.2-mswin32 → 0.3-mswin32

Sign up to get free protection for your applications and to get access to all the features.
@@ -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