rb8-trepanning 0.1.5 → 0.1.6

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 (52) hide show
  1. data/CHANGES +18 -4
  2. data/ChangeLog +100 -87
  3. data/Makefile +23 -4
  4. data/README.textile +3 -3
  5. data/Rakefile +26 -20
  6. data/app/complete.rb +13 -13
  7. data/app/default.rb +8 -8
  8. data/app/display.rb +7 -7
  9. data/app/frame.rb +8 -8
  10. data/app/irb.rb +15 -15
  11. data/app/options.rb +25 -25
  12. data/app/run.rb +16 -8
  13. data/app/util.rb +7 -7
  14. data/bin/trepan8 +2 -2
  15. data/check-filter.rb +21 -0
  16. data/interface.rb +4 -4
  17. data/interface/user.rb +11 -11
  18. data/io.rb +18 -19
  19. data/io/input.rb +14 -12
  20. data/lib/debugger.rb +3 -1
  21. data/lib/trepanning.rb +30 -28
  22. data/processor.rb +41 -38
  23. data/processor/command.rb +9 -9
  24. data/processor/command/alias.rb +6 -6
  25. data/processor/command/down.rb +1 -2
  26. data/processor/command/edit.rb +12 -8
  27. data/processor/command/eval.rb +7 -7
  28. data/processor/command/info_subcmd/macro.rb +6 -6
  29. data/processor/command/info_subcmd/program.rb +5 -1
  30. data/processor/command/macro.rb +6 -6
  31. data/processor/command/show_subcmd/abbrev.rb +2 -2
  32. data/processor/command/up.rb +1 -2
  33. data/processor/complete.rb +120 -0
  34. data/processor/default.rb +13 -9
  35. data/processor/load_cmds.rb +18 -97
  36. data/processor/location.rb +34 -31
  37. data/processor/msg.rb +5 -5
  38. data/processor/validate.rb +44 -35
  39. data/test/data/break_loop_bug.right +2 -2
  40. data/test/data/edit.cmd +1 -1
  41. data/test/data/edit.right +7 -1
  42. data/test/data/printvar.right +2 -2
  43. data/test/data/raise.right +0 -1
  44. data/test/data/trace-mingw.right +28 -0
  45. data/test/integration/.gitignore +1 -0
  46. data/test/integration/test-raise.rb +10 -1
  47. data/test/integration/test-trace.rb +10 -6
  48. data/test/unit/test-app-options.rb +9 -3
  49. data/test/unit/test-app-run.rb +8 -1
  50. data/test/unit/test-cmd-alias.rb +2 -2
  51. data/test/unit/test-proc-default.rb +34 -0
  52. metadata +10 -6
@@ -1,9 +1,9 @@
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
8
  require 'rubygems'; require 'require_relative'
9
9
  require_relative '../app/complete'
@@ -14,9 +14,9 @@ class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
14
14
  # indexed by alias name
15
15
  attr_reader :commands # Hash[String] of command objects
16
16
  # indexed by name
17
- attr_reader :macros # Hash[String] of Proc objects
17
+ attr_reader :macros # Hash[String] of Proc objects
18
18
  # indexed by macro name.
19
- attr_reader :leading_str # leading part of string. Used in
19
+ attr_reader :leading_str # leading part of string. Used in
20
20
  # command completion
21
21
 
22
22
  # "initialize" for multi-file class. Called from main.rb's "initialize".
@@ -27,13 +27,13 @@ class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
27
27
 
28
28
  cmd_dirs = [ File.join(File.dirname(__FILE__), 'command') ]
29
29
  cmd_dirs << @settings[:user_cmd_dir] if @settings[:user_cmd_dir]
30
- cmd_dirs.each do |cmd_dir|
30
+ cmd_dirs.each do |cmd_dir|
31
31
  load_debugger_commands(cmd_dir) if File.directory?(cmd_dir)
32
32
  end
33
33
  end
34
34
 
35
35
  # Loads in debugger commands by require'ing each ruby file in the
36
- # 'command' directory. Then a new instance of each class of the
36
+ # 'command' directory. Then a new instance of each class of the
37
37
  # form Trepan::xxCommand is added to @commands and that array
38
38
  # is returned.
39
39
  def load_debugger_commands(file_or_dir)
