ruby-debug 0.10.0 → 0.10.1

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 (152) hide show
  1. data/CHANGES +94 -2
  2. data/ChangeLog +5225 -0
  3. data/README +30 -1
  4. data/Rakefile +55 -24
  5. data/bin/rdebug +249 -128
  6. data/cli/ruby-debug/command.rb +30 -3
  7. data/cli/ruby-debug/commands/breakpoints.rb +54 -24
  8. data/cli/ruby-debug/commands/catchpoint.rb +13 -12
  9. data/cli/ruby-debug/commands/condition.rb +49 -0
  10. data/cli/ruby-debug/commands/continue.rb +32 -0
  11. data/cli/ruby-debug/commands/control.rb +19 -43
  12. data/cli/ruby-debug/commands/disassemble.RB +38 -0
  13. data/cli/ruby-debug/commands/display.rb +1 -1
  14. data/cli/ruby-debug/commands/edit.rb +48 -0
  15. data/cli/ruby-debug/commands/enable.rb +78 -35
  16. data/cli/ruby-debug/commands/eval.rb +6 -5
  17. data/cli/ruby-debug/commands/finish.rb +42 -0
  18. data/cli/ruby-debug/commands/frame.rb +64 -33
  19. data/cli/ruby-debug/commands/help.rb +19 -15
  20. data/cli/ruby-debug/commands/info.rb +295 -36
  21. data/cli/ruby-debug/commands/irb.rb +3 -1
  22. data/cli/ruby-debug/commands/list.rb +27 -50
  23. data/cli/ruby-debug/commands/quit.rb +38 -0
  24. data/cli/ruby-debug/commands/reload.rb +40 -0
  25. data/cli/ruby-debug/commands/save.rb +80 -0
  26. data/cli/ruby-debug/commands/{settings.rb → set.rb} +50 -12
  27. data/cli/ruby-debug/commands/show.rb +83 -27
  28. data/cli/ruby-debug/commands/source.rb +36 -0
  29. data/cli/ruby-debug/commands/stepping.rb +36 -72
  30. data/cli/ruby-debug/commands/threads.rb +32 -23
  31. data/cli/ruby-debug/commands/variables.rb +34 -4
  32. data/cli/ruby-debug/helper.rb +10 -75
  33. data/cli/ruby-debug/interface.rb +72 -9
  34. data/cli/ruby-debug/processor.rb +203 -100
  35. data/doc/rdebug.1 +7 -2
  36. data/rdbg.rb +33 -0
  37. data/test/{test-ruby-debug-base.rb → base/base.rb} +27 -29
  38. data/test/base/binding.rb +31 -0
  39. data/test/base/catchpoint.rb +26 -0
  40. data/test/base/load.rb +40 -0
  41. data/test/data/annotate.cmd +29 -0
  42. data/test/data/annotate.right +137 -0
  43. data/test/data/break_bad.cmd +18 -0
  44. data/test/data/break_bad.right +28 -0
  45. data/test/data/breakpoints.cmd +38 -0
  46. data/test/data/breakpoints.right +98 -0
  47. data/test/data/condition.cmd +28 -0
  48. data/test/data/condition.right +65 -0
  49. data/test/data/ctrl.cmd +23 -0
  50. data/test/data/ctrl.right +69 -0
  51. data/test/{display.cmd → data/display.cmd} +7 -1
  52. data/test/{display.right → data/display.right} +13 -6
  53. data/test/data/dollar-0.right +2 -0
  54. data/test/data/dollar-0a.right +2 -0
  55. data/test/data/dollar-0b.right +2 -0
  56. data/test/data/edit.cmd +12 -0
  57. data/test/data/edit.right +19 -0
  58. data/test/{breakpoints.cmd → data/emacs_basic.cmd} +0 -0
  59. data/test/{breakpoints.right → data/emacs_basic.right} +24 -12
  60. data/test/data/enable.cmd +20 -0
  61. data/test/data/enable.right +36 -0
  62. data/test/data/finish.cmd +16 -0
  63. data/test/data/finish.right +43 -0
  64. data/test/{frame.cmd → data/frame.cmd} +2 -0
  65. data/test/{frame.right → data/frame.right} +8 -2
  66. data/test/{help.cmd → data/help.cmd} +8 -0
  67. data/test/data/help.right +21 -0
  68. data/test/data/history.right +7 -0
  69. data/test/data/info-thread.cmd +13 -0
  70. data/test/data/info-thread.right +37 -0
  71. data/test/data/info-var-bug2.cmd +5 -0
  72. data/test/data/info-var-bug2.right +10 -0
  73. data/test/{info-var.cmd → data/info-var.cmd} +3 -3
  74. data/test/{info-var.right → data/info-var.right} +20 -15
  75. data/test/{info.cmd → data/info.cmd} +10 -1
  76. data/test/data/info.right +65 -0
  77. data/test/data/linetrace.cmd +6 -0
  78. data/test/data/linetrace.right +32 -0
  79. data/test/data/linetracep.cmd +7 -0
  80. data/test/data/linetracep.right +25 -0
  81. data/test/data/list.cmd +19 -0
  82. data/test/data/list.right +127 -0
  83. data/test/data/noquit.right +1 -0
  84. data/test/data/output.cmd +6 -0
  85. data/test/data/output.right +41 -0
  86. data/test/data/post-mortem-next.cmd +8 -0
  87. data/test/data/post-mortem-next.right +14 -0
  88. data/test/data/post-mortem-osx.right +31 -0
  89. data/test/data/post-mortem.cmd +13 -0
  90. data/test/data/post-mortem.right +31 -0
  91. data/test/{quit.cmd → data/quit.cmd} +2 -5
  92. data/test/data/quit.right +9 -0
  93. data/test/data/raise.cmd +11 -0
  94. data/test/data/raise.right +26 -0
  95. data/test/{setshow.cmd → data/setshow.cmd} +0 -1
  96. data/test/{setshow.right → data/setshow.right} +0 -1
  97. data/test/data/source.cmd +5 -0
  98. data/test/data/source.right +15 -0
  99. data/test/{stepping.cmd → data/stepping.cmd} +6 -2
  100. data/test/{stepping.right → data/stepping.right} +13 -3
  101. data/test/data/test-init-cygwin.right +7 -0
  102. data/test/data/test-init-osx.right +4 -0
  103. data/test/data/test-init.right +5 -0
  104. data/test/data/trace.right +23 -0
  105. data/test/dollar-0.rb +5 -0
  106. data/test/except-bug2.rb +7 -0
  107. data/test/gcd-dbg-nox.rb +31 -0
  108. data/test/gcd-dbg.rb +30 -0
  109. data/test/helper.rb +44 -14
  110. data/test/info-var-bug.rb +2 -0
  111. data/test/info-var-bug2.rb +2 -0
  112. data/test/null.rb +1 -0
  113. data/test/output.rb +2 -0
  114. data/test/pm-base.rb +22 -0
  115. data/test/pm.rb +11 -0
  116. data/test/raise.rb +3 -0
  117. data/test/tdebug.rb +88 -40
  118. data/test/test-annotate.rb +25 -0
  119. data/test/test-break-bad.rb +25 -0
  120. data/test/test-breakpoints.rb +14 -17
  121. data/test/test-condition.rb +25 -0
  122. data/test/test-ctrl.rb +54 -0
  123. data/test/test-display.rb +15 -15
  124. data/test/test-dollar-0.rb +39 -0
  125. data/test/test-edit.rb +26 -0
  126. data/test/test-emacs-basic.rb +26 -0
  127. data/test/test-enable.rb +25 -0
  128. data/test/test-finish.rb +34 -0
  129. data/test/test-frame.rb +15 -16
  130. data/test/test-help.rb +34 -18
  131. data/test/test-hist.rb +68 -0
  132. data/test/test-info-thread.rb +32 -0
  133. data/test/test-info-var.rb +28 -14
  134. data/test/test-info.rb +15 -17
  135. data/test/test-init.rb +41 -0
  136. data/test/test-list.rb +25 -0
  137. data/test/test-output.rb +26 -0
  138. data/test/test-pm.rb +46 -0
  139. data/test/test-quit.rb +19 -17
  140. data/test/test-raise.rb +25 -0
  141. data/test/test-setshow.rb +14 -13
  142. data/test/test-source.rb +25 -0
  143. data/test/test-stepping.rb +14 -14
  144. data/test/test-trace.rb +63 -0
  145. data/test/thread1.rb +26 -0
  146. metadata +125 -31
  147. data/cli/ruby-debug/commands/script.rb +0 -64
  148. data/runner.sh +0 -7
  149. data/test/help.right +0 -4
  150. data/test/info.right +0 -35
  151. data/test/quit.right +0 -22
  152. data/test/test-columnize.rb +0 -46
