trepanning 0.1.6 → 1.93.32

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 (113) hide show
  1. data/COPYING +57 -0
  2. data/ChangeLog +585 -736
  3. data/NEWS +26 -12
  4. data/README.md +62 -0
  5. data/Rakefile +15 -9
  6. data/app/breakpoint.rb +11 -12
  7. data/app/complete.rb +14 -14
  8. data/app/core.rb +34 -30
  9. data/app/default.rb +8 -7
  10. data/app/markdown.rb +191 -0
  11. data/app/options.rb +104 -99
  12. data/app/run.rb +9 -1
  13. data/app/util.rb +7 -7
  14. data/bin/trepan +7 -7
  15. data/interface.rb +0 -4
  16. data/interface/user.rb +11 -11
  17. data/io/input.rb +13 -13
  18. data/lib/trepanning.rb +30 -29
  19. data/processor.rb +40 -40
  20. data/processor/command.rb +13 -9
  21. data/processor/command/alias.rb +21 -15
  22. data/processor/command/backtrace.rb +27 -19
  23. data/processor/command/break.rb +24 -21
  24. data/processor/command/complete.rb +5 -2
  25. data/processor/command/condition.rb +14 -9
  26. data/processor/command/debug.rb +8 -8
  27. data/processor/command/down.rb +6 -6
  28. data/processor/command/edit.rb +4 -0
  29. data/processor/command/eval.rb +2 -2
  30. data/processor/command/exit.rb +12 -9
  31. data/processor/command/finish.rb +25 -23
  32. data/processor/command/frame.rb +30 -26
  33. data/processor/command/help.rb +203 -185
  34. data/processor/command/help/{command.txt → command.md} +21 -18
  35. data/processor/command/help/examples.md +20 -0
  36. data/processor/command/help/filename.md +46 -0
  37. data/processor/command/help/location.md +34 -0
  38. data/processor/command/help/suffixes.md +19 -0
  39. data/processor/command/info.rb +6 -4
  40. data/processor/command/info_subcmd/breakpoints.rb +13 -13
  41. data/processor/command/info_subcmd/files.rb +35 -31
  42. data/processor/command/info_subcmd/frame.rb +82 -33
  43. data/processor/command/info_subcmd/macro.rb +1 -1
  44. data/processor/command/info_subcmd/program.rb +8 -5
  45. data/processor/command/info_subcmd/registers.rb +15 -13
  46. data/processor/command/kill.rb +23 -17
  47. data/processor/command/list.rb +63 -56
  48. data/processor/command/macro.rb +45 -28
  49. data/processor/command/next.rb +29 -23
  50. data/processor/command/pp.rb +11 -9
  51. data/processor/command/pr.rb +10 -8
  52. data/processor/command/ps.rb +5 -5
  53. data/processor/command/quit.rb +24 -17
  54. data/processor/command/raise.rb +6 -6
  55. data/processor/command/reload.rb +9 -2
  56. data/processor/command/reload_subcmd/command.rb +4 -4
  57. data/processor/command/restart.rb +9 -4
  58. data/processor/command/save.rb +9 -9
  59. data/processor/command/server.rb +18 -17
  60. data/processor/command/set.rb +8 -6
  61. data/processor/command/set_subcmd/confirm.rb +15 -2
  62. data/processor/command/set_subcmd/different.rb +7 -5
  63. data/processor/command/set_subcmd/highlight.rb +14 -3
  64. data/processor/command/set_subcmd/pc.rb +62 -0
  65. data/processor/command/set_subcmd/sp.rb +8 -2
  66. data/processor/command/shell.rb +25 -23
  67. data/processor/command/show.rb +9 -7
  68. data/processor/command/show_subcmd/confirm.rb +12 -1
  69. data/processor/command/show_subcmd/highlight.rb +13 -3
  70. data/processor/command/source.rb +27 -26
  71. data/processor/command/step.rb +52 -43
  72. data/processor/command/tbreak.rb +9 -4
  73. data/processor/command/unalias.rb +9 -7
  74. data/processor/command/undisplay.rb +11 -7
  75. data/processor/command/up.rb +18 -13
  76. data/processor/command/watchg.rb +20 -17
  77. data/processor/complete.rb +120 -0
  78. data/processor/default.rb +47 -43
  79. data/processor/list.rb +23 -6
  80. data/processor/load_cmds.rb +25 -105
  81. data/processor/location.rb +104 -96
  82. data/processor/mock.rb +12 -12
  83. data/processor/msg.rb +61 -52
  84. data/processor/validate.rb +36 -27
  85. data/test/data/fname-with-blank.right +0 -1
  86. data/test/data/trace-mingw.right +28 -0
  87. data/test/data/trace.right +0 -2
  88. data/test/functional/test-raise.rb +3 -0
  89. data/test/integration/helper.rb +16 -16
  90. data/test/integration/test-debugger-stop.rb +8 -2
  91. data/test/integration/test-quit.rb +16 -15
  92. data/test/integration/test-trace.rb +19 -10
  93. data/test/unit/cmd-helper.rb +4 -1
  94. data/test/unit/test-app-complete.rb +3 -1
  95. data/test/unit/test-app-options.rb +7 -1
  96. data/test/unit/test-app-run.rb +9 -1
  97. data/test/unit/test-cmd-alias.rb +1 -1
  98. data/test/unit/test-cmd-edit.rb +2 -0
  99. data/test/unit/test-cmd-help.rb +10 -5
  100. data/test/unit/test-cmd-parse_list_cmd.rb +3 -3
  101. data/test/unit/test-completion.rb +2 -2
  102. data/test/unit/test-proc-default.rb +34 -0
  103. data/trepanning.gemspec +15 -14
  104. metadata +70 -44
  105. data/README.textile +0 -50
  106. data/processor/command/help/examples.txt +0 -16
  107. data/processor/command/help/filename.txt +0 -40
  108. data/processor/command/help/location.txt +0 -37
  109. data/processor/command/help/suffixes.txt +0 -17
  110. data/processor/command/info_subcmd/registers_subcmd/dfp.rb +0 -28
  111. data/processor/command/info_subcmd/registers_subcmd/lfp.rb +0 -47
  112. data/processor/command/nocache.rb +0 -32
  113. data/processor/command/parsetree.rb +0 -56