@@ -42,13 +42,13 @@ class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
42
42
  # change $0 so it doesn't get in the way of __FILE__ = $0
43
43
  old_dollar0 = $0
44
44
  $0 = ''
45
- Dir.glob(File.join(dir, '*.rb')).each do |rb|
45
+ Dir.glob(File.join(dir, '*.rb')).each do |rb|
46
46
  # We use require so that multiple calls have no effect.
47
47
  require rb
48
48
  end
49
49
  $0 = old_dollar0
50
50
  elsif File.readable?(file_or_dir)
51
- # We use load in case we are reloading.
51
+ # We use load in case we are reloading.
52
52
  # 'require' would not be effective here
53
53
  load file_or_dir
54
54
  else
@@ -61,7 +61,7 @@ class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
61
61
 
62
62
  # Add to list of commands and aliases.
63
63
  cmd_name = klass.const_get(:NAME)
64
- if klass.constants.member?('ALIASES') ||
64
+ if klass.constants.member?('ALIASES') ||
65
65
  klass.constants.member?(:ALIASES)
66
66
  aliases= klass.const_get('ALIASES') || klass.const_get(:ALIASES)
67
67
  aliases.each {|a| @aliases[a] = cmd_name}
@@ -79,7 +79,7 @@ class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
79
79
  end
80
80
  end
81
81
 
82
- # Looks up cmd_array[0] in @commands and runs that. We do lots of
82
+ # Looks up cmd_array[0] in @commands and runs that. We do lots of
83
83
  # validity testing on cmd_array.
84
84
  def run_cmd(cmd_array)
85
85
  unless cmd_array.is_a?(Array)
@@ -87,12 +87,12 @@ class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
87
87
  return
88
88
  end
89
89
  if cmd_array.detect{|item| !item.is_a?(String)}
90
- errmsg "run_cmd argument Array should only contain strings. " +
90
+ errmsg "run_cmd argument Array should only contain strings. " +
91
91
  "Got #{cmd_array.inspect}"
92
92
  return
93
93
  end
94
94
  if cmd_array.empty?
95
- errmsg "run_cmd Array should have at least one item. " +
95
+ errmsg "run_cmd Array should have at least one item. " +
96
96
  "Got: #{cmd_array.inspect}"
97
97
  return
98
98
  end
@@ -103,7 +103,7 @@ class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
103
103
  end
104
104
 
105
105
  def save_commands(opts)
106
- save_filename = opts[:filename] ||
106
+ save_filename = opts[:filename] ||
107
107
  File.join(Dir.tmpdir, "trepanning-save-#{$$}.txt")
108
108
  begin
109
109
  save_file = File.open(save_filename, 'w')
@@ -117,16 +117,16 @@ class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
117
117
  cmd_obj.save_command if cmd_obj.respond_to?(:save_command)
118
118
  next unless cmd_obj.is_a?(Trepan::SubcommandMgr)
119
119
  cmd_obj.subcmds.subcmds.each do |subcmd_name, subcmd_obj|
120
- save_file.puts subcmd_obj.save_command if
120
+ save_file.puts subcmd_obj.save_command if
121
121
  subcmd_obj.respond_to?(:save_command)
122
122
  next unless subcmd_obj.is_a?(Trepan::SubSubcommandMgr)
123
123
  subcmd_obj.subcmds.subcmds.each do |subsubcmd_name, subsubcmd_obj|
124
- save_file.puts subsubcmd_obj.save_command if
124
+ save_file.puts subsubcmd_obj.save_command if
125
125
  subsubcmd_obj.respond_to?(:save_command)
126
126
  end
127
127
  end
128
128
  end
129
- save_file.puts "!FileUtils.rm #{save_filename.inspect}" if
129
+ save_file.puts "!FileUtils.rm #{save_filename.inspect}" if
130
130
  opts[:erase]
131
131
  save_file.close
132
132
 
@@ -140,90 +140,15 @@ class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
140
140
  # command, but I don't know it. And eval works.
141
141
  klass = self.instance_eval("Trepan::Command::#{command}")
142
142
  cmd = klass.send(:new, self)
143
-
143
+
144
144
  # Add to list of commands and aliases.
145
145
  cmd_name = klass.const_get(:NAME)
146
146
  if klass.constants.member?(:ALIASES)