@@ -1,13 +1,43 @@
1
1
  module Debugger
2
- class LocalInterface # :nodoc:
2
+ class Interface # :nodoc:
3
+
4
+ # Common routine for reporting debugger error messages.
5
+ # Derived classed may want to override this to capture output.
6
+ def errmsg(*args)
7
+ if Debugger.annotate.to_i > 2
8
+ aprint 'error-begin'
9
+ print(*args)
10
+ aprint ''
11
+ else
12
+ print '*** '
13
+ print(*args)
14
+ end
15
+ end
16
+
17
+ # Format msg with gdb-style annotation header
18
+ def afmt(msg, newline="\n")
19
+ "\032\032#{msg}#{newline}"
20
+ end
21
+
22
+ def aprint(msg)
23
+ print afmt(msg)
24
+ end
25
+
26
+ end
27
+
28
+ class LocalInterface < Interface # :nodoc:
29
+ attr_accessor :command_queue
3
30
  attr_accessor :histfile
4
31
  attr_accessor :history_save
5
32
  attr_accessor :history_length
33
+ attr_accessor :restart_file
6
34
 
7
35
  unless defined?(FILE_HISTORY)
8
36
  FILE_HISTORY = ".rdebug_hist"
9
37
  end
10
38
  def initialize()
39
+ super
40
+ @command_queue = []
11
41
  @history_save = true
