trepanning 0.1.3 → 0.1.4
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/ChangeLog +465 -0
- data/NEWS +26 -1
- data/README.textile +1 -1
- data/app/cmd_parse.kpeg +2 -1
- data/app/cmd_parser.rb +30 -3
- data/app/core.rb +1 -1
- data/app/display.rb +39 -1
- data/app/frame.rb +1 -1
- data/app/irb.rb +42 -40
- data/app/options.rb +3 -2
- data/app/run.rb +21 -7
- data/app/util.rb +12 -2
- data/app/yarv.rb +0 -2
- data/bin/trepan +2 -3
- data/data/perldb.bindings +17 -0
- data/interface/script.rb +1 -1
- data/interface/server.rb +1 -1
- data/interface/user.rb +3 -1
- data/{interface/base_intf.rb → interface.rb} +1 -1
- data/io/input.rb +1 -3
- data/io/null_output.rb +1 -1
- data/io/string_array.rb +1 -2
- data/io/tcpclient.rb +1 -1
- data/io/tcpserver.rb +1 -1
- data/{io/base_io.rb → io.rb} +0 -0
- data/lib/trepanning.rb +2 -1
- data/processor/command/alias.rb +15 -4
- data/processor/command/backtrace.rb +2 -2
- data/processor/command/base/subcmd.rb +1 -5
- data/processor/command/base/submgr.rb +1 -1
- data/processor/command/base/subsubcmd.rb +1 -1
- data/processor/command/base/subsubmgr.rb +4 -4
- data/processor/command/break.rb +1 -1
- data/processor/command/complete.rb +1 -1
- data/processor/command/condition.rb +2 -2
- data/processor/command/continue.rb +1 -1
- data/processor/command/debug.rb +1 -1
- data/processor/command/delete.rb +10 -7
- data/processor/command/directory.rb +1 -1
- data/processor/command/disable.rb +25 -19
- data/processor/command/disassemble.rb +1 -1
- data/processor/command/display.rb +35 -28
- data/processor/command/down.rb +8 -8
- data/processor/command/edit.rb +1 -1
- data/processor/command/enable.rb +10 -12
- data/processor/command/eval.rb +1 -1
- data/processor/command/exit.rb +1 -1
- data/processor/command/finish.rb +1 -1
- data/processor/command/frame.rb +2 -2
- data/processor/command/help.rb +6 -8
- data/processor/command/info.rb +2 -0
- data/processor/command/info_subcmd/files.rb +17 -11
- data/processor/command/info_subcmd/frame.rb +0 -1
- data/processor/command/info_subcmd/locals.rb +6 -73
- data/processor/command/info_subcmd/source.rb +10 -4
- data/processor/command/info_subcmd/variables.rb +34 -0
- data/processor/command/info_subcmd/variables_subcmd/.gitignore +1 -0
- data/processor/command/info_subcmd/variables_subcmd/class.rb +40 -0
- data/processor/command/info_subcmd/variables_subcmd/constant.rb +41 -0
- data/processor/command/info_subcmd/{globals.rb → variables_subcmd/globals.rb} +21 -16
- data/processor/command/info_subcmd/variables_subcmd/instance.rb +41 -0
- data/processor/command/info_subcmd/variables_subcmd/locals.rb +99 -0
- data/processor/command/kill.rb +9 -8
- data/processor/command/list.rb +9 -107
- data/processor/command/macro.rb +27 -9
- data/processor/command/next.rb +1 -1
- data/processor/command/nocache.rb +2 -2
- data/processor/command/parsetree.rb +1 -1
- data/processor/command/pp.rb +1 -1
- data/processor/command/pr.rb +1 -1
- data/processor/command/ps.rb +1 -1
- data/processor/command/quit.rb +18 -7
- data/processor/command/raise.rb +1 -1
- data/processor/command/reload.rb +10 -10
- data/processor/command/restart.rb +1 -1
- data/processor/command/save.rb +1 -1
- data/processor/command/server.rb +1 -1
- data/processor/command/set_subcmd/auto.rb +7 -1
- data/processor/command/set_subcmd/different.rb +5 -4
- data/processor/command/set_subcmd/substitute_subcmd/eval.rb +2 -2
- data/processor/command/set_subcmd/trace.rb +5 -4
- data/processor/command/set_subcmd/trace_subcmd/print.rb +4 -3
- data/processor/command/shell.rb +5 -3
- data/processor/command/show_subcmd/{alias.rb → aliases.rb} +2 -2
- data/processor/command/show_subcmd/auto_subcmd/eval.rb +2 -7
- data/processor/command/show_subcmd/trace_subcmd/print.rb +3 -3
- data/processor/command/show_subcmd/version.rb +24 -0
- data/processor/command/source.rb +1 -1
- data/processor/command/step.rb +1 -1
- data/processor/command/tbreak.rb +1 -1
- data/processor/command/unalias.rb +11 -6
- data/processor/command/undisplay.rb +14 -10
- data/processor/command/up.rb +12 -13
- data/processor/command/watchg.rb +1 -1
- data/processor/{command/base/cmd.rb → command.rb} +3 -2
- data/processor/display.rb +34 -0
- data/processor/frame.rb +2 -2
- data/processor/help.rb +6 -4
- data/processor/hook.rb +95 -96
- data/processor/list.rb +146 -0
- data/processor/location.rb +26 -0
- data/processor/mock.rb +4 -7
- data/processor/msg.rb +54 -42
- data/processor/running.rb +6 -3
- data/processor/subcmd.rb +16 -41
- data/processor/validate.rb +6 -9
- data/{processor/main.rb → processor.rb} +11 -40
- data/sample/rocky-trepan-colors.rb +0 -1
- data/test/data/enable.cmd +1 -1
- data/test/data/trace.cmd +6 -0
- data/test/data/trace.right +39 -0
- data/test/example/gcd.rb +0 -1
- data/test/functional/test-next.rb +1 -1
- data/test/integration/helper.rb +4 -0
- data/test/integration/test-trace.rb +18 -0
- data/test/unit/cmd-helper.rb +4 -4
- data/test/unit/test-app-cmd_parse.rb +1 -1
- data/test/unit/test-app-display.rb +22 -0
- data/test/unit/test-app-options.rb +14 -10
- data/test/unit/test-app-run.rb +7 -1
- data/test/unit/test-base-subcmd.rb +1 -1
- data/test/unit/test-cmd-kill.rb +11 -4
- data/test/unit/test-cmd-parse_list_cmd.rb +1 -1
- data/test/unit/{test-base-cmd.rb → test-command.rb} +1 -1
- data/test/unit/test-proc-eval.rb +1 -2
- data/test/unit/test-proc-frame.rb +1 -2
- data/test/unit/test-proc-list.rb +52 -0
- data/test/unit/test-proc-load_cmds.rb +1 -1
- data/test/unit/test-proc-location.rb +11 -4
- data/test/unit/test-proc-main.rb +1 -1
- data/test/unit/test-proc-validate.rb +1 -2
- data/test/unit/test-subcmd-help.rb +1 -1
- data/trepanning.gemspec +1 -1
- metadata +26 -12
data/processor/hook.rb
CHANGED
@@ -1,109 +1,108 @@
|
|
1
1
|
# Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
|
2
2
|
require_relative 'virtual'
|
3
|
-
class Trepan
|
4
|
-
class CmdProcessor < VirtualCmdProcessor
|
5
|
-
# Command processor hooks.
|
6
|
-
attr_reader :autoirb_hook
|
7
|
-
attr_reader :autolist_hook
|
8
|
-
attr_reader :debug_dbgr_hook
|
9
|
-
attr_reader :display_hook
|
10
|
-
attr_reader :timer_hook
|
11
|
-
attr_reader :trace_hook
|
12
|
-
attr_reader :tracebuf_hook
|
13
|
-
attr_reader :unconditional_prehooks
|
14
|
-
attr_reader :cmdloop_posthooks
|
15
|
-
attr_reader :cmdloop_prehooks
|
16
3
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
hook.call(name, *args)
|
4
|
+
class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
|
5
|
+
# Command processor hooks.
|
6
|
+
attr_reader :autoirb_hook
|
7
|
+
attr_reader :autolist_hook
|
8
|
+
attr_reader :debug_dbgr_hook
|
9
|
+
attr_reader :display_hook
|
10
|
+
attr_reader :timer_hook
|
11
|
+
attr_reader :trace_hook
|
12
|
+
attr_reader :tracebuf_hook
|
13
|
+
attr_reader :unconditional_prehooks
|
14
|
+
attr_reader :cmdloop_posthooks
|
15
|
+
attr_reader :cmdloop_prehooks
|
16
|
+
|
17
|
+
# Used to time how long a debugger action takes
|
18
|
+
attr_accessor :time_last
|
19
|
+
|
20
|
+
class Hook
|
21
|
+
attr_accessor :list
|
22
|
+
|
23
|
+
def initialize(list=[])
|
24
|
+
@list = list
|
25
|
+
end
|
26
|
+
|
27
|
+
def delete_by_name(delete_name)
|
28
|
+
@list.delete_if {|hook_name, priority, hook| hook_name == delete_name}
|
29
|
+
end
|
30
|
+
|
31
|
+
def empty?
|
32
|
+
@list.empty?
|
33
|
+
end
|
34
|
+
|
35
|
+
def insert(priority, name, hook)
|
36
|
+
insert_loc = @list.size # at end
|
37
|
+
@list.each_with_index do |entry, index|
|
38
|
+
n, p, h = entry
|
39
|
+
if priority > p
|
40
|
+
insert_loc = index
|
41
|
+
break
|
56
42
|
end
|
57
43
|
end
|
58
|
-
|
59
|
-
# Could add delete_at and delete if necessary.
|
44
|
+
@list.insert(insert_loc, [name, priority, hook])
|
60
45
|
end
|
61
46
|
|
62
|
-
def
|
63
|
-
|
64
|
-
|
65
|
-
@unconditional_prehooks = Hook.new
|
66
|
-
|
67
|
-
irb_cmd = commands['irb']
|
68
|
-
@autoirb_hook = ['autoirb',
|
69
|
-
Proc.new{|*args| irb_cmd.run(['irb']) if irb_cmd}]
|
70
|
-
|
71
|
-
@debug_dbgr_hook = ['dbgdbgr',
|
72
|
-
Proc.new{|*args|
|
73
|
-
if settings[:debugdbgr]
|
74
|
-
$trepan_cmdproc = self
|
75
|
-
$trepan_frame = frame
|
76
|
-
else
|
77
|
-
$trepan_cmdproc = nil
|
78
|
-
$trepan_frame = nil
|
79
|
-
end}]
|
80
|
-
|
81
|
-
display_cmd = commands['display']
|
82
|
-
@display_hook = ['display',
|
83
|
-
Proc.new{|*args| display_cmd.run(['display']) if
|
84
|
-
display_cmd}]
|
85
|
-
|
86
|
-
list_cmd = commands['list']
|
87
|
-
@autolist_hook = ['autolist',
|
88
|
-
Proc.new{|*args| list_cmd.run(['list']) if list_cmd}]
|
89
|
-
|
90
|
-
@timer_hook = ['timer',
|
91
|
-
Proc.new{|*args|
|
92
|
-
now = Time.now
|
93
|
-
msg("%g seconds" %
|
94
|
-
(now - @time_last)) if @time_last
|
95
|
-
@time_last = now
|
96
|
-
}]
|
97
|
-
@timer_posthook = ['timer', Proc.new{|*args| @time_last = Time.now}]
|
98
|
-
@trace_hook = ['trace',
|
99
|
-
Proc.new{|*args| print_location}]
|
100
|
-
@tracebuf_hook = ['tracebuffer',
|
101
|
-
Proc.new{|*args| @eventbuf.append(@event, @frame,
|
102
|
-
@core.hook_arg)}]
|
47
|
+
def insert_if_new(priority, name, hook)
|
48
|
+
insert(priority, name, hook) unless
|
49
|
+
@list.find {|try_name, try_priority, try_hook| try_name == name}
|
103
50
|
end
|
104
|
-
|
51
|
+
|
52
|
+
# Run each function in `hooks' with args
|
53
|
+
def run(*args)
|
54
|
+
@list.each do |name, priority, hook|
|
55
|
+
hook.call(name, *args)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Could add delete_at and delete if necessary.
|
60
|
+
end
|
61
|
+
|
62
|
+
def hook_initialize(commands)
|
63
|
+
@cmdloop_posthooks = Hook.new
|
64
|
+
@cmdloop_prehooks = Hook.new
|
65
|
+
@unconditional_prehooks = Hook.new
|
66
|
+
|
67
|
+
irb_cmd = commands['shell']
|
68
|
+
@autoirb_hook = ['autoirb',
|
69
|
+
Proc.new{|*args| irb_cmd.run(['shell']) if irb_cmd}]
|
70
|
+
|
71
|
+
@debug_dbgr_hook = ['dbgdbgr',
|
72
|
+
Proc.new{|*args|
|
73
|
+
if settings[:debugdbgr]
|
74
|
+
$trepan_cmdproc = self
|
75
|
+
$trepan_frame = @frame
|
76
|
+
else
|
77
|
+
$trepan_cmdproc = nil
|
78
|
+
$trepan_frame = nil
|
79
|
+
end}]
|
80
|
+
|
81
|
+
display_cmd = commands['display']
|
82
|
+
@display_hook = ['display',
|
83
|
+
Proc.new{|*args| display_cmd.run(['display']) if
|
84
|
+
display_cmd}]
|
85
|
+
|
86
|
+
list_cmd = commands['list']
|
87
|
+
@autolist_hook = ['autolist',
|
88
|
+
Proc.new{|*args| list_cmd.run(['list']) if list_cmd}]
|
89
|
+
|
90
|
+
@timer_hook = ['timer',
|
91
|
+
Proc.new{|*args|
|
92
|
+
now = Time.now
|
93
|
+
msg("%g seconds" %
|
94
|
+
(now - @time_last)) if @time_last
|
95
|
+
@time_last = now
|
96
|
+
}]
|
97
|
+
@timer_posthook = ['timer', Proc.new{|*args| @time_last = Time.now}]
|
98
|
+
@trace_hook = ['trace',
|
99
|
+
Proc.new{|*args| print_location}]
|
100
|
+
@tracebuf_hook = ['tracebuffer',
|
101
|
+
Proc.new{|*args| @eventbuf.append(@event, @frame,
|
102
|
+
@core.hook_arg)}]
|
105
103
|
end
|
106
104
|
end
|
105
|
+
|
107
106
|
if __FILE__ == $0
|
108
107
|
# Demo it.
|
109
108
|
hooks = Trepan::CmdProcessor::Hook.new
|
data/processor/list.rb
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
# Copyright (C) 2011 Rocky Bernstein <rockyb@rubyforge.net>
|
2
|
+
|
3
|
+
# Trepan command list validation routines. A String type is
|
4
|
+
# usually passed in as the argument to validation routines.
|
5
|
+
|
6
|
+
require 'rubygems'
|
7
|
+
|
8
|
+
require_relative './validate'
|
9
|
+
|
10
|
+
class Trepan
|
11
|
+
class CmdProcessor < VirtualCmdProcessor
|
12
|
+
|
13
|
+
# If last is less than first, assume last is a count rather than an
|
14
|
+
# end line number. If last is negative, range is [first+last..first].
|
15
|
+
def adjust_last(first, last)
|
16
|
+
last < first ? first + last - 1 : last
|
17
|
+
end
|
18
|
+
|
19
|
+
def frame_filename
|
20
|
+
|
21
|
+
container = frame_container(frame, false)
|
22
|
+
|
23
|
+
# FIXME: put into a helper routine
|
24
|
+
# See also duplicate code in print_location
|
25
|
+
if container[0] != 'file'
|
26
|
+
try_container = container
|
27
|
+
while try_container[0] != 'file' && frame.prev do
|
28
|
+
frame = frame.prev
|
29
|
+
try_container = frame_container(frame, false)
|
30
|
+
end
|
31
|
+
container = try_container if try_container[0] == 'file'
|
32
|
+
end
|
33
|
+
|
34
|
+
return container[1]
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
# Parse a list command. On success return:
|
39
|
+
# - the line number - a Fixnum
|
40
|
+
# - file name
|
41
|
+
def parse_list_cmd(position_str, listsize, center_correction=0)
|
42
|
+
iseq = nil
|
43
|
+
if position_str.empty?
|
44
|
+
filename = frame_filename
|
45
|
+
first = [1, frame_line - center_correction].max
|
46
|
+
else
|
47
|
+
list_cmd_parse = parse_list(position_str,
|
48
|
+
:file_exists_proc => file_exists_proc)
|
49
|
+
return [nil] * 4 unless list_cmd_parse
|
50
|
+
last = list_cmd_parse.num
|
51
|
+
position = list_cmd_parse.position
|
52
|
+
|
53
|
+
if position.is_a?(String)
|
54
|
+
if position == '-'
|
55
|
+
return no_frame_msg_for_list unless frame_line
|
56
|
+
first = [1, frame_line - 2*listsize - 1].max
|
57
|
+
elsif position == '.'
|
58
|
+
return no_frame_msg_for_list unless frame_line
|
59
|
+
if (second = list_cmd_parse.num)
|
60
|
+
first = frame_line
|
61
|
+
last = adjust_last(first, second)
|
62
|
+
else
|
63
|
+
first = [1, frame_line - center_correction].max
|
64
|
+
last = first + listsize - 1
|
65
|
+
end
|
66
|
+
end
|
67
|
+
filename = frame_filename
|
68
|
+
else
|
69
|
+
meth_or_frame, filename, offset, offset_type =
|
70
|
+
parse_position(position)
|
71
|
+
return [nil] * 4 unless filename
|
72
|
+
if offset_type == :line
|
73
|
+
first = offset
|
74
|
+
elsif meth_or_frame
|
75
|
+
if iseq = meth_or_frame.iseq
|
76
|
+
iseq, first, vm_offset =
|
77
|
+
position_to_line_and_offset(iseq, filename, position, offset_type)
|
78
|
+
unless first
|
79
|
+
errmsg("Unable to get location in #{meth_or_frame}")
|
80
|
+
return [nil] * 4
|
81
|
+
end
|
82
|
+
end
|
83
|
+
elsif !offset
|
84
|
+
first = 1
|
85
|
+
else
|
86
|
+
errmsg("Unable to parse list position #{position_str}")
|
87
|
+
return [nil] * 4
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
if last
|
92
|
+
first, last = [first + last, first] if last < 0
|
93
|
+
last = adjust_last(first, last)
|
94
|
+
else
|
95
|
+
first = [1, first - center_correction].max
|
96
|
+
last = first + listsize - 1 unless last
|
97
|
+
end
|
98
|
+
LineCache::cache(filename) unless LineCache::cached?(filename)
|
99
|
+
return [iseq, filename, first, last]
|
100
|
+
end
|
101
|
+
|
102
|
+
def no_frame_msg_for_list
|
103
|
+
errmsg("No Ruby program loaded.")
|
104
|
+
return nil, nil, nil, nil
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
if __FILE__ == $0
|
111
|
+
# Demo it.
|
112
|
+
if !(ARGV.size == 1 && ARGV[0] == 'noload')
|
113
|
+
ARGV[0..-1] = ['noload']
|
114
|
+
load(__FILE__)
|
115
|
+
else
|
116
|
+
require 'thread_frame'
|
117
|
+
require_relative '../app/mock'
|
118
|
+
require_relative './default'
|
119
|
+
require_relative 'frame'
|
120
|
+
|
121
|
+
# FIXME: Have to include before defining CmdProcessor!
|
122
|
+
require_relative '../processor'
|
123
|
+
|
124
|
+
cmdproc = Trepan::CmdProcessor.new(Trepan::MockCore.new())
|
125
|
+
cmdproc.frame_initialize
|
126
|
+
cmdproc.instance_variable_set('@settings',
|
127
|
+
Trepan::CmdProcessor::DEFAULT_SETTINGS)
|
128
|
+
cmdproc.frame_setup(RubyVM::ThreadFrame.current)
|
129
|
+
def foo; 5 end
|
130
|
+
def cmdproc.errmsg(msg)
|
131
|
+
puts msg
|
132
|
+
end
|
133
|
+
puts '-' * 20
|
134
|
+
p cmdproc.parse_list_cmd('.', 10)
|
135
|
+
p cmdproc.parse_list_cmd('-', 10)
|
136
|
+
p cmdproc.parse_list_cmd('foo', 10)
|
137
|
+
p cmdproc.parse_list_cmd('@0', 10)
|
138
|
+
p cmdproc.parse_list_cmd("#{__LINE__}", 10)
|
139
|
+
p cmdproc.parse_list_cmd("#{__FILE__} @0", 10)
|
140
|
+
p cmdproc.parse_list_cmd("#{__FILE__}:#{__LINE__}", 10)
|
141
|
+
p cmdproc.parse_list_cmd("#{__FILE__} #{__LINE__}", 10)
|
142
|
+
p cmdproc.parse_list_cmd("cmdproc.errmsg", 10)
|
143
|
+
p cmdproc.parse_list_cmd("cmdproc.errmsg:@0", 10)
|
144
|
+
p cmdproc.parse_list_cmd("cmdproc.errmsg:@0", -10)
|
145
|
+
end
|
146
|
+
end
|
data/processor/location.rb
CHANGED
@@ -8,6 +8,32 @@ require_relative 'virtual'
|
|
8
8
|
class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
|
9
9
|
include Trepan::Frame
|
10
10
|
|
11
|
+
unless defined?(EVENT2ICON)
|
12
|
+
# Event icons used in printing locations.
|
13
|
+
EVENT2ICON = {
|
14
|
+
'brkpt' => 'xx',
|
15
|
+
'tbrkpt' => 'x1',
|
16
|
+
'c-call' => 'C>',
|
17
|
+
'c-return' => '<C',
|
18
|
+
'call' => '->',
|
19
|
+
'send' => '=>',
|
20
|
+
'leave' => '<=',
|
21
|
+
'class' => '::',
|
22
|
+
'coverage' => '[]',
|
23
|
+
'debugger-call' => ':o',
|
24
|
+
'end' => '-|',
|
25
|
+
'line' => '--',
|
26
|
+
'raise' => '!!',
|
27
|
+
'return' => '<-',
|
28
|
+
'switch' => 'sw',
|
29
|
+
'trace-var' => '$V',
|
30
|
+
'unknown' => '?!',
|
31
|
+
'vm' => 'VM',
|
32
|
+
'vm-insn' => '..',
|
33
|
+
'yield' => '<>',
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
11
37
|
def canonic_container(container)
|
12
38
|
[container[0], canonic_file(container[1])]
|
13
39
|
end
|
data/processor/mock.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
|
2
2
|
# Mock setup for commands.
|
3
|
-
require_relative '
|
3
|
+
require_relative '../processor'
|
4
4
|
|
5
5
|
require_relative '../app/core'
|
6
6
|
require_relative '../app/default'
|
@@ -93,7 +93,7 @@ module MockDebugger
|
|
93
93
|
cmd.proc.frame_setup(RubyVM::ThreadFrame::current.prev)
|
94
94
|
cmd.proc.event = 'debugger-call'
|
95
95
|
sub_cmd = sub_class.new(cmd)
|
96
|
-
sub_cmd.summary_help(sub_cmd
|
96
|
+
sub_cmd.summary_help(sub_cmd)
|
97
97
|
puts
|
98
98
|
sub_cmd.run([cmd.name]) if run
|
99
99
|
return sub_cmd
|
@@ -101,12 +101,9 @@ module MockDebugger
|
|
101
101
|
module_function :sub_setup
|
102
102
|
|
103
103
|
def subsub_setup(sub_class, subsub_class, run=true)
|
104
|
+
sub_cmd = sub_setup(sub_class)
|
104
105
|
subsub_name = subsub_class.const_get('PREFIX')
|
105
|
-
|
106
|
-
cmd.proc.frame_setup(RubyVM::ThreadFrame::current.prev)
|
107
|
-
cmd.proc.event = 'debugger-call'
|
108
|
-
sub_cmd = sub_class.new(dbgr.core.processor, cmd)
|
109
|
-
subsub_cmd = subsub_class.new(cmd.proc, sub_cmd, subsub_name.join(''))
|
106
|
+
subsub_cmd = subsub_class.new(sub_cmd.proc, sub_cmd, subsub_name)
|
110
107
|
subsub_cmd.summary_help(subsub_cmd.name)
|
111
108
|
puts
|
112
109
|
subsub_cmd.run([]) if run
|
data/processor/msg.rb
CHANGED
@@ -2,60 +2,72 @@
|
|
2
2
|
# I/O related command processor methods
|
3
3
|
require_relative '../app/util'
|
4
4
|
require_relative 'virtual'
|
5
|
-
class Trepan
|
6
|
-
class CmdProcessor < VirtualCmdProcessor
|
7
5
|
|
8
|
-
|
6
|
+
begin require 'term/ansicolor'; rescue LoadError; end
|
9
7
|
|
10
|
-
|
11
|
-
|
12
|
-
if @settings[:highlight] && defined?(Term::ANSIColor)
|
13
|
-
message =
|
14
|
-
Term::ANSIColor.italic + message + Term::ANSIColor.reset
|
15
|
-
end
|
16
|
-
@dbgr.intf[-1].errmsg(message)
|
17
|
-
end
|
8
|
+
class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
|
9
|
+
attr_accessor :ruby_highlighter
|
18
10
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
end
|
11
|
+
def confirm(msg, default)
|
12
|
+
@settings[:confirm] ? @dbgr.intf[-1].confirm(msg, default) : true
|
13
|
+
end
|
23
14
|
|
24
|
-
|
15
|
+
def errmsg(message, opts={})
|
16
|
+
if message.kind_of?(Array)
|
17
|
+
message.each do |mess|
|
18
|
+
errmsg(mess, opts)
|
19
|
+
end
|
20
|
+
return
|
21
|
+
else
|
25
22
|
message = safe_rep(message) unless opts[:unlimited]
|
26
|
-
@dbgr.intf[-1].msg_nocr(message)
|
27
23
|
end
|
28
|
-
|
29
|
-
|
30
|
-
|
24
|
+
if @settings[:highlight] && defined?(Term::ANSIColor)
|
25
|
+
message =
|
26
|
+
Term::ANSIColor.italic + message + Term::ANSIColor.reset
|
31
27
|
end
|
28
|
+
@dbgr.intf[-1].errmsg(message)
|
29
|
+
end
|
32
30
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
require 'term/ansicolor'
|
39
|
-
@ruby_highlighter = CodeRay::Duo[:ruby, :term]
|
40
|
-
rescue LoadError
|
41
|
-
return text
|
42
|
-
end
|
43
|
-
end
|
44
|
-
return @ruby_highlighter.encode(text)
|
45
|
-
end
|
31
|
+
def msg(message, opts={})
|
32
|
+
message = safe_rep(message) unless opts[:unlimited]
|
33
|
+
message = ruby_format(message) if opts[:code]
|
34
|
+
@dbgr.intf[-1].msg(message)
|
35
|
+
end
|
46
36
|
|
47
|
-
|
48
|
-
|
49
|
-
|
37
|
+
def msg_nocr(message, opts={})
|
38
|
+
message = safe_rep(message) unless opts[:unlimited]
|
39
|
+
@dbgr.intf[-1].msg_nocr(message)
|
40
|
+
end
|
50
41
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
42
|
+
def read_command()
|
43
|
+
@dbgr.intf[-1].read_command(@prompt)
|
44
|
+
end
|
45
|
+
|
46
|
+
def ruby_format(text)
|
47
|
+
return text unless settings[:highlight]
|
48
|
+
unless @ruby_highlighter
|
49
|
+
begin
|
50
|
+
require 'coderay'
|
51
|
+
require 'term/ansicolor'
|
52
|
+
@ruby_highlighter = CodeRay::Duo[:ruby, :term]
|
53
|
+
rescue LoadError
|
54
|
+
return text
|
56
55
|
end
|
57
|
-
@dbgr.intf[-1].msg(message)
|
58
56
|
end
|
57
|
+
return @ruby_highlighter.encode(text)
|
58
|
+
end
|
59
59
|
|
60
|
+
def safe_rep(str)
|
61
|
+
Trepan::Util::safe_repr(str, @settings[:maxstring])
|
60
62
|
end
|
63
|
+
|
64
|
+
def section(message, opts={})
|
65
|
+
message = safe_rep(message) unless opts[:unlimited]
|
66
|
+
if @settings[:highlight] && defined?(Term::ANSIColor)
|
67
|
+
message =
|
68
|
+
Term::ANSIColor.bold + message + Term::ANSIColor.reset
|
69
|
+
end
|
70
|
+
@dbgr.intf[-1].msg(message)
|
71
|
+
end
|
72
|
+
|
61
73
|
end
|
data/processor/running.rb
CHANGED
@@ -24,7 +24,11 @@ class Trepan
|
|
24
24
|
@next_level = 32000 # I'm guessing the stack size can't
|
25
25
|
# ever reach this
|
26
26
|
@next_thread = nil
|
27
|
-
@
|
27
|
+
if @settings[:traceprint]
|
28
|
+
@core.step_count = 1 # traceprint will avoid stopping
|
29
|
+
else
|
30
|
+
@core.step_count = -1 # No more event stepping
|
31
|
+
end
|
28
32
|
@leave_cmd_loop = true # Break out of the processor command loop.
|
29
33
|
end
|
30
34
|
|
@@ -90,7 +94,6 @@ class Trepan
|
|
90
94
|
when '<'
|
91
95
|
opts[:stop_events] = Set.new(%w(c-return return))
|
92
96
|
when '>'
|
93
|
-
opts[:stop_events] = Set.new(%w(c-call call))
|
94
97
|
if step_cmd.size > 1 && step_cmd[-2..-2] == '<'
|
95
98
|
opts[:stop_events] = Set.new(%w(c-call c-return call return))
|
96
99
|
else
|
@@ -119,7 +122,7 @@ class Trepan
|
|
119
122
|
|
120
123
|
return true if
|
121
124
|
!frame || (@next_level < @frame.stack_size &&
|
122
|
-
Thread.current == @next_thread)
|
125
|
+
Thread.current == @next_thread && @event != 'raise')
|
123
126
|
|
124
127
|
new_pos = [@frame.source_container, frame_line,
|
125
128
|
@stack_size, @current_thread, @event, @frame.pc_offset]
|
data/processor/subcmd.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
|
2
2
|
# gdb-like subcommand processing.
|
3
3
|
|
4
|
+
### FIXME: move into command/base/submgr.rb
|
4
5
|
class Trepan
|
5
6
|
class Subcmd
|
6
7
|
|
@@ -14,17 +15,24 @@ class Trepan
|
|
14
15
|
|
15
16
|
# Find subcmd in self.subcmds
|
16
17
|
def lookup(subcmd_prefix, use_regexp=true)
|
17
|
-
compare =
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
compare =
|
19
|
+
if !@cmd.settings[:abbrev]
|
20
|
+
lambda{|name| name.to_s == subcmd_prefix}
|
21
|
+
elsif use_regexp
|
22
|
+
lambda{|name| name.to_s =~ /^#{subcmd_prefix}/}
|
23
|
+
else
|
24
|
+
lambda{|name| 0 == name.to_s.index(subcmd_prefix)}
|
25
|
+
end
|
26
|
+
candidates = []
|
22
27
|
@subcmds.each do |subcmd_name, subcmd|
|
23
28
|
if compare.call(subcmd_name) &&
|
24
29
|
subcmd_prefix.size >= subcmd.class.const_get(:MIN_ABBREV)
|
25
|
-
|
30
|
+
candidates << subcmd
|
26
31
|
end
|
27
32
|
end
|
33
|
+
if candidates.size == 1
|
34
|
+
return candidates.first
|
35
|
+
end
|
28
36
|
return nil
|
29
37
|
end
|
30
38
|
|
@@ -61,48 +69,15 @@ class Trepan
|
|
61
69
|
@cmdlist << subcmd_name
|
62
70
|
end
|
63
71
|
|
64
|
-
# Run subcmd_name with args using obj for the environent
|
65
|
-
def run( subcmd_name, arg)
|
66
|
-
entry=lookup(subcmd_name)
|
67
|
-
if entry
|
68
|
-
entry['callback'].send(arg)
|
69
|
-
else
|
70
|
-
@proc.undefined_cmd(entry.__class__.name, subcmd_name)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
72
|
# help for subcommands
|
75
73
|
# Note: format of help is compatible with ddd.
|
76
74
|
def help(*args)
|
77
|
-
|
78
|
-
msg args
|
79
|
-
subcmd_prefix = args[0]
|
80
|
-
if not subcmd_prefix or subcmd_prefix.size == 0
|
81
|
-
@proc.msg(self.doc)
|
82
|
-
@proc.msg("\nList of %s subcommands:\n" % [@name])
|
83
|
-
@list.each do |subcmd_name|
|
84
|
-
subcmd_helper(subcmd_name, obj, true, true)
|
85
|
-
end
|
86
|
-
|
87
|
-
entry = lookup(subcmd_prefix)
|
88
|
-
if entry and entry.respond_to? :help
|
89
|
-
entry.help(args)
|
90
|
-
else
|
91
|
-
@proc.errmsg("Unknown 'help %s' subcommand %s" %
|
92
|
-
[@name, subcmd_prefix])
|
93
|
-
end
|
94
|
-
end
|
75
|
+
# Not used but tested for.
|
95
76
|
end
|
96
77
|
|
97
78
|
def list
|
98
79
|
@subcmds.keys.sort
|
99
80
|
end
|
100
|
-
|
101
|
-
# Error message when a subcommand doesn't exist.
|
102
|
-
def undefined_subcmd(cmd, subcmd)
|
103
|
-
@proc.errmsg('Undefined "%s" command: "%s". Try "help".' %
|
104
|
-
[cmd, subcmd])
|
105
|
-
end
|
106
81
|
end
|
107
82
|
end
|
108
83
|
|
@@ -110,7 +85,7 @@ end
|
|
110
85
|
if __FILE__ == $0
|
111
86
|
|
112
87
|
require_relative 'mock'
|
113
|
-
require_relative 'command
|
88
|
+
require_relative 'command'
|
114
89
|
|
115
90
|
class Trepan::TestCommand < Trepan::Command
|
116
91
|
|