trepanning 0.1.6 → 1.93.32
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/COPYING +57 -0
- data/ChangeLog +585 -736
- data/NEWS +26 -12
- data/README.md +62 -0
- data/Rakefile +15 -9
- data/app/breakpoint.rb +11 -12
- data/app/complete.rb +14 -14
- data/app/core.rb +34 -30
- data/app/default.rb +8 -7
- data/app/markdown.rb +191 -0
- data/app/options.rb +104 -99
- data/app/run.rb +9 -1
- data/app/util.rb +7 -7
- data/bin/trepan +7 -7
- data/interface.rb +0 -4
- data/interface/user.rb +11 -11
- data/io/input.rb +13 -13
- data/lib/trepanning.rb +30 -29
- data/processor.rb +40 -40
- data/processor/command.rb +13 -9
- data/processor/command/alias.rb +21 -15
- data/processor/command/backtrace.rb +27 -19
- data/processor/command/break.rb +24 -21
- data/processor/command/complete.rb +5 -2
- data/processor/command/condition.rb +14 -9
- data/processor/command/debug.rb +8 -8
- data/processor/command/down.rb +6 -6
- data/processor/command/edit.rb +4 -0
- data/processor/command/eval.rb +2 -2
- data/processor/command/exit.rb +12 -9
- data/processor/command/finish.rb +25 -23
- data/processor/command/frame.rb +30 -26
- data/processor/command/help.rb +203 -185
- data/processor/command/help/{command.txt → command.md} +21 -18
- data/processor/command/help/examples.md +20 -0
- data/processor/command/help/filename.md +46 -0
- data/processor/command/help/location.md +34 -0
- data/processor/command/help/suffixes.md +19 -0
- data/processor/command/info.rb +6 -4
- data/processor/command/info_subcmd/breakpoints.rb +13 -13
- data/processor/command/info_subcmd/files.rb +35 -31
- data/processor/command/info_subcmd/frame.rb +82 -33
- data/processor/command/info_subcmd/macro.rb +1 -1
- data/processor/command/info_subcmd/program.rb +8 -5
- data/processor/command/info_subcmd/registers.rb +15 -13
- data/processor/command/kill.rb +23 -17
- data/processor/command/list.rb +63 -56
- data/processor/command/macro.rb +45 -28
- data/processor/command/next.rb +29 -23
- data/processor/command/pp.rb +11 -9
- data/processor/command/pr.rb +10 -8
- data/processor/command/ps.rb +5 -5
- data/processor/command/quit.rb +24 -17
- data/processor/command/raise.rb +6 -6
- data/processor/command/reload.rb +9 -2
- data/processor/command/reload_subcmd/command.rb +4 -4
- data/processor/command/restart.rb +9 -4
- data/processor/command/save.rb +9 -9
- data/processor/command/server.rb +18 -17
- data/processor/command/set.rb +8 -6
- data/processor/command/set_subcmd/confirm.rb +15 -2
- data/processor/command/set_subcmd/different.rb +7 -5
- data/processor/command/set_subcmd/highlight.rb +14 -3
- data/processor/command/set_subcmd/pc.rb +62 -0
- data/processor/command/set_subcmd/sp.rb +8 -2
- data/processor/command/shell.rb +25 -23
- data/processor/command/show.rb +9 -7
- data/processor/command/show_subcmd/confirm.rb +12 -1
- data/processor/command/show_subcmd/highlight.rb +13 -3
- data/processor/command/source.rb +27 -26
- data/processor/command/step.rb +52 -43
- data/processor/command/tbreak.rb +9 -4
- data/processor/command/unalias.rb +9 -7
- data/processor/command/undisplay.rb +11 -7
- data/processor/command/up.rb +18 -13
- data/processor/command/watchg.rb +20 -17
- data/processor/complete.rb +120 -0
- data/processor/default.rb +47 -43
- data/processor/list.rb +23 -6
- data/processor/load_cmds.rb +25 -105
- data/processor/location.rb +104 -96
- data/processor/mock.rb +12 -12
- data/processor/msg.rb +61 -52
- data/processor/validate.rb +36 -27
- data/test/data/fname-with-blank.right +0 -1
- data/test/data/trace-mingw.right +28 -0
- data/test/data/trace.right +0 -2
- data/test/functional/test-raise.rb +3 -0
- data/test/integration/helper.rb +16 -16
- data/test/integration/test-debugger-stop.rb +8 -2
- data/test/integration/test-quit.rb +16 -15
- data/test/integration/test-trace.rb +19 -10
- data/test/unit/cmd-helper.rb +4 -1
- data/test/unit/test-app-complete.rb +3 -1
- data/test/unit/test-app-options.rb +7 -1
- data/test/unit/test-app-run.rb +9 -1
- data/test/unit/test-cmd-alias.rb +1 -1
- data/test/unit/test-cmd-edit.rb +2 -0
- data/test/unit/test-cmd-help.rb +10 -5
- data/test/unit/test-cmd-parse_list_cmd.rb +3 -3
- data/test/unit/test-completion.rb +2 -2
- data/test/unit/test-proc-default.rb +34 -0
- data/trepanning.gemspec +15 -14
- metadata +70 -44
- data/README.textile +0 -50
- data/processor/command/help/examples.txt +0 -16
- data/processor/command/help/filename.txt +0 -40
- data/processor/command/help/location.txt +0 -37
- data/processor/command/help/suffixes.txt +0 -17
- data/processor/command/info_subcmd/registers_subcmd/dfp.rb +0 -28
- data/processor/command/info_subcmd/registers_subcmd/lfp.rb +0 -47
- data/processor/command/nocache.rb +0 -32
- data/processor/command/parsetree.rb +0 -56
@@ -14,7 +14,7 @@ class Trepan::Subcommand::InfoMacro < Trepan::Subcommand
|
|
14
14
|
In the first form a list of the existing macro names are shown
|
15
15
|
in column format.
|
16
16
|
|
17
|
-
In the second form, all macro names and their definitions are
|
17
|
+
In the second form, all macro names and their definitions are shown.
|
18
18
|
|
19
19
|
In the last form the only definitions of the given macro names is shown.
|
20
20
|
HELP
|
@@ -15,18 +15,21 @@ class Trepan::Subcommand::InfoProgram < Trepan::Subcommand
|
|
15
15
|
def run(args)
|
16
16
|
frame = @proc.frame
|
17
17
|
m = 'Program stop event: %s' % @proc.event
|
18
|
-
m +=
|
18
|
+
m +=
|
19
19
|
if frame.iseq
|
20
|
-
'; PC offset %d of instruction sequence: %s' %
|
20
|
+
'; PC offset %d of instruction sequence: %s' %
|
21
21
|
[frame.pc_offset, frame.iseq.name]
|
22
22
|
else
|
23
23
|
'.'
|
24
24
|
end
|
25
25
|
msg m
|
26
|
-
if 'return' == @proc.event
|
27
|
-
msg 'R=> %s' % @proc.frame.sp(1).inspect
|
26
|
+
if 'return' == @proc.event
|
27
|
+
msg 'R=> %s' % @proc.frame.sp(1).inspect
|
28
28
|
elsif 'raise' == @proc.event
|
29
|
-
|
29
|
+
msg @proc.core.hook_arg.inspect if @proc.core.hook_arg
|
30
|
+
if @proc.frame.iseq.catch_table_size == 0
|
31
|
+
msg "Warning: exception raised is non-local!"
|
32
|
+
end
|
30
33
|
end
|
31
34
|
|
32
35
|
if @proc.brkpt
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
|
-
# Copyright (C) 2010,
|
2
|
+
# Copyright (C) 2010-2011, 2015 Rocky Bernstein <rockyb@rubyforge.net>
|
3
3
|
require_relative '../base/subsubcmd'
|
4
4
|
require_relative '../base/subsubmgr'
|
5
5
|
|
@@ -7,18 +7,20 @@ class Trepan::SubSubcommand::InfoRegisters < Trepan::SubSubcommandMgr
|
|
7
7
|
unless defined?(HELP)
|
8
8
|
Trepanning::Subcommand.set_name_prefix(__FILE__, self)
|
9
9
|
HELP = <<-EOH
|
10
|
-
|
10
|
+
**#{CMD}** [**lfp**|**pc**|**sp**]
|
11
11
|
|
12
12
|
List of contents for the registers of the current stack frame.
|
13
13
|
If a register name given, only only that register is show.
|
14
14
|
|
15
15
|
Examples:
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
info reg sp
|
21
|
-
info reg
|
16
|
+
---------
|
17
|
+
|
18
|
+
#{CMD} # show all registers
|
19
|
+
#{CMD} pc # show only the pc register
|
20
|
+
info reg sp # show all stack pointer registers
|
21
|
+
info reg sp 1 3 # show sp(1) and sp(3)
|
22
|
+
info reg sp size # show sp size
|
23
|
+
info reg lfp # show lfp(0)
|
22
24
|
EOH
|
23
25
|
MIN_ABBREV = 'reg'.size # Note we have "info return"
|
24
26
|
NEED_STACK = true
|
@@ -28,14 +30,14 @@ info reg lfp # show lfp(0)
|
|
28
30
|
def run(args)
|
29
31
|
|
30
32
|
args = @parent.last_args
|
31
|
-
unavailable_regs =
|
33
|
+
unavailable_regs =
|
32
34
|
if 'CFUNC' == @proc.frame.type
|
33
|
-
%w(inforegisterslfp inforegisterspc)
|
35
|
+
%w(inforegisterslfp inforegisterspc)
|
34
36
|
else
|
35
37
|
[]
|
36
38
|
end
|
37
39
|
all_regs = @subcmds.subcmds.keys.sort - unavailable_regs
|
38
|
-
|
40
|
+
|
39
41
|
if args.size == 2
|
40
42
|
# Form is: "info registers"
|
41
43
|
all_regs.sort.each do |subcmd_name|
|
@@ -49,10 +51,10 @@ info reg lfp # show lfp(0)
|
|
49
51
|
subcmd = @subcmds.subcmds[key_name]
|
50
52
|
if @proc.ok_for_running(subcmd, subcmd.class.const_get('CMD'),
|
51
53
|
remain_args.size)
|
52
|
-
@subcmds.subcmds[key_name].run(remain_args)
|
54
|
+
@subcmds.subcmds[key_name].run(remain_args)
|
53
55
|
end
|
54
56
|
elsif unavailable_regs.member?(key_name)
|
55
|
-
msg("info registers: %s can not be displayed for frame type %s." %
|
57
|
+
msg("info registers: %s can not be displayed for frame type %s." %
|
56
58
|
[subcmd_name, @proc.frame.type])
|
57
59
|
else
|
58
60
|
errmsg("info registers: %s is not a valid register name" % subcmd_name)
|
data/processor/command/kill.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 '../command'
|
3
3
|
require_relative '../../app/complete'
|
4
4
|
class Trepan::Command::KillCommand < Trepan::Command
|
@@ -6,26 +6,32 @@ class Trepan::Command::KillCommand < Trepan::Command
|
|
6
6
|
unless defined?(HELP)
|
7
7
|
NAME = File.basename(__FILE__, '.rb')
|
8
8
|
HELP = <<-HELP
|
9
|
-
|
9
|
+
**#{NAME}** [signal-number|signal-name]
|
10
10
|
|
11
11
|
Kill execution of program being debugged.
|
12
12
|
|
13
|
-
Equivalent of Process.kill('KILL', Process.pid)
|
13
|
+
Equivalent of `Process.kill('KILL', Process.pid)`. This is an unmaskable
|
14
14
|
signal. When all else fails, e.g. in thread code, use this.
|
15
15
|
|
16
16
|
If you are in interactive mode, you are prompted to confirm killing.
|
17
|
-
However when this command is aliased from a command ending in
|
17
|
+
However when this command is aliased from a command ending in "!", no
|
18
18
|
questions are asked.
|
19
19
|
|
20
20
|
Examples:
|
21
|
+
---------
|
21
22
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
23
|
+
#{NAME}
|
24
|
+
#{NAME} unconditionally
|
25
|
+
#{NAME} KILL # same as above
|
26
|
+
#{NAME} kill # same as above
|
27
|
+
#{NAME} -9 # same as above
|
28
|
+
#{NAME} 9 # same as above
|
29
|
+
#{NAME}! 9 # above, but unconditional
|
30
|
+
|
31
|
+
See also:
|
32
|
+
---------
|
33
|
+
|
34
|
+
`quit`, `exit`
|
29
35
|
HELP
|
30
36
|
|
31
37
|
ALIASES = %w(kill!)
|
@@ -33,15 +39,15 @@ Examples:
|
|
33
39
|
MAX_ARGS = 1 # Need at most this many
|
34
40
|
SHORT_HELP = 'Send this process a POSIX signal (default "9" is "kill -9")'
|
35
41
|
end
|
36
|
-
|
42
|
+
|
37
43
|
def complete(prefix)
|
38
44
|
completions = Signal.list.keys + Signal.list.keys.map{|k| k.downcase} +
|
39
|
-
Signal.list.values.map{|i| i.to_s} +
|
40
|
-
Signal.list.values.map{|i| (-i).to_s} +
|
45
|
+
Signal.list.values.map{|i| i.to_s} +
|
46
|
+
Signal.list.values.map{|i| (-i).to_s} +
|
41
47
|
['unconditionally']
|
42
48
|
Trepan::Complete.complete_token(completions, prefix)
|
43
49
|
end
|
44
|
-
|
50
|
+
|
45
51
|
# This method runs the command
|
46
52
|
def run(args) # :nodoc
|
47
53
|
unconditional = ('!' == args[0][-1..-1])
|
@@ -54,7 +60,7 @@ Examples:
|
|
54
60
|
else
|
55
61
|
if unconditional || confirm('Really quit?', false)
|
56
62
|
sig = 'KILL'
|
57
|
-
else
|
63
|
+
else
|
58
64
|
msg('Kill not confirmed.')
|
59
65
|
return
|
60
66
|
end
|
@@ -71,7 +77,7 @@ end
|
|
71
77
|
if __FILE__ == $0
|
72
78
|
require_relative '../mock'
|
73
79
|
dbgr, cmd = MockDebugger::setup
|
74
|
-
%w(fooo 100 1 -1 HUP -9).each do |arg|
|
80
|
+
%w(fooo 100 1 -1 HUP -9).each do |arg|
|
75
81
|
puts "#{cmd.name} #{arg}"
|
76
82
|
cmd.run([cmd.name, arg])
|
77
83
|
puts '=' * 40
|
data/processor/command/list.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2010,
|
1
|
+
# Copyright (C) 2010-2011, 2015 Rocky Bernstein <rockyb@rubyforge.net>
|
2
2
|
# -*- coding: utf-8 -*-
|
3
3
|
require 'linecache'
|
4
4
|
require_relative '../command'
|
@@ -8,79 +8,86 @@ class Trepan::Command::ListCommand < Trepan::Command
|
|
8
8
|
unless defined?(HELP)
|
9
9
|
NAME = File.basename(__FILE__, '.rb')
|
10
10
|
HELP = <<-HELP
|
11
|
-
|
12
|
-
|
11
|
+
**#{NAME}[>]** [*module*] [*first* [*num*]]
|
12
|
+
**#{NAME}[>]** *location [*num*]
|
13
13
|
|
14
|
-
|
14
|
+
List source code.
|
15
15
|
|
16
|
-
Without arguments, prints lines centered around the current
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
16
|
+
Without arguments, prints lines centered around the current line. If
|
17
|
+
this is the first #{NAME} command issued since the debugger command
|
18
|
+
loop was entered, then the current line is the current frame. If a
|
19
|
+
subsequent #{NAME} command was issued with no intervening frame
|
20
|
+
changing, then that is start the line after we last one previously
|
21
|
+
shown.
|
22
22
|
|
23
|
-
If the command has a
|
23
|
+
If the command has a ">" suffix, then line centering is disabled and
|
24
24
|
listing begins at the specificed location.
|
25
25
|
|
26
26
|
The number of lines to show is controlled by the debugger "listsize"
|
27
27
|
setting. Use 'set max list' or 'show max list' to see or set the
|
28
28
|
value.
|
29
29
|
|
30
|
-
\"#{NAME} -\" shows lines before a previous listing.
|
30
|
+
\"#{NAME} -\" shows lines before a previous listing.
|
31
31
|
|
32
|
-
A
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
32
|
+
A *location* is a either:
|
33
|
+
|
34
|
+
* number, e.g. 5,
|
35
|
+
* a function, e.g. *join* or *os.path.join*
|
36
|
+
* a module, e.g. *os* or *os.path*
|
37
|
+
* a filename, colon, and a number, e.g. *foo.rb:5*,
|
38
|
+
* or a module name and a number, e.g,. *os.path:5*.
|
39
|
+
* a "." for the current line number
|
40
|
+
* a "-" for the lines before the current line number
|
40
41
|
|
41
42
|
If the location form is used with a subsequent parameter, the
|
42
43
|
parameter is the starting line number. When there two numbers are
|
43
44
|
given, the last number value is treated as a stopping line unless it
|
44
45
|
is positive and less than the start line. In this case, it is taken to
|
45
|
-
mean the number of lines to list instead. If last is negative, we
|
46
|
-
that many lines back from first and list to first.
|
46
|
+
mean the number of lines to list instead. If last is negative, we
|
47
|
+
start that many lines back from first and list to first.
|
47
48
|
|
48
|
-
Wherever a number is expected, it does not need to be a constant
|
49
|
+
Wherever a number is expected, it does not need to be a constant,
|
49
50
|
just something that evaluates to a positive integer.
|
50
51
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
#{NAME}
|
55
|
-
#{NAME} 5
|
56
|
-
#{NAME}
|
57
|
-
#{NAME} foo.rb
|
58
|
-
#{NAME}
|
59
|
-
#{NAME} foo.rb
|
60
|
-
#{NAME} foo.rb 5
|
61
|
-
#{NAME} foo.rb
|
62
|
-
#{NAME} foo.rb
|
63
|
-
#{NAME}
|
64
|
-
#{NAME} .
|
65
|
-
#{NAME} .
|
66
|
-
|
67
|
-
#
|
52
|
+
Examples:
|
53
|
+
---------
|
54
|
+
|
55
|
+
#{NAME} 5 # List centered around line 5
|
56
|
+
#{NAME} @5 # List lines centered around bytecode offset 5.
|
57
|
+
#{NAME} 5> # List starting at line 5
|
58
|
+
#{NAME} foo.rb:5 # List centered around line 5 of foo.rb
|
59
|
+
#{NAME} foo.rb 5 # Same as above.
|
60
|
+
#{NAME}> foo.rb:5 # List starting around line 5 of foo.rb
|
61
|
+
#{NAME} foo.rb 5 6 # list lines 5 and 6 of foo.rb
|
62
|
+
#{NAME} foo.rb 5 2 # Same as above, since 2 < 5.
|
63
|
+
#{NAME} foo.rb:5 2 # Same as above
|
64
|
+
#{NAME} foo.rb 15 -5 # List lines 10..15 of foo
|
65
|
+
#{NAME} FileUtils.cp # List lines around the FileUtils.cp function.
|
66
|
+
#{NAME} . # List lines centered from where we currently are stopped
|
67
|
+
#{NAME} . 3 # List 3 lines starting from where we currently are stopped
|
68
|
+
# if . > 3. Otherwise we list from . to 3.
|
69
|
+
#{NAME} - # List lines previous to those just shown
|
68
70
|
|
69
71
|
The output of the #{NAME} command gives a line number, and some status
|
70
|
-
information about the line and the text of the line. Here is some
|
72
|
+
information about the line and the text of the line. Here is some
|
71
73
|
hypothetical #{NAME} output modeled roughly around line 251 of one
|
72
74
|
version of this code:
|
73
75
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
76
|
+
251 cmd.proc.frame_setup(tf)
|
77
|
+
252 -> brkpt_cmd.run(['break'])
|
78
|
+
253 B01 line = __LINE__
|
79
|
+
254 b02 cmd.run(['list', __LINE__.to_s])
|
80
|
+
255 t03 puts '--' * 10
|
79
81
|
|
80
82
|
Line 251 has nothing special about it. Line 252 is where we are
|
81
83
|
currently stopped. On line 253 there is a breakpoint 1 which is
|
82
84
|
enabled, while at line 255 there is an breakpoint 2 which is
|
83
85
|
disabled.
|
86
|
+
|
87
|
+
See also:
|
88
|
+
---------
|
89
|
+
|
90
|
+
`set max list`, `show max list`, `disassemble`, `help syntax location`
|
84
91
|
HELP
|
85
92
|
|
86
93
|
ALIASES = %W(l #{NAME}> l> cat)
|
@@ -95,14 +102,14 @@ disabled.
|
|
95
102
|
return
|
96
103
|
end
|
97
104
|
listsize = settings[:maxlist]
|
98
|
-
center_correction =
|
105
|
+
center_correction =
|
99
106
|
if args[0][-1..-1] == '>'
|
100
107
|
0
|
101
108
|
else
|
102
109
|
(listsize-1) / 2
|
103
110
|
end
|
104
111
|
|
105
|
-
iseq, filename, first, last =
|
112
|
+
iseq, filename, first, last =
|
106
113
|
@proc.parse_list_cmd(@proc.cmd_argstr, listsize, center_correction)
|
107
114
|
return unless filename
|
108
115
|
container = iseq ? iseq.source_container : ['file', filename]
|
@@ -110,7 +117,7 @@ disabled.
|
|
110
117
|
|
111
118
|
# We now have range information. Do the listing.
|
112
119
|
max_line = LineCache::size(filename)
|
113
|
-
unless max_line
|
120
|
+
unless max_line
|
114
121
|
errmsg('File "%s" not found.' % filename)
|
115
122
|
return
|
116
123
|
end
|
@@ -140,14 +147,14 @@ disabled.
|
|
140
147
|
end
|
141
148
|
line.chomp!
|
142
149
|
s = '%3d' % lineno
|
143
|
-
s = s + ' ' if s.size < 4
|
150
|
+
s = s + ' ' if s.size < 4
|
144
151
|
s += if breaklist.member?(lineno)
|
145
152
|
bp = breaklist[lineno]
|
146
153
|
a_pad = '%02d' % bp.id
|
147
154
|
bp.icon_char
|
148
|
-
else
|
155
|
+
else
|
149
156
|
a_pad = ' '
|
150
|
-
' '
|
157
|
+
' '
|
151
158
|
end
|
152
159
|
s += (frame && lineno == @proc.frame_line &&
|
153
160
|
filename == frame.source_container[1]) ? '->' : a_pad
|
@@ -164,7 +171,7 @@ if __FILE__ == $0
|
|
164
171
|
if !(ARGV.size == 1 && ARGV[0] == 'noload')
|
165
172
|
ARGV[0..-1] = ['noload']
|
166
173
|
load(__FILE__)
|
167
|
-
else
|
174
|
+
else
|
168
175
|
require_relative '../location'
|
169
176
|
require_relative '../mock'
|
170
177
|
require_relative '../frame'
|
@@ -185,7 +192,7 @@ if __FILE__ == $0
|
|
185
192
|
puts "%s %s %s" % [seps, args.join(' '), seps]
|
186
193
|
run_cmd(cmd,args)
|
187
194
|
end
|
188
|
-
|
195
|
+
|
189
196
|
|
190
197
|
load 'tmpdir.rb'
|
191
198
|
run_cmd2(cmd, %w(list tmpdir.rb 10))
|
@@ -204,7 +211,7 @@ if __FILE__ == $0
|
|
204
211
|
run_cmd2(cmd, %w(list 3000))
|
205
212
|
run_cmd2(cmd, %w(list run_cmd2))
|
206
213
|
|
207
|
-
p = Proc.new do
|
214
|
+
p = Proc.new do
|
208
215
|
|x,y| x + y
|
209
216
|
end
|
210
217
|
require 'thread_frame'
|
@@ -221,7 +228,7 @@ if __FILE__ == $0
|
|
221
228
|
# Start line and count, since 3 < 30
|
222
229
|
run_cmd2(cmd, %W(#{cmd.name} Columnize.columnize 30 3))
|
223
230
|
|
224
|
-
# Start line finish line
|
231
|
+
# Start line finish line
|
225
232
|
run_cmd2(cmd, %W(#{cmd.name} Columnize.columnize 40 50))
|
226
233
|
|
227
234
|
# puts '--' * 10
|
data/processor/command/macro.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
|
-
# Copyright (C) 2010,
|
2
|
+
# Copyright (C) 2010-2011, 2015 Rocky Bernstein <rockyb@rubyforge.net>
|
3
3
|
require_relative '../command'
|
4
4
|
require_relative '../eval'
|
5
5
|
class Trepan::Command::MacroCommand < Trepan::Command
|
@@ -7,65 +7,82 @@ class Trepan::Command::MacroCommand < Trepan::Command
|
|
7
7
|
unless defined?(HELP)
|
8
8
|
NAME = File.basename(__FILE__, '.rb')
|
9
9
|
HELP = <<-HELP
|
10
|
-
|
10
|
+
**#{NAME}** *macro-name* *Proc-object*
|
11
11
|
|
12
|
-
Define
|
13
|
-
arguments
|
14
|
-
|
12
|
+
Define *macro-name* as a debugger macro. Debugger macros get a list of
|
13
|
+
arguments which you supply without parenthesis or commas. See below
|
14
|
+
for an example.
|
15
15
|
|
16
|
-
The macro (really a Ruby Proc) should return either a String or
|
17
|
-
Array of Strings
|
18
|
-
|
19
|
-
String#split . Note that macro processing is done right after
|
20
|
-
splitting on ;; so if the macro returns a string containing ;; this
|
21
|
-
will not be handled on the string returned.
|
16
|
+
The macro (really a Ruby *Proc()*) should return either a *String* or
|
17
|
+
an *Array* of *Strings*. Each component string in either case
|
18
|
+
refers to a debugger command.
|
22
19
|
|
23
|
-
If
|
20
|
+
If the return is a *String*, that gets tokenized by a simple
|
21
|
+
*String#split*. Note that macro processing is done right after
|
22
|
+
splitting on `;;` so if the macro returns a string containing `;;`
|
23
|
+
this will not be handled on the string returned.
|
24
|
+
|
25
|
+
Here is a simple macro using a string:
|
26
|
+
|
27
|
+
macro resize Proc.new{"set max width"}
|
28
|
+
|
29
|
+
We have to use a macro here rather than an *alias*, because the
|
30
|
+
expansion is more than to a command name, but contains the 3 tokens,
|
31
|
+
"set", "max", and "width".
|
32
|
+
|
33
|
+
If an Array of Strings is returned instead, then the first string is
|
24
34
|
shifted from the array and executed. The remaining strings are pushed
|
25
35
|
onto the command queue. In contrast to the first string, subsequent
|
26
36
|
strings can contain other macros, and ;; in those strings will be
|
27
37
|
split into separate commands.
|
28
38
|
|
29
|
-
Here is an example. The below creates a
|
30
|
-
issues two commands 'finish' followed by
|
39
|
+
Here is an example using na Array of Strings. The below creates a
|
40
|
+
macro called fin+ which issues two commands 'finish' followed by
|
41
|
+
'step':
|
31
42
|
|
32
|
-
|
43
|
+
macro fin+ Proc.new{|*args| %w(finish step)}
|
33
44
|
|
34
45
|
If you wanted to parameterize the argument of the 'finish' command
|
35
46
|
you could do that this way:
|
36
47
|
|
37
|
-
|
48
|
+
macro fin+ Proc.new{|*args| ["finish \#{args[0]}" 'step']}
|
49
|
+
|
50
|
+
Invoking with:
|
38
51
|
|
39
|
-
|
40
|
-
fin+ 3
|
52
|
+
fin+ 3
|
41
53
|
|
42
54
|
would expand to ["finish 3", "step"]
|
43
55
|
|
44
|
-
If you were to add another parameter for 'step', the note that the
|
45
|
-
invocation might be
|
46
|
-
|
56
|
+
If you were to add another parameter for 'step', the note that the
|
57
|
+
invocation might be:
|
58
|
+
|
59
|
+
fin+ 3 2
|
47
60
|
|
48
61
|
rather than 'fin+(3,2)' or 'fin+ 3, 2'.
|
49
62
|
|
50
63
|
Here is another example using arguments. I use the following to debug
|
51
64
|
a debugger command:
|
52
65
|
|
53
|
-
|
66
|
+
macro dbgcmd Proc.new{|*args| ["set debug dbgr", "debug $trepan_cmdproc.commands['\#{args[0]}'].run(\#{args.inspect})"]}
|
67
|
+
|
68
|
+
With the above, 'dbgcmd list 5' will ultimately expand to:
|
54
69
|
|
55
|
-
|
56
|
-
|
57
|
-
debug $trepan_cmdproc.commands['list'].run(['5'])
|
70
|
+
set debug dbgr
|
71
|
+
debug $trepan_cmdproc.commands['list'].run(['5'])
|
58
72
|
|
59
73
|
and will debug the debugger's 'list' command on the command 'list 5'.
|
60
74
|
|
61
|
-
See also
|
75
|
+
See also:
|
76
|
+
---------
|
77
|
+
|
78
|
+
`alias` and `info macro`.
|
62
79
|
HELP
|
63
80
|
|
64
81
|
CATEGORY = 'support'
|
65
82
|
MIN_ARGS = 2 # Need at least this many
|
66
83
|
SHORT_HELP = 'Define a macro'
|
67
84
|
end
|
68
|
-
|
85
|
+
|
69
86
|
def run(args)
|
70
87
|
cmd_name = args[1]
|
71
88
|
cmd_argstr = @proc.cmd_argstr[cmd_name.size..-1].lstrip
|
@@ -80,7 +97,7 @@ See also 'info macro'.
|
|
80
97
|
end
|
81
98
|
end
|
82
99
|
end
|
83
|
-
|
100
|
+
|
84
101
|
if __FILE__ == $0
|
85
102
|
require_relative '../mock'
|
86
103
|
dbgr, cmd = MockDebugger::setup
|