12
42
  # take gdb's default
13
43
  @history_length = ENV["HISTSIZE"] ? ENV["HISTSIZE"].to_i : 256
@@ -18,7 +48,8 @@ module Debugger
18
48
  line.chomp!
19
49
  Readline::HISTORY << line
20
50
  end
21
- end if File.exists?(@histfile)
51
+ end if File.exist?(@histfile)
52
+ @restart_file = nil
22
53
  end
23
54
 
24
55
  def read_command(prompt)
@@ -35,24 +66,36 @@ module Debugger
35
66
 
36
67
  def close
37
68
  end
69
+
70
+ # Things to do before quitting
71
+ def finalize
72
+ if Debugger.method_defined?("annotate") and Debugger.annotate.to_i > 2
73
+ print "\032\032exited\n\n"
74
+ end
75
+ if Debugger.respond_to?(:save_history)
76
+ Debugger.save_history
77
+ end
78
+ end
38
79
 
39
80
  private
40
-
41
81
  begin
42
82
  require 'readline'
43
83
  class << Debugger
44
84
  define_method(:save_history) do
45
- @histfile ||= File.join(ENV["HOME"]||ENV["HOMEPATH"]||".",
85
+ iface = self.handler.interface
86
+ iface.histfile ||= File.join(ENV["HOME"]||ENV["HOMEPATH"]||".",
46
87
  FILE_HISTORY)
47
- open(@histfile, 'w') do |file|
48
- Readline::HISTORY.to_a.last(@history_length).each do |line|
88
+ open(iface.histfile, 'w') do |file|
89
+ Readline::HISTORY.to_a.last(iface.history_length).each do |line|
49
90
  file.puts line unless line.strip.empty?
50
- end if @history_save
91
+ end if defined?(iface.history_save) and iface.history_save
51
92
  end rescue nil
52
93
  end
53
94
  public :save_history
54
95
  end
55
- Debugger.debug_at_exit { Debugger.save_history }
96
+ Debugger.debug_at_exit do
97
+ finalize if respond_to?(:finalize)
98
+ end
56
99
 
57
100
  def readline(prompt, hist)
58
101
  Readline::readline(prompt, hist)
@@ -72,15 +115,29 @@ module Debugger
72
115
  end
73
116
 
74
117
  class RemoteInterface # :nodoc:
118
+ attr_accessor :command_queue
75
119
  attr_accessor :histfile
76
120
  attr_accessor :history_save
77
121
  attr_accessor :history_length
122
+ attr_accessor :restart_file
78
123
 
79
124
  def initialize(socket)
125
+ @command_queue = []
80
126
  @socket = socket
81
127
  @history_save = false
82
128
  @history_length = 256
83
129
  @histfile = ''
130
+ # Do we read the histfile?
131
+ # open(@histfile, 'r') do |file|
132
+ # file.each do |line|
133
+ # line.chomp!
134
+ # Readline::HISTORY << line
135
+ # end
136
+ # end if File.exist?(@histfile)
137
+ @restart_file = nil
138
+ end
139
+
140
+ def finalize
84
141
  end
85
142
 
86
143
  def read_command(prompt)
@@ -110,11 +167,14 @@ module Debugger
110
167
  end
111
168
  end
112
169
 
113
- class ScriptInterface # :nodoc:
170
+ class ScriptInterface < Interface # :nodoc:
171
+ attr_accessor :command_queue
114
172
  attr_accessor :histfile
115
173
  attr_accessor :history_save
116
174
  attr_accessor :history_length
117
175
  def initialize(file, out, verbose=false)
176
+ super()
177
+ @command_queue = []
118
178
  @file = file.respond_to?(:gets) ? file : open(file)
119
179
  @out = out
120
180
  @verbose = verbose
@@ -123,6 +183,9 @@ module Debugger
123
183
  @histfile = ''
124
184
  end
125
185
 
186
+ def finalize
187
+ end
188
+
126
189
  def read_command(prompt)
127
190
  while result = @file.gets
128
191
  puts "# #{result}" if @verbose
@@ -3,16 +3,60 @@ require 'ruby-debug/command'
3
3
 
4
4
  module Debugger
5
5
 
6
- annotate = 0
7
-
8
- class CommandProcessor # :nodoc:
6
+ # Should this be a mixin?
7
+ class Processor # :nodoc
9
8
  attr_accessor :interface
10
- attr_reader :display
9
+
10
+ # Format msg with gdb-style annotation header
11
+ def afmt(msg, newline="\n")
12
+ "\032\032#{msg}#{newline}"
13
+ end
11
14
 
12
- @@Show_breakpoints_postcmd = ["break", "tbreak", "disable", "enable",
13
- "condition", "clear", "delete"]
14
- @@Show_annotations_preloop = ["step", "continue", "next", "finish"]
15
- @@Show_annotations_postcmd = ["down", "frame", "up"]
15
+ def aprint(msg)
16
+ print afmt(msg) if Debugger.annotate.to_i > 2
17
+ end
18
+
19
+ # FIXME: use delegate?
20
+ def errmsg(*args)
21
+ @interface.errmsg(*args)
22
+ end
23
+
24
+ # Callers of this routine should make sure to use comma to
25
+ # separate format argments rather than %. Otherwise it seems that
26
+ # if the string you want to print has format specifier, which
27
+ # could happen if you are trying to show say a source-code line
28
+ # with "puts" or "print" in it, this print routine will give an
29
+ # error saying it is looking for more arguments.
30
+ def print(*args)
31
+ @interface.print(*args)
32
+ end
33
+
34
+ end
35
+
36
+ class CommandProcessor < Processor # :nodoc:
37
+ attr_reader :display
38
+
39
+ # FIXME: get from Command regexp method.
40
+ @@Show_breakpoints_postcmd = [
41
+ /^\s*b(?:reak)?/,
42
+ /^\s* cond(?:ition)? (?:\s+(\d+)\s*(.*))?$/ix,
43
+ /^\s*del(?:ete)?(?:\s+(.*))?$/ix,
44
+ /^\s* dis(?:able)? (?:\s+(.*))?$/ix,
45
+ /^\s* en(?:able)? (?:\s+(.*))?$/ix,
46
+ # "tbreak", "clear",
47
+ ]
48
+ @@Show_annotations_run = [
49
+ /^\s*c(?:ont(?:inue)?)?(?:\s+(.*))?$/,
50
+ /^\s*fin(?:ish)?$/,
51
+ /^\s*n(?:ext)?([+-])?(?:\s+(.*))?$/,
52
+ /^\s*s(?:tep)?([+-])?(?:\s+(.*))?$/
53
+ ]
54
+
55
+ @@Show_annotations_postcmd = [
56
+ /^\s* down (?:\s+(.*))? .*$/x,
57
+ /^\s* f(?:rame)? (?:\s+ (.*))? \s*$/x,
58
+ /^\s* u(?:p)? (?:\s+(.*))?$/x
59
+ ]
16
60
 
17
61
  def initialize(interface = LocalInterface.new)
18
62
  @interface = interface
@@ -20,10 +64,11 @@ module Debugger
20
64
 
21
65
  @mutex = Mutex.new
22
66
  @last_cmd = nil
23
- @actions = []
24
67
  @last_file = nil # Filename the last time we stopped
25
68
  @last_line = nil # line number the last time we stopped
26
- @output_annotation_in_progress = false
69
+ @debugger_breakpoints_were_empty = false # Show breakpoints 1st time
70
+ @debugger_displays_were_empty = true # No display 1st time
71
+ @debugger_context_was_dead = true # Assume we haven't started.
27
72
  end
28
73
 
29
74
  def interface=(interface)
@@ -50,8 +95,15 @@ module Debugger
50
95
  end
51
96
 
52
97
  def self.print_location_and_text(file, line)
53
- print "#{"\032\032" if ENV['EMACS']}#{canonic_file(file)}:#{line}\n" +
54
- "#{Debugger.line_at(file, line)}"
98
+ file_line = "%s:%s\n%s" % [canonic_file(file), line,
99
+ Debugger.line_at(file, line)]
100
+ # FIXME: use annotations routines
101
+ if Debugger.annotate.to_i > 2
102
+ file_line = "\032\032source #{file_line}"
103
+ elsif ENV['EMACS']
104
+ file_line = "\032\032#{file_line}"
105
+ end
106
+ print file_line
55
107
  end
56
108
 
57
109
  def self.protect(mname)
@@ -72,31 +124,23 @@ module Debugger
72
124
  end
73
125
 
74
126
  def at_breakpoint(context, breakpoint)
75
- if @output_annotation_in_progress
76
- print "\032\032\n"
77
- @output_annotation_in_progress = false
78
- end
79
-
127
+ aprint 'stopped' if Debugger.annotate.to_i > 2
80
128
  n = Debugger.breakpoints.index(breakpoint) + 1
81
- print("\032\032%s:%s\n",
82
- CommandProcessor.canonic_file(breakpoint.source),
83
- breakpoint.pos) if ENV['EMACS']
84
- print "Breakpoint %d at %s:%s\n", n, breakpoint.source, breakpoint.pos
129
+ file = CommandProcessor.canonic_file(breakpoint.source)
130
+ line = breakpoint.pos
131
+ if Debugger.annotate.to_i > 2
132
+ print afmt("source #{file}:#{line}")
133
+ end
134
+ print "Breakpoint %d at %s:%s\n", n, file, line
85
135
  end
86
136
  protect :at_breakpoint
87
137
 
88
138
  def at_catchpoint(context, excpt)
89
- if @output_annotation_in_progress
90
- print "\032\032\n"
91
- @output_annotation_in_progress = false
92
- end
93
-
94
- print "\032\032%s:%d\n",
95
- CommandProcessor.canonic_file(context.frame_file(1)),
96
- context.frame_line(1) if ENV['EMACS']
97
- print "Catchpoint at %s:%d: `%s' (%s)\n",
98
- CommandProcessor.canonic_file(context.frame_file(1)),
99
- context.frame_line(1), excpt, excpt.class
139
+ aprint 'stopped' if Debugger.annotate.to_i > 2
140
+ file = CommandProcessor.canonic_file(context.frame_file(0))
141
+ line = context.frame_line(0)
142
+ print afmt("%s:%d" % [file, line]) if ENV['EMACS']
143
+ print "Catchpoint at %s:%d: `%s' (%s)\n", file, line, excpt, excpt.class
100
144
  fs = context.stack_size
101
145
  tb = caller(0)[-fs..-1]
102
146
  if tb
@@ -108,11 +152,8 @@ module Debugger
108
152
  protect :at_catchpoint
109
153
 
110
154
  def at_tracing(context, file, line)
111
- if @output_annotation_in_progress
112
- print "\032\032\n"
113
- @output_annotation_in_progress = false
114
- end
115
-
155
+ return if defined?(Debugger::RDEBUG_FILE) &&
156
+ Debugger::RDEBUG_FILE == file # Don't trace ourself
116
157
  @last_file = CommandProcessor.canonic_file(file)
117
158
  file = CommandProcessor.canonic_file(file)
118
159
  unless file == @last_file and @last_line == line and
@@ -131,30 +172,33 @@ module Debugger
131
172
  end
132
173
  protect :at_line
133
174
 
134
- private
135
-
136
- # Callers of this routine should make sure to use comma to
137
- # separate format argments rather than %. Otherwise it seems that
138
- # if the string you want to print has format specifier, which
139
- # could happen if you are trying to show say a source-code line
140
- # with "puts" or "print" in it, this print routine will give an
141
- # error saying it is looking for more arguments.
142
- def print(*args)
143
- @interface.print(*args)
175
+ def at_return(context, file, line)
176
+ context.stop_frame = -1
177
+ process_commands(context, file, line)
144
178
  end
145
179
 
180
+ private
181
+
182
+ # The prompt shown before reading a command.
146
183
  def prompt(context)
147
- if context.dead?
148
- "(rdb:post-mortem) "
149
- else
150
- "(rdb:%d) " % context.thnum
151
- end
184
+ p = '(rdb:%s) ' % (context.dead? ? 'post-mortem' : context.thnum)
185
+ p = afmt("pre-prompt")+p+"\n"+afmt("prompt") if
186
+ Debugger.annotate.to_i > 2
187
+ return p
152
188
  end
153
189
 
154
190
  # Run these commands, for example display commands or possibly
155
191
  # the list or irb in an "autolist" or "autoirb".
192
+ # We return a list of commands that are acceptable to run bound
193
+ # to the current state.
156
194
  def always_run(context, file, line, run_level)
157
195
  event_cmds = Command.commands.select{|cmd| cmd.event }
196
+
197
+ # Remove some commands in post-mortem
198
+ event_cmds = event_cmds.find_all do |cmd|
199
+ cmd.allow_in_post_mortem
200
+ end if context.dead?
201
+
158
202
  state = State.new do |s|
159
203
  s.context = context
160
204
  s.file = file
@@ -166,18 +210,17 @@ module Debugger
166
210
  end
167
211
  @interface.state = state if @interface.respond_to?('state=')
168
212
 
169
- commands = event_cmds.map{|cmd| cmd.new(state) }
170
- commands.select{|cmd| cmd.class.always_run >= run_level}.each{|cmd| cmd.execute }
213
+ # Bind commands to the current state.
214
+ commands = event_cmds.map{|cmd| cmd.new(state)}
215
+
216
+ commands.select do |cmd|
217
+ cmd.class.always_run >= run_level
218
+ end.each {|cmd| cmd.execute}
171
219
  return state, commands
172
220
  end
173
221
 
174
222
  # Handle debugger commands
175
223
  def process_commands(context, file, line)
176
- if @output_annotation_in_progress
177
- print "\032\032\n"
178
- @output_annotation_in_progress = false
179
- end
180
-
181
224
  state, commands = always_run(context, file, line, 1)
182
225
 
183
226
  splitter = lambda do |str|
@@ -195,10 +238,16 @@ module Debugger
195
238
  m
196
239
  end
197
240
  end
198
-
241
+
199
242
  preloop(commands, context)
200
243
  CommandProcessor.print_location_and_text(file, line)
201
- while !state.proceed? and input = @interface.read_command(prompt(context))
244
+ while !state.proceed?
245
+ input = if @interface.command_queue.empty?
246
+ @interface.read_command(prompt(context))
247
+ else
248
+ @interface.command_queue.shift
249
+ end
250
+ break unless input
202
251
  catch(:debug_error) do
203
252
  if input == ""
204
253
  next unless @last_cmd
@@ -212,11 +261,7 @@ module Debugger
212
261
  end
213
262
  end
214
263
  end
215
-
216
- if Debugger.annotate and Debugger.annotate > 2
217
- print "\032\032starting\n"
218
- @output_annotation_in_progress = true
219
- end
264
+ postloop(commands, context)
220
265
  end # process_commands
221
266
 
222
267
  def one_cmd(commands, context, input)
@@ -236,56 +281,93 @@ module Debugger
236
281
  end
237
282
  end
238
283
 
239
- def postcmd(commands, context, cmd)
240
- if Debugger.annotate and Debugger.annotate > 0
241
- # FIXME: need to cannonicalize command names
242
- # e.g. b vs. break
243
- # and break out the command name "break 10"
244
- # until then we'll refresh always
245
- # cmd = @last_cmd unless cmd
246
- #if @@Show_breakpoints_postcmd.member?(cmd)
247
- annotation('breakpoints', commands, context, "info breakpoints") unless
248
- Debugger.breakpoints.empty?
249
- annotation('display', commands, context, "display")
250
- # end
251
- # if @@Show_annotations_postcmd.member?(cmd)
252
- annotation('stack', commands, context, "where") if
253
- context.stack_size > 0
254
- annotation('variables', commands, context, "info variables")
255
- # end
284
+ def preloop(commands, context)
285
+ aprint('stopped') if Debugger.annotate.to_i > 2
286
+ if context.dead?
287
+ unless @debugger_context_was_dead
288
+ if Debugger.annotate.to_i > 2
289
+ aprint('exited')
290
+ print "The program finished.\n"
291
+ end
292
+ @debugger_context_was_dead = true
293
+ end
256
294
  end
257
- end
258
295
 
259
- def preloop(commands, context)
260
- if Debugger.annotate and Debugger.annotate > 0
296
+ if Debugger.annotate.to_i > 2
261
297
  # if we are here, the stack frames have changed outside the
262
298
  # command loop (e.g. after a "continue" command), so we show
263
299
  # the annotations again
264
- annotation('breakpoints', commands, context, "info breakpoints")
300
+ breakpoint_annotations(commands, context)
301
+ display_annotations(commands, context)
265
302
  annotation('stack', commands, context, "where")
266
- annotation('variables', commands, context, "info variables")
267
- annotation('display', commands, context, "display")
303
+ annotation('variables', commands, context, "info variables") unless
304
+ context.dead?
305
+ end
306
+ end
307
+
308
+ def postcmd(commands, context, cmd)
309
+ if Debugger.annotate.to_i > 0
310
+ cmd = @last_cmd unless cmd
311
+ breakpoint_annotations(commands, context) if
312
+ @@Show_breakpoints_postcmd.find{|pat| cmd =~ pat}
313
+ display_annotations(commands, context)
314
+ if @@Show_annotations_postcmd.find{|pat| cmd =~ pat}
315
+ annotation('stack', commands, context, "where") if
316
+ context.stack_size > 0
317
+ annotation('variables', commands, context, "info variables") unless
318
+ context.dead?
319
+ end
320
+ if not context.dead? and @@Show_annotations_run.find{|pat| cmd =~ pat}
321
+ aprint 'starting' if Debugger.annotate.to_i > 2
322
+
323
+ @debugger_context_was_dead = false
324
+ end
268
325
  end
269
326
  end
270
327
 
328
+ def postloop(commands, context)
329
+ end
330
+
271
331
  def annotation(label, commands, context, cmd)
272
- print "\032\032#{label}\n"
332
+ print afmt(label)
273
333
  one_cmd(commands, context, cmd)
334
+ ### FIXME ANNOTATE: the following line should be deleted
274
335
  print "\032\032\n"
275
336
  end
276
337
 
338
+ def breakpoint_annotations(commands, context)
339
+ unless Debugger.breakpoints.empty? and @debugger_breakpoints_were_empty
340
+ annotation('breakpoints', commands, context, "info breakpoints")
341
+ @debugger_breakpoints_were_empty = Debugger.breakpoints.empty?
342
+ end
343
+ end
344
+
345
+ def display_annotations(commands, context)
346
+ return if display.empty?
347
+ # have_display = display.find{|d| d[0]}
348
+ # return unless have_display and @debugger_displays_were_empty
349
+ # @debugger_displays_were_empty = have_display
350
+ annotation('display', commands, context, "display")
351
+ end
352
+
277
353
  class State # :nodoc:
278
354
  attr_accessor :context, :file, :line, :binding
279
355
  attr_accessor :frame_pos, :previous_line, :display
280
356
  attr_accessor :interface, :commands
281
357
 
282
358
  def initialize
359
+ super()
283
360
  @frame_pos = 0
284
361
  @previous_line = nil
285
362
  @proceed = false
286
363
  yield self
287
364
  end
288
365
 
366
+ # FIXME: use delegate?
367
+ def errmsg(*args)
368
+ @interface.errmsg(*args)
369
+ end
370
+
289
371
  def print(*args)
290
372
  @interface.print(*args)
291
373
  end
@@ -304,21 +386,29 @@ module Debugger
304
386
  end
305
387
  end
306
388
 
307
- class ControlCommandProcessor # :nodoc:
389
+ class ControlCommandProcessor < Processor # :nodoc:
308
390
  def initialize(interface)
391
+ super()
309
392
  @interface = interface
310
- end
311
-
312
- def print(*args)
313
- @interface.print(*args)
393
+ @debugger_context_was_dead = true # Assume we haven't started.
314
394
  end
315
395
 
316
396
  def process_commands
317
- control_cmds = Command.commands.select{|cmd| cmd.control }
397
+ control_cmds = Command.commands.select do |cmd|
398
+ cmd.allow_in_control
399
+ end
318
400
  state = State.new(@interface, control_cmds)
319
401
  commands = control_cmds.map{|cmd| cmd.new(state) }
320
-
321
- while input = @interface.read_command("(rdb:ctrl) ")
402
+
403
+ unless @debugger_context_was_dead
404
+ if Debugger.annotate.to_i > 2
405
+ aprint 'exited'
406
+ print "The program finished.\n"
407
+ end
408
+ @debugger_context_was_dead = true
409
+ end
410
+
411
+ while input = @interface.read_command(prompt(nil))
322
412
  catch(:debug_error) do
323
413
  if cmd = commands.find{|c| c.match(input) }
324
414
  cmd.execute
@@ -334,7 +424,16 @@ module Debugger
334
424
  ensure
335
425
  @interface.close
336
426
  end
337
-
427
+
428
+ # The prompt shown before reading a command.
429
+ # Note: have an unused 'context' parameter to match the local interface.
430
+ def prompt(context)
431
+ p = '(rdb:ctrl) '
432
+ p = afmt("pre-prompt")+p+"\n"+afmt("prompt") if
433
+ Debugger.annotate.to_i > 2
434
+ return p
435
+ end
436
+
338
437
  class State # :nodoc:
339
438
  attr_reader :commands, :interface
340
439
 
@@ -346,6 +445,10 @@ module Debugger
346
445
  def proceed
347
446
  end
348
447
 
448
+ def errmsg(*args)
449
+ @interface.print(*args)
450
+ end
451
+
349
452
  def print(*args)
350
453
  @interface.print(*args)
351
454
  end
@@ -362,6 +465,6 @@ module Debugger
362
465
  print "No filename given.\n"
363
466
  throw :debug_error
364
467
  end
365
- end
468
+ end # State
366
469
  end
367
470
  end