ruby-debug 0.10.4 → 0.10.5.rc1

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 (129) hide show
  1. data/AUTHORS +5 -0
  2. data/CHANGES +17 -0
  3. data/ChangeLog +6086 -3711
  4. data/README +39 -0
  5. data/Rakefile +67 -82
  6. data/cli/ruby-debug/commands/breakpoints.rb +4 -2
  7. data/cli/ruby-debug/commands/edit.rb +3 -2
  8. data/cli/ruby-debug/commands/info.rb +5 -4
  9. data/cli/ruby-debug/commands/irb.rb +7 -8
  10. data/cli/ruby-debug/commands/list.rb +1 -1
  11. data/cli/ruby-debug/commands/set.rb +7 -1
  12. data/cli/ruby-debug/commands/show.rb +8 -3
  13. data/cli/ruby-debug/processor.rb +10 -4
  14. data/doc/rdebug.1 +1 -1
  15. data/rdbg.rb +1 -1
  16. data/test/base/base.rb +7 -4
  17. data/test/base/binding.rb +3 -12
  18. data/test/base/catchpoint.rb +2 -9
  19. data/test/base/load.rb +18 -14
  20. data/test/base/reload_bug.rb +2 -2
  21. data/test/cli/commands/catchpoint_test.rb +1 -13
  22. data/test/cli/commands/unit/regexp.rb +2 -8
  23. data/test/data/annotate.cmd +2 -2
  24. data/test/data/annotate.right +8 -8
  25. data/test/data/at-exit.cmd +4 -0
  26. data/test/data/at-exit.right +12 -0
  27. data/test/data/break_bad.cmd +3 -5
  28. data/test/data/break_bad.right +4 -6
  29. data/test/data/break_tracelines.cmd +9 -0
  30. data/test/data/break_tracelines.right +17 -0
  31. data/test/data/breakpoints-basename.cmd +2 -0
  32. data/test/data/breakpoints-basename.right +10 -0
  33. data/test/data/breakpoints.cmd +0 -1
  34. data/test/data/breakpoints.right +1 -3
  35. data/test/data/catch.cmd +1 -0
  36. data/test/data/catch.right +2 -0
  37. data/test/data/continue_bad.cmd +4 -0
  38. data/test/data/continue_bad.right +9 -0
  39. data/test/data/ctrl.right +2 -1
  40. data/test/data/dollar-0.right +3 -2
  41. data/test/data/dollar-0a.right +1 -0
  42. data/test/data/dollar-0b.right +1 -0
  43. data/test/data/edit.cmd +1 -1
  44. data/test/data/edit.right +4 -4
  45. data/test/data/emacs_basic.cmd +1 -34
  46. data/test/data/emacs_basic.right +10 -92
  47. data/test/data/frame.cmd +0 -3
  48. data/test/data/frame.right +0 -4
  49. data/test/data/info-file-break.cmd +4 -0
  50. data/test/data/info-file-break.right +11 -0
  51. data/test/data/info-thread.right +4 -4
  52. data/test/data/info-var-bug2.right +2 -2
  53. data/test/data/info.cmd +0 -1
  54. data/test/data/info.right +1 -5
  55. data/test/data/linetrace-jruby.right +23 -0
  56. data/test/data/list.right +13 -13
  57. data/test/data/output.right +4 -4
  58. data/test/data/post-mortem-osx.right +5 -4
  59. data/test/data/quit.right +9 -0
  60. data/test/data/raise-jruby.right +26 -0
  61. data/test/data/raise.right +1 -1
  62. data/test/data/save.cmd +1 -0
  63. data/test/data/save.right +4 -2
  64. data/test/data/stepping.cmd +2 -2
  65. data/test/data/stepping.right +4 -4
  66. data/test/data/test-init.right +2 -2
  67. data/test/data/trace-jruby.right +14 -0
  68. data/test/example/a/example.rb +1 -0
  69. data/test/example/at-exit.rb +3 -0
  70. data/test/example/b/example.rb +1 -0
  71. data/test/{bp_loop_issue.rb → example/bp_loop_issue.rb} +0 -0
  72. data/test/example/breakpoints-basename.rb +2 -0
  73. data/test/{brkpt-class-bug.rb → example/brkpt-class-bug.rb} +0 -0
  74. data/test/{classes.rb → example/classes.rb} +0 -0
  75. data/test/{dollar-0.rb → example/dollar-0.rb} +1 -0
  76. data/test/{except-bug1.rb → example/except-bug1.rb} +0 -0
  77. data/test/file with space.rb b/data/test/example/file with → space.rb +0 -0
  78. data/test/{gcd.rb → example/gcd.rb} +0 -0
  79. data/test/{info-var-bug.rb → example/info-var-bug.rb} +0 -0
  80. data/test/{info-var-bug2.rb → example/info-var-bug2.rb} +0 -0
  81. data/test/{null.rb → example/null.rb} +0 -0
  82. data/test/{output.rb → example/output.rb} +0 -0
  83. data/test/{pm-bug.rb → example/pm-bug.rb} +0 -0
  84. data/test/{pm.rb → example/pm.rb} +0 -0
  85. data/test/{raise.rb → example/raise.rb} +0 -0
  86. data/test/helper.rb +52 -34
  87. data/test/rdebug-save.1 +2 -2
  88. data/test/test-annotate.rb +4 -16
  89. data/test/test-at-exit.rb +13 -0
  90. data/test/test-break-bad.rb +14 -25
  91. data/test/test-breakpoints.rb +13 -14
  92. data/test/test-brkpt-class-bug.rb +3 -16
  93. data/test/test-catch.rb +3 -15
  94. data/test/test-condition.rb +3 -15
  95. data/test/test-display.rb +3 -15
  96. data/test/test-dollar-0.rb +23 -35
  97. data/test/test-edit.rb +4 -16
  98. data/test/test-emacs-basic.rb +4 -17
  99. data/test/test-enable.rb +3 -15
  100. data/test/test-except-bug1.rb +6 -21
  101. data/test/test-file-with-space.rb +3 -15
  102. data/test/test-finish.rb +11 -23
  103. data/test/test-frame.rb +14 -20
  104. data/test/test-hist.rb +6 -10
  105. data/test/test-info-thread.rb +13 -21
  106. data/test/test-info-var.rb +20 -37
  107. data/test/test-info.rb +16 -15
  108. data/test/test-list.rb +3 -14
  109. data/test/test-method.rb +9 -23
  110. data/test/test-output.rb +3 -16
  111. data/test/test-pm.rb +16 -38
  112. data/test/test-quit.rb +3 -20
  113. data/test/test-raise.rb +3 -15
  114. data/test/test-save.rb +12 -21
  115. data/test/test-setshow.rb +3 -15
  116. data/test/test-source.rb +3 -15
  117. data/test/test-stepping.rb +3 -15
  118. data/test/test-trace.rb +22 -45
  119. metadata +199 -159
  120. data/VERSION +0 -3
  121. data/cli/ruby-debug/commands/continue.RB +0 -48
  122. data/cli/ruby-debug/commands/disassemble.RB +0 -38
  123. data/cli/ruby-debug/commands/raise.RB +0 -41
  124. data/cli/ruby-debug/commands/source.RB +0 -44
  125. data/cli/ruby-debug/processor.RB +0 -484
  126. data/runner.sh +0 -7
  127. data/test/except-bug2.rb +0 -7
  128. data/test/scope-test.rb +0 -8
  129. data/test/tvar.rb +0 -3
