rb8-trepanning 0.1.5 → 0.1.6

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