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.
- data/CHANGES +18 -4
- data/ChangeLog +100 -87
- data/Makefile +23 -4
- data/README.textile +3 -3
- data/Rakefile +26 -20
- data/app/complete.rb +13 -13
- data/app/default.rb +8 -8
- data/app/display.rb +7 -7
- data/app/frame.rb +8 -8
- data/app/irb.rb +15 -15
- data/app/options.rb +25 -25
- data/app/run.rb +16 -8
- data/app/util.rb +7 -7
- data/bin/trepan8 +2 -2
- data/check-filter.rb +21 -0
- data/interface.rb +4 -4
- data/interface/user.rb +11 -11
- data/io.rb +18 -19
- data/io/input.rb +14 -12
- data/lib/debugger.rb +3 -1
- data/lib/trepanning.rb +30 -28
- data/processor.rb +41 -38
- data/processor/command.rb +9 -9
- data/processor/command/alias.rb +6 -6
- data/processor/command/down.rb +1 -2
- data/processor/command/edit.rb +12 -8
- data/processor/command/eval.rb +7 -7
- data/processor/command/info_subcmd/macro.rb +6 -6
- data/processor/command/info_subcmd/program.rb +5 -1
- data/processor/command/macro.rb +6 -6
- data/processor/command/show_subcmd/abbrev.rb +2 -2
- data/processor/command/up.rb +1 -2
- data/processor/complete.rb +120 -0
- data/processor/default.rb +13 -9
- data/processor/load_cmds.rb +18 -97
- data/processor/location.rb +34 -31
- data/processor/msg.rb +5 -5
- data/processor/validate.rb +44 -35
- data/test/data/break_loop_bug.right +2 -2
- data/test/data/edit.cmd +1 -1
- data/test/data/edit.right +7 -1
- data/test/data/printvar.right +2 -2
- data/test/data/raise.right +0 -1
- data/test/data/trace-mingw.right +28 -0
- data/test/integration/.gitignore +1 -0
- data/test/integration/test-raise.rb +10 -1
- data/test/integration/test-trace.rb +10 -6
- data/test/unit/test-app-options.rb +9 -3
- data/test/unit/test-app-run.rb +8 -1
- data/test/unit/test-cmd-alias.rb +2 -2
- data/test/unit/test-proc-default.rb +34 -0
- metadata +10 -6
data/processor/load_cmds.rb
CHANGED
@@ -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
|
data/processor/location.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
# Copyright (C) 2010,
|
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
|
-
'
|
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
|
data/processor/msg.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2010,
|
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
|
data/processor/validate.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
-
# Copyright (C) 2010,
|
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
|