147
- aliases= klass.const_get(:ALIASES)
147
+ aliases= klass.const_get(:ALIASES)
148
148
  aliases.each {|a| @aliases[a] = cmd_name}
149
149
  end
150
150
  @commands[cmd_name] = cmd
151
151
  end
152
-
153
- # Handle initial completion. We draw from the commands, aliases,
154
- # and macros for completion. However we won't include aliases which
155
- # are prefixes of other commands.
156
- def complete(str, last_token)
157
- @leading_str = str
158
- next_blank_pos, token = Trepan::Complete.next_token(str, 0)
159
- return [''] if token.empty? && !last_token.empty?
160
- match_pairs = Trepan::Complete.complete_token_with_next(@commands,
161
- token)
162
- match_hash = {}
163
- match_pairs.each do |pair|
164
- match_hash[pair[0]] = pair[1]
165
- end
166
- alias_pairs = Trepan::Complete.
167
- complete_token_filtered_with_next(@aliases, token, match_hash,
168
- @commands)
169
- match_pairs += alias_pairs
170
- if str[next_blank_pos..-1].empty?
171
- return match_pairs.map{|pair| pair[0]}.sort
172
- else
173
- alias_pairs.each do |pair|
174
- match_hash[pair[0]] = pair[1]
175
- end
176
- end
177
- if match_pairs.size > 1
178
- # FIXME: figure out what to do here.
179
- # Matched multiple items in the middle of the string
180
- # We can't handle this so do nothing.
181
- return []
182
- # return match_pairs.map do |name, cmd|
183
- # ["#{name} #{args[1..-1].join(' ')}"]
184
- # end
185
- end
186
- # match_pairs.size == 1
187
- next_complete(str, next_blank_pos, match_pairs[0][1], last_token)
188
- end
189
-
190
- def next_complete(str, next_blank_pos, cmd, last_token)
191
- next_blank_pos, token = Trepan::Complete.next_token(str, next_blank_pos)
192
- return [] if token.empty? && !last_token.empty?
193
-
194
- if cmd.respond_to?(:complete_token_with_next)
195
- match_pairs = cmd.complete_token_with_next(token)
196
- return [] if match_pairs.empty?
197
- if str[next_blank_pos..-1].rstrip.empty? &&
198
- (token.empty? || token == last_token)
199
- return match_pairs.map { |completion, junk| completion }
200
- else
201
- if match_pairs.size == 1
202
- return next_complete(str, next_blank_pos, match_pairs[0][1],
203
- last_token)
204
- else
205
- # FIXME: figure out what to do here.
206
- # Matched multiple items in the middle of the string
207
- # We can't handle this so do nothing.
208
- return []
209
- end
210
- end
211
- elsif cmd.respond_to?(:complete)
212
- matches = cmd.complete(token)
213
- return [] if matches.empty?
214
- if str[next_blank_pos..-1].rstrip.empty? &&
215
- (token.empty? || token == last_token)
216
- return matches
217
- else
218
- # FIXME: figure out what to do here.
219
- # Matched multiple items in the middle of the string
220
- # We can't handle this so do nothing.
221
- return []
222
- end
223
- else
224
- return []
225
- end
226
- end
227
152
  end
228
153
 
229
154
  if __FILE__ == $0
@@ -251,8 +176,4 @@ if __FILE__ == $0
251
176
  cmdproc.run_cmd('foo') # Invalid - not an Array
252
177
  cmdproc.run_cmd([]) # Invalid - empty Array
253
178
  cmdproc.run_cmd(['list', 5]) # Invalid - nonstring arg
254
- p cmdproc.complete("d", 'd')
255
- require 'ruby-debug'; Debugger.start; debugger
256
- p cmdproc.complete("sho d", 'd')
257
- p cmdproc.complete('', '')
258
179
  end
@@ -1,5 +1,5 @@
1
- # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
2
- require 'rubygems';
1
+ # Copyright (C) 2010-2011, 2013 Rocky Bernstein <rockyb@rubyforge.net>
2
+ require 'rubygems';
3
3
  begin
4
4
  require 'linecache'
5
5
  rescue LoadError
@@ -16,17 +16,20 @@ class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
16
16
  unless defined?(EVENT2ICON)
17
17
  # Event icons used in printing locations.
