trepanning 1.93.35 → 2.15.33
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.
- checksums.yaml +7 -0
- data/ChangeLog +491 -55
- data/LICENSE +1 -1
- data/NEWS +18 -14
- data/README.md +5 -22
- data/Rakefile +22 -1
- data/app/breakpoint.rb +5 -3
- data/app/core.rb +147 -179
- data/app/default.rb +47 -46
- data/app/file.rb +6 -7
- data/app/frame.rb +183 -176
- data/app/markdown.rb +2 -9
- data/app/options.rb +1 -1
- data/app/run.rb +71 -37
- data/interface/script.rb +8 -8
- data/io.rb +19 -20
- data/lib/trepanning.rb +292 -297
- data/processor.rb +332 -344
- data/processor/breakpoint.rb +98 -96
- data/processor/command/base/submgr.rb +9 -9
- data/processor/command/break.rb +40 -38
- data/processor/command/continue.rb +15 -10
- data/processor/command/debug.rb +6 -25
- data/processor/command/delete.rb +21 -12
- data/processor/command/directory.rb +15 -13
- data/processor/command/disable.rb +12 -9
- data/processor/command/disassemble.rb +80 -74
- data/processor/command/display.rb +15 -12
- data/processor/command/down.rb +8 -3
- data/processor/command/edit.rb +37 -23
- data/processor/command/enable.rb +11 -8
- data/processor/command/eval.rb +24 -22
- data/processor/command/finish.rb +50 -48
- data/processor/command/help.rb +1 -1
- data/processor/command/info_subcmd/breakpoints.rb +7 -7
- data/processor/command/info_subcmd/files.rb +195 -196
- data/processor/command/info_subcmd/frame.rb +7 -4
- data/processor/command/info_subcmd/locals.rb +29 -12
- data/processor/command/info_subcmd/program.rb +48 -39
- data/processor/command/info_subcmd/registers_subcmd/ep.rb +46 -0
- data/processor/command/info_subcmd/registers_subcmd/helper.rb +32 -35
- data/processor/command/info_subcmd/registers_subcmd/sp.rb +29 -23
- data/processor/command/info_subcmd/return.rb +28 -10
- data/processor/command/info_subcmd/variables_subcmd/class.rb +3 -3
- data/processor/command/info_subcmd/variables_subcmd/constants.rb +77 -0
- data/processor/command/info_subcmd/variables_subcmd/globals.rb +7 -7
- data/processor/command/info_subcmd/variables_subcmd/instance.rb +68 -22
- data/processor/command/info_subcmd/variables_subcmd/locals.rb +148 -67
- data/processor/command/list.rb +14 -8
- data/processor/command/macro.rb +1 -1
- data/processor/command/next.rb +1 -0
- data/processor/command/set_subcmd/auto.rb +3 -3
- data/processor/command/set_subcmd/different.rb +30 -29
- data/processor/command/set_subcmd/events.rb +74 -48
- data/processor/command/set_subcmd/max_subcmd/list.rb +12 -5
- data/processor/command/set_subcmd/max_subcmd/width.rb +28 -19
- data/processor/command/set_subcmd/register.rb +37 -0
- data/processor/command/set_subcmd/register_subcmd/pc.rb +67 -0
- data/processor/command/set_subcmd/register_subcmd/sp.rb +75 -0
- data/processor/command/set_subcmd/reload.rb +12 -10
- data/processor/command/set_subcmd/return.rb +68 -44
- data/processor/command/shell.rb +3 -2
- data/processor/command/show_subcmd/different.rb +17 -14
- data/processor/command/show_subcmd/events.rb +25 -25
- data/processor/default.rb +1 -1
- data/processor/eval.rb +14 -15
- data/processor/frame.rb +43 -36
- data/processor/help.rb +5 -5
- data/processor/hook.rb +26 -29
- data/processor/location.rb +54 -51
- data/processor/mock.rb +4 -3
- data/processor/running.rb +113 -103
- data/processor/validate.rb +401 -373
- data/test/data/debug.cmd +8 -0
- data/test/data/debug.right +13 -0
- data/test/data/debugger-stop.right +6 -4
- data/test/data/fname-with-blank.cmd +1 -1
- data/test/data/fname-with-blank.right +5 -0
- data/test/data/pc.cmd +8 -0
- data/test/data/pc.right +10 -0
- data/test/data/quit.right +3 -1
- data/test/data/trace.cmd +2 -2
- data/test/data/trace.right +41 -20
- data/test/example/assign.rb +6 -0
- data/test/functional/fn_helper.rb +11 -17
- data/test/functional/test-break-long.rb +15 -16
- data/test/functional/test-break.rb +6 -8
- data/test/functional/test-condition.rb +8 -10
- data/test/functional/test-debugger-call-bug.rb +21 -22
- data/test/functional/test-delete.rb +57 -59
- data/test/functional/test-eval.rb +101 -103
- data/test/functional/test-finish.rb +24 -33
- data/test/functional/test-immediate-step-bug.rb +6 -10
- data/test/functional/test-next.rb +64 -65
- data/test/functional/test-raise.rb +63 -64
- data/test/functional/test-recursive-bt.rb +81 -76
- data/test/functional/test-remap.rb +6 -7
- data/test/functional/test-return.rb +44 -38
- data/test/functional/test-step.rb +55 -53
- data/test/functional/test-stepbug.rb +6 -9
- data/test/functional/test-watchg.rb +40 -39
- data/test/integration/test-debug.rb +12 -0
- data/test/integration/test-debugger-stop.rb +7 -7
- data/test/integration/test-pc.rb +24 -0
- data/test/integration/test-trace.rb +1 -1
- data/test/unit/cmd-helper.rb +0 -1
- data/test/unit/test-app-brkpt.rb +21 -21
- data/test/unit/test-app-brkptmgr.rb +7 -8
- data/test/unit/test-app-display.rb +3 -4
- data/test/unit/test-app-frame.rb +4 -5
- data/test/unit/test-base-subsubcmd.rb +2 -2
- data/test/unit/test-cmd-break.rb +6 -6
- data/test/unit/test-cmd-endisable.rb +7 -6
- data/test/unit/test-cmd-parse_list_cmd.rb +24 -24
- data/test/unit/test-io-tcpserver.rb +39 -35
- data/test/unit/test-proc-default.rb +23 -22
- data/test/unit/test-proc-eval.rb +1 -2
- data/test/unit/test-proc-frame.rb +8 -9
- data/test/unit/test-proc-list.rb +1 -1
- data/test/unit/test-proc-location.rb +2 -2
- data/test/unit/test-proc-main.rb +10 -10
- data/test/unit/test-proc-validate.rb +11 -13
- data/test/unit/test-subcmd-help.rb +1 -2
- data/trepanning.gemspec +8 -13
- metadata +44 -95
- data/COPYING +0 -57
- data/data/custom_require.rb +0 -44
- data/data/perldb.bindings +0 -17
- data/data/prelude.rb +0 -38
- data/processor/command/info_subcmd/variables_subcmd/constant.rb +0 -41
- data/processor/command/raise.rb +0 -48
- data/processor/command/set_subcmd/pc.rb +0 -62
- data/processor/command/set_subcmd/sp.rb +0 -67
- data/processor/eventbuf.rb +0 -133
data/processor/mock.rb
CHANGED
@@ -40,6 +40,7 @@ module MockDebugger
|
|
40
40
|
|
41
41
|
# Don't allow user commands in mocks.
|
42
42
|
@core.processor.settings[:user_cmd_dir] = nil
|
43
|
+
@core.processor.hidelevels = {}
|
43
44
|
|
44
45
|
end
|
45
46
|
|
@@ -51,7 +52,7 @@ module MockDebugger
|
|
51
52
|
# Common Mock debugger setup
|
52
53
|
def setup(name=nil, show_constants=true)
|
53
54
|
unless name
|
54
|
-
tf = RubyVM::Frame.
|
55
|
+
tf = RubyVM::Frame.get(1)
|
55
56
|
name = File.basename(tf.source_container[1], '.rb')
|
56
57
|
end
|
57
58
|
if ARGV.size > 0 && ARGV[0] == 'debug'
|
@@ -64,7 +65,7 @@ module MockDebugger
|
|
64
65
|
|
65
66
|
cmds = dbgr.core.processor.commands
|
66
67
|
cmd = cmds[name]
|
67
|
-
cmd.proc.frame_setup(RubyVM::Frame::
|
68
|
+
cmd.proc.frame_setup(RubyVM::Frame::get(1))
|
68
69
|
show_special_class_constants(cmd) if show_constants
|
69
70
|
|
70
71
|
def cmd.confirm(prompt, default)
|
@@ -90,7 +91,7 @@ module MockDebugger
|
|
90
91
|
def sub_setup(sub_class, run=true)
|
91
92
|
sub_name = sub_class.const_get('PREFIX')
|
92
93
|
dbgr, cmd = setup(sub_name[0], false)
|
93
|
-
cmd.proc.frame_setup(RubyVM::Frame::
|
94
|
+
cmd.proc.frame_setup(RubyVM::Frame::get)
|
94
95
|
cmd.proc.event = 'debugger-call'
|
95
96
|
sub_cmd = sub_class.new(cmd)
|
96
97
|
sub_cmd.summary_help(sub_cmd)
|
data/processor/running.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2010,
|
1
|
+
# Copyright (C) 2010-2011, 2015 Rocky Bernstein <rockyb@rubyforge.net>
|
2
2
|
require_relative 'virtual'
|
3
3
|
class Trepan
|
4
4
|
class CmdProcessor < VirtualCmdProcessor
|
@@ -16,57 +16,65 @@ class Trepan
|
|
16
16
|
# be more temporarily changed via
|
17
17
|
# "step>" or "step!" commands.
|
18
18
|
attr_accessor :to_method
|
19
|
-
|
19
|
+
|
20
20
|
# Does whatever needs to be done to set to continue program
|
21
21
|
# execution.
|
22
22
|
# FIXME: turn line_number into a condition.
|
23
23
|
def continue
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
@
|
29
|
-
|
30
|
-
@
|
31
|
-
|
32
|
-
|
24
|
+
|
25
|
+
# FIXME: with the ruby-supported stepping, we might not
|
26
|
+
# need the below any more.
|
27
|
+
# I'm guessing the stack size can't ever reach this
|
28
|
+
@next_level = 32000
|
29
|
+
|
30
|
+
@next_thread = nil
|
31
|
+
if @settings[:traceprint]
|
32
|
+
@core.step_count = 1 # traceprint will avoid stopping
|
33
|
+
else
|
34
|
+
@core.step_count = -1 # No more event stepping
|
35
|
+
end
|
36
|
+
@leave_cmd_loop = true # Break out of the processor command loop.
|
33
37
|
end
|
34
38
|
|
35
39
|
# Does whatever setup needs to be done to set to ignore stepping
|
36
40
|
# to the finish of the current method.
|
37
41
|
def finish(level_count=0, opts={})
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
42
|
+
step(0, opts)
|
43
|
+
# @next_level = @frame.stack_size - level_count
|
44
|
+
# @next_thread = Thread.current
|
45
|
+
# @stop_events = Set.new(%w(return leave yield))
|
46
|
+
|
47
|
+
# Try high-speed (run-time-assisted) method
|
48
|
+
# FIXME: if frame is not the top frame, then we should to do more...
|
49
|
+
@frame.step_out
|
46
50
|
end
|
47
51
|
|
48
52
|
# Does whatever needs to be done to set to do "step over" or ignore
|
49
|
-
# stepping into methods called from this stack but step into any in
|
53
|
+
# stepping into methods called from this stack but step into any in
|
50
54
|
# the same level. We do this by keeping track of the number of
|
51
55
|
# stack frames and the current thread. Elsewhere in "skipping_step?"
|
52
56
|
# we do the checking.
|
53
57
|
def next(step_count=1, opts={})
|
54
|
-
|
55
|
-
|
56
|
-
|
58
|
+
step(step_count, opts)
|
59
|
+
# FIXME: if frame is not the top frame, then we should to do more...
|
60
|
+
# Try high-speed (run-time-assisted) method
|
61
|
+
@frame.step_over
|
62
|
+
# @next_level = @top_frame.stack_size
|
63
|
+
# @next_thread = Thread.current
|
57
64
|
end
|
58
65
|
|
59
66
|
# Does whatever needs to be done to set to step program
|
60
67
|
# execution.
|
61
68
|
def step(step_count=1, opts={}, condition=nil)
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
opts
|
66
|
-
|
67
|
-
|
68
|
-
opts
|
69
|
-
|
69
|
+
@frame.step_in if @frame
|
70
|
+
continue
|
71
|
+
@core.step_count = step_count
|
72
|
+
@different_pos = opts[:different_pos] if
|
73
|
+
opts.keys.member?(:different_pos)
|
74
|
+
@stop_condition = condition
|
75
|
+
@stop_events = opts[:stop_events] if
|
76
|
+
opts.keys.member?(:stop_events)
|
77
|
+
@to_method = opts[:to_method]
|
70
78
|
end
|
71
79
|
|
72
80
|
def quit(cmd='quit')
|
@@ -81,26 +89,26 @@ class Trepan
|
|
81
89
|
end
|
82
90
|
|
83
91
|
def parse_next_step_suffix(step_cmd)
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
92
|
+
opts = {}
|
93
|
+
case step_cmd[-1..-1]
|
94
|
+
when '-'
|
95
|
+
opts[:different_pos] = false
|
96
|
+
when '+'
|
97
|
+
opts[:different_pos] = 'nostack'
|
98
|
+
when '='
|
99
|
+
opts[:different_pos] = true
|
100
|
+
when '!'
|
101
|
+
opts[:stop_events] = Set.new(%w(raise))
|
102
|
+
when '<'
|
103
|
+
opts[:stop_events] = Set.new(%w(c_return return))
|
104
|
+
when '>'
|
105
|
+
if step_cmd.size > 1 && step_cmd[-2..-2] == '<'
|
106
|
+
opts[:stop_events] = Set.new(%w(c_call c_return call return))
|
107
|
+
else
|
108
|
+
opts[:stop_events] = Set.new(%w(c_call call))
|
109
|
+
end
|
101
110
|
end
|
102
|
-
|
103
|
-
return opts
|
111
|
+
return opts
|
104
112
|
end
|
105
113
|
|
106
114
|
def running_initialize
|
@@ -111,67 +119,69 @@ class Trepan
|
|
111
119
|
|
112
120
|
def stepping_skip?
|
113
121
|
|
114
|
-
|
122
|
+
return true if @core.step_count < 0
|
123
|
+
|
124
|
+
if @settings[:'debugskip']
|
125
|
+
msg "diff: #{@different_pos}, event : #{@event}, #{@stop_events.inspect}"
|
126
|
+
msg "step_count : #{@core.step_count}"
|
127
|
+
msg "next_level : #{@next_level}, ssize : #{@stack_size}"
|
128
|
+
msg "next_thread : #{@next_thread}, thread: #{Thread.current}"
|
129
|
+
end
|
115
130
|
|
116
|
-
if @settings[:'debugskip']
|
117
|
-
msg "diff: #{@different_pos}, event : #{@event}, #{@stop_events.inspect}"
|
118
|
-
msg "step_count : #{@core.step_count}"
|
119
|
-
msg "next_level : #{@next_level}, ssize : #{@stack_size}"
|
120
|
-
msg "next_thread : #{@next_thread}, thread: #{Thread.current}"
|
121
|
-
end
|
122
131
|
|
123
|
-
|
124
|
-
|
125
|
-
|
132
|
+
# FIXME: with the ruby-supported stepping, we might not
|
133
|
+
# need @next_level an the below test.
|
134
|
+
return true if
|
135
|
+
!frame || (@next_level < @frame.stack_size &&
|
136
|
+
Thread.current == @next_thread && @event.to_s != 'raise')
|
126
137
|
|
127
|
-
|
128
|
-
|
138
|
+
new_pos = [@frame.source_container, frame_line,
|
139
|
+
@stack_size, @current_thread, @event, @frame.pc_offset]
|
129
140
|
|
130
|
-
|
141
|
+
skip_val = @stop_events && !@stop_events.member?(@event.to_s)
|
131
142
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
143
|
+
# If the last stop was a breakpoint, don't stop again if we are at
|
144
|
+
# the same location with a line event.
|
145
|
+
skip_val ||= (@last_pos[4] == 'brkpt' &&
|
146
|
+
@event.to_s == 'line' &&
|
147
|
+
@frame.pc_offset == @last_pos[5])
|
137
148
|
|
138
|
-
|
139
|
-
puts "skip: #{skip_val.inspect}, last: #{@last_pos}, new: #{new_pos}"
|
140
|
-
|
149
|
+
if @settings[:'debugskip']
|
150
|
+
puts "skip: #{skip_val.inspect}, last: #{@last_pos}, new: #{new_pos}"
|
151
|
+
end
|
141
152
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
153
|
+
@last_pos[2] = new_pos[2] if 'nostack' == @different_pos
|
154
|
+
unless skip_val
|
155
|
+
condition_met =
|
156
|
+
if @stop_condition
|
146
157
|
puts 'stop_cond' if @settings[:'debugskip']
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
@last_pos = new_pos if !@stop_events || @stop_events.member?(@event)
|
165
|
-
|
166
|
-
unless skip_val
|
167
|
-
# Set up the default values for the
|
168
|
-
# next time we consider skipping.
|
169
|
-
@different_pos = @settings[:different]
|
170
|
-
@stop_events = nil
|
171
|
-
end
|
172
|
-
|
173
|
-
return skip_val
|
174
|
-
end
|
158
|
+
debug_eval_no_errmsg(@stop_condition)
|
159
|
+
elsif @to_method
|
160
|
+
puts "method #{@frame.method} #{@to_method}" if
|
161
|
+
@settings[:'debugskip']
|
162
|
+
@frame.method == @to_method
|
163
|
+
else
|
164
|
+
puts 'uncond' if @settings[:'debugskip']
|
165
|
+
true
|
166
|
+
end
|
167
|
+
|
168
|
+
msg("condition_met: #{condition_met}, last: #{@last_pos}, " +
|
169
|
+
"new: #{new_pos}, different #{@different_pos.inspect}") if
|
170
|
+
@settings[:'debugskip']
|
171
|
+
skip_val = ((@last_pos[0..3] == new_pos[0..3] && @different_pos) ||
|
172
|
+
!condition_met)
|
173
|
+
end
|
175
174
|
|
175
|
+
@last_pos = new_pos if !@stop_events || @stop_events.member?(@event)
|
176
|
+
|
177
|
+
unless skip_val
|
178
|
+
# Set up the default values for the
|
179
|
+
# next time we consider skipping.
|
180
|
+
@different_pos = @settings[:different]
|
181
|
+
@stop_events = nil
|
182
|
+
end
|
183
|
+
|
184
|
+
return skip_val
|
185
|
+
end
|
176
186
|
end
|
177
187
|
end
|
data/processor/validate.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2010-2011, 2013 Rocky Bernstein <rockyb@rubyforge.net>
|
1
|
+
# Copyright (C) 2010-2011, 2013, 2015 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.
|
@@ -17,409 +17,437 @@ require_relative 'msg' # for errmsg, msg
|
|
17
17
|
require_relative 'virtual'
|
18
18
|
|
19
19
|
class Trepan
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
20
|
+
class CmdProcessor < VirtualCmdProcessor
|
21
|
+
|
22
|
+
attr_reader :dbgr_script_iseqs
|
23
|
+
attr_reader :dbgr_iseqs
|
24
|
+
attr_reader :file_exists_proc # Like File.exists? but checks using
|
25
|
+
# cached files
|
26
|
+
|
27
|
+
include Trepanning
|
28
|
+
include Trepan::ThreadHelper
|
29
|
+
include Trepan::Condition
|
30
|
+
|
31
|
+
# Return true if file is a text file. We do this based on
|
32
|
+
# reading the beginning portion and checking the encoding
|
33
|
+
# This code has been adapted from ptools. We've upped the threshhold though
|
34
|
+
# from about 30% to 90% to be able to handle DLs which have a fair amount of
|
35
|
+
# text in them.
|
36
|
+
def text_file?(file)
|
37
|
+
return false unless File.readable?(file)
|
38
|
+
bytes = File.stat(file).blksize
|
39
|
+
bytes = 4096 if bytes > 4096
|
40
|
+
s = (File.read(file, bytes) || "")
|
41
|
+
s = s.encode('US-ASCII', :undef => :replace).split(//)
|
42
|
+
return (s.grep(" ".."~").size.to_f / s.size.to_f) > 0.85
|
40
43
|
end
|
41
|
-
return nil
|
42
|
-
end
|
43
|
-
if opts[:min_value] and ret_value < opts[:min_value]
|
44
|
-
errmsg("Expecting integer value to be at least %d; got %d." %
|
45
|
-
[opts[:min_value], ret_value])
|
46
|
-
return nil
|
47
|
-
elsif opts[:max_value] and ret_value > opts[:max_value]
|
48
|
-
errmsg("Expecting integer value to be at most %d; got %d." %
|
49
|
-
[opts[:max_value], ret_value])
|
50
|
-
return nil
|
51
|
-
end
|
52
|
-
return ret_value
|
53
|
-
end
|
54
|
-
|
55
|
-
unless defined?(DEFAULT_GET_INT_OPTS)
|
56
|
-
DEFAULT_GET_INT_OPTS = {
|
57
|
-
:min_value => 0, :default => 1, :cmdname => nil, :max_value => nil}
|
58
|
-
end
|
59
44
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
errmsg(("Command '%s' expects an integer at least" +
|
83
|
-
' %d; got: %d.') %
|
84
|
-
[opts[:cmdname], opts[:min_value], opts[:default]])
|
85
|
-
else
|
86
|
-
errmsg(("Expecting a positive integer at least" +
|
87
|
-
' %d; got: %d') %
|
88
|
-
[opts[:min_value], opts[:default]])
|
89
|
-
end
|
90
|
-
return nil
|
91
|
-
elsif opts[:max_value] and val > opts[:max_value]
|
92
|
-
if opts[:cmdname]
|
93
|
-
errmsg(("Command '%s' expects an integer at most" +
|
94
|
-
' %d; got: %d.') %
|
95
|
-
[opts[:cmdname], opts[:max_value], val])
|
96
|
-
else
|
97
|
-
errmsg(("Expecting an integer at most %d; got: %d") %
|
98
|
-
[opts[:max_value], val])
|
45
|
+
# Check that arg is an Integer between opts[:min_value] and
|
46
|
+
# opts[:max_value]
|
47
|
+
def get_an_int(arg, opts={})
|
48
|
+
ret_value = get_int_noerr(arg)
|
49
|
+
if !ret_value
|
50
|
+
if opts[:msg_on_error]
|
51
|
+
errmsg(opts[:msg_on_error])
|
52
|
+
else
|
53
|
+
errmsg("Expecting an integer, got: #{arg}.")
|
54
|
+
end
|
55
|
+
return nil
|
56
|
+
end
|
57
|
+
if opts[:min_value] and ret_value < opts[:min_value]
|
58
|
+
errmsg("Expecting integer value to be at least %d; got %d." %
|
59
|
+
[opts[:min_value], ret_value])
|
60
|
+
return nil
|
61
|
+
elsif opts[:max_value] and ret_value > opts[:max_value]
|
62
|
+
errmsg("Expecting integer value to be at most %d; got %d." %
|
63
|
+
[opts[:max_value], ret_value])
|
64
|
+
return nil
|
65
|
+
end
|
66
|
+
return ret_value
|
99
67
|
end
|
100
|
-
return nil
|
101
|
-
end
|
102
|
-
return val
|
103
|
-
end
|
104
|
-
|
105
|
-
def get_int_list(args, opts={})
|
106
|
-
args.map{|arg| get_an_int(arg, opts)}.compact
|
107
|
-
end
|
108
|
-
|
109
|
-
# Eval arg and it is an integer return the value. Otherwise
|
110
|
-
# return nil
|
111
|
-
def get_int_noerr(arg)
|
112
|
-
b = @frame ? @frame.binding : nil
|
113
|
-
val = Integer(eval(arg, b))
|
114
|
-
rescue SyntaxError
|
115
|
-
nil
|
116
|
-
rescue
|
117
|
-
nil
|
118
|
-
end
|
119
68
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
elsif id_or_num_str.downcase == 'm'
|
124
|
-
Thread.main
|
125
|
-
else
|
126
|
-
num = get_int_noerr(id_or_num_str)
|
127
|
-
if num
|
128
|
-
get_thread(num)
|
129
|
-
else
|
130
|
-
nil
|
69
|
+
unless defined?(DEFAULT_GET_INT_OPTS)
|
70
|
+
DEFAULT_GET_INT_OPTS = {
|
71
|
+
:min_value => 0, :default => 1, :cmdname => nil, :max_value => nil}
|
131
72
|
end
|
132
|
-
end
|
133
|
-
end
|
134
73
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
74
|
+
# If argument parameter 'arg' is not given, then use what is in
|
75
|
+
# opts[:default]. If String 'arg' evaluates to an integer between
|
76
|
+
# least min_value and at_most, use that. Otherwise report an
|
77
|
+
# error. If there's a stack frame use that for bindings in
|
78
|
+
# evaluation.
|
79
|
+
def get_int(arg, opts={})
|
80
|
+
|
81
|
+
return default unless arg
|
82
|
+
opts = DEFAULT_GET_INT_OPTS.merge(opts)
|
83
|
+
val = arg ? get_int_noerr(arg) : opts[:default]
|
84
|
+
unless val
|
85
|
+
if opts[:cmdname]
|
86
|
+
errmsg(("Command '%s' expects an integer; " +
|
87
|
+
"got: %s.") % [opts[:cmdname], arg])
|
88
|
+
else
|
89
|
+
errmsg('Expecting a positive integer, got: %s' % arg)
|
90
|
+
end
|
91
|
+
return nil
|
92
|
+
end
|
93
|
+
|
94
|
+
if val < opts[:min_value]
|
95
|
+
if opts[:cmdname]
|
96
|
+
errmsg(("Command '%s' expects an integer at least" +
|
97
|
+
' %d; got: %d.') %
|
98
|
+
[opts[:cmdname], opts[:min_value], opts[:default]])
|
99
|
+
else
|
100
|
+
errmsg(("Expecting a positive integer at least" +
|
101
|
+
' %d; got: %d') %
|
102
|
+
[opts[:min_value], opts[:default]])
|
103
|
+
end
|
104
|
+
return nil
|
105
|
+
elsif opts[:max_value] and val > opts[:max_value]
|
106
|
+
if opts[:cmdname]
|
107
|
+
errmsg(("Command '%s' expects an integer at most" +
|
108
|
+
' %d; got: %d.') %
|
109
|
+
[opts[:cmdname], opts[:max_value], val])
|
110
|
+
else
|
111
|
+
errmsg(("Expecting an integer at most %d; got: %d") %
|
112
|
+
[opts[:max_value], val])
|
113
|
+
end
|
114
|
+
return nil
|
115
|
+
end
|
116
|
+
return val
|
170
117
|
end
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
line_no = ary.first
|
175
|
-
vm_offset = position
|
176
|
-
else
|
177
|
-
errmsg "Unable to find line for offset #{position} in #{iseq}"
|
178
|
-
return [nil, nil]
|
118
|
+
|
119
|
+
def get_int_list(args, opts={})
|
120
|
+
args.map{|arg| get_an_int(arg, opts)}.compact
|
179
121
|
end
|
180
|
-
when nil
|
181
|
-
vm_offset = 0
|
182
|
-
line_no = iseq.offset2lines(vm_offset).first
|
183
|
-
else
|
184
|
-
errmsg "Bad parse offset_type: #{offset_type.inspect}"
|
185
|
-
return [nil, nil]
|
186
|
-
end
|
187
|
-
return [iseq, line_no, vm_offset]
|
188
|
-
end
|
189
122
|
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
else
|
200
|
-
parse_breakpoint_no_condition(position_str)
|
201
|
-
end
|
202
|
-
return [nil] * 5 unless break_cmd_parse
|
203
|
-
tail = [break_cmd_parse.condition, break_cmd_parse.negate]
|
204
|
-
meth_or_frame, file, position, offset_type =
|
205
|
-
parse_position(break_cmd_parse.position)
|
206
|
-
if meth_or_frame
|
207
|
-
if iseq = meth_or_frame.iseq
|
208
|
-
iseq, line_no, vm_offset =
|
209
|
-
position_to_line_and_offset(iseq, file, position, offset_type)
|
210
|
-
if vm_offset && line_no
|
211
|
-
return [iseq, line_no, vm_offset] + tail
|
212
|
-
end
|
213
|
-
else
|
214
|
-
errmsg("Unable to set breakpoint in #{meth_or_frame}")
|
123
|
+
# Eval arg and it is an integer return the value. Otherwise
|
124
|
+
# return nil
|
125
|
+
def get_int_noerr(arg)
|
126
|
+
b = @frame ? @frame.binding : nil
|
127
|
+
val = Integer(eval(arg, b))
|
128
|
+
rescue SyntaxError
|
129
|
+
nil
|
130
|
+
rescue
|
131
|
+
nil
|
215
132
|
end
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
133
|
+
|
134
|
+
def get_thread_from_string(id_or_num_str)
|
135
|
+
if id_or_num_str == '.'
|
136
|
+
Thread.current
|
137
|
+
elsif id_or_num_str.downcase == 'm'
|
138
|
+
Thread.main
|
139
|
+
else
|
140
|
+
num = get_int_noerr(id_or_num_str)
|
141
|
+
if num
|
142
|
+
get_thread(num)
|
143
|
+
else
|
144
|
+
nil
|
145
|
+
end
|
146
|
+
end
|
229
147
|
end
|
230
|
-
elsif @frame.respond_to?(:file) and @frame.file == file
|
231
|
-
line_no, vm_offset = position_to_line_and_offset(@frame.iseq, position,
|
232
|
-
offset_type)
|
233
|
-
return [@frame.iseq, line_no, vm_offset] + tail
|
234
|
-
else
|
235
|
-
errmsg("Unable to parse breakpoint position #{position_str}")
|
236
|
-
end
|
237
|
-
return [nil] * 5
|
238
|
-
end
|
239
148
|
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
149
|
+
# Return the instruction sequence associated with string
|
150
|
+
# OBJECT_STRING or nil if no instruction sequence
|
151
|
+
def object_iseq(object_string)
|
152
|
+
iseqs = find_iseqs(ISEQS__, object_string)
|
153
|
+
# FIXME: do something if there is more than one.
|
154
|
+
if iseqs.size == 1
|
155
|
+
iseqs[-1]
|
156
|
+
elsif meth = method?(object_string)
|
157
|
+
meth.iseq
|
158
|
+
else
|
159
|
+
nil
|
160
|
+
end
|
161
|
+
rescue
|
162
|
+
nil
|
249
163
|
end
|
250
|
-
return default
|
251
|
-
end
|
252
|
-
darg = arg.downcase
|
253
|
-
return true if arg == '1' || darg == 'on'
|
254
|
-
return false if arg == '0' || darg =='off'
|
255
|
-
|
256
|
-
errmsg("Expecting 'on', 1, 'off', or 0. Got: %s." % arg.to_s) if
|
257
|
-
print_error
|
258
|
-
raise TypeError
|
259
|
-
end
|
260
164
|
|
261
|
-
|
165
|
+
def position_to_line_and_offset(iseq, filename, position, offset_type)
|
166
|
+
case offset_type
|
167
|
+
when :line
|
168
|
+
if ary = iseq.lineoffsets[position]
|
169
|
+
# Also, there may be multiple offsets for a given line.
|
170
|
+
# we pick the *first* one for the line.
|
171
|
+
vm_offset = ary[0]
|
172
|
+
line_no = position
|
173
|
+
elsif found_iseq = find_iseqs_with_lineno(filename, position)
|
174
|
+
return position_to_line_and_offset(found_iseq, filename, position,
|
175
|
+
offset_type)
|
176
|
+
elsif found_iseq = find_iseq_with_line_from_iseq(iseq, position)
|
177
|
+
return position_to_line_and_offset(found_iseq, filename, position,
|
178
|
+
offset_type)
|
179
|
+
else
|
180
|
+
errmsg("Unable to find offset for line #{position}\n\t" +
|
181
|
+
"in #{iseq.label} of file #{filename}")
|
182
|
+
return [nil, nil]
|
183
|
+
end
|
184
|
+
when :offset
|
185
|
+
position = position.position unless position.kind_of?(Fixnum)
|
186
|
+
start_insn = iseq.start_insn(position)
|
187
|
+
if ary=iseq.offset2lines(start_insn)
|
188
|
+
line_no = ary.first
|
189
|
+
vm_offset = start_insn
|
190
|
+
else
|
191
|
+
errmsg "Unable to find line for offset #{position} in #{iseq}"
|
192
|
+
return [nil, nil]
|
193
|
+
end
|
194
|
+
when nil
|
195
|
+
vm_offset = 0
|
196
|
+
line_no = iseq.offset2lines(vm_offset).first
|
197
|
+
else
|
198
|
+
errmsg "Bad parse offset_type: #{offset_type.inspect}"
|
199
|
+
return [nil, nil]
|
200
|
+
end
|
201
|
+
return [iseq, line_no, vm_offset]
|
202
|
+
end
|
262
203
|
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
204
|
+
# Parse a breakpoint position. On success return:
|
205
|
+
# - the instruction sequence to use
|
206
|
+
# - the line number - a Fixnum
|
207
|
+
# - vm_offset - a Fixnum
|
208
|
+
# - the condition (by default 'true') to use for this breakpoint
|
209
|
+
# - true condition should be negated. Used in *condition* if/unless
|
210
|
+
def breakpoint_position(position_str, allow_condition)
|
211
|
+
break_cmd_parse = if allow_condition
|
212
|
+
parse_breakpoint(position_str)
|
213
|
+
else
|
214
|
+
parse_breakpoint_no_condition(position_str)
|
215
|
+
end
|
216
|
+
return [nil] * 5 unless break_cmd_parse
|
217
|
+
tail = [break_cmd_parse.condition, break_cmd_parse.negate]
|
218
|
+
meth_or_frame, file, position, offset_type =
|
219
|
+
parse_position(break_cmd_parse.position)
|
220
|
+
if meth_or_frame
|
221
|
+
if iseq = meth_or_frame.iseq
|
222
|
+
iseq, line_no, vm_offset =
|
223
|
+
position_to_line_and_offset(iseq, file, position,
|
224
|
+
offset_type)
|
225
|
+
if vm_offset && line_no
|
226
|
+
return [iseq, line_no, vm_offset] + tail
|
227
|
+
end
|
228
|
+
else
|
229
|
+
errmsg("Unable to set breakpoint in #{meth_or_frame}")
|
230
|
+
end
|
231
|
+
elsif file && position
|
232
|
+
if :line == offset_type
|
233
|
+
iseq = find_iseqs_with_lineno(file, position)
|
234
|
+
if iseq
|
235
|
+
junk, line_no, vm_offset =
|
236
|
+
position_to_line_and_offset(iseq, file, position,
|
237
|
+
offset_type)
|
238
|
+
return [@frame.iseq, line_no, vm_offset] + tail
|
239
|
+
else
|
240
|
+
errmsg("Unable to find instruction sequence for" +
|
241
|
+
" position #{position} in #{file}")
|
242
|
+
end
|
243
|
+
else
|
244
|
+
errmsg "Come back later..."
|
245
|
+
end
|
246
|
+
elsif @frame.respond_to?(:file) and @frame.file == file
|
247
|
+
puts "parsing line and offset #{position}, #{offset_type}"
|
248
|
+
line_no, vm_offset = position_to_line_and_offset(@frame.iseq, position,
|
249
|
+
offset_type)
|
250
|
+
return [@frame.iseq, line_no, vm_offset] + tail
|
251
|
+
else
|
252
|
+
errmsg("Unable to parse breakpoint position #{position_str}")
|
253
|
+
end
|
254
|
+
return [nil] * 5
|
269
255
|
end
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
256
|
+
|
257
|
+
# Return true if arg is 'on' or 1 and false arg is 'off' or 0.
|
258
|
+
# Any other value is raises TypeError.
|
259
|
+
def get_onoff(arg, default=nil, print_error=true)
|
260
|
+
unless arg
|
261
|
+
if !default
|
262
|
+
if print_error
|
263
|
+
errmsg("Expecting 'on', or 'off'. Got nothing.")
|
264
|
+
end
|
265
|
+
raise TypeError
|
266
|
+
end
|
267
|
+
return default
|
268
|
+
end
|
269
|
+
darg = arg.downcase
|
270
|
+
return true if arg == '1' || darg == 'on'
|
271
|
+
return false if arg == '0' || darg =='off'
|
272
|
+
|
273
|
+
errmsg("Expecting 'on', or 'off'. Got: %s." % arg.to_s) if
|
274
|
+
print_error
|
275
|
+
raise TypeError
|
278
276
|
end
|
279
|
-
end
|
280
|
-
end
|
281
277
|
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
278
|
+
include CmdParser
|
279
|
+
|
280
|
+
def get_method(meth)
|
281
|
+
start_binding =
|
282
|
+
begin
|
283
|
+
@frame.binding
|
284
|
+
rescue
|
285
|
+
binding
|
286
|
+
end
|
287
|
+
if meth.kind_of?(String)
|
288
|
+
meth_for_string(meth, start_binding)
|
289
|
+
else
|
290
|
+
begin
|
291
|
+
meth_for_parse_struct(meth, start_binding)
|
292
|
+
rescue NameError
|
293
|
+
errmsg("Can't evaluate #{meth.name} to get a method")
|
294
|
+
return nil
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|
287
298
|
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
# Make sure it works for C:\foo\bar.py:12
|
293
|
-
def parse_position(info)
|
294
|
-
## FIXME: push into parse
|
295
|
-
if RbConfig::CONFIG['target_os'].start_with?('mingw') and
|
296
|
-
info =~ /^[A-Za-z]:/
|
297
|
-
drive_letter = info[0..1]
|
298
|
-
info = info[2..-1]
|
299
|
-
else
|
300
|
-
drive_leter = nil
|
301
|
-
end
|
302
|
-
info = parse_location(info) if info.kind_of?(String)
|
303
|
-
case info.container_type
|
304
|
-
when :fn
|
305
|
-
if (meth = method?(info.container)) && meth.iseq
|
306
|
-
return [meth, meth.iseq.source_container[1], info.position,
|
307
|
-
info.position_type]
|
308
|
-
else
|
309
|
-
return [nil] * 4
|
299
|
+
# FIXME: this is a ? method but we return
|
300
|
+
# the method value.
|
301
|
+
def method?(meth)
|
302
|
+
get_method(meth)
|
310
303
|
end
|
311
|
-
|
312
|
-
filename
|
313
|
-
#
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
304
|
+
|
305
|
+
# parse_position(self)->(meth, filename, offset, offset_type)
|
306
|
+
# See app/cmd_parser.kpeg for the syntax of a position which
|
307
|
+
# should include things like:
|
308
|
+
# Parse arg as [filename:]lineno | function | module
|
309
|
+
# Make sure it works for C:\foo\bar.py:12
|
310
|
+
def parse_position(info)
|
311
|
+
## FIXME: push into parse
|
312
|
+
if RbConfig::CONFIG['target_os'].start_with?('mingw') and
|
313
|
+
info =~ /^[A-Za-z]:/
|
314
|
+
drive_letter = info[0..1]
|
315
|
+
info = info[2..-1]
|
316
|
+
else
|
317
|
+
drive_leter = nil
|
318
|
+
end
|
319
|
+
info = parse_location(info) if info.kind_of?(String)
|
320
|
+
case info.container_type
|
321
|
+
when :fn
|
322
|
+
if (meth = method?(info.container)) && meth.iseq
|
323
|
+
return [meth, meth.iseq.source_container[1], info.position,
|
324
|
+
info.position_type]
|
325
|
+
else
|
326
|
+
return [nil] * 4
|
327
|
+
end
|
328
|
+
when :file
|
329
|
+
filename = canonic_file(info.container)
|
330
|
+
# ?? Try to look up method here?
|
331
|
+
frame =
|
332
|
+
if @frame
|
333
|
+
container = frame_container(@frame, false)
|
334
|
+
try_filename = container[1]
|
335
|
+
frame = (canonic_file(try_filename) == filename) ? @frame : nil
|
336
|
+
else
|
337
|
+
nil
|
338
|
+
end
|
339
|
+
# else
|
340
|
+
# LineCache.compiled_method(filename)
|
341
|
+
# end
|
342
|
+
return frame, filename, info.position, info.position_type
|
343
|
+
when nil
|
344
|
+
if [:line, :offset].member?(info.position_type)
|
345
|
+
if @frame
|
346
|
+
container = frame_container(@frame, false)
|
347
|
+
filename = container[1]
|
348
|
+
else
|
349
|
+
errmsg "No stack"
|
350
|
+
return [nil] * 4
|
351
|
+
end
|
352
|
+
|
353
|
+
return @frame, canonic_file(filename), info.position, info.position_type
|
354
|
+
elsif !info.position_type
|
355
|
+
errmsg "Can't parse #{arg} as a position"
|
356
|
+
return [nil] * 4
|
357
|
+
else
|
358
|
+
errmsg "Unknown position type #{info.position_type} for location #{arg}"
|
359
|
+
return [nil] * 4
|
360
|
+
end
|
361
|
+
else
|
362
|
+
errmsg "Unknown container type #{info.container_type} for location #{arg}"
|
363
|
+
return [nil] * 4
|
364
|
+
end
|
332
365
|
end
|
333
|
-
else
|
334
|
-
errmsg "Unknown container type #{info.container_type} for location #{arg}"
|
335
|
-
return [nil] * 4
|
336
|
-
end
|
337
|
-
end
|
338
366
|
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
367
|
+
def validate_initialize
|
368
|
+
## top_srcdir = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
369
|
+
## @dbgr_script_iseqs, @dbgr_iseqs = filter_scripts(top_srcdir)
|
370
|
+
@file_exists_proc = Proc.new {|filename|
|
371
|
+
if LineCache.cached?(filename) || LineCache.cached_script?(filename) ||
|
372
|
+
(File.readable?(filename) && !File.directory?(filename))
|
373
|
+
true
|
374
|
+
else
|
375
|
+
matches = find_scripts(filename)
|
376
|
+
if matches.size == 1
|
377
|
+
LineCache.remap_file(filename, matches[0])
|
378
|
+
true
|
379
|
+
else
|
380
|
+
false
|
381
|
+
end
|
382
|
+
end
|
383
|
+
}
|
354
384
|
end
|
355
|
-
}
|
356
385
|
end
|
357
|
-
end
|
358
386
|
end
|
359
387
|
|
360
388
|
if __FILE__ == $0
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
389
|
+
# Demo it.
|
390
|
+
if !(ARGV.size == 1 && ARGV[0] == 'noload')
|
391
|
+
ARGV[0..-1] = ['noload']
|
392
|
+
load(__FILE__)
|
393
|
+
else
|
394
|
+
require 'thread_frame'
|
395
|
+
require_relative '../app/mock'
|
396
|
+
require_relative './default'
|
397
|
+
require_relative 'frame'
|
398
|
+
|
399
|
+
# FIXME: Have to include before defining CmdProcessor!
|
400
|
+
require_relative '../processor'
|
401
|
+
|
402
|
+
cmdproc = Trepan::CmdProcessor.new(Trepan::MockCore.new())
|
403
|
+
cmdproc.frame_initialize
|
404
|
+
cmdproc.instance_variable_set('@settings',
|
405
|
+
Trepan::CmdProcessor::DEFAULT_SETTINGS)
|
406
|
+
cmdproc.frame_setup(RubyVM::Frame.get)
|
407
|
+
onoff = %w(1 0 on off)
|
408
|
+
onoff.each { |val| puts "onoff(#{val}) = #{cmdproc.get_onoff(val)}" }
|
409
|
+
%w(1 1E bad 1+1 -5).each do |val|
|
410
|
+
puts "get_int_noerr(#{val}) = #{cmdproc.get_int_noerr(val).inspect}"
|
411
|
+
end
|
412
|
+
def foo; 5 end
|
413
|
+
def cmdproc.errmsg(msg)
|
414
|
+
puts msg
|
415
|
+
end
|
416
|
+
# puts cmdproc.object_iseq('food').inspect
|
417
|
+
# puts cmdproc.object_iseq('foo').inspect
|
390
418
|
|
391
|
-
|
392
|
-
|
419
|
+
# puts cmdproc.object_iseq('foo@validate.rb').inspect
|
420
|
+
# puts cmdproc.object_iseq('cmdproc.object_iseq').inspect
|
393
421
|
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
422
|
+
puts cmdproc.parse_position(__FILE__).inspect
|
423
|
+
puts cmdproc.parse_position('@8').inspect
|
424
|
+
puts cmdproc.parse_position('8').inspect
|
425
|
+
puts cmdproc.parse_position("#{__FILE__} #{__LINE__}").inspect
|
398
426
|
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
427
|
+
puts '=' * 40
|
428
|
+
['Array.map', 'Trepan::CmdProcessor.new',
|
429
|
+
'foo', 'cmdproc.errmsg'].each do |str|
|
430
|
+
puts "#{str} should be method: #{!!cmdproc.method?(str)}"
|
431
|
+
end
|
432
|
+
puts '=' * 40
|
405
433
|
|
406
|
-
|
407
|
-
|
434
|
+
# FIXME:
|
435
|
+
puts "Trepan::CmdProcessor.allocate is: #{cmdproc.get_method('Trepan::CmdProcessor.allocate')}"
|
408
436
|
|
409
|
-
|
410
|
-
|
437
|
+
['food', '.errmsg'].each do |str|
|
438
|
+
puts "#{str} should be false: #{cmdproc.method?(str).to_s}"
|
439
|
+
end
|
440
|
+
puts '-' * 20
|
441
|
+
p cmdproc.breakpoint_position('foo', true)
|
442
|
+
p cmdproc.breakpoint_position('@0', true)
|
443
|
+
p cmdproc.breakpoint_position("#{__LINE__}", true)
|
444
|
+
p cmdproc.breakpoint_position("#{__FILE__} @0", false)
|
445
|
+
p cmdproc.breakpoint_position("#{__FILE__}:#{__LINE__}", true)
|
446
|
+
p cmdproc.breakpoint_position("#{__FILE__} #{__LINE__} if 1 == a", true)
|
447
|
+
p cmdproc.breakpoint_position("cmdproc.errmsg", false)
|
448
|
+
p cmdproc.breakpoint_position("cmdproc.errmsg:@0", false)
|
449
|
+
### p cmdproc.breakpoint_position(%w(2 if a > b))
|
450
|
+
p cmdproc.get_int_list(%w(1+0 3-1 3))
|
451
|
+
p cmdproc.get_int_list(%w(a 2 3))
|
411
452
|
end
|
412
|
-
puts '-' * 20
|
413
|
-
p cmdproc.breakpoint_position('foo', true)
|
414
|
-
p cmdproc.breakpoint_position('@0', true)
|
415
|
-
p cmdproc.breakpoint_position("#{__LINE__}", true)
|
416
|
-
p cmdproc.breakpoint_position("#{__FILE__} @0", false)
|
417
|
-
p cmdproc.breakpoint_position("#{__FILE__}:#{__LINE__}", true)
|
418
|
-
p cmdproc.breakpoint_position("#{__FILE__} #{__LINE__} if 1 == a", true)
|
419
|
-
p cmdproc.breakpoint_position("cmdproc.errmsg", false)
|
420
|
-
p cmdproc.breakpoint_position("cmdproc.errmsg:@0", false)
|
421
|
-
### p cmdproc.breakpoint_position(%w(2 if a > b))
|
422
|
-
p cmdproc.get_int_list(%w(1+0 3-1 3))
|
423
|
-
p cmdproc.get_int_list(%w(a 2 3))
|
424
|
-
end
|
425
453
|
end
|