data/VERSION DELETED
@@ -1,3 +0,0 @@
1
- # This file was created automatically from data in ext/ruby_debug.c via:
2
- # rake :make_version_file.
3
- 0.10.4
@@ -1,48 +0,0 @@
1
- module Debugger
2
-
3
- # Implements debugger "continue" command.
4
- class ContinueCommand < Command
5
- self.allow_in_post_mortem = false
6
- self.need_context = true
7
- def regexp
8
- /^\s* c(?:ont(?:inue)?)? (?:\s+(.*))? $/x
9
- end
10
-
11
- def execute
12
- unless @state.context
13
- errmsg "We are not in a state we can continue.\n"
14
- return
15
- end
16
- if @match[1] && !@state.context.dead?
17
- if '-' == @match[1]
18
- Debugger.stop if Debugger.started?
19
- else
20
- filename = File.expand_path(@state.file)
21
- line_number = get_int(@match[1], "Continue", 0, nil, 0)
22
- return unless line_number
23
- unless LineCache.trace_line_numbers(filename).member?(line_number)
24
- errmsg("Line %d is not a stopping point in file \"%s\".\n",
25
- line_number, filename)
26
- return
27
- end
28
- @state.context.set_breakpoint(filename, line_number)
29
- end
30
- end
31
- @state.proceed
32
- end
33
-
34
- class << self
35
- def help_command
36
- 'continue'
37
- end
38
-
39
- def help(cmd)
40
- %{
41
- c[ont[inue]][ nnn | -]\trun until program ends, hits a breakpoint or reaches line nnn.
42
-
43
- If - is given then we issue a Debugger.stop to remove tracing the program continues at full speed.
44
- }
45
- end
46
- end
47
- end
48
- end
@@ -1,38 +0,0 @@
1
- module Debugger
2
-
3
- require 'pp'
4
- require 'nodepp'
5
- require 'classtree'
6
- require 'parse_tree'
7
- class Disassemble < Command # :nodoc:
8
- self.allow_in_control = false
9
- @@parse_tree = ParseTree.new(true)
10
-
11
- def regexp
12
- /^\s*(dis(?:assemble)?)\s+/
13
- end
14
-
15
- def execute
16
- expr = @match ? @match.post_match : @input
17
- binding = @state.context ? get_binding : TOPLEVEL_BINDING
18
- method_str = "method(:#{expr})"
19
- if method_obj = debug_eval(method_str, binding)
20
- print @@parse_tree.parse_tree_for_method(method_obj.class,
21
- method_str).inspect
22
- print "#{method_obj}\n"
23
- end
24
- end
25
-
26
- class << self
27
- def help_command
28
- %w|disassemble method-name|
29
- end
30
-
31
- def help(cmd)
32
- %{
33
- dis[assemble] method-name\tdo live unparsing of method name
34
- }
35
- end
36
- end
37
- end if false
38
- end
@@ -1,41 +0,0 @@
1
- module Debugger
2
- class RaiseCommand < Command # :nodoc:
3
- self.allow_in_control = false
4
-
5
- def regexp
6
- /^\s* raise
7
- (?:\s+ (\S+))? \s* $/ix
8
- end
9
-
10
- def execute
11
- excn = @match[1]
12
- exception =
13
- if not excn
14
- # No args given.
15
- RuntimeError
16
- else
17
- unless debug_eval("#{excn}.is_a?(Class)", binding)
18
- errmsg "#{excn} is not known to be a Class\n"
19
- return
20
- end
21
- debug_eval(excn, binding)
22
- end
23
- @state.exception = exception
24
- @state.proceed
25
- end
26
-
27
- class << self
28
- def help_command
29
- 'raise'
30
- end
31
-
32
- def help(cmd)
33
- %{
34
- raise EXCEPTION
35
-
36
- Raise an exception in the debugged program."
37
- }
38
- end
39
- end
40
- end
41
- end
@@ -1,44 +0,0 @@
1
- module Debugger
2
- # Implements debugger "source" command.
3
- class SourceCommand < Command
4
- self.allow_in_control = true
5
-
6
- def regexp
7
- /^\s* so(?:urce)? (\s+ -v)? \s+ (.+) $/x
8
- end
9
-
10
- def execute
11
- if 3 == @match.size then
12
- verbose=true
13
- file=@match[2]
14
- else
15
- verbose=false
16
- file=@match[1]
17
- end
18
-
19
- file = File.expand_path(file).strip
20
- unless File.exist?(file)
21
- errmsg "Command file '#{file}' is not found\n"
22
- return
23
- end
24
- if @state and @state.interface
25
- @state.interface.command_queue += File.open(file).readlines
26
- else
27
- Debugger.run_script(file, @state, verbose)
28
- end
29
- end
30
-
31
- class << self
32
- def help_command
33
- 'source'
34
- end
35
-
36
- def help(cmd)
37
- %{
38
- source FILE\texecutes a file containing debugger commands
39
- }
40
- end
41
- end
42
- end
43
-
44
- end
@@ -1,484 +0,0 @@
1
- require 'ruby-debug/interface'
2
- require 'ruby-debug/command'
3
-
4
- module Debugger
5
-
6
- # Should this be a mixin?
7
- class Processor # :nodoc
8
- attr_accessor :interface
9
- attr_reader :processor
10
- attr_reader :commands
11
-
12
- # Format msg with gdb-style annotation header
13
- def afmt(msg, newline="\n")
14
- "\032\032#{msg}#{newline}"
15
- end
16
-
17
- def aprint(msg)
18
- print afmt(msg) if Debugger.annotate.to_i > 2
19
- end
20
-
21
- # FIXME: use delegate?
22
- def errmsg(*args)
23
- @interface.errmsg(*args)
24
- end
25
-
26
- # Callers of this routine should make sure to use comma to
27
- # separate format argments rather than %. Otherwise it seems that
28
- # if the string you want to print has format specifier, which
29
- # could happen if you are trying to show say a source-code line
30
- # with "puts" or "print" in it, this print routine will give an
31
- # error saying it is looking for more arguments.
32
- def print(*args)
33
- @interface.print(*args)
34
- end
35
-
36
- end
37
-
38
- class CommandProcessor < Processor # :nodoc:
39
- attr_reader :display
40
-
41
- # FIXME: get from Command regexp method.
42
- @@Show_breakpoints_postcmd = [
43
- /^\s*b(?:reak)?/,
44
- /^\s* cond(?:ition)? (?:\s+(\d+)\s*(.*))?$/ix,
45
- /^\s*del(?:ete)?(?:\s+(.*))?$/ix,
46
- /^\s* dis(?:able)? (?:\s+(.*))?$/ix,
47
- /^\s* en(?:able)? (?:\s+(.*))?$/ix,
48
- # "tbreak", "clear",
49
- ]
50
- @@Show_annotations_run = [
51
- /^\s*c(?:ont(?:inue)?)?(?:\s+(.*))?$/,
52
- /^\s*fin(?:ish)?$/,
53
- /^\s*n(?:ext)?([+-])?(?:\s+(.*))?$/,
54
- /^\s*s(?:tep)?([+-])?(?:\s+(.*))?$/
55
- ]
56
-
57
- @@Show_annotations_postcmd = [
58
- /^\s* down (?:\s+(.*))? .*$/x,
59
- /^\s* f(?:rame)? (?:\s+ (.*))? \s*$/x,
60
- /^\s* u(?:p)? (?:\s+(.*))?$/x
61
- ]
62
-
63
- def initialize(interface = LocalInterface.new)
64
- @interface = interface
65
- @commands = []
66
- @display = []
67
-
68
- @mutex = Mutex.new
69
- @last_cmd = nil
70
- @last_file = nil # Filename the last time we stopped
71
- @last_line = nil # line number the last time we stopped
72
- @debugger_breakpoints_were_empty = false # Show breakpoints 1st time
73
- @debugger_displays_were_empty = true # No display 1st time
74
- @debugger_context_was_dead = true # Assume we haven't started.
75
- end
76
-
77
- def interface=(interface)
78
- @mutex.synchronize do
79
- @interface.close if @interface
80
- @interface = interface
81
- end
82
- end
83
-
84
- require 'pathname' # For cleanpath
85
-
86
- # Regularize file name.
87
- # This is also used as a common funnel place if basename is
88
- # desired or if we are working remotely and want to change the
89
- # basename. Or we are eliding filenames.
90
- def self.canonic_file(filename)
91
- # For now we want resolved filenames
92
- if Command.settings[:basename]
93
- File.basename(filename)
94
- else
95
- # Cache this?
96
- Pathname.new(filename).cleanpath.to_s
97
- end
98
- end
99
-
100
- def self.print_location_and_text(file, line)
101
- file_line = "%s:%s\n%s" % [canonic_file(file), line,
102
- Debugger.line_at(file, line)]
103
- # FIXME: use annotations routines
104
- if Debugger.annotate.to_i > 2
105
- file_line = "\032\032source #{file_line}"
106
- elsif ENV['EMACS']
107
- file_line = "\032\032#{file_line}"
108
- end
109
- print file_line
110
- end
111
-
112
- def self.protect(mname)
113
- alias_method "__#{mname}", mname
114
- module_eval %{
115
- def #{mname}(*args)
116
- @mutex.synchronize do
117
- return unless @interface
118
- __#{mname}(*args)
119
- end
120
- rescue IOError, Errno::EPIPE
121
- self.interface = nil
122
- rescue SignalException
123
- raise
124
- rescue Exception => e
125
- unless
126
- print "INTERNAL ERROR!!! #\{$!\}\n" rescue nil
127
- print $!.backtrace.map{|l| "\t#\{l\}"}.join("\n") rescue nil
128
- end
129
- }
130
- end
131
-
132
- def at_breakpoint(context, breakpoint)
133
- aprint 'stopped' if Debugger.annotate.to_i > 2
134
- n = Debugger.breakpoints.index(breakpoint) + 1
135
- file = CommandProcessor.canonic_file(breakpoint.source)
136
- line = breakpoint.pos
137
- if Debugger.annotate.to_i > 2
138
- print afmt("source #{file}:#{line}")
139
- end
140
- print "Breakpoint %d at %s:%s\n", n, file, line
141
- end
142
- protect :at_breakpoint
143
-
144
- def at_catchpoint(context, excpt)
145
- aprint 'stopped' if Debugger.annotate.to_i > 2
146
- file = CommandProcessor.canonic_file(context.frame_file(0))
147
- line = context.frame_line(0)
148
- print afmt("%s:%d" % [file, line]) if ENV['EMACS']
149
- print "Catchpoint at %s:%d: `%s' (%s)\n", file, line, excpt, excpt.class
150
- fs = context.stack_size
151
- tb = caller(0)[-fs..-1]
152
- if tb
153
- for i in tb
154
- print "\tfrom %s\n", i
155
- end
156
- end
157
- end
158
- protect :at_catchpoint
159
-
160
- def at_tracing(context, file, line)
161
- return if defined?(Debugger::RDEBUG_FILE) &&
162
- Debugger::RDEBUG_FILE == file # Don't trace ourself
163
- @last_file = CommandProcessor.canonic_file(file)
164
- file = CommandProcessor.canonic_file(file)
165
- unless file == @last_file and @last_line == line and
166
- Command.settings[:tracing_plus]
167
- print "Tracing(%d):%s:%s %s",
168
- context.thnum, file, line, Debugger.line_at(file, line)
169
- @last_file = file
170
- @last_line = line
171
- end
172
- always_run(context, file, line, 2)
173
- end
174
- protect :at_tracing
175
-
176
- def at_line(context, file, line)
177
- process_commands(context, file, line)
178
- end
179
- protect :at_line
180
-
181
- def at_return(context, file, line)
182
- context.stop_frame = -1
183
- process_commands(context, file, line)
184
- end
185
-
186
- def one_cmd(commands, context, input)
187
- if cmd = commands.find{ |c| c.match(input) }
188
- if context.dead? && cmd.class.need_context
189
- p cmd
190
- print "Command is unavailable\n"
191
- else
192
- cmd.execute
193
- end
194
- else
195
- unknown_cmd = commands.find{|cmd| cmd.class.unknown }
196
- if unknown_cmd
197
- unknown_cmd.execute
198
- else
199
- errmsg "Unknown command: \"#{input}\". Try \"help\".\n"
200
- end
201
- end
202
- end
203
-
204
- private
205
-
206
- # The prompt shown before reading a command.
207
- def prompt(context)
208
- p = '(rdb:%s) ' % (context.dead? ? 'post-mortem' : context.thnum)
209
- p = afmt("pre-prompt")+p+"\n"+afmt("prompt") if
210
- Debugger.annotate.to_i > 2
211
- return p
212
- end
213
-
214
- # Run these commands, for example display commands or possibly
215
- # the list or irb in an "autolist" or "autoirb".
216
- # We return a list of commands that are acceptable to run bound
217
- # to the current state.
218
- def always_run(context, file, line, run_level)
219
- event_cmds = Command.commands.select{|cmd| cmd.event }
220
-
221
- # Remove some commands in post-mortem
222
- event_cmds = event_cmds.find_all do |cmd|
223
- cmd.allow_in_post_mortem
224
- end if context.dead?
225
-
226
- state = State.new(self) do |s|
227
- s.context = context
228
- s.file = file
229
- s.line = line
230
- s.binding = context.frame_binding(0)
231
- s.display = display
232
- s.interface = interface
233
- s.commands = event_cmds
234
- end
235
- @interface.state = state if @interface.respond_to?('state=')
236
-
237
- # Bind commands to the current state.
238
- commands = event_cmds.map{|cmd| cmd.new(state)}
239
-
240
- commands.select do |cmd|
241
- cmd.class.always_run >= run_level
242
- end.each {|cmd| cmd.execute}
243
- return state, commands
244
- end
245
-
246
- # Handle debugger commands
247
- def process_commands(context, file, line)
248
- state, @commands = always_run(context, file, line, 1)
249
- $rdebug_state = state if Command.settings[:debuggertesting]
250
- splitter = lambda do |str|
251
- str.split(/;/).inject([]) do |m, v|
252
- if m.empty?
253
- m << v
254
- else
255
- if m.last[-1] == ?\\
256
- m.last[-1,1] = ''
257
- m.last << ';' << v
258
- else
259
- m << v
260
- end
261
- end
262
- m
263
- end
264
- end
265
-
266
- preloop(@commands, context)
267
- CommandProcessor.print_location_and_text(file, line)
268
- while !state.proceed?
269
- input = if @interface.command_queue.empty?
270
- @interface.read_command(prompt(context))
271
- else
272
- @interface.command_queue.shift
273
- end
274
- break unless input
275
- catch(:debug_error) do
276
- if input == ""
277
- next unless @last_cmd
278
- input = @last_cmd
279
- else
280
- @last_cmd = input
281
- end
282
- splitter[input].each do |cmd|
283
- one_cmd(@commands, context, cmd)
284
- postcmd(@commands, context, cmd)
285
- end
286
- end
287
- end
288
- postloop(@commands, context)
289
- exception = state.exception
290
- @exception = nil
291
- puts "raising exception #{state.exception}"
292
- raise exception if exception
293
- end # process_commands
294
-
295
- def preloop(commands, context)
296
- aprint('stopped') if Debugger.annotate.to_i > 2
297
- if context.dead?
298
- unless @debugger_context_was_dead
299
- if Debugger.annotate.to_i > 2
300
- aprint('exited')
301
- print "The program finished.\n"
302
- end
303
- @debugger_context_was_dead = true
304
- end
305
- end
306
-
307
- if Debugger.annotate.to_i > 2
308
- # if we are here, the stack frames have changed outside the
309
- # command loop (e.g. after a "continue" command), so we show
310
- # the annotations again
311
- breakpoint_annotations(commands, context)
312
- display_annotations(commands, context)
313
- annotation('stack', commands, context, "where")
314
- annotation('variables', commands, context, "info variables") unless
315
- context.dead?
316
- end
317
- end
318
-
319
- def postcmd(commands, context, cmd)
320
- if Debugger.annotate.to_i > 0
321
- cmd = @last_cmd unless cmd
322
- breakpoint_annotations(commands, context) if
323
- @@Show_breakpoints_postcmd.find{|pat| cmd =~ pat}
324
- display_annotations(commands, context)
325
- if @@Show_annotations_postcmd.find{|pat| cmd =~ pat}
326
- annotation('stack', commands, context, "where") if
327
- context.stack_size > 0
328
- annotation('variables', commands, context, "info variables") unless
329
- context.dead?
330
- end
331
- if not context.dead? and @@Show_annotations_run.find{|pat| cmd =~ pat}
332
- aprint 'starting' if Debugger.annotate.to_i > 2
333
-
334
- @debugger_context_was_dead = false
335
- end
336
- end
337
- end
338
-
339
- def postloop(commands, context)
340
- end
341
-
342
- def annotation(label, commands, context, cmd)
343
- print afmt(label)
344
- one_cmd(commands, context, cmd)
345
- ### FIXME ANNOTATE: the following line should be deleted
346
- print "\032\032\n"
347
- end
348
-
349
- def breakpoint_annotations(commands, context)
350
- unless Debugger.breakpoints.empty? and @debugger_breakpoints_were_empty
351
- annotation('breakpoints', commands, context, "info breakpoints")
352
- @debugger_breakpoints_were_empty = Debugger.breakpoints.empty?
353
- end
354
- end
355
-
356
- def display_annotations(commands, context)
357
- return if display.empty?
358
- # have_display = display.find{|d| d[0]}
359
- # return unless have_display and @debugger_displays_were_empty
360
- # @debugger_displays_were_empty = have_display
361
- annotation('display', commands, context, "display")
362
- end
363
-
364
- class State # :nodoc:
365
- attr_accessor :context, :file, :line, :binding
366
- attr_accessor :frame_pos, :previous_line, :display
367
- attr_accessor :interface, :commands, :processor
368
- attr_accessor :exception
369
-
370
- def initialize(processor=nil)
371
- super()
372
- @frame_pos = 0
373
- @previous_line = nil
374
- @proceed = false
375
- @processor = processor
376
- yield self
377
- end
378
-
379
- # FIXME: use delegate?
380
- def errmsg(*args)
381
- @interface.errmsg(*args)
382
- end
383
-
384
- def print(*args)
385
- @interface.print(*args)
386
- end
387
-
388
- def confirm(*args)
389
- @interface.confirm(*args)
390
- end
391
-
392
- def proceed?
393
- @proceed
394
- end
395
-
396
- def proceed
397
- @proceed = true
398
- end
399
- end
400
- end
401
-
402
- class ControlCommandProcessor < Processor # :nodoc:
403
- def initialize(interface)
404
- super()
405
- @interface = interface
406
- @debugger_context_was_dead = true # Assume we haven't started.
407
- end
408
-
409
- def process_commands(verbose=false)
410
- control_cmds = Command.commands.select do |cmd|
411
- cmd.allow_in_control
412
- end
413
- state = State.new(@interface, control_cmds)
414
- @commands = control_cmds.map{|cmd| cmd.new(state) }
415
-
416
- unless @debugger_context_was_dead
417
- if Debugger.annotate.to_i > 2
418
- aprint 'exited'
419
- print "The program finished.\n"
420
- end
421
- @debugger_context_was_dead = true
422
- end
423
-
424
- while input = @interface.read_command(prompt(nil))
425
- print "+#{input}" if verbose
426
- catch(:debug_error) do
427
- if cmd = @commands.find{|c| c.match(input) }
428
- cmd.execute
429
- else
430
- errmsg "Unknown command\n"
431
- end
432
- end
433
- end
434
- rescue IOError, Errno::EPIPE
435
- rescue Exception
436
- print "INTERNAL ERROR!!! #{$!}\n" rescue nil
437
- print $!.backtrace.map{|l| "\t#{l}"}.join("\n") rescue nil
438
- ensure
439
- @interface.close
440
- end
441
-
442
- # The prompt shown before reading a command.
443
- # Note: have an unused 'context' parameter to match the local interface.
444
- def prompt(context)
445
- p = '(rdb:ctrl) '
446
- p = afmt("pre-prompt")+p+"\n"+afmt("prompt") if
447
- Debugger.annotate.to_i > 2
448
- return p
449
- end
450
-
451
- class State # :nodoc:
452
- attr_reader :commands, :interface
453
-
454
- def initialize(interface, commands)
455
- @interface = interface
456
- @commands = commands
457
- end
458
-
459
- def proceed
460
- end
461
-
462
- def errmsg(*args)
463
- @interface.print(*args)
464
- end
465
-
466
- def print(*args)
467
- @interface.print(*args)
468
- end
469
-
470
- def confirm(*args)
471
- 'y'
472
- end
473
-
474
- def context
475
- nil
476
- end
477
-
478
- def file
479
- errmsg "No filename given.\n"
480
- throw :debug_error
481
- end
482
- end # State
483
- end
484
- end