18
18
  EVENT2ICON = {
19
- 'brkpt' => 'xx',
19
+ 'breakpoint' => 'xx',
20
20
  'tbrkpt' => 'x1',
21
21
  'c-call' => 'C>',
22
22
  'c-return' => '<C',
23
23
  'step-call' => '->',
24
24
  'call' => '->',
25
+ 'catchpoint' => '!!',
25
26
  'class' => '::',
26
27
  'coverage' => '[]',
27
28
  'debugger-call' => ':o',
28
29
  'end' => '-|',
29
30
  'line' => '--',
31
+ 'step' => '--',
32
+ 'post-mortem' => ':/',
30
33
  'raise' => '!!',
31
34
  'return' => '<-',
32
35
  'start' => '>>',
@@ -35,17 +38,17 @@ class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
35
38
  'unknown' => '?!',
36
39
  'vm' => 'VM',
37
40
  'vm-insn' => '..',
38
- }
41
+ }
39
42
  end
40
43
 
41
44
  def canonic_file(filename, resolve=true)
42
- # For now we want resolved filenames
43
- if @settings[:basename]
45
+ # For now we want resolved filenames
46
+ if @settings[:basename]
44
47
  return File.basename(filename)
45
48
  end
46
49
  if resolve
47
50
  filename = LineCache::unmap_file(filename)
48
- if !File.exist?(filename)
51
+ if !File.exist?(filename)
49
52
  if (try_filename = resolve_file_with_dir(filename))
50
53
  filename = try_filename if File.exist?(filename)
51
54
  end
@@ -58,10 +61,10 @@ class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
58
61
  def current_source_text
59
62
  LineCache::getline(@frame.file, @frame.line).chomp
60
63
  end
61
-
64
+
62
65
  def resolve_file_with_dir(path_suffix)
63
66
  settings[:directory].split(/:/).each do |dir|
64
- dir =
67
+ dir =
65
68
  if '$cwd' == dir
66
69
  Dir.pwd
67
70
  else
@@ -73,10 +76,10 @@ class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
73
76
  end
74
77
  nil
75
78
  end
76
-
79
+
77
80
  # Get line +line_number+ from file named +filename+. Return "\n"
78
81
  # there was a problem. Leading blanks are stripped off.
