rbx-trepanning 0.0.4-universal-rubinius-1.2 → 0.0.6-universal-rubinius-1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +682 -0
- data/NEWS +19 -0
- data/README.textile +8 -9
- data/Rakefile +8 -8
- data/app/complete.rb +52 -0
- data/app/complete.rbc +1288 -0
- data/app/irb.rb +1 -2
- data/app/irb.rbc +55 -72
- data/app/llvm.rbc +780 -878
- data/app/method.rb +1 -1
- data/app/method.rbc +31 -35
- data/app/method_name.rbc +2467 -0
- data/app/options.rb +7 -24
- data/app/options.rbc +238 -132
- data/app/rbx-llvm.rbc +2478 -0
- data/app/util.rb +3 -3
- data/app/util.rbc +23 -27
- data/bin/trepanx +4 -3
- data/bin/trepanx.compiled.rbc +42 -32
- data/data/irbrc +41 -0
- data/data/irbrc.compiled.rbc +640 -0
- data/interface/base_intf.rb +9 -5
- data/interface/base_intf.rbc +200 -146
- data/interface/comcodes.rb +10 -8
- data/interface/comcodes.rbc +68 -26
- data/interface/script.rbc +21 -9
- data/interface/user.rb +74 -8
- data/interface/user.rbc +1702 -156
- data/io/input.rb +37 -14
- data/io/input.rbc +869 -320
- data/io/tcpclient.rb +7 -1
- data/io/tcpclient.rbc +205 -113
- data/io/tcpfns.rb +5 -3
- data/io/tcpfns.rbc +82 -40
- data/io/tcpserver.rb +13 -10
- data/io/tcpserver.rbc +236 -183
- data/lib/trepanning.rb +62 -21
- data/lib/trepanning.rbc +1304 -874
- data/lib/{trepanning.rb.orig → trepanning2.rb} +12 -4
- data/processor/breakpoint.rb +4 -1
- data/processor/command/base/cmd.rb +48 -3
- data/processor/command/base/subcmd.rb +2 -1
- data/processor/command/base/submgr.rb +23 -20
- data/processor/command/base/subsubmgr.rb +13 -2
- data/processor/command/complete.rb +7 -17
- data/processor/command/continue.rb +19 -11
- data/processor/command/disassemble.rb +39 -12
- data/processor/command/eval.rb +23 -5
- data/processor/command/help.rb +60 -6
- data/processor/command/info_subcmd/{file.rb → files.rb} +76 -18
- data/processor/command/info_subcmd/line.rb +86 -0
- data/processor/command/info_subcmd/program.rb +2 -11
- data/processor/command/info_subcmd/ruby.rb +62 -0
- data/processor/command/info_subcmd/variables.rb +7 -0
- data/processor/command/irb.rb +39 -7
- data/processor/command/macro.rb +76 -0
- data/processor/command/set_subcmd/confirm.rb +24 -0
- data/processor/command/set_subcmd/max.rb +4 -5
- data/processor/command/show.rb +11 -0
- data/processor/command/show_subcmd/auto.rb +1 -0
- data/processor/command/show_subcmd/basename.rb +1 -2
- data/processor/command/show_subcmd/confirm.rb +18 -0
- data/processor/command/show_subcmd/max.rb +0 -2
- data/processor/command/source.rb +0 -1
- data/processor/default.rb +2 -0
- data/processor/disassemble.rb +1 -0
- data/processor/load_cmds.rb +104 -20
- data/processor/location.rb +11 -12
- data/processor/main.rb +10 -6
- data/processor/mock.rb +6 -2
- data/processor/stepping.rb +1 -4
- data/processor/subcmd.rb +3 -2
- data/processor/validate.rb +3 -3
- data/sample/list-terminal-colors.rbc +158 -4
- data/sample/rocky-trepanx-colors.rb +15 -7
- data/sample/rocky-trepanx-colors.rbc +530 -0
- data/test/data/quit2.cmd +6 -0
- data/test/data/quit2.right +3 -0
- data/test/data/step-bug.cmd +11 -0
- data/test/data/step-bug.right +3 -0
- data/test/example/step-bug.rb +14 -0
- data/test/integration/helper.rb +1 -1
- data/test/integration/skip-test-step-bug.rb +17 -0
- data/test/integration/test-quit.rb +11 -0
- data/test/unit/test-app-util.rb +0 -1
- data/test/unit/test-base-cmd.rb +47 -0
- data/test/unit/test-base-subcmd.rb +2 -2
- data/test/unit/test-base-submgr.rb +24 -0
- data/test/unit/test-cmd-help.rb +4 -0
- data/test/unit/test-completion.rb +38 -0
- data/test/unit/test-intf-user.rb +2 -2
- data/test/unit/test-io-tcpclient.rb +3 -2
- data/test/unit/test-proc-eval.rb +1 -1
- data/test/unit/test-proc-load_cmds.rb +9 -0
- data/test/unit/test-subcmd-help.rb +1 -5
- metadata +182 -167
- data/app/options.rb.orig +0 -154
- data/bin/trepan.orig +0 -0
- data/bin/trepan.rej +0 -11
- data/lib/trepanning.rb.rej +0 -11
- data/sample/rocky-dot-trepanrc.orig +0 -0
- data/sample/rocky-dot-trepanrc.rej +0 -11
@@ -48,10 +48,15 @@ class Trepan
|
|
48
48
|
@input = @settings[:input] || STDIN
|
49
49
|
@output = @settings[:output] || STDOUT
|
50
50
|
|
51
|
-
cmdproc_settings = {:
|
51
|
+
cmdproc_settings = {:highlight => @settings[:highlight]}
|
52
52
|
|
53
53
|
@processor = CmdProcessor.new(self, cmdproc_settings)
|
54
|
-
|
54
|
+
completion_proc = Proc.new do |str|
|
55
|
+
completed_ary = @processor.complete(Readline.line_buffer, true)
|
56
|
+
Readline.line_buffer = '' unless completed_ary.empty?
|
57
|
+
completed_ary
|
58
|
+
end
|
59
|
+
|
55
60
|
@intf =
|
56
61
|
if @settings[:server]
|
57
62
|
opts = Trepan::ServerInterface::DEFAULT_INIT_CONNECTION_OPTS.dup
|
@@ -64,9 +69,11 @@ class Trepan
|
|
64
69
|
opts = Trepan::ClientInterface::DEFAULT_INIT_CONNECTION_OPTS.dup
|
65
70
|
opts[:port] = @settings[:port] if @settings[:port]
|
66
71
|
opts[:host] = @settings[:host] if @settings[:host]
|
72
|
+
opts[:complete] = completion_proc
|
67
73
|
[Trepan::ClientInterface.new(nil, nil, nil, nil, opts)]
|
68
74
|
else
|
69
|
-
|
75
|
+
opts = {:complete => completion_proc}
|
76
|
+
[Trepan::UserInterface.new(@input, @output, opts)]
|
70
77
|
end
|
71
78
|
|
72
79
|
process_cmdfile_setting(@settings)
|
@@ -86,7 +93,8 @@ class Trepan
|
|
86
93
|
@history_path = File.expand_path("~/.trepanx")
|
87
94
|
|
88
95
|
if File.exists?(@history_path)
|
89
|
-
File.readlines(@history_path).
|
96
|
+
File.readlines(@history_path).each_with_index do |line, i|
|
97
|
+
break if i > 50 # FIXME: remove constant 50
|
90
98
|
Readline::HISTORY << line.strip
|
91
99
|
end
|
92
100
|
@history_io = File.new(@history_path, "a")
|
data/processor/breakpoint.rb
CHANGED
@@ -58,7 +58,7 @@ class Trepan
|
|
58
58
|
if line
|
59
59
|
ip = cm.first_ip_on_line(line)
|
60
60
|
|
61
|
-
|
61
|
+
unless ip
|
62
62
|
errmsg "Unknown line '#{line}' in method '#{cm.name}'"
|
63
63
|
return nil
|
64
64
|
end
|
@@ -67,6 +67,9 @@ class Trepan
|
|
67
67
|
ip = 0
|
68
68
|
end
|
69
69
|
|
70
|
+
# def lines without code will have value -1.
|
71
|
+
ip = 0 if -1 == ip
|
72
|
+
|
70
73
|
bp = @brkpts.add(descriptor, cm, ip, line, @brkpts.max+1, opts)
|
71
74
|
bp.activate
|
72
75
|
msg("Set %sbreakpoint #{bp.id}: #{meth.name}() at #{bp.location}" %
|
@@ -3,8 +3,9 @@
|
|
3
3
|
# Base class of all commands. Code common to all commands is here.
|
4
4
|
# Note: don't end classname with Command (capital C) since main
|
5
5
|
# will think this a command name like QuitCommand
|
6
|
-
require 'rubygems'
|
6
|
+
require 'rubygems'; require 'require_relative'
|
7
7
|
require 'columnize'
|
8
|
+
require_relative '../../../app/complete'
|
8
9
|
|
9
10
|
class Trepan
|
10
11
|
class Command
|
@@ -60,8 +61,8 @@ class Trepan
|
|
60
61
|
end
|
61
62
|
|
62
63
|
# Convenience short-hand for @dbgr.intf[-1].msg_nocr
|
63
|
-
def msg_nocr(msg)
|
64
|
-
@proc.msg_nocr(msg, opts
|
64
|
+
def msg_nocr(msg, opts={})
|
65
|
+
@proc.msg_nocr(msg, opts)
|
65
66
|
end
|
66
67
|
|
67
68
|
def my_const(name)
|
@@ -103,6 +104,14 @@ class Trepan
|
|
103
104
|
my_const(help_constant_sym)
|
104
105
|
end
|
105
106
|
|
107
|
+
# Define a method called 'complete' on the singleton class.
|
108
|
+
def self.completion(ary)
|
109
|
+
self.send(:define_method,
|
110
|
+
:complete,
|
111
|
+
Proc.new {|prefix|
|
112
|
+
Trepan::Complete.complete_token(ary, prefix) })
|
113
|
+
end
|
114
|
+
|
106
115
|
# From reference debugger
|
107
116
|
def run_code(str)
|
108
117
|
@proc.dbgr.current_frame.run(str)
|
@@ -126,3 +135,39 @@ class Trepan
|
|
126
135
|
|
127
136
|
end
|
128
137
|
end
|
138
|
+
if __FILE__ == $0
|
139
|
+
class Trepan
|
140
|
+
class CmdProcessor
|
141
|
+
def initialize(dbgr)
|
142
|
+
end
|
143
|
+
def confirm(message, default)
|
144
|
+
p ['confirm: ', message, default]
|
145
|
+
end
|
146
|
+
def errmsg(message, opts)
|
147
|
+
p ['err:', message, opts]
|
148
|
+
end
|
149
|
+
def msg(message, opts)
|
150
|
+
p [message, opts]
|
151
|
+
end
|
152
|
+
def msg_nocr(message, opts)
|
153
|
+
p ['nocr: ', message, opts]
|
154
|
+
end
|
155
|
+
def section(message, opts)
|
156
|
+
p ['section: ', message, opts]
|
157
|
+
end
|
158
|
+
end
|
159
|
+
class Command::Test < Trepan::Command
|
160
|
+
NAME = 'test'
|
161
|
+
CATEGORY = 'testcategory'
|
162
|
+
completion %w(a aa ab ba aac)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
proc = Trepan::CmdProcessor.new(nil)
|
166
|
+
cmd = Trepan::Command::Test.new(proc)
|
167
|
+
%w(confirm errmsg msg msg_nocr section).each do |meth|
|
168
|
+
cmd.send(meth, 'test', nil)
|
169
|
+
end
|
170
|
+
p cmd.complete('aa')
|
171
|
+
cmd.instance_variable_set('@completions', %w(aardvark apple))
|
172
|
+
p cmd.complete('aa')
|
173
|
+
end
|
@@ -160,10 +160,11 @@ class Trepan
|
|
160
160
|
def summary_help(subcmd_name)
|
161
161
|
msg_nocr("%-12s: %s" % [subcmd_name, my_const(:SHORT_HELP)])
|
162
162
|
end
|
163
|
-
|
164
163
|
end
|
165
164
|
|
166
165
|
class SetBoolSubcommand < Subcommand
|
166
|
+
completion %w(on off)
|
167
|
+
|
167
168
|
def run(args)
|
168
169
|
run_set_bool(args)
|
169
170
|
end
|
@@ -1,9 +1,10 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
|
-
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
2
|
+
# Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
|
3
3
|
require 'rubygems'; require 'require_relative'
|
4
4
|
require_relative 'cmd'
|
5
5
|
require_relative '../../subcmd'
|
6
6
|
require_relative '../../help'
|
7
|
+
require_relative '../../../app/complete'
|
7
8
|
|
8
9
|
class Trepan::SubcommandMgr < Trepan::Command
|
9
10
|
|
@@ -18,7 +19,7 @@ class Trepan::SubcommandMgr < Trepan::Command
|
|
18
19
|
NEED_STACK = false
|
19
20
|
end
|
20
21
|
|
21
|
-
attr_accessor :subcmds #
|
22
|
+
attr_accessor :subcmds # Trepan::Subcmd
|
22
23
|
attr_reader :name # Name of command
|
23
24
|
attr_reader :last_args # Last arguments seen
|
24
25
|
|
@@ -60,20 +61,18 @@ class Trepan::SubcommandMgr < Trepan::Command
|
|
60
61
|
subcommands = {}
|
61
62
|
cmd_names.each do |name|
|
62
63
|
next unless Trepan::Subcommand.constants.member?(name)
|
63
|
-
|
64
|
-
cmd =
|
65
|
-
cmd_name = cmd.name
|
64
|
+
klass = Trepan::Subcommand.const_get(name)
|
65
|
+
cmd = klass.send(:new, self)
|
66
66
|
@subcmds.add(cmd)
|
67
67
|
end
|
68
68
|
subcmd_names.each do |name|
|
69
69
|
next unless Trepan::SubSubcommand.constants.member?(name)
|
70
|
-
subcmd_class =
|
70
|
+
subcmd_class = Trepan::SubSubcommand.const_get(name)
|
71
71
|
begin
|
72
|
-
cmd =
|
72
|
+
cmd = subcmd_class.send(:new, self, parent)
|
73
73
|
rescue
|
74
74
|
puts "Subcmd #{name} is bad"
|
75
75
|
end
|
76
|
-
cmd_name = cmd.name
|
77
76
|
@subcmds.add(cmd)
|
78
77
|
end
|
79
78
|
end
|
@@ -143,7 +142,18 @@ class Trepan::SubcommandMgr < Trepan::Command
|
|
143
142
|
end
|
144
143
|
end
|
145
144
|
|
146
|
-
|
145
|
+
# Return an Array of subcommands that can start with +arg+. If none
|
146
|
+
# found we just return +arg+.
|
147
|
+
# FIXME: Not used any more?
|
148
|
+
def complete(prefix)
|
149
|
+
Trepan::Complete.complete_token(@subcmds.subcmds.keys, prefix)
|
150
|
+
end
|
151
|
+
|
152
|
+
def complete_token_with_next(prefix)
|
153
|
+
Trepan::Complete.complete_token_with_next(@subcmds.subcmds, prefix)
|
154
|
+
end
|
155
|
+
|
156
|
+
def run(args) # nodoc
|
147
157
|
@last_args = args
|
148
158
|
if args.size < 2 || args.size == 2 && args[-1] == '*'
|
149
159
|
summary_list(obj_const(self, :NAME), @subcmds)
|
@@ -165,15 +175,8 @@ end
|
|
165
175
|
if __FILE__ == $0
|
166
176
|
# Demo it.
|
167
177
|
require_relative '../../mock'
|
168
|
-
dbgr = MockDebugger::
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
# puts cmd.help(%w(help set))
|
173
|
-
# puts '=' * 40
|
174
|
-
# # require_relative '../../../lib/trepanning)
|
175
|
-
# # Trepan.debug(:set_restart => true)
|
176
|
-
# puts cmd.help(%w(help set *))
|
177
|
-
# puts '=' * 40
|
178
|
-
# puts cmd.help(%w(help set d.*))
|
178
|
+
dbgr, cmd = MockDebugger::setup('show')
|
179
|
+
p cmd.complete('d')
|
180
|
+
p cmd.subcmds.lookup('ar').prefix
|
181
|
+
p cmd.subcmds.lookup('a')
|
179
182
|
end
|
@@ -5,7 +5,6 @@ require_relative 'subcmd'
|
|
5
5
|
require_relative '../../subcmd'
|
6
6
|
require_relative '../../help'
|
7
7
|
|
8
|
-
require 'rubygems'; require 'require_relative'
|
9
8
|
class Trepan::SubSubcommandMgr < Trepan::Subcommand
|
10
9
|
|
11
10
|
include Trepan::Help
|
@@ -146,6 +145,18 @@ class Trepan::SubSubcommandMgr < Trepan::Subcommand
|
|
146
145
|
end
|
147
146
|
end
|
148
147
|
|
148
|
+
# Return an Array of subcommands that can start with +arg+. If none
|
149
|
+
# found we just return +arg+.
|
150
|
+
def complete(prefix)
|
151
|
+
prior = self.prefix.join('').size
|
152
|
+
last_args = @subcmds.list.map{|str| str[prior..-1]}
|
153
|
+
Trepan::Complete.complete_token(last_args, prefix)
|
154
|
+
end
|
155
|
+
|
156
|
+
def complete_token_with_next(prefix)
|
157
|
+
Trepan::Complete.complete_token_with_next(@subcmds.subcmds, prefix)
|
158
|
+
end
|
159
|
+
|
149
160
|
def run(args)
|
150
161
|
args = @parent.last_args if args.size == 0
|
151
162
|
if args.size < 3 || args.size == 3 && args[-1] == '*'
|
@@ -179,6 +190,6 @@ if __FILE__ == $0
|
|
179
190
|
# puts '=' * 40
|
180
191
|
# FIXME
|
181
192
|
# require_relative '../../lib/trepanning'
|
182
|
-
# Trepan.
|
193
|
+
# Trepan.debugger
|
183
194
|
# puts cmd.help(%w(help info registers p.*))
|
184
195
|
end
|
@@ -1,35 +1,25 @@
|
|
1
1
|
# Copyright (C) 2011 Rocky Bernstein <rockyb@rubyforge.net>
|
2
2
|
require 'rubygems'; require 'require_relative'
|
3
3
|
require_relative 'base/cmd'
|
4
|
+
require_relative '../load_cmds'
|
4
5
|
class Trepan::Command::CompleteCommand < Trepan::Command
|
5
6
|
|
6
7
|
unless defined?(HELP)
|
7
|
-
|
8
|
-
|
8
|
+
NAME = File.basename(__FILE__, '.rb')
|
9
|
+
HELP = <<-HELP
|
10
|
+
#{NAME} COMMAND-PREFIX
|
9
11
|
|
10
12
|
List the completions for the rest of the line as a command.
|
11
|
-
|
12
|
-
NOTE: For now we just handle completion of the first token.
|
13
|
-
"
|
13
|
+
HELP
|
14
14
|
CATEGORY = 'support'
|
15
|
-
NAME = File.basename(__FILE__, '.rb')
|
16
15
|
NEED_STACK = false
|
17
16
|
SHORT_HELP = 'List the completions for the rest of the line as a command'
|
18
17
|
end
|
19
18
|
|
20
19
|
# This method runs the command
|
21
20
|
def run(args) # :nodoc
|
22
|
-
|
23
|
-
|
24
|
-
cmd.start_with?(args[1])
|
25
|
-
end
|
26
|
-
alias_matches = @proc.aliases.keys.select do |cmd|
|
27
|
-
cmd.start_with?(args[1]) && !cmd_matches.member?(@proc.aliases[cmd])
|
28
|
-
end
|
29
|
-
(cmd_matches+alias_matches).sort.each do |match|
|
30
|
-
msg match
|
31
|
-
end
|
32
|
-
else # FIXME: handle more complex completions
|
21
|
+
@proc.complete(args[1..-1]).each do |match|
|
22
|
+
msg match
|
33
23
|
end
|
34
24
|
end
|
35
25
|
end
|
@@ -1,31 +1,38 @@
|
|
1
|
+
# Copyright (C) 2011 Rocky Bernstein <rockyb@rubyforge.net>
|
1
2
|
require 'rubygems'; require 'require_relative'
|
2
3
|
require_relative 'base/cmd'
|
3
4
|
require_relative '../stepping'
|
4
5
|
|
5
6
|
class Trepan::Command::ContinueCommand < Trepan::Command
|
6
|
-
|
7
|
-
|
7
|
+
unless defined?(HELP)
|
8
|
+
NAME = File.basename(__FILE__, '.rb')
|
9
|
+
HELP = <<-HELP
|
8
10
|
#{NAME} [breakpoint-position]
|
9
11
|
|
10
12
|
Leave the debugger loop and continue execution. Subsequent entry to
|
11
13
|
the debugger however may occur via breakpoints or explicit calls, or
|
12
14
|
exceptions.
|
13
15
|
|
14
|
-
If a parameter is given, a
|
15
|
-
before continuing.
|
16
|
+
If a parameter is given, a temporary breakpoint is set at that position
|
17
|
+
before continuing. Offset are numbers prefixed with an "O" otherwise
|
18
|
+
the parameter is taken as a line number.
|
16
19
|
|
17
20
|
Examples:
|
18
21
|
#{NAME}
|
19
22
|
#{NAME} 10 # continue to line 10
|
20
|
-
#{NAME}
|
23
|
+
#{NAME} o20 # continue to VM Instruction Sequence offset 20
|
24
|
+
#{NAME} gcd # continue to first instruction of method gcd
|
25
|
+
#{NAME} IRB.start o7 # continue to IRB.start offset 7
|
21
26
|
|
22
27
|
See also 'step', 'next', 'finish', and 'nexti' commands.
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
28
|
+
HELP
|
29
|
+
|
30
|
+
ALIASES = %w(c cont)
|
31
|
+
CATEGORY = 'running'
|
32
|
+
MAX_ARGS = 2 # Need at most this many
|
33
|
+
NEED_RUNNING = true
|
34
|
+
SHORT_HELP = 'Continue execution of the debugged program'
|
35
|
+
end
|
29
36
|
|
30
37
|
# This is the method that runs the command
|
31
38
|
def run(args)
|
@@ -80,4 +87,5 @@ end
|
|
80
87
|
if __FILE__ == $0
|
81
88
|
require_relative '../mock'
|
82
89
|
dbgr, cmd = MockDebugger::setup
|
90
|
+
p cmd.run([cmd.name])
|
83
91
|
end
|
@@ -2,20 +2,31 @@
|
|
2
2
|
# Copyright (C) 2011 Rocky Bernstein <rockyb@rubyforge.net>
|
3
3
|
require 'rubygems'; require 'require_relative'
|
4
4
|
require_relative './base/cmd'
|
5
|
+
require_relative '../../app/method'
|
5
6
|
require_relative '../../app/iseq'
|
6
7
|
|
7
8
|
class Trepan::Command::DisassembleCommand < Trepan::Command
|
9
|
+
|
10
|
+
include Trepanning::Method
|
11
|
+
|
8
12
|
NAME = File.basename(__FILE__, '.rb')
|
9
|
-
ALIASES
|
13
|
+
ALIASES = %w(disas disassem) # Note we (will) have disable
|
10
14
|
CATEGORY = 'data'
|
11
15
|
HELP = <<-HELP
|
12
|
-
#{NAME} [all
|
16
|
+
#{NAME} [all]
|
17
|
+
#{NAME} [method|LINE-NUM]...
|
13
18
|
|
14
19
|
Disassembles Rubinius VM instructions. By default, the bytecode for the
|
15
20
|
current line is disassembled only.
|
16
21
|
|
17
|
-
If a method name is given, disassemble just that method.
|
18
|
-
|
22
|
+
If a method name is given, disassemble just that method.
|
23
|
+
|
24
|
+
If a line number given, then disassemble just that line number if it
|
25
|
+
has bytecode assocated with that line. Note that if a line has
|
26
|
+
discontinuous regions we will show just the first region associated
|
27
|
+
with that line.
|
28
|
+
|
29
|
+
If the argument is 'all', the entire method is shown as bytecode.
|
19
30
|
|
20
31
|
Examples:
|
21
32
|
#{NAME} # dissasemble VM for current line
|
@@ -23,7 +34,8 @@ Examples:
|
|
23
34
|
#{NAME} [1,2].max # disassemble max method of Array
|
24
35
|
#{NAME} Object.is_a? # disassemble Object.is_a?
|
25
36
|
#{NAME} is_a? # same as above (probably)
|
26
|
-
|
37
|
+
#{NAME} 6 # Disassemble line 6 if there is bytecode for it
|
38
|
+
#{NAME} 6 is_a? # The above two commands combined into one
|
27
39
|
HELP
|
28
40
|
|
29
41
|
NEED_STACK = true
|
@@ -66,7 +78,7 @@ Examples:
|
|
66
78
|
# FIXME DRY with ../disassemble.rb
|
67
79
|
if settings[:highlight]
|
68
80
|
require_relative '../../app/rbx-llvm'
|
69
|
-
@llvm_highlighter
|
81
|
+
@llvm_highlighter ||= CodeRay::Duo[:llvm, :term]
|
70
82
|
# llvm_scanner = CodeRay.scanner :llvm
|
71
83
|
# p llvm_scanner.tokenize(disasm)
|
72
84
|
disasm = @llvm_highlighter.encode(disasm)
|
@@ -85,12 +97,25 @@ Examples:
|
|
85
97
|
section "Bytecode for #{@proc.frame.vm_location.describe}"
|
86
98
|
disassemble_method(current_method)
|
87
99
|
else
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
100
|
+
args[1..-1].each do |arg|
|
101
|
+
cm = @proc.parse_method(arg)
|
102
|
+
if cm
|
103
|
+
section "Bytecode for method #{arg}"
|
104
|
+
disassemble_method(cm.executable)
|
105
|
+
else
|
106
|
+
opts = {:msg_on_error => false }
|
107
|
+
line_num = @proc.get_an_int(arg, opts)
|
108
|
+
if line_num
|
109
|
+
cm = find_method_with_line(current_method, line_num)
|
110
|
+
if cm
|
111
|
+
@proc.show_bytecode(line_num)
|
112
|
+
else
|
113
|
+
errmsg "Can't find that bytecode for line #{line_num}"
|
114
|
+
end
|
115
|
+
else
|
116
|
+
errmsg "Method #{arg} not found"
|
117
|
+
end
|
118
|
+
end
|
94
119
|
end
|
95
120
|
end
|
96
121
|
end
|
@@ -113,6 +138,8 @@ if __FILE__ == $0
|
|
113
138
|
# require_relative '../../lib/trepanning'
|
114
139
|
# debugger
|
115
140
|
cmd.run([cmd.name, 'self.setup'])
|
141
|
+
puts '=' * 40
|
142
|
+
cmd.run([cmd.name, __LINE__.to_s])
|
116
143
|
end
|
117
144
|
foo(cmd)
|
118
145
|
end
|
data/processor/command/eval.rb
CHANGED
@@ -5,20 +5,40 @@ require_relative './base/cmd'
|
|
5
5
|
|
6
6
|
class Trepan::Command::EvalCommand < Trepan::Command
|
7
7
|
|
8
|
+
NAME = File.basename(__FILE__, '.rb')
|
8
9
|
CATEGORY = 'data'
|
9
10
|
HELP = <<-HELP
|
11
|
+
#{NAME} [STRING]
|
12
|
+
|
10
13
|
Run code in the context of the current frame.
|
11
14
|
|
12
15
|
The value of the expression is stored into a global variable so it
|
13
16
|
may be used again easily. The name of the global variable is printed
|
14
17
|
next to the inspect output of the value.
|
18
|
+
|
19
|
+
If no string is given we run the string from the current source code
|
20
|
+
about to be run
|
21
|
+
|
22
|
+
#{NAME} 1+2 # 3
|
23
|
+
#{NAME} @v
|
24
|
+
#{NAME} # Run current source-code line
|
25
|
+
|
26
|
+
See also 'set autoeval'
|
15
27
|
HELP
|
16
28
|
|
17
29
|
NAME = File.basename(__FILE__, '.rb')
|
18
30
|
NEED_STACK = true
|
19
31
|
SHORT_HELP = 'Run code in the current context'
|
20
32
|
def run(args)
|
21
|
-
|
33
|
+
if args.size == 1
|
34
|
+
loc = @proc.source_location_info
|
35
|
+
opts = {:reload_on_change => @proc.reload_on_change}
|
36
|
+
loc, junk, text = @proc.loc_and_text(loc, opts)
|
37
|
+
msg "eval: #{text}"
|
38
|
+
else
|
39
|
+
text = @proc.cmd_argstr
|
40
|
+
end
|
41
|
+
@proc.eval_code(text, settings[:maxstring])
|
22
42
|
end
|
23
43
|
end
|
24
44
|
|
@@ -26,8 +46,6 @@ if __FILE__ == $0
|
|
26
46
|
require_relative '../mock'
|
27
47
|
dbgr, cmd = MockDebugger::setup
|
28
48
|
arg_str = '1 + 2'
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
## cmd.run([cmd.name, arg_str])
|
49
|
+
cmd.proc.instance_variable_set('@cmd_argstr', arg_str)
|
50
|
+
puts "eval #{arg_str} is: #{cmd.run([cmd.name, arg_str])}"
|
33
51
|
end
|
data/processor/command/help.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
|
2
2
|
require 'rubygems'; require 'require_relative'
|
3
3
|
require_relative 'base/cmd'
|
4
|
+
require_relative '../../app/complete'
|
4
5
|
class Trepan::Command::HelpCommand < Trepan::Command
|
5
6
|
|
6
7
|
unless defined?(HELP)
|
@@ -40,6 +41,30 @@ See also 'examine' and 'whatis'.
|
|
40
41
|
SHORT_HELP = 'Print commands or give help for command(s)'
|
41
42
|
end
|
42
43
|
|
44
|
+
def complete(prefix)
|
45
|
+
matches = Trepan::Complete.complete_token(CATEGORIES.keys +
|
46
|
+
%w(* syntax all) +
|
47
|
+
@proc.commands.keys, prefix)
|
48
|
+
aliases = Trepan::Complete.complete_token_filtered(@proc.aliases, prefix,
|
49
|
+
matches)
|
50
|
+
(matches + aliases).sort
|
51
|
+
end
|
52
|
+
|
53
|
+
def complete(prefix)
|
54
|
+
matches = Trepan::Complete.complete_token(CATEGORIES.keys +
|
55
|
+
%w(* syntax all) +
|
56
|
+
@proc.commands.keys, prefix)
|
57
|
+
aliases = Trepan::Complete.complete_token_filtered(@proc.aliases, prefix,
|
58
|
+
matches)
|
59
|
+
(matches + aliases).sort
|
60
|
+
end
|
61
|
+
|
62
|
+
def complete_token_with_next(prefix)
|
63
|
+
complete(prefix).map do |cmd|
|
64
|
+
[cmd, @proc.commands.member?(cmd) ? @proc.commands[cmd] : nil]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
43
68
|
# List the command categories and a short description of each.
|
44
69
|
def list_categories
|
45
70
|
section 'Classes of commands:'
|
@@ -49,7 +74,9 @@ See also 'examine' and 'whatis'.
|
|
49
74
|
final_msg = '
|
50
75
|
Type "help" followed by a class name for a list of commands in that class.
|
51
76
|
Type "help syntax" for information on debugger command syntax.
|
52
|
-
Type "help
|
77
|
+
Type "help aliases" for a list of current aliases
|
78
|
+
Type "help macros" for a list of current macros
|
79
|
+
Type "help *" for the list of all commands, macros and aliases.
|
53
80
|
Type "help all" for the list of all commands.
|
54
81
|
Type "help REGEXP" for the list of commands matching /^#{REGEXP}/
|
55
82
|
Type "help CLASS *" for the list of all commands in class CLASS.
|
@@ -65,6 +92,12 @@ Type "help" followed by command name for full documentation.
|
|
65
92
|
if cmd_name == '*'
|
66
93
|
section 'All command names:'
|
67
94
|
msg columnize_commands(@proc.commands.keys.sort)
|
95
|
+
show_aliases unless @proc.aliases.empty?
|
96
|
+
show_macros unless @proc.macros.empty?
|
97
|
+
elsif cmd_name =~ /^aliases$/i
|
98
|
+
show_aliases
|
99
|
+
elsif cmd_name =~ /^macros$/i
|
100
|
+
show_macros
|
68
101
|
elsif cmd_name =~ /^syntax$/i
|
69
102
|
show_command_syntax
|
70
103
|
elsif cmd_name =~ /^all$/i
|
@@ -91,6 +124,9 @@ Type "help" followed by command name for full documentation.
|
|
91
124
|
msg "Aliases: #{cmd_obj.class.const_get(:ALIASES).join(', ')}"
|
92
125
|
end
|
93
126
|
end
|
127
|
+
elsif @proc.macros.member?(cmd_name)
|
128
|
+
msg "#{cmd_name} is a macro which expands to:"
|
129
|
+
msg " #{@proc.macros[cmd_name]}", {:unlimited => true}
|
94
130
|
else
|
95
131
|
matches = @proc.commands.keys.grep(/^#{cmd_name}/).sort rescue []
|
96
132
|
if matches.empty?
|
@@ -105,6 +141,11 @@ Type "help" followed by command name for full documentation.
|
|
105
141
|
end
|
106
142
|
end
|
107
143
|
|
144
|
+
def show_aliases
|
145
|
+
section 'All alias names:'
|
146
|
+
msg columnize_commands(@proc.aliases.keys.sort)
|
147
|
+
end
|
148
|
+
|
108
149
|
# Show short help for all commands in `category'.
|
109
150
|
def show_category(category, args)
|
110
151
|
|
@@ -130,7 +171,7 @@ Type "help" followed by command name for full documentation.
|
|
130
171
|
def show_command_syntax
|
131
172
|
section "Debugger command syntax"
|
132
173
|
msg <<-EOS
|
133
|
-
Command
|
174
|
+
Command tokenization syntax is very simple-minded.
|
134
175
|
|
135
176
|
If a line starts with #, the command is ignored.
|
136
177
|
If a line starts with !, the line is eval'd.
|
@@ -144,11 +185,16 @@ after the leading command string are put back on a command queue.
|
|
144
185
|
|
145
186
|
Within a single command, tokens are then white-space split. Again,
|
146
187
|
this process disregards quotes or symbols that have meaning in Ruby.
|
188
|
+
Some commands like 'eval' and 'macro' have access to the untokenized
|
189
|
+
string entered and make use of that rather than the tokenized list.
|
147
190
|
|
148
|
-
The
|
149
|
-
|
150
|
-
|
151
|
-
|
191
|
+
The leading token is first looked up in the macro table. If it
|
192
|
+
found there, the expansion is replaces the current command and possibly
|
193
|
+
other commands pushed onto a command queue. Next the leading token is
|
194
|
+
looked up in the debugger alias table and the name may be substituted
|
195
|
+
there. Finally, the leading token is looked up in the debugger alias
|
196
|
+
table. If a match is found, the command name and arguments are
|
197
|
+
dispatched to the command object that process the command.
|
152
198
|
|
153
199
|
If the command is not found and "auto eval" is set on, then the
|
154
200
|
command is eval'd in the context that the program is currently stopped
|
@@ -172,6 +218,12 @@ pr "hi ;;-)" # Syntax error since ;; splits the line and " is not closed.
|
|
172
218
|
See also "alias", "irb", "set auto eval", and "set auto irb".
|
173
219
|
EOS
|
174
220
|
end
|
221
|
+
|
222
|
+
def show_macros
|
223
|
+
section 'All macro names:'
|
224
|
+
msg columnize_commands(@proc.macros.keys.sort)
|
225
|
+
end
|
226
|
+
|
175
227
|
end
|
176
228
|
|
177
229
|
if __FILE__ == $0
|
@@ -194,4 +246,6 @@ if __FILE__ == $0
|
|
194
246
|
cmd.run %W(#{cmd.name} s.*)
|
195
247
|
puts '=' * 40
|
196
248
|
cmd.run %W(#{cmd.name} s<>)
|
249
|
+
puts '=' * 40
|
250
|
+
p cmd.complete('br')
|
197
251
|
end
|