@@ -1,50 +1,54 @@
1
- # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
1
+ # Copyright (C) 2010-2011, 2013 Rocky Bernstein <rockyb@rubyforge.net>
2
2
  require_relative '../app/default'
3
3
  require_relative 'virtual'
4
4
  class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
5
5
 
6
- DEFAULT_SETTINGS = {
7
- :abbrev => true, # Allow abbreviations of debugger commands?
8
- :autoeval => true, # Ruby eval non-debugger commands
9
- :autoirb => false, # Go into IRB in debugger command loop
10
- :autolist => false, # Run 'list'
11
-
12
- :basename => false, # Show basename of filenames only
13
- :confirm => true, # Confirm potentially dangerous operations?
14
- :different => 'nostack', # stop *only* when different position?
15
-
16
- :debugdbgr => false, # Debugging the debugger
17
- :debugexcept => true, # Internal debugging of command exceptions
18
- :debugmacro => false, # debugging macros
19
- :debugskip => false, # Internal debugging of step/next skipping
20
- :directory => # last-resort path-search for files
21
- '$cdir:$cwd', # that are not fully qualified.
22
-
23
- :hidestack => nil, # Fixnum. How many hidden outer
24
- # debugger stack frames to hide?
25
- # nil or -1 means compute value. 0
26
- # means hide none. Less than 0 means show
27
- # all stack entries.
28
- :hightlight => false, # Use terminal highlight?
29
-
30
- :maxlist => 10, # Number of source lines to list
31
- :maxstack => 10, # backtrace limit
32
- :maxstring => 150, # Strings which are larger than this
33
- # will be truncated to this length when
34
- # printed
35
- :maxwidth => (ENV['COLUMNS'] || '80').to_i,
36
- :prompt => 'trepan', # core part of prompt. Additional info like
37
- # debug nesting and
38
- :reload => false, # Reread source file if we determine
39
- # it has changed?
40
- :save_cmdfile => nil, # If set, debugger command file to be
41
- # used on restart
42
- :timer => false, # show elapsed time between events
43
- :traceprint => false, # event tracing printing
44
- :tracebuffer => false, # save events to a trace buffer.
45
- :user_cmd_dir => File.join(%W(#{Trepan::HOME_DIR} trepan command)),
46
- # User command directory
47
- }
6
+ computed_displaywidth = (ENV['COLUMNS'] || `tput cols &2>/dev/null`).to_i rescue 80
7
+ computed_displaywidth = 80 unless computed_displaywidth >= 10
8
+
9
+
10
+ DEFAULT_SETTINGS = {
11
+ :abbrev => true, # Allow abbreviations of debugger commands?
12
+ :autoeval => true, # Ruby eval non-debugger commands
13
+ :autoirb => false, # Go into IRB in debugger command loop
14
+ :autolist => false, # Run 'list'
15
+
16
+ :basename => false, # Show basename of filenames only
17
+ :confirm => true, # Confirm potentially dangerous operations?
18
+ :different => 'on', # stop *only* when different position?
19
+
20
+ :debugdbgr => false, # Debugging the debugger
21
+ :debugexcept => true, # Internal debugging of command exceptions
22
+ :debugmacro => false, # debugging macros
23
+ :debugskip => false, # Internal debugging of step/next skipping
24
+ :directory => # last-resort path-search for files
25
+ '$cdir:$cwd', # that are not fully qualified.
26
+
27
+ :hidestack => nil, # Fixnum. How many hidden outer
28
+ # debugger stack frames to hide?
29
+ # nil or -1 means compute value. 0
30
+ # means hide none. Less than 0 means show
31
+ # all stack entries.
32
+ :highlight => true, # Use terminal highlight?
33
+
34
+ :maxlist => 10, # Number of source lines to list
35
+ :maxstack => 10, # backtrace limit
36
+ :maxstring => 150, # Strings which are larger than this
37
+ # will be truncated to this length when
38
+ # printed
39
+ :maxwidth => computed_displaywidth,
40
+ :prompt => 'trepan', # core part of prompt. Additional info like
41
+ # debug nesting and
42
+ :reload => false, # Reread source file if we determine
43
+ # it has changed?
44
+ :save_cmdfile => nil, # If set, debugger command file to be
45
+ # used on restart
46
+ :timer => false, # show elapsed time between events
47
+ :traceprint => false, # event tracing printing
48
+ :tracebuffer => false, # save events to a trace buffer.
49
+ :user_cmd_dir => File.join(%W(#{Trepan::HOME_DIR} trepan command)),
50
+ # User command directory
51
+ } unless defined?(DEFAULT_SETTINGS)
48
52
  end
49
53
 
50
54
  if __FILE__ == $0
@@ -1,10 +1,10 @@
1
- # Copyright (C) 2011 Rocky Bernstein <rockyb@rubyforge.net>
1
+ # Copyright (C) 2011, 2013 Rocky Bernstein <rockyb@rubyforge.net>
2
2
 
3
3
  # Trepan command list validation routines. A String type is
4
4
  # usually passed in as the argument to validation routines.
5
5
 
6
6
  require 'rubygems'
7
-
7
+ require 'rbconfig'
8
8
  require_relative './validate'
9
9
 
10
10
  class Trepan
@@ -24,9 +24,14 @@ class Trepan
24
24
  # See also duplicate code in print_location
25
25
  if container[0] != 'file'
26
26
  try_container = container
27
- while try_container[0] != 'file' && frame.prev do
28
- frame = frame.prev
29
- try_container = frame_container(frame, false)
27
+ begin
28
+ while try_container[0] != 'file' && frame.prev do
29
+ frame = frame.prev
30
+ last unless frame
31
+ try_container = frame_container(frame, false)
32
+ end
33
+ rescue
34
+ return nil
30
35
  end
31
36
  container = try_container if try_container[0] == 'file'
32
37
  end
@@ -44,6 +49,14 @@ class Trepan
44
49
  filename = frame_filename
45
50
  first = [1, frame_line - center_correction].max
46
51
  else
52
+ ## FIXME: push into parse
53
+ if RbConfig::CONFIG['target_os'].start_with?('mingw') and
54
+ position_str =~ /^[A-Za-z]:/
55
+ drive_letter = position_str[0..1]
56
+ position_str = position_str[2..-1]
57
+ else
58
+ drive_leter = nil
59
+ end
47
60
  list_cmd_parse = parse_list(position_str,
48
61
  :file_exists_proc => file_exists_proc)
49
62
  return [nil] * 4 unless list_cmd_parse
@@ -95,7 +108,11 @@ class Trepan
95
108
  first = [1, first - center_correction].max
96
109
  last = first + listsize - 1 unless last
97
110
  end
98
- LineCache::cache(filename) unless LineCache::cached?(filename)
111
+ if filename
112
+ LineCache::cache(filename) unless LineCache::cached?(filename)
113
+ else
114
+ errmsg("Don't have a filename here")
115
+ end
99
116
  return [iseq, filename, first, last]
100
117
  end
101
118
 
@@ -1,11 +1,10 @@
1
1
  # -*- coding: utf-8 -*-
2
- # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
2
+ # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
3
3
  require 'tmpdir'
4
4
 
5
5
  # Part of Trepan::CmdProcess that loads up debugger commands from
6
- # builtin and user directories.
6
+ # builtin and user directories.
7
7
  # Sets @commands, @aliases, @macros
8
- require_relative '../app/complete'
9
8
  require_relative 'virtual'
10
9
  class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
11
10
 
@@ -13,11 +12,8 @@ class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
13
12
  # indexed by alias name
14
13
  attr_reader :commands # Hash[String] of command objects
15
14
  # indexed by name
16
- attr_reader :macros # Hash[String] of Proc objects
15
+ attr_reader :macros # Hash[String] of Proc objects
17
16
  # indexed by macro name.
18
- attr_reader :leading_str # leading part of string. Used in
19
- # command completion
20
-
21
17
  # "initialize" for multi-file class. Called from main.rb's "initialize".
22
18
  def load_cmds_initialize
23
19
  @commands = {}
@@ -26,13 +22,13 @@ class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
26
22
 
27
23
  cmd_dirs = [ File.join(File.dirname(__FILE__), 'command') ]
28
24
  cmd_dirs << @settings[:user_cmd_dir] if @settings[:user_cmd_dir]
29
- cmd_dirs.each do |cmd_dir|
25
+ cmd_dirs.each do |cmd_dir|
30
26
  load_debugger_commands(cmd_dir) if File.directory?(cmd_dir)
31
27
  end
32
28
  end
33
29
 
34
30
  # Loads in debugger commands by require'ing each ruby file in the
35
- # 'command' directory. Then a new instance of each class of the
31
+ # 'command' directory. Then a new instance of each class of the
36
32
  # form Trepan::xxCommand is added to @commands and that array
37
33
  # is returned.
38
34
  def load_debugger_commands(file_or_dir)
@@ -41,13 +37,13 @@ class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
41
37
  # change $0 so it doesn't get in the way of __FILE__ = $0
42
38
  old_dollar0 = $0
43
39
  $0 = ''
44
- Dir.glob(File.join(dir, '*.rb')).each do |rb|
40
+ Dir.glob(File.join(dir, '*.rb')).each do |rb|
45
41
  # We use require so that multiple calls have no effect.
46
42
  require rb
47
43
  end
48
44
  $0 = old_dollar0
49
45
  elsif File.readable?(file_or_dir)
50
- # We use load in case we are reloading.
46
+ # We use load in case we are reloading.
51
47
  # 'require' would not be effective here
52
48
  load file_or_dir
53
49
  else
@@ -68,7 +64,7 @@ class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
68
64
  end
69
65
  end
70
66
 
71
- # Looks up cmd_array[0] in @commands and runs that. We do lots of
67
+ # Looks up cmd_array[0] in @commands and runs that. We do lots of
72
68
  # validity testing on cmd_array.
73
69
  def run_cmd(cmd_array)
74
70
  unless cmd_array.is_a?(Array)
@@ -76,12 +72,12 @@ class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
76
72
  return
77
73
  end
78
74
  if cmd_array.detect{|item| !item.is_a?(String)}
79
- errmsg "run_cmd argument Array should only contain strings. " +
75
+ errmsg "run_cmd argument Array should only contain strings. " +
80
76
  "Got #{cmd_array.inspect}"
81
77
  return
82
78
  end
83
79
  if cmd_array.empty?
84
- errmsg "run_cmd Array should have at least one item. " +
80
+ errmsg "run_cmd Array should have at least one item. " +
85
81
  "Got: #{cmd_array.inspect}"
86
82
  return
87
83
  end
@@ -92,7 +88,7 @@ class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
92
88
  end
93
89
 
94
90
  def save_commands(opts)
95
- save_filename = opts[:filename] ||
91
+ save_filename = opts[:filename] ||
96
92
  File.join(Dir.tmpdir, Dir::Tmpname.make_tmpname(['trepanning-save', '.txt'], nil))
97
93
  begin
98
94
  save_file = File.open(save_filename, 'w')
@@ -106,16 +102,16 @@ class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
106
102
  cmd_obj.save_command if cmd_obj.respond_to?(:save_command)
107
103
  next unless cmd_obj.is_a?(Trepan::SubcommandMgr)
108
104
  cmd_obj.subcmds.subcmds.each do |subcmd_name, subcmd_obj|
109
- save_file.puts subcmd_obj.save_command if
105
+ save_file.puts subcmd_obj.save_command if
110
106
  subcmd_obj.respond_to?(:save_command)
111
107
  next unless subcmd_obj.is_a?(Trepan::SubSubcommandMgr)
112
108
  subcmd_obj.subcmds.subcmds.each do |subsubcmd_name, subsubcmd_obj|
113
- save_file.puts subsubcmd_obj.save_command if
109
+ save_file.puts subsubcmd_obj.save_command if
114
110
  subsubcmd_obj.respond_to?(:save_command)
115
111
  end
116
112
  end
117
113
  end
118
- save_file.puts "!FileUtils.rm #{save_filename.inspect}" if
114
+ save_file.puts "!FileUtils.rm #{save_filename.inspect}" if
119
115
  opts[:erase]
120
116
  save_file.close
121
117
 
@@ -129,90 +125,16 @@ class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
129
125
  # command, but I don't know it. And eval works.
130
126
  klass = self.instance_eval("Trepan::Command::#{command}")
131
127
  cmd = klass.send(:new, self)
132
-
128
+
133
129
  # Add to list of commands and aliases.
134
130
  cmd_name = klass.const_get(:NAME)
135
131
  if klass.constants.member?(:ALIASES)
136
- aliases= klass.const_get(:ALIASES)
132
+ aliases= klass.const_get(:ALIASES)
137
133
  aliases.each {|a| @aliases[a] = cmd_name}
138
134
  end
139
135
  @commands[cmd_name] = cmd
140
136
  end
141
137
 
142
- # Handle initial completion. We draw from the commands, aliases,
143
- # and macros for completion. However we won't include aliases which
144
- # are prefixes of other commands.
145
- def complete(str, last_token)
146
- @leading_str = str
147
- next_blank_pos, token = Trepan::Complete.next_token(str, 0)
148
- return [''] if token.empty? && !last_token.empty?
149
- match_pairs = Trepan::Complete.complete_token_with_next(@commands,
150
- token)
151
- match_hash = {}
152
- match_pairs.each do |pair|
153
- match_hash[pair[0]] = pair[1]
154
- end
155
- alias_pairs = Trepan::Complete.
156
- complete_token_filtered_with_next(@aliases, token, match_hash,
157
- @commands)
158
- match_pairs += alias_pairs
159
- if str[next_blank_pos..-1].empty?
160
- return match_pairs.map{|pair| pair[0]}.sort
161
- else
162
- alias_pairs.each do |pair|
163
- match_hash[pair[0]] = pair[1]
164
- end
165
- end
166
- if match_pairs.size > 1
167
- # FIXME: figure out what to do here.
168
- # Matched multiple items in the middle of the string
169
- # We can't handle this so do nothing.
170
- return []
171
- # return match_pairs.map do |name, cmd|
172
- # ["#{name} #{args[1..-1].join(' ')}"]
173
- # end
174
- end
175
- # match_pairs.size == 1
176
- next_complete(str, next_blank_pos, match_pairs[0][1], last_token)
177
- end
178
-
179
- def next_complete(str, next_blank_pos, cmd, last_token)
180
- next_blank_pos, token = Trepan::Complete.next_token(str, next_blank_pos)
181
- return [] if token.empty? && !last_token.empty?
182
-
183
- if cmd.respond_to?(:complete_token_with_next)
184
- match_pairs = cmd.complete_token_with_next(token)
185
- return [] if match_pairs.empty?
186
- if str[next_blank_pos..-1].rstrip.empty? &&
187
- (token.empty? || token == last_token)
188
- return match_pairs.map { |completion, junk| completion }
189
- else
190
- if match_pairs.size == 1
191
- return next_complete(str, next_blank_pos, match_pairs[0][1],
192
- last_token)
193
- else
194
- # FIXME: figure out what to do here.
195
- # Matched multiple items in the middle of the string
196
- # We can't handle this so do nothing.
197
- return []
198
- end
199
- end
200
- elsif cmd.respond_to?(:complete)
201
- matches = cmd.complete(token)
202
- return [] if matches.empty?
203
- if str[next_blank_pos..-1].rstrip.empty? &&
204
- (token.empty? || token == last_token)
205
- return matches
206
- else
207
- # FIXME: figure out what to do here.
208
- # Matched multiple items in the middle of the string
209
- # We can't handle this so do nothing.
210
- return []
211
- end
212
- else
213
- return []
214
- end
215
- end
216
138
  end
217
139
 
218
140
  if __FILE__ == $0
@@ -222,14 +144,6 @@ if __FILE__ == $0
222
144
  end
223
145
 
224
146
  cmdproc = Trepan::CmdProcessor.new(nil)
225
- cmddir = File.join(File.dirname(__FILE__), 'command')
226
- cmdproc.instance_variable_set('@settings', {})
227
- cmdproc.load_cmds_initialize
228
- require 'columnize'
229
- puts Columnize.columnize(cmdproc.commands.keys.sort)
230
- puts '=' * 20
231
- puts Columnize.columnize(cmdproc.aliases.keys.sort)
232
- puts '=' * 20
233
147
 
234
148
  def cmdproc.errmsg(mess)
235
149
  puts "** #{mess}"
@@ -239,10 +153,16 @@ if __FILE__ == $0
239
153
  puts mess
240
154
  end
241
155
 
156
+ cmddir = File.join(File.dirname(__FILE__), 'command')
157
+ cmdproc.instance_variable_set('@settings', {})
158
+ cmdproc.load_cmds_initialize
159
+ require 'columnize'
160
+ puts Columnize.columnize(cmdproc.commands.keys.sort)
161
+ puts '=' * 20
162
+ puts Columnize.columnize(cmdproc.aliases.keys.sort)
163
+ puts '=' * 20
164
+
242
165
  cmdproc.run_cmd('foo') # Invalid - not an Array
243
166
  cmdproc.run_cmd([]) # Invalid - empty Array
244
167
  cmdproc.run_cmd(['list', 5]) # Invalid - nonstring arg
245
- p cmdproc.complete("d", 'd')
246
- p cmdproc.complete("sho d", 'd')
247
- p cmdproc.complete('', '')
248
168
  end
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
1
+ # Copyright (C) 2010-2011, 2013, 2015 Rocky Bernstein <rockyb@rubyforge.net>
2
2
  require 'rubygems'
3
3
  require 'linecache'
4
4
  require 'pathname' # For cleanpath
@@ -32,39 +32,39 @@ class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
32
32
  'vm' => 'VM',
33
33
  'vm-insn' => '..',
34
34
  'yield' => '<>',
35
- }
35
+ }
36
36
  end
37
37
 
38
38
  def canonic_container(container)
39
39
  [container[0], canonic_file(container[1])]
40
40
  end
41
-
42
- def canonic_file(filename, resolve=true)
43
- # For now we want resolved filenames
44
- if @settings[:basename]
45
- File.basename(filename)
46
- elsif resolve
47
- filename = LineCache::map_file(filename)
48
- File.expand_path(Pathname.new(filename).cleanpath.to_s)
49
- else
50
- filename
41
+
42
+ def canonic_file(filename, resolve=true)
43
+ # For now we want resolved filenames
44
+ if @settings[:basename]
45
+ File.basename(filename)
46
+ elsif resolve
47
+ filename = LineCache::map_file(filename)
48
+ File.expand_path(Pathname.new(filename).cleanpath.to_s)
49
+ else
50
+ filename
51
+ end
51
52
  end
52
- end
53
53
 
54
54
  # Return the text to the current source line.
55
55
  # FIXME: loc_and_text should call this rather than the other
56
56
  # way around.
57
57
  def current_source_text
58
58
  opts = {:reload_on_change => @reload}
59
- junk1, junk2, text, found_line =
60
- loc_and_text('', frame, frame.source_location[0],
59
+ junk1, junk2, text, found_line =
60
+ loc_and_text('', frame, frame.source_location[0],
61
61
  frame.source_container, opts)
62
62
  text
63
63
  end
64
-
64
+
65
65
  def resolve_file_with_dir(path_suffix)
66
66
  @settings[:directory].split(/:/).each do |dir|
67
- dir =
67
+ dir =
68
68
  if '$cwd' == dir
69
69
  Dir.pwd
70
70
  elsif '$cdir' == dir
@@ -78,7 +78,7 @@ class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
78
78
  end
79
79
  nil
80
80
  end
81
-
81
+
82
82
  # Get line +line_number+ from file named +filename+. Return ''
83
83
  # if there was a problem. Leading blanks are stripped off.
84
84
  def line_at(filename, line_number,
@@ -87,12 +87,12 @@ class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
87
87
  :output => @settings[:highlight]
88
88
  })
89
89
  line = LineCache::getline(filename, line_number, opts)
90
-
90
+
91
91
  unless line
92
92
  # Try using search directories (set with command "directory")
93
93
  if filename[0..0] != File::SEPARATOR
94
- try_filename = resolve_file_with_dir(filename)
95
- if try_filename &&
94
+ try_filename = resolve_file_with_dir(filename)
95
+ if try_filename &&
96
96
  line = LineCache::getline(try_filename, line_number, opts)
97
97
  LineCache::remap_file(filename, try_filename)
98
98
  end
@@ -103,89 +103,97 @@ class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
103
103
 
104
104
  def loc_and_text(loc, frame, line_no, source_container,
105
105
  opts = {
106
- :reload_on_change => @settings[:reload],
107
- :output => @settings[:highlight]
106
+ :reload_on_change => @settings[:reload],
107
+ :output => @settings[:highlight]
108
108
  })
109
- found_line = true
110
- ## FIXME: condition is too long.
111
- if source_container[0] == 'string' && frame.iseq && frame.iseq.eval_source
112
- file = LineCache::map_iseq(frame.iseq)
113
- text = LineCache::getline(frame.iseq, line_no, opts)
114
- loc += " remapped #{canonic_file(file)}:#{line_no}"
115
- elsif source_container[0] != 'file'
116
- via = loc
117
- while source_container[0] != 'file' && frame.prev do
118
- frame = frame.prev
119
- source_container = frame_container(frame, false)
120
- end
121
- if source_container[0] == 'file'
122
- line_no = frame.source_location[0]
123
- filename = source_container[1]
124
- loc += " via #{canonic_file(filename)}:#{line_no}"
125
- text = line_at(filename, line_no, opts)
126
- found_line = false
127
- end
128
- else
129
- container = source_container[1]
130
- map_file, map_line = LineCache::map_file_line(container, line_no)
131
- if [container, line_no] != [map_file, map_line]
132
- loc += " remapped #{canonic_file(map_file)}:#{map_line}"
109
+ found_line = true
110
+ ## FIXME: condition is too long.
111
+ if source_container[0] == 'string' && frame.iseq && frame.iseq.eval_source
112
+ file = LineCache::map_iseq(frame.iseq)
113
+ text = LineCache::getline(frame.iseq, line_no, opts)
114
+ loc += " remapped #{canonic_file(file)}:#{line_no}"
115
+ elsif source_container[0] != 'file'
116
+ via = loc
117
+ # while not (source_container[0] == 'file' and text_file?(source_container[1])) and
118
+ while not (source_container[0] == 'file') and
119
+ frame.prev do
120
+ frame = frame.prev
121
+ source_container = frame_container(frame, false)
122
+ end
123
+ if source_container[0] == 'file'
124
+ sloc = frame.source_location
125
+ line_no = sloc && sloc.size > 0 ? sloc[0] : '?'
126
+ filename = source_container[1]
127
+ loc += " via #{canonic_file(filename)}:#{line_no}"
128
+ text = line_at(filename, line_no, opts)
129
+ found_line = false
130
+ end
131
+ else
132
+ container = source_container[1]
133
+ map_file, map_line = LineCache::map_file_line(container, line_no)
134
+ if [container, line_no] != [map_file, map_line]
135
+ loc += " remapped #{canonic_file(map_file)}:#{map_line}"
136
+ end
137
+
138
+ text = line_at(container, line_no, opts)
133
139
  end
134
-
135
- text = line_at(container, line_no, opts)
136
- end
137
- [loc, line_no, text, found_line]
140
+ [loc, line_no, text, found_line]
138
141
  end
139
-
142
+
140
143
  def print_location
141
- if %w(c-call call).member?(@event)
142
- # FIXME: Fix Ruby so we don't need this workaround?
143
- # See also where.rb
144
- opts = {}
145
- opts[:class] = @core.hook_arg if
146
- 'CFUNC' == @frame.type && @core.hook_arg && 0 == @frame_index
147
- msg format_stack_call(@frame, opts)
148
- elsif 'raise' == @event
149
- msg @core.hook_arg.inspect if @core.hook_arg # Exception object
150
- end
151
-
152
- text = nil
153
- source_container = frame_container(@frame, false)
154
- ev = if @event.nil? || 0 != @frame_index
155
- ' '
156
- else
157
- (EVENT2ICON[@event] || @event)
158
- end
159
- @line_no = frame_line
160
-
161
- loc = source_location_info(source_container, @line_no, @frame)
162
- loc, @line_no, text, found_line =
163
- loc_and_text(loc, @frame, @line_no, source_container)
164
-
165
- ip_str = @frame.iseq ? " @#{frame.pc_offset}" : ''
166
- msg "#{ev} (#{loc}#{ip_str})"
167
-
168
- if %w(return c-return).member?(@event)
169
- retval = Trepan::Frame.value_returned(@frame, @event)
170
- msg 'R=> %s' % retval.inspect
171
- end
172
-
173
- if text && !text.strip.empty?
174
- msg text
175
- @line_no -= 1
176
- end
177
- unless found_line
178
- # Can't find source line, so give assembly as consolation.
179
- # This great idea comes from the Rubinius reference debugger.
180
- run_command('disassemble')
181
- end
144
+ if %w(c-call call).member?(@event)
145
+ # FIXME: Fix Ruby so we don't need this workaround?
146
+ # See also where.rb
147
+ opts = {}
148
+ opts[:class] = @core.hook_arg if
149
+ 'CFUNC' == @frame.type && @core.hook_arg && 0 == @frame_index
150
+ msg format_stack_call(@frame, opts)
151
+ elsif 'raise' == @event
152
+ msg @core.hook_arg.inspect if @core.hook_arg # Exception object
153
+ end
154
+
155
+ text = nil
156
+ source_container = frame_container(@frame, false)
157
+ ev = if @event.nil? || 0 != @frame_index
158
+ ' '
159
+ else
160
+ (EVENT2ICON[@event] || @event)
161
+ end
162
+ @line_no = frame_line
163
+
164
+ loc = source_location_info(source_container, @line_no, @frame)
165
+ loc, @line_no, text, found_line =
166
+ loc_and_text(loc, @frame, @line_no, source_container)
167
+
168
+ ip_str = @frame.iseq ? " @#{frame.pc_offset}" : ''
169
+ msg "#{ev} (#{loc}#{ip_str})"
170
+
171
+ if %w(return c-return).member?(@event)
172
+ retval = Trepan::Frame.value_returned(@frame, @event)
173
+ msg 'R=> %s' % retval.inspect
174
+ elsif @event == 'raise'
175
+ # msg @proc.core.hook_arg.inspect if @proc.core.hook_arg
176
+ if @frame.iseq and @frame.iseq.catch_table_size == 0
177
+ msg "Warning: exception raised is non-local!"
178
+ end
179
+ end
180
+
181
+ if text && !text.strip.empty?
182
+ msg text
183
+ @line_no -= 1
184
+ end
185
+ unless found_line
186
+ # Can't find source line, so give assembly as consolation.
187
+ # This great idea comes from the Rubinius reference debugger.
188
+ run_command('disassemble')
189
+ end
182
190
  end
183
-
191
+
184
192
  def source_location_info(source_container, line_no, frame)
185
193
  filename = source_container[1]
186
194
  ## FIXME: condition is too long.
187
- canonic_filename =
188
- if 'string' == source_container[0] && frame.iseq &&
195
+ canonic_filename =
196
+ if 'string' == source_container[0] && frame.iseq &&
189
197
  frame.iseq.eval_source
190
198
  eval_str = frame.iseq.eval_source
191
199
  'eval "' + safe_repr(eval_str.gsub(/\n/,';'), 15) + '"'