79
- def line_at(filename, line_number,
82
+ def line_at(filename, line_number,
80
83
  opts = {
81
84
  :reload_on_change => @settings[:reload],
82
85
  :output => @settings[:highlight]
@@ -87,9 +90,9 @@ class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
87
90
  unless line
88
91
  # Try using search directories (set with command "directory")
89
92
  if filename[0..0] != File::SEPARATOR
90
- try_filename = resolve_file_with_dir(filename)
91
- if try_filename &&
92
- line = LineCache::getline(try_filename, line_number, opts)
93
+ try_filename = resolve_file_with_dir(filename)
94
+ if try_filename &&
95
+ line = LineCache::getline(try_filename, line_number, opts)
93
96
  LineCache::remap_file(filename, try_filename)
94
97
  end
95
98
  end
@@ -97,16 +100,16 @@ class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
97
100
  return nil unless line
98
101
  return line.lstrip.chomp
99
102
  end
100
-
103
+
101
104
  def loc_and_text(opts=
102
105
  {:reload_on_change => @settings[:reload],
103
106
  :output => @settings[:highlight]
104
107
  })
105
-
108
+
106
109
  loc = source_location_info
107
110
  line_no = @frame.line
108
111
  filename = @frame.file
109
-
112
+
110
113
  # if @frame.eval?
111
114
  # file = LineCache::map_script(static.script)
112
115
  # text = LineCache::getline(static.script, line_no, opts)
@@ -120,40 +123,40 @@ class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
120
123
  # end
121
124
  [loc, line_no, text]
122
125
  end
123
-
126
+
124
127
  def format_location(event=@event, frame=@frame, frame_index=@frame.index)
125
128
  text = nil
126
129
  ev = if event.nil? || 0 != frame_index
127
- ' '
130
+ ' '
128
131
  else
129
132
  (EVENT2ICON[event] || event)
130
133
  end
131
-
134
+
132
135
  @line_no = frame.line
133
136
  loc, @line_no, text = loc_and_text
134
-
137
+
135
138
  "#{ev} (#{loc}"
136
139
  end
137
-
140
+
138
141
  # FIXME: Use above format_location routine
139
142
  def print_location
140
143
  text = nil
141
144
  ev = if @event.nil? || 0 != @frame.index
142
- ' '
145
+ ' '
143
146
  else
144
147
  (EVENT2ICON[@event] || @event)
145
148
  end
146
-
149
+
147
150
  @line_no = @frame.line
148
151
  loc, @line_no, text = loc_and_text
149
-
152
+
150
153
  msg "#{ev} (#{loc})"
151
-
154
+
152
155
  # if %w(return c-return).member?(@core.event)
153
156
  # retval = Trepan::Frame.value_returned(@frame, @core.event)
154
- # msg 'R=> %s' % retval.inspect
157
+ # msg 'R=> %s' % retval.inspect
155
158
  # end
156
-
159
+
157
160
  if text && !text.strip.empty?
158
161
  old_maxstring = @settings[:maxstring]
159
162
  @settings[:maxstring] = -1
@@ -162,10 +165,10 @@ class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
162
165
  @line_no -= 1
163
166
  end
164
167
  end
165
-
168
+
166
169
  def source_location_info
167
170
  filename = @frame.file
168
- canonic_filename =
171
+ canonic_filename =
169
172
  ## if @frame.eval?
170
173
  ## 'eval ' + safe_repr(@frame.eval_string.gsub("\n", ';').inspect, 20)
171
174
  ## else
@@ -173,7 +176,7 @@ class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
173
176
  ## end
174
177
  loc = "#{canonic_filename}:#{@frame.line}"
175
178
  return loc
176
- end
179
+ end
177
180
  end
178
181
 
179
182
  if __FILE__ == $0 && caller.size == 0
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
1
+ # Copyright (C) 2010-2011, 2013 Rocky Bernstein <rockyb@rubyforge.net>
2
2
  # I/O related command processor methods
3
3
  require 'rubygems'; require 'require_relative'
4
4
  require_relative '../app/util'
@@ -23,8 +23,8 @@ class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
23
23
  message = safe_rep(message) unless opts[:unlimited]
24
24
  end
25
25
  if @settings[:highlight] && defined?(Term::ANSIColor)
26
- message =
27
- Term::ANSIColor.italic + message + Term::ANSIColor.reset
26
+ message =
27
+ Term::ANSIColor.italic + message + Term::ANSIColor.reset
28
28
  end
29
29
  @intf.errmsg(message)
30
30
  end
@@ -65,8 +65,8 @@ class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
65
65
  def section(message, opts={})
66
66
  message = safe_rep(message) unless opts[:unlimited]
67
67
  if @settings[:highlight] && defined?(Term::ANSIColor)
68
- message =
69
- Term::ANSIColor.bold + message + Term::ANSIColor.reset
68
+ message =
69
+ Term::ANSIColor.bold + message + Term::ANSIColor.reset
70
70
  end
71
71
  @intf.msg(message)
72
72
  end
@@ -1,8 +1,9 @@
1
- # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
1
+ # Copyright (C) 2010-2011, 2013 Rocky Bernstein <rockyb@rubyforge.net>
2
2
 
3
3
  # Trepan command input validation routines. A String type is
4
4
  # usually passed in as the argument to validation routines.
5
5
 
6
+ require 'rbconfig'
6
7
  require 'rubygems'
7
8
  require 'require_relative'
8
9
  begin
@@ -23,7 +24,7 @@ require_relative 'msg' # for errmsg, msg
23
24
 
24
25
  module Trepan
25
26
  class CmdProcessor < VirtualCmdProcessor
26
-
27
+
27
28
  attr_reader :file_exists_proc # Like File.exists? but checks using
28
29
  # cached files
29
30
 
@@ -36,7 +37,7 @@ module Trepan
36
37
  def confirm(msg, default)
37
38
  @settings[:confirm] ? @intf.confirm(msg, default) : true
38
39
  end
39
-
40
+
40
41
  # Like cmdfns.get_an_int(), but if there's a stack frame use that
41
42
  # in evaluation.
42
43
  def get_an_int(arg, opts={})
@@ -60,19 +61,19 @@ module Trepan
60
61
  end
61
62
  return ret_value
62
63
  end
63
-
64
+
64
65
  unless defined?(DEFAULT_GET_INT_OPTS)
65
66
  DEFAULT_GET_INT_OPTS = {
66
67
  :min_value => 0, :default => 1, :cmdname => nil, :max_value => nil}
67
68
  end
68
-
69
+
69
70
  # If argument parameter 'arg' is not given, then use what is in
70
71
  # opts[:default]. If String 'arg' evaluates to an integer between
71
72
  # least min_value and at_most, use that. Otherwise report an
72
73
  # error. If there's a stack frame use that for bindings in
73
74
  # evaluation.
74
75
  def get_int(arg, opts={})
75
-
76
+
76
77
  return default unless arg
77
78
  opts = DEFAULT_GET_INT_OPTS.merge(opts)
78
79
  val = arg ? get_int_noerr(arg) : opts[:default]
@@ -85,7 +86,7 @@ module Trepan
85
86
  end
86
87
  return nil
87
88
  end
88
-
89
+
89
90
  if val < opts[:min_value]
90
91
  if opts[:cmdname]
91
92
  errmsg(("Command '%s' expects an integer at least" +
@@ -110,11 +111,11 @@ module Trepan
110
111
  end
111
112
  return val
112
113
  end
113
-
114
+
114
115
  def get_int_list(args, opts={})
115
116
  args.map{|arg| get_an_int(arg, opts)}.compact
116
117
  end
117
-
118
+
118
119
  # Eval arg and it is an integer return the value. Otherwise
119
120
  # return nil
120
121
  def get_int_noerr(arg)
@@ -122,10 +123,10 @@ module Trepan
122
123
  val = Integer(eval(arg, b))
123
124
  rescue SyntaxError
124
125
  nil
125
- rescue
126
+ rescue
126
127
  nil
127
128
  end
128
-
129
+
129
130
  def get_thread_from_string(id_or_num_str)
130
131
  if id_or_num_str == '.'
131
132
  Thread.current
@@ -140,7 +141,7 @@ module Trepan
140
141
  end
141
142
  end
142
143
  end
143
-
144
+
144
145
  # Parse a breakpoint position. On success return:
145
146
  # - the Method the position is in
146
147
  # - the file name - a Fixnum
@@ -155,7 +156,7 @@ module Trepan
155
156
  end
156
157
  return [nil] * 5 unless break_cmd_parse
157
158
  tail = [break_cmd_parse.condition, break_cmd_parse.negate]
158
- cm, file, line, position_type =
159
+ cm, file, line, position_type =
159
160
  parse_position(break_cmd_parse.position)
160
161
  if cm or file or line
161
162
  return [cm, file, line, position_type] + tail
@@ -163,7 +164,7 @@ module Trepan
163
164
  errmsg("Unable to get breakpoint position for #{position_str}")
164
165
  return [nil] * 5
165
166
  end
166
-
167
+
167
168
  # Return true if arg is 'on' or 1 and false arg is 'off' or 0.
168
169
  # Any other value is raises TypeError.
169
170
  def get_onoff(arg, default=nil, print_error=true)
@@ -179,16 +180,16 @@ module Trepan
179
180
  darg = arg.downcase
180
181
  return true if arg == '1' || darg == 'on'
181
182
  return false if arg == '0' || darg =='off'
182
-
183
+
183
184
  errmsg("Expecting 'on', 1, 'off', or 0. Got: %s." % arg.to_s) if
184
185
  print_error
185
186
  raise TypeError
186
187
  end
187
-
188
+
188
189
  include Trepan::CmdParser
189
-
190
+
190
191
  def get_method(meth)
191
- start_binding =
192
+ start_binding =
192
193
  begin
193
194
  @frame.binding
194
195
  rescue
@@ -205,13 +206,13 @@ module Trepan
205
206
  end
206
207
  end
207
208
  end
208
-
209
- # FIXME: this is a ? method but we return
210
- # the method value.
209
+
210
+ # FIXME: this is a ? method but we return
211
+ # the method value.
211
212
  def method?(meth)
212
213
  get_method(meth)
213
214
  end
214
-
215
+
215
216
  # parse_position(self)->(meth, filename, offset, offset_type)
216
217
  # See app/cmd_parser.kpeg for the syntax of a position which
217
218
  # should include things like:
@@ -219,6 +220,14 @@ module Trepan
219
220
  # Make sure it works for C:\foo\bar.py:12
220
221
  def parse_position(info)
221
222
  info = parse_location(info) if info.kind_of?(String)
223
+ ## FIXME: push into parse
224
+ if RbConfig::CONFIG['target_os'].start_with?('mingw') and
225
+ info =~ /^[A-Za-z]:/
226
+ drive_letter = info[0..1]
227
+ info = info[2..-1]
228
+ else
229
+ drive_leter = nil
230
+ end
222
231
  case info.container_type
223
232
  when :fn
224
233
  unless info.container
@@ -227,7 +236,7 @@ module Trepan
227
236
  end
228
237
  if cm = method?(info.container)
229
238
  ## Add bogus - canonic_file: active-path
230
- return [cm, 'bogus', info.position,
239
+ return [cm, 'bogus', info.position,
231
240
  info.position_type]
232
241
  else
233
242
  return [nil] * 4
@@ -235,13 +244,13 @@ module Trepan
235
244
  when :file
236
245
  ## filename = canonic_file(info.container)
237
246
  filename = info.container
238
- # cm =
239
- # if canonic_file(@frame.file) == filename
247
+ # cm =
248
+ # if canonic_file(@frame.file) == filename
240
249
  # cm = @frame.method
241
250
  # if :line == info.position_type
242
251
  # find_method_with_line(cm, info.position)
243
252
  # end
244
- # else
253
+ # else
245
254
  # LineCache.compiled_method(filename)
246
255
  # end
247
256
  return nil, filename, info.position, info.position_type
@@ -265,9 +274,9 @@ module Trepan
265
274
  return [nil] * 4
266
275
  end
267
276
  end
268
-
277
+
269
278
  def parse_method(meth_str)
270
- begin
279
+ begin
271
280
  meth_for_string(meth_str, @frame.binding)
272
281
  rescue NameError
273
282
  nil
@@ -275,7 +284,7 @@ module Trepan
275
284
  nil
276
285
  end
277
286
  end
278
-
287
+
279
288
  def validate_initialize
280
289
  ## top_srcdir = File.expand_path(File.join(File.dirname(__FILE__), '..'))
281
290
  ## @dbgr_script_iseqs, @dbgr_iseqs = filter_scripts(top_srcdir)
@@ -296,15 +305,15 @@ if __FILE__ == $0
296
305
  # FIXME have to pull in main for its initalize routine
297
306
  DIRNAME = File.dirname(__FILE__)
298
307
  load File.join(DIRNAME, 'main.rb')
299
-
308
+
300
309
  require_relative 'mock'
301
310
  dbgr, cmd = MockDebugger::setup('exit', false)
302
311
  cmdproc = cmd.proc
303
312
  onoff = %w(1 0 on off)
304
313
  onoff.each { |val| puts "onoff(#{val}) = #{cmdproc.get_onoff(val)}" }
305
314
  cmdproc.frame.instance_variable_set('@binding', binding)
306
- %w(1 1E bad 1+1 -5).each do |val|
307
- puts "get_int_noerr(#{val}) = #{cmdproc.get_int_noerr(val).inspect}"
315
+ %w(1 1E bad 1+1 -5).each do |val|
316
+ puts "get_int_noerr(#{val}) = #{cmdproc.get_int_noerr(val).inspect}"
308
317
  end
309
318
  def foo; 5 end
310
319
  def cmdproc.errmsg(msg)
@@ -322,7 +331,7 @@ if __FILE__ == $0
322
331
 
323
332
  puts "To be continued...."
324
333
  exit
325
-
334
+
326
335
  cmdproc.method?('cmdproc.errmsg')
327
336
  puts '=' * 40
328
337
  ['Array.map', 'Trepan::CmdProcessor.new',
@@ -330,11 +339,11 @@ if __FILE__ == $0
330
339
  puts "#{str} should be true: #{cmdproc.method?(str).inspect}"
331
340
  end
332
341
  puts '=' * 40
333
-
342
+
334
343
  # FIXME:
335
344
  # Array#foo should be false: true
336
345
  # Trepan::CmdProcessor.allocate should be false: true
337
-
346
+
338
347
  ['food', '.errmsg'].each do |str|
339
348
  puts "#{str} should be false: #{cmdproc.method?(str).inspect}"
340
349
  end