trepanning 0.1.0 → 0.1.1
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/.gitignore +4 -0
- data/ChangeLog +1279 -235
- data/Makefile +13 -0
- data/NEWS +30 -0
- data/Rakefile +50 -14
- data/app/.gitignore +1 -0
- data/app/breakpoint.rb +7 -2
- data/app/brkptmgr.rb +12 -0
- data/app/cmd_parse.citrus +167 -0
- data/app/cmd_parse.kpeg +221 -0
- data/app/cmd_parse.rb +201 -0
- data/app/cmd_parser.rb +1914 -0
- data/app/complete.rb +79 -0
- data/app/condition.rb +1 -1
- data/app/core.rb +7 -11
- data/app/default.rb +1 -1
- data/app/disassemble.rb +3 -2
- data/app/file.rb +12 -36
- data/app/frame.rb +3 -2
- data/app/irb.rb +9 -5
- data/app/iseq.rb +46 -0
- data/app/options.rb +6 -30
- data/app/run.rb +5 -2
- data/app/util.rb +1 -2
- data/app/yarv.rb +11 -1
- data/bin/.gitignore +1 -0
- data/bin/trepan +6 -6
- data/data/.gitignore +1 -0
- data/interface/.gitignore +1 -0
- data/interface/base_intf.rb +9 -5
- data/interface/comcodes.rb +10 -8
- data/interface/user.rb +76 -17
- data/io/.gitignore +1 -0
- data/io/input.rb +39 -15
- data/io/tcpclient.rb +7 -1
- data/io/tcpfns.rb +5 -3
- data/io/tcpserver.rb +13 -10
- data/lib/.gitignore +1 -0
- data/lib/trepanning.rb +50 -13
- data/processor/.gitignore +1 -0
- data/processor/Makefile +7 -0
- data/processor/breakpoint.rb +7 -2
- data/processor/command/.gitignore +1 -0
- data/processor/command/Makefile +7 -0
- data/processor/command/alias.rb +2 -2
- data/processor/command/backtrace.rb +4 -0
- data/processor/command/base/cmd.rb +45 -2
- data/processor/command/base/subcmd.rb +4 -2
- data/processor/command/base/submgr.rb +23 -19
- data/processor/command/base/subsubcmd.rb +23 -1
- data/processor/command/base/subsubmgr.rb +13 -0
- data/processor/command/break.rb +34 -29
- data/processor/command/complete.rb +37 -0
- data/processor/command/condition.rb +2 -0
- data/processor/command/continue.rb +15 -18
- data/processor/command/disassemble.rb +5 -0
- data/processor/command/down.rb +1 -1
- data/processor/command/eval.rb +70 -0
- data/processor/command/exit.rb +4 -1
- data/processor/command/finish.rb +6 -4
- data/processor/command/frame.rb +6 -3
- data/processor/command/help.rb +97 -54
- data/processor/command/help/.gitignore +1 -0
- data/processor/command/help/README +10 -0
- data/processor/command/help/command.txt +48 -0
- data/processor/command/help/filename.txt +40 -0
- data/processor/command/help/location.txt +37 -0
- data/processor/command/info_subcmd/.gitignore +1 -0
- data/processor/command/info_subcmd/breakpoints.rb +9 -9
- data/processor/command/info_subcmd/{file.rb → files.rb} +92 -27
- data/processor/command/info_subcmd/frame.rb +41 -15
- data/processor/command/info_subcmd/iseq.rb +39 -17
- data/processor/command/info_subcmd/program.rb +2 -8
- data/processor/command/info_subcmd/registers.rb +12 -10
- data/processor/command/info_subcmd/registers_subcmd/.gitignore +1 -0
- data/processor/command/info_subcmd/ruby.rb +60 -0
- data/processor/command/irb.rb +26 -3
- data/processor/command/kill.rb +21 -10
- data/processor/command/list.rb +1 -1
- data/processor/command/macro.rb +37 -23
- data/processor/command/pr.rb +1 -1
- data/processor/command/reload.rb +4 -0
- data/processor/command/reload_subcmd/.gitignore +1 -0
- data/processor/command/restart.rb +9 -9
- data/processor/command/save.rb +29 -36
- data/processor/command/set_subcmd/.gitignore +1 -0
- data/processor/command/set_subcmd/auto_subcmd/.gitignore +1 -0
- data/processor/command/set_subcmd/confirm.rb +23 -0
- data/processor/command/set_subcmd/debug_subcmd/.gitignore +1 -0
- data/processor/command/set_subcmd/different.rb +2 -0
- data/processor/command/set_subcmd/events.rb +2 -0
- data/processor/command/set_subcmd/max.rb +9 -12
- data/processor/command/set_subcmd/max_subcmd/.gitignore +1 -0
- data/processor/command/set_subcmd/substitute_subcmd/.gitignore +1 -0
- data/processor/command/set_subcmd/trace.rb +7 -13
- data/processor/command/set_subcmd/trace_subcmd/.gitignore +1 -0
- data/processor/command/set_subcmd/trace_subcmd/buffer.rb +12 -27
- data/processor/command/set_subcmd/trace_subcmd/print.rb +10 -8
- data/processor/command/set_subcmd/trace_subcmd/var.rb +6 -10
- data/processor/command/show.rb +12 -1
- data/processor/command/show_subcmd/.gitignore +1 -0
- data/processor/command/show_subcmd/alias.rb +11 -15
- data/processor/command/show_subcmd/auto_subcmd/.gitignore +1 -0
- data/processor/command/show_subcmd/basename.rb +1 -9
- data/processor/command/show_subcmd/confirm.rb +25 -0
- data/processor/command/show_subcmd/debug_subcmd/.gitignore +1 -0
- data/processor/command/show_subcmd/macro.rb +32 -14
- data/processor/command/show_subcmd/max_subcmd/.gitignore +1 -0
- data/processor/command/show_subcmd/trace_subcmd/.gitignore +1 -0
- data/processor/command/show_subcmd/trace_subcmd/buffer.rb +11 -31
- data/processor/command/show_subcmd/trace_subcmd/print.rb +4 -20
- data/processor/command/source.rb +7 -1
- data/processor/command/up.rb +7 -4
- data/processor/default.rb +3 -1
- data/processor/eval.rb +13 -0
- data/processor/eventbuf.rb +3 -2
- data/processor/frame.rb +19 -0
- data/processor/help.rb +20 -0
- data/processor/load_cmds.rb +143 -24
- data/processor/location.rb +61 -10
- data/processor/main.rb +30 -11
- data/processor/mock.rb +5 -3
- data/processor/msg.rb +17 -0
- data/processor/running.rb +1 -1
- data/processor/subcmd.rb +3 -2
- data/processor/validate.rb +173 -185
- data/sample/.gitignore +1 -0
- data/sample/list-terminal-colors.rb +139 -0
- data/sample/rocky-dot-trepanrc +14 -0
- data/sample/rocky-trepan-colors.rb +47 -0
- data/test/Makefile +7 -0
- data/test/data/.gitignore +1 -0
- data/test/data/debugger-stop.cmd +3 -0
- data/test/data/debugger-stop.right +5 -0
- data/test/data/fname-with-blank.right +0 -3
- data/test/data/quit.right +0 -1
- data/test/data/quit2.cmd +6 -0
- data/test/data/quit2.right +3 -0
- data/test/data/testing.cmd +1 -0
- data/test/example/.gitignore +1 -0
- data/test/example/debugger-stop.rb +14 -0
- data/test/functional/.gitignore +2 -0
- data/test/functional/fn_helper.rb +7 -9
- data/test/functional/test-break-long.rb +7 -7
- data/test/functional/test-break.rb +7 -7
- data/test/functional/test-condition.rb +4 -4
- data/test/functional/test-delete.rb +6 -5
- data/test/functional/test-eval.rb +115 -0
- data/test/functional/test-raise.rb +1 -1
- data/test/functional/test-return.rb +1 -1
- data/test/integration/.gitignore +2 -0
- data/test/integration/helper.rb +6 -3
- data/test/integration/test-debugger-stop.rb +22 -0
- data/test/integration/test-quit.rb +8 -0
- data/test/unit/.gitignore +1 -0
- data/test/unit/Makefile +7 -0
- data/test/unit/test-app-brkpt.rb +0 -1
- data/test/unit/test-app-cmd_parse.rb +107 -0
- data/test/unit/test-app-cmd_parser.rb +22 -0
- data/test/unit/test-app-complete.rb +38 -0
- data/test/unit/test-app-condition.rb +20 -0
- data/test/unit/test-app-iseq.rb +31 -0
- data/test/unit/test-app-options.rb +9 -1
- data/test/unit/test-app-util.rb +0 -1
- data/test/unit/test-base-cmd.rb +46 -0
- data/test/unit/test-base-subcmd.rb +11 -2
- data/test/unit/test-base-submgr.rb +23 -0
- data/test/unit/test-base-subsubcmd.rb +20 -0
- data/test/unit/test-cmd-break.rb +22 -23
- data/test/unit/test-cmd-help.rb +4 -0
- data/test/unit/test-completion.rb +43 -0
- data/test/unit/test-io-tcpclient.rb +3 -2
- data/test/unit/test-proc-load_cmds.rb +10 -1
- data/test/unit/test-proc-location.rb +39 -0
- data/test/unit/test-proc-main.rb +1 -1
- data/test/unit/test-proc-validate.rb +47 -31
- data/trepanning.gemspec +45 -0
- metadata +247 -179
- data/app/core.rb-consider +0 -198
- data/test/functional/tmp/b3.rb +0 -5
- data/test/functional/tmp/immediate-bug1.rb +0 -9
@@ -1,13 +1,13 @@
|
|
1
|
-
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
1
|
+
# Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
|
2
2
|
require_relative 'base/cmd'
|
3
3
|
require_relative '../running'
|
4
4
|
require_relative '../../app/breakpoint' # FIXME: possibly temporary
|
5
|
-
class Trepan::Command::ContinueCommand < Trepan::Command
|
6
5
|
|
6
|
+
class Trepan::Command::ContinueCommand < Trepan::Command
|
7
7
|
unless defined?(HELP)
|
8
|
-
NAME
|
8
|
+
NAME = File.basename(__FILE__, '.rb')
|
9
9
|
HELP = <<-HELP
|
10
|
-
#{NAME} [
|
10
|
+
#{NAME} [LOCATION]
|
11
11
|
|
12
12
|
Leave the debugger loop and continue execution. Subsequent entry to
|
13
13
|
the debugger however may occur via breakpoints or explicit calls, or
|
@@ -21,32 +21,29 @@ Examples:
|
|
21
21
|
#{NAME}
|
22
22
|
#{NAME} 10 # continue to line 10
|
23
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
|
26
|
+
|
27
|
+
See also 'step', 'next', 'finish', 'nexti' commands and "help location".
|
24
28
|
HELP
|
25
29
|
|
26
30
|
ALIASES = %w(c cont)
|
27
31
|
CATEGORY = 'running'
|
28
|
-
MAX_ARGS =
|
32
|
+
MAX_ARGS = 2 # Need at most this many
|
29
33
|
NEED_RUNNING = true
|
30
|
-
SHORT_HELP = 'Continue execution of debugged program'
|
34
|
+
SHORT_HELP = 'Continue execution of the debugged program'
|
31
35
|
end
|
32
36
|
|
33
|
-
# This method runs the command
|
37
|
+
# This is the method that runs the command
|
34
38
|
def run(args)
|
35
39
|
if args.size == 1
|
36
40
|
# Form is: "continue"
|
37
41
|
@proc.continue
|
38
42
|
else
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
return false unless position && iseq
|
44
|
-
bp =
|
45
|
-
if use_offset
|
46
|
-
@proc.breakpoint_offset(position, iseq, true)
|
47
|
-
else
|
48
|
-
@proc.breakpoint_line(position, iseq, true)
|
49
|
-
end
|
43
|
+
iseq, line_number, vm_offset, condition, negate =
|
44
|
+
@proc.breakpoint_position(@proc.cmd_argstr, false)
|
45
|
+
return false unless iseq && vm_offset
|
46
|
+
bp = @proc.breakpoint_offset(vm_offset, iseq, condition, negate)
|
50
47
|
return unless bp
|
51
48
|
@proc.continue
|
52
49
|
end
|
@@ -35,6 +35,8 @@ Examples:
|
|
35
35
|
SHORT_HELP = 'Disassemble Ruby VM instructions'
|
36
36
|
end
|
37
37
|
|
38
|
+
completion %w(. full)
|
39
|
+
|
38
40
|
# FIXME: put in processor/data.rb?
|
39
41
|
|
40
42
|
def marked_disassemble(iseq_param, include_children)
|
@@ -99,4 +101,7 @@ if __FILE__ == $0
|
|
99
101
|
end
|
100
102
|
cmd.proc.frame_setup(RubyVM::ThreadFrame::current)
|
101
103
|
cmd.run([cmd.name, 'p'])
|
104
|
+
puts cmd.complete('f')
|
105
|
+
require 'irb'
|
106
|
+
cmd.run([cmd.name, 'IRB.start'])
|
102
107
|
end
|
data/processor/command/down.rb
CHANGED
@@ -0,0 +1,70 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# Copyright (C) 2011 Rocky Bernstein <rockyb@rubyforge.net>
|
3
|
+
require_relative './base/cmd'
|
4
|
+
|
5
|
+
class Trepan::Command::EvalCommand < Trepan::Command
|
6
|
+
|
7
|
+
old_verbose = $VERBOSE
|
8
|
+
$VERBOSE = nil
|
9
|
+
NAME = File.basename(__FILE__, '.rb')
|
10
|
+
HELP = <<-HELP
|
11
|
+
#{NAME} [STRING]
|
12
|
+
|
13
|
+
Run code in the context of the current frame.
|
14
|
+
|
15
|
+
The value of the expression is stored into a global variable so it
|
16
|
+
may be used again easily. The name of the global variable is printed
|
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. If the command ends ? (via an alias) and no string is
|
21
|
+
given we will also strip off any leading 'if', 'while', 'elseif',
|
22
|
+
'return', 'case', 'unless', or 'until' in the string.
|
23
|
+
|
24
|
+
#{NAME} 1+2 # 3
|
25
|
+
#{NAME} @v
|
26
|
+
#{NAME} # Run current source-code line
|
27
|
+
#{NAME}? # but strips off leading 'if', 'while', ..
|
28
|
+
# from command
|
29
|
+
|
30
|
+
See also 'set autoeval'. The command helps one predict future execution.
|
31
|
+
See 'set buffer trace' for showing what may have already been run.
|
32
|
+
HELP
|
33
|
+
|
34
|
+
ALIASES = %w(eval? ev? ev)
|
35
|
+
CATEGORY = 'data'
|
36
|
+
NEED_STACK = true
|
37
|
+
SHORT_HELP = 'Run code in the current context'
|
38
|
+
$VERBOSE = old_verbose
|
39
|
+
|
40
|
+
def run(args)
|
41
|
+
if args.size == 1
|
42
|
+
text = @proc.current_source_text
|
43
|
+
if '?' == args[0][-1..-1]
|
44
|
+
if text =~ /^\s*(?:if|elsif|unless)\s+/
|
45
|
+
text.gsub!(/^\s*(?:if|elsif|unless)\s+/,'')
|
46
|
+
text.gsub!(/\s+then\s*$/, '')
|
47
|
+
elsif text =~ /^\s*(?:until|while)\s+/
|
48
|
+
text.gsub!(/^\s*(?:until|while)\s+/,'')
|
49
|
+
text.gsub!(/\s+do\s*$/, '')
|
50
|
+
elsif text =~ /^\s*return\s+/
|
51
|
+
text.gsub!(/^\s*return\s+/,'')
|
52
|
+
elsif text =~ /^\s*case\s+/
|
53
|
+
text.gsub!(/^\s*case\s*/,'')
|
54
|
+
end
|
55
|
+
msg "eval: #{text}"
|
56
|
+
end
|
57
|
+
else
|
58
|
+
text = @proc.cmd_argstr
|
59
|
+
end
|
60
|
+
@proc.eval_code(text, settings[:maxstring])
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
if __FILE__ == $0
|
65
|
+
require_relative '../mock'
|
66
|
+
dbgr, cmd = MockDebugger::setup
|
67
|
+
arg_str = '1 + 2'
|
68
|
+
cmd.proc.instance_variable_set('@cmd_argstr', arg_str)
|
69
|
+
puts "eval #{arg_str} is: #{cmd.run([cmd.name, arg_str])}"
|
70
|
+
end
|
data/processor/command/exit.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
1
|
+
# Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
|
2
2
|
require_relative 'base/cmd'
|
3
3
|
class Trepan::Command::ExitCommand < Trepan::Command
|
4
4
|
|
@@ -43,6 +43,9 @@ See also the commands "quit" and "kill".
|
|
43
43
|
exitrc = (args.size > 1) ? exitrc = Integer(args[1]) rescue 0 : 0
|
44
44
|
# No graceful way to stop threads...
|
45
45
|
# A little harsh, but for now let's go with this.
|
46
|
+
# FIXME: Is this the best/most general way?
|
47
|
+
@proc.finalize
|
48
|
+
@proc.dbgr.intf[-1].finalize
|
46
49
|
exit! exitrc
|
47
50
|
end
|
48
51
|
end
|
data/processor/command/finish.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
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_relative 'base/cmd'
|
4
4
|
|
5
5
|
class Trepan::Command::FinishCommand < Trepan::Command
|
@@ -9,8 +9,9 @@ class Trepan::Command::FinishCommand < Trepan::Command
|
|
9
9
|
HELP = <<-HELP
|
10
10
|
#{NAME} [levels]
|
11
11
|
|
12
|
-
Continue execution until leaving the current
|
13
|
-
|
12
|
+
Continue execution until the program is about to leaving the current
|
13
|
+
function or switch context via yielding or ending a block which was
|
14
|
+
yield to. Sometimes this is called 'step out'.
|
14
15
|
|
15
16
|
When `levels' is specified, that many frame levels need to be
|
16
17
|
popped. The default is 1. Note that 'yield' and exceptions raised my
|
@@ -24,6 +25,7 @@ one.
|
|
24
25
|
See the break command if you want to stop at a particular point in a
|
25
26
|
program. In general, '#{NAME}', 'step' and 'next' may slow a program down
|
26
27
|
while 'break' will have less overhead.
|
28
|
+
|
27
29
|
HELP
|
28
30
|
ALIASES = %w(fin)
|
29
31
|
CATEGORY = 'running'
|
@@ -54,7 +56,7 @@ while 'break' will have less overhead.
|
|
54
56
|
# step 1 is core.level_count = 0 or "stop next event"
|
55
57
|
level_count = count - 1
|
56
58
|
end
|
57
|
-
if 0 == level_count and %w(return c-return).member?(@proc.event)
|
59
|
+
if 0 == level_count and %w(return c-return yield leave).member?(@proc.event)
|
58
60
|
errmsg "You are already at the requested return event."
|
59
61
|
else
|
60
62
|
@proc.finish(level_count, opts)
|
data/processor/command/frame.rb
CHANGED
@@ -46,15 +46,18 @@ See also 'up', 'down' 'where' and 'info thread'.
|
|
46
46
|
SHORT_HELP = 'Select and print a stack frame'
|
47
47
|
end
|
48
48
|
|
49
|
+
def complete(prefix)
|
50
|
+
@proc.frame_complete(prefix, nil)
|
51
|
+
end
|
52
|
+
|
49
53
|
# The simple case: thread frame switching has been done or is
|
50
54
|
# not needed and we have an explicit position number as a string
|
51
55
|
def one_arg_run(position_str)
|
52
|
-
|
56
|
+
low, high = @proc.frame_low_high(nil)
|
53
57
|
opts={
|
54
58
|
:msg_on_error =>
|
55
59
|
"The '#{NAME}' command requires a frame number. Got: #{position_str}",
|
56
|
-
:min_value =>
|
57
|
-
:max_value => stack_size-1
|
60
|
+
:min_value => low, :max_value => high
|
58
61
|
}
|
59
62
|
frame_num = @proc.get_an_int(position_str, opts)
|
60
63
|
return false unless frame_num
|
data/processor/command/help.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
|
2
2
|
require_relative 'base/cmd'
|
3
|
+
require_relative '../../app/complete'
|
3
4
|
class Trepan::Command::HelpCommand < Trepan::Command
|
4
|
-
|
5
5
|
unless defined?(HELP)
|
6
6
|
NAME = File.basename(__FILE__, '.rb')
|
7
7
|
HELP = <<-HELP
|
@@ -32,25 +32,61 @@ See also 'examine' and 'whatis'.
|
|
32
32
|
'running' => 'Running the program',
|
33
33
|
'status' => 'Status inquiries',
|
34
34
|
'support' => 'Support facilities',
|
35
|
-
'stack' => 'Examining the call stack'
|
35
|
+
'stack' => 'Examining the call stack',
|
36
|
+
'syntax' => 'Debugger command syntax'
|
36
37
|
}
|
37
38
|
CATEGORY = 'support'
|
38
39
|
NEED_STACK = false
|
39
40
|
SHORT_HELP = 'Print commands or give help for command(s)'
|
41
|
+
|
42
|
+
require 'thread_frame'
|
43
|
+
ROOT_DIR = File.dirname(RubyVM::ThreadFrame.current.source_container[1])
|
44
|
+
HELP_DIR = File.join(ROOT_DIR, 'help')
|
45
|
+
end
|
46
|
+
|
47
|
+
def complete(prefix)
|
48
|
+
matches = Trepan::Complete.complete_token(CATEGORIES.keys +
|
49
|
+
%w(* syntax all) +
|
50
|
+
@proc.commands.keys, prefix)
|
51
|
+
aliases = Trepan::Complete.complete_token_filtered(@proc.aliases, prefix,
|
52
|
+
matches)
|
53
|
+
(matches + aliases).sort
|
54
|
+
end
|
55
|
+
|
56
|
+
def complete(prefix)
|
57
|
+
matches = Trepan::Complete.complete_token(CATEGORIES.keys + %w(* all) +
|
58
|
+
@proc.commands.keys, prefix)
|
59
|
+
aliases = Trepan::Complete.complete_token_filtered(@proc.aliases, prefix,
|
60
|
+
matches)
|
61
|
+
(matches + aliases).sort
|
62
|
+
end
|
63
|
+
|
64
|
+
def complete_token_with_next(prefix)
|
65
|
+
complete(prefix).map do |cmd|
|
66
|
+
[cmd, @proc.commands.member?(cmd) ? @proc.commands[cmd] : nil]
|
67
|
+
# complete_method =
|
68
|
+
# if 'syntax' == cmd
|
69
|
+
# Syntax.new(syntax_files)
|
70
|
+
# else
|
71
|
+
# @proc.commands.member?(cmd) ? @proc.commands[cmd] : nil
|
72
|
+
# end
|
73
|
+
# [cmd, complete_method]
|
74
|
+
end
|
40
75
|
end
|
41
76
|
|
42
77
|
# List the command categories and a short description of each.
|
43
78
|
def list_categories
|
44
|
-
section '
|
79
|
+
section 'Help classes:'
|
45
80
|
CATEGORIES.keys.sort.each do |cat|
|
46
81
|
msg("%-13s -- %s" % [cat, CATEGORIES[cat]])
|
47
82
|
end
|
48
83
|
final_msg = '
|
49
|
-
Type "help" followed by a class name for a list of
|
50
|
-
Type "help
|
51
|
-
Type "help
|
84
|
+
Type "help" followed by a class name for a list of help items in that class.
|
85
|
+
Type "help aliases" for a list of current aliases.
|
86
|
+
Type "help macros" for a list of current macros.
|
87
|
+
Type "help *" for the list of all commands, macros and aliases.
|
52
88
|
Type "help all" for the list of all commands.
|
53
|
-
Type "help REGEXP" for the list of commands matching /^#{REGEXP}
|
89
|
+
Type "help REGEXP" for the list of commands matching /^#{REGEXP}/.
|
54
90
|
Type "help CLASS *" for the list of all commands in class CLASS.
|
55
91
|
Type "help" followed by command name for full documentation.
|
56
92
|
'
|
@@ -64,8 +100,14 @@ Type "help" followed by command name for full documentation.
|
|
64
100
|
if cmd_name == '*'
|
65
101
|
section 'All command names:'
|
66
102
|
msg columnize_commands(@proc.commands.keys.sort)
|
103
|
+
show_aliases unless @proc.aliases.empty?
|
104
|
+
show_macros unless @proc.macros.empty?
|
105
|
+
elsif cmd_name =~ /^aliases$/i
|
106
|
+
show_aliases
|
107
|
+
elsif cmd_name =~ /^macros$/i
|
108
|
+
show_macros
|
67
109
|
elsif cmd_name =~ /^syntax$/i
|
68
|
-
show_command_syntax
|
110
|
+
show_command_syntax(args)
|
69
111
|
elsif cmd_name =~ /^all$/i
|
70
112
|
CATEGORIES.sort.each do |category|
|
71
113
|
show_category(category[0], [])
|
@@ -90,6 +132,9 @@ Type "help" followed by command name for full documentation.
|
|
90
132
|
msg "Aliases: #{cmd_obj.class.const_get(:ALIASES).join(', ')}"
|
91
133
|
end
|
92
134
|
end
|
135
|
+
elsif @proc.macros.member?(cmd_name)
|
136
|
+
msg "#{cmd_name} is a macro which expands to:"
|
137
|
+
msg " #{@proc.macros[cmd_name]}", {:unlimited => true}
|
93
138
|
else
|
94
139
|
matches = @proc.commands.keys.grep(/^#{cmd_name}/).sort rescue []
|
95
140
|
if matches.empty?
|
@@ -104,9 +149,14 @@ Type "help" followed by command name for full documentation.
|
|
104
149
|
end
|
105
150
|
end
|
106
151
|
|
152
|
+
def show_aliases
|
153
|
+
section 'All alias names:'
|
154
|
+
msg columnize_commands(@proc.aliases.keys.sort)
|
155
|
+
end
|
156
|
+
|
107
157
|
# Show short help for all commands in `category'.
|
108
158
|
def show_category(category, args)
|
109
|
-
|
159
|
+
|
110
160
|
if args.size == 1 && args[0] == '*'
|
111
161
|
section "Commands in class %s:" % category
|
112
162
|
|
@@ -116,7 +166,7 @@ Type "help" followed by command name for full documentation.
|
|
116
166
|
width = settings[:maxwidth]
|
117
167
|
return columnize_commands(cmds)
|
118
168
|
end
|
119
|
-
|
169
|
+
|
120
170
|
msg('')
|
121
171
|
section "Command class: %s" % category
|
122
172
|
msg('')
|
@@ -125,52 +175,42 @@ Type "help" followed by command name for full documentation.
|
|
125
175
|
msg("%-13s -- %s" % [name, @proc.commands[name].short_help])
|
126
176
|
end
|
127
177
|
end
|
178
|
+
|
179
|
+
def syntax_files
|
180
|
+
@syntax_files ||= Dir.glob(File.join(HELP_DIR, '*.txt')).map do |txt|
|
181
|
+
basename = File.basename(txt, '.txt')
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
def show_command_syntax(args)
|
186
|
+
if args.size == 2
|
187
|
+
@syntax_summary_help ||= {}
|
188
|
+
section "List of syntax help"
|
189
|
+
syntax_files.each do |name|
|
190
|
+
@syntax_summary_help[name] ||=
|
191
|
+
File.open(File.join(HELP_DIR, "#{name}.txt")).readline.chomp
|
192
|
+
msg " %-8s -- %s" % [name, @syntax_summary_help[name]]
|
193
|
+
end
|
194
|
+
else
|
195
|
+
args[2..-1].each do |name|
|
196
|
+
if syntax_files.member?(name)
|
197
|
+
@syntax_help ||= {}
|
198
|
+
@syntax_help[name] =
|
199
|
+
File.open(File.join(HELP_DIR, "#{name}.txt")).readlines[2..-1].join
|
200
|
+
section "Debugger syntax for a #{name}:"
|
201
|
+
msg @syntax_help[name]
|
202
|
+
else
|
203
|
+
errmsg "No syntax help for #{name}"
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
128
208
|
|
129
|
-
def
|
130
|
-
section
|
131
|
-
msg
|
132
|
-
Command command syntax is very simple-minded.
|
133
|
-
|
134
|
-
If a line starts with #, the command is ignored.
|
135
|
-
If a line starts with !, the line is eval'd.
|
136
|
-
|
137
|
-
If the command you want eval'd uses the Ruby ! initally, add that
|
138
|
-
after the first !.
|
139
|
-
|
140
|
-
Commands are split at whereever ;; appears. This process disregards
|
141
|
-
any quotes or other symbols that have meaning in Ruby. The strings
|
142
|
-
after the leading command string are put back on a command queue.
|
143
|
-
|
144
|
-
Within a single command, tokens are then white-space split. Again,
|
145
|
-
this process disregards quotes or symbols that have meaning in Ruby.
|
146
|
-
|
147
|
-
The first token is then looked up in the debugger command table and
|
148
|
-
then the debugger alias table. If a match is found the command name
|
149
|
-
and arguments are dispatched to the command object that process the
|
150
|
-
command.
|
151
|
-
|
152
|
-
If the command is not found and "auto eval" is set on, then the
|
153
|
-
command is eval'd in the context that the program is currently stopped
|
154
|
-
at. If "auto eval" is not set on, then we display an error message
|
155
|
-
that the entered string is "undefined".
|
156
|
-
|
157
|
-
If you want irb-like command-processing, it's possible to go into an
|
158
|
-
irb shell with the "irb" command. It is also possible to arrange going
|
159
|
-
into an irb shell every time you enter the debugger.
|
160
|
-
|
161
|
-
Examples:
|
162
|
-
|
163
|
-
# This line does nothing. It is a comment
|
164
|
-
s # by default, this is an alias for the "step" command
|
165
|
-
!s # shows the value of variable step.
|
166
|
-
!!s # Evaluates !s (or "not s"). The first ! is indicates evaluate.
|
167
|
-
info program;; list # Runs two commands "info program" and "list"
|
168
|
-
pr "hi ;;-)" # Syntax error since ;; splits the line and " is not closed.
|
169
|
-
!puts "hi ;;-)" # One way to do the above.
|
170
|
-
|
171
|
-
See also "alias", "irb", "set auto eval", and "set auto irb".
|
172
|
-
EOS
|
209
|
+
def show_macros
|
210
|
+
section 'All macro names:'
|
211
|
+
msg columnize_commands(@proc.macros.keys.sort)
|
173
212
|
end
|
213
|
+
|
174
214
|
end
|
175
215
|
|
176
216
|
if __FILE__ == $0
|
@@ -193,4 +233,7 @@ if __FILE__ == $0
|
|
193
233
|
cmd.run %W(#{cmd.name} s.*)
|
194
234
|
puts '=' * 40
|
195
235
|
cmd.run %W(#{cmd.name} s<>)
|
236
|
+
puts '=' * 40
|
237
|
+
p cmd.complete('br')
|
238
|
+
p cmd.complete('un')
|
196
239
|
end
|