trepanning 0.1.6 → 1.93.32
Sign up to get free protection for your applications and to get access to all the features.
- 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
data/processor/command/step.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
|
-
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
2
|
+
# Copyright (C) 2010, 2015 Rocky Bernstein <rockyb@rubyforge.net>
|
3
3
|
require_relative '../command'
|
4
4
|
require_relative '../../app/condition'
|
5
5
|
class Trepan::Command::StepCommand < Trepan::Command
|
@@ -7,66 +7,75 @@ class Trepan::Command::StepCommand < Trepan::Command
|
|
7
7
|
unless defined?(HELP)
|
8
8
|
NAME = File.basename(__FILE__, '.rb')
|
9
9
|
HELP = <<-HELP
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
10
|
+
**#{NAME}**[**+**|**=**|**-**|**<**|**>**|**!**|**<>**] [**into**] [*event-name*...] [*count*]
|
11
|
+
|
12
|
+
**#{NAME} until** *expression*
|
13
|
+
|
14
|
+
**#{NAME} thread**
|
15
|
+
|
16
|
+
**#{NAME} to** *method-name*
|
17
|
+
|
18
|
+
**#{NAME} over**
|
19
|
+
|
20
|
+
**#{NAME} out**
|
16
21
|
|
17
22
|
Execute the current line, stopping at the next event. Sometimes this
|
18
23
|
is called 'step into'.
|
19
24
|
|
20
|
-
With an integer argument, step that many times. With an
|
25
|
+
With an integer argument, step that many times. With an *until*
|
21
26
|
expression that expression is evaluated and we stop the first time it
|
22
27
|
is true.
|
23
28
|
|
24
|
-
|
25
|
-
|
29
|
+
*event-name*... is list of an event name which is one on *call*,
|
30
|
+
*return*, *line*, *exception* *c-call*, *c-return* or *c-exception*.
|
26
31
|
If specified, only those stepping events will be considered. If no
|
27
32
|
list of event names is given, then any event triggers a stop when the
|
28
33
|
count is 0.
|
29
34
|
|
30
|
-
There is however another way to specify an
|
31
|
-
suffixing one of the symbols
|
32
|
-
an alias of that. A suffix of
|
33
|
-
move to another position, while a suffix of
|
34
|
-
requirement. A suffix of '
|
35
|
-
call. (
|
35
|
+
There is however another way to specify an single *event-name*, by
|
36
|
+
suffixing one of the symbols `<`, `>`, or `!` after the command or on
|
37
|
+
an alias of that. A suffix of `+` on a command or an alias forces a
|
38
|
+
move to another position, while a suffix of `-` disables this
|
39
|
+
requirement. A suffix of `>'`will continue until the next
|
40
|
+
call. (`finish` will run run until the return for that call.)
|
36
41
|
|
37
42
|
If no suffix is given, the debugger setting 'different' determines
|
38
43
|
this behavior.
|
39
44
|
|
40
|
-
Examples:
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
45
|
+
Examples:
|
46
|
+
--------
|
47
|
+
|
48
|
+
#{NAME} # step 1 event, *any* event obeying 'set different' setting
|
49
|
+
#{NAME} 1 # same as above
|
50
|
+
#{NAME}+ # same but force stopping on a new line
|
51
|
+
#{NAME}= # same but force stopping on a new line a new frame added
|
52
|
+
#{NAME}- # same but force stopping on a new line a new frame added
|
53
|
+
#{NAME} 5/5+0 # same as above
|
54
|
+
#{NAME} line # step only line events
|
55
|
+
#{NAME} call # step only call call events
|
56
|
+
#{NAME}> # step call and c-call events
|
57
|
+
#{NAME}< # step only return and c-return events
|
58
|
+
#{NAME} call line # step line *and* call events
|
59
|
+
#{NAME}<> # same as step call c-call return c-return
|
60
|
+
#{NAME} until a > b
|
61
|
+
#{NAME} over # same as 'next'
|
62
|
+
#{NAME} out # same as 'finish'
|
63
|
+
#{NAME} thread # step stopping only in the current thread. Is the same
|
64
|
+
# as step until Thread.current.object_id == #object_id
|
65
|
+
|
66
|
+
Related and similar is the `next` (step over) and `finish` (step out)
|
60
67
|
commands. All of these are slower than running to a breakpoint.
|
61
68
|
|
62
|
-
See also
|
63
|
-
|
64
|
-
'
|
69
|
+
See also:
|
70
|
+
---------
|
71
|
+
`skip`, `jump` (there's no 'hop' yet), `continue`, `return` and
|
72
|
+
`finish` for other ways to progress execution.
|
65
73
|
HELP
|
66
74
|
|
67
|
-
ALIASES = %w(s step+ step- step< step> step<> step! s> s< s+ s-
|
75
|
+
ALIASES = %w(s step+ step- step< step> step<> step! s> s< s+ s-
|
68
76
|
s<> s! s=)
|
69
77
|
CATEGORY = 'running'
|
78
|
+
NEED_STACK = true
|
70
79
|
NEED_RUNNING = true
|
71
80
|
SHORT_HELP = 'Step program (possibly entering called functions)'
|
72
81
|
|
@@ -116,15 +125,15 @@ See also the commands:
|
|
116
125
|
else
|
117
126
|
count_str = args[1]
|
118
127
|
int_opts = {
|
119
|
-
:msg_on_error =>
|
120
|
-
"The 'step' command argument must eval to an integer. Got: %s" %
|
128
|
+
:msg_on_error =>
|
129
|
+
"The 'step' command argument must eval to an integer. Got: %s" %
|
121
130
|
count_str,
|
122
131
|
:min_value => 1
|
123
132
|
}.merge(opts)
|
124
133
|
count = @proc.get_an_int(count_str, int_opts)
|
125
134
|
return unless count
|
126
135
|
# step 1 is core.step_count = 0 or "stop next event"
|
127
|
-
step_count = count - 1
|
136
|
+
step_count = count - 1
|
128
137
|
end
|
129
138
|
end
|
130
139
|
@proc.step(step_count, opts, condition)
|
data/processor/command/tbreak.rb
CHANGED
@@ -1,20 +1,25 @@
|
|
1
1
|
require_relative './../command'
|
2
2
|
require_relative 'break'
|
3
3
|
|
4
|
-
class Trepan::Command::SetTempBreakpointCommand <
|
4
|
+
class Trepan::Command::SetTempBreakpointCommand <
|
5
5
|
Trepan::Command::BreakCommand
|
6
6
|
ALIASES = []
|
7
7
|
CATEGORY = 'breakpoints'
|
8
8
|
NAME = File.basename(__FILE__, '.rb')
|
9
9
|
HELP = <<-HELP
|
10
|
+
**#{NAME}**
|
11
|
+
**#{NAME}** *location* [ {if|unless} *condition* ]
|
12
|
+
#{NAME}
|
13
|
+
|
10
14
|
Same as break, but the breakpoint is deleted when it is hit.
|
11
15
|
|
12
|
-
See also
|
16
|
+
See also:
|
17
|
+
---------
|
18
|
+
`condition`, `continue`, `help syntax location`, and `break`
|
13
19
|
HELP
|
14
20
|
SHORT_HELP = 'Set a temporary breakpoint'
|
15
|
-
|
21
|
+
|
16
22
|
def run(args)
|
17
23
|
super args, true
|
18
24
|
end
|
19
25
|
end
|
20
|
-
|
@@ -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
|
|
@@ -6,26 +6,28 @@ class Trepan::Command::UnaliasCommand < Trepan::Command
|
|
6
6
|
|
7
7
|
unless defined?(HELP)
|
8
8
|
HELP = <<-HELP
|
9
|
-
unalias
|
9
|
+
**unalias** *alias*
|
10
10
|
|
11
|
-
Remove alias
|
11
|
+
Remove alias *alias*.
|
12
12
|
|
13
|
-
See also
|
13
|
+
See also:
|
14
|
+
---------
|
15
|
+
`alias` and `show alias`.
|
14
16
|
HELP
|
15
17
|
|
16
18
|
CATEGORY = 'support'
|
17
19
|
MIN_ARGS = 1
|
18
20
|
# MAX_ARGS = 1 # Need at most this many
|
19
21
|
NAME = File.basename(__FILE__, '.rb')
|
20
|
-
NEED_STACK =
|
22
|
+
NEED_STACK = false
|
21
23
|
SHORT_HELP = 'Remove an alias'
|
22
24
|
end
|
23
|
-
|
25
|
+
|
24
26
|
def complete(prefix)
|
25
27
|
Trepan::Complete.complete_token(@proc.aliases.keys, prefix)
|
26
28
|
end
|
27
29
|
|
28
|
-
# Run command.
|
30
|
+
# Run command.
|
29
31
|
def run(args)
|
30
32
|
args[1..-1].each do |arg|
|
31
33
|
if @proc.aliases.member?(arg)
|
@@ -1,19 +1,23 @@
|
|
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
|
|
5
5
|
# undisplay display-number...
|
6
6
|
class Trepan::Command::UndisplayCommand < Trepan::Command
|
7
|
-
|
7
|
+
|
8
8
|
unless defined?(HELP)
|
9
9
|
NAME = File.basename(__FILE__, '.rb')
|
10
10
|
HELP = <<EOH
|
11
|
-
|
11
|
+
**#{NAME}** *display-number* ...
|
12
|
+
|
12
13
|
Cancel some expressions to be displayed when program stops.
|
13
14
|
Arguments are the code numbers of the expressions to stop displaying.
|
14
15
|
No argument means cancel all automatic-display expressions.
|
15
|
-
|
16
|
-
|
16
|
+
|
17
|
+
See also:
|
18
|
+
---------
|
19
|
+
`delete display` has the same effect as this command.
|
20
|
+
Use `info display` to see current list of display numbers.
|
17
21
|
EOH
|
18
22
|
|
19
23
|
CATEGORY = 'data'
|
@@ -26,7 +30,7 @@ EOH
|
|
26
30
|
end
|
27
31
|
|
28
32
|
def run(args)
|
29
|
-
|
33
|
+
|
30
34
|
if args.size == 1
|
31
35
|
if confirm('Delete all displays?', false)
|
32
36
|
@proc.displays.clear
|
@@ -37,7 +41,7 @@ EOH
|
|
37
41
|
args[1..-1].each do |arg|
|
38
42
|
opts = {:msg_on_error => '%s must be a display number' % arg}
|
39
43
|
i = @proc.get_an_int(arg, opts)
|
40
|
-
if i
|
44
|
+
if i
|
41
45
|
unless @proc.displays.delete_index(i)
|
42
46
|
errmsg("No display number %d." % i)
|
43
47
|
return
|
data/processor/command/up.rb
CHANGED
@@ -1,21 +1,26 @@
|
|
1
|
-
# Copyright (C) 2010,
|
1
|
+
# Copyright (C) 2010-2011, 2013, 2015 Rocky Bernstein <rockyb@rubyforge.net>
|
2
2
|
require_relative '../command'
|
3
3
|
require_relative '../../app/util'
|
4
4
|
|
5
5
|
# up command. Like 'down' but the direction (set by DIRECTION) is different.
|
6
6
|
#
|
7
|
-
# NOTE: The down command subclasses this, so beware when changing!
|
7
|
+
# NOTE: The down command subclasses this, so beware when changing!
|
8
8
|
class Trepan::Command::UpCommand < Trepan::Command
|
9
9
|
|
10
10
|
Trepan::Util.suppress_warnings {
|
11
11
|
NAME = File.basename(__FILE__, '.rb')
|
12
12
|
HELP = <<-HELP
|
13
|
-
|
13
|
+
**#{NAME}** [*count*]
|
14
14
|
|
15
15
|
Move the current frame up in the stack trace (to an older frame). 0 is
|
16
|
-
the most
|
16
|
+
the most-recent frame. If no count is given, move up 1.
|
17
17
|
|
18
|
-
|
18
|
+
A negative number moves in the opposite direction.
|
19
|
+
|
20
|
+
See also:
|
21
|
+
---------
|
22
|
+
|
23
|
+
`down`, `frame`.
|
19
24
|
HELP
|
20
25
|
|
21
26
|
CATEGORY = 'stack'
|
@@ -23,20 +28,20 @@ See also 'down' and 'frame'.
|
|
23
28
|
NEED_STACK = true
|
24
29
|
SHORT_HELP = 'Move frame in the direction of the caller of the last-selected frame'
|
25
30
|
}
|
26
|
-
|
31
|
+
|
27
32
|
require_relative '../../app/frame'
|
28
33
|
include Trepan::Frame
|
29
34
|
|
30
35
|
def complete(prefix)
|
31
36
|
@proc.frame_complete(prefix, @direction)
|
32
37
|
end
|
33
|
-
|
38
|
+
|
34
39
|
def initialize(proc)
|
35
40
|
super
|
36
41
|
@direction = +1 # -1 for down.
|
37
42
|
end
|
38
43
|
|
39
|
-
# Run 'up' command.
|
44
|
+
# Run 'up' command.
|
40
45
|
def run(args)
|
41
46
|
|
42
47
|
# FIXME: move into @proc and test based on NEED_STACK.
|
@@ -53,7 +58,7 @@ See also 'down' and 'frame'.
|
|
53
58
|
count_str = args[1]
|
54
59
|
name_or_id = args[1]
|
55
60
|
opts = {
|
56
|
-
:msg_on_error =>
|
61
|
+
:msg_on_error =>
|
57
62
|
"The '#{NAME}' command argument requires a frame number. Got: %s" % count_str,
|
58
63
|
:min_value => low, :max_value => high
|
59
64
|
}
|
@@ -72,20 +77,20 @@ if __FILE__ == $0
|
|
72
77
|
|
73
78
|
def sep ; puts '=' * 40 end
|
74
79
|
cmd.run [cmd.name]
|
75
|
-
%w(-1 0 1 -2).each do |count|
|
80
|
+
%w(-1 0 1 -2).each do |count|
|
76
81
|
puts "#{cmd.name} #{count}"
|
77
82
|
cmd.run([cmd.name, count])
|
78
|
-
sep
|
83
|
+
sep
|
79
84
|
end
|
80
85
|
def foo(cmd, name)
|
81
86
|
cmd.proc.frame_setup(RubyVM::Frame::current)
|
82
87
|
puts "#{name}"
|
83
88
|
cmd.run([name])
|
84
89
|
sep
|
85
|
-
%w(-2 -1).each do |count|
|
90
|
+
%w(-2 -1).each do |count|
|
86
91
|
puts "#{name} #{count}"
|
87
92
|
cmd.run([name, count])
|
88
|
-
sep
|
93
|
+
sep
|
89
94
|
end
|
90
95
|
end
|
91
96
|
foo(cmd, cmd.name)
|
data/processor/command/watchg.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 '../../app/complete'
|
5
5
|
|
@@ -8,29 +8,33 @@ class Trepan::Command::WatchgCommand < Trepan::Command
|
|
8
8
|
NAME = File.basename(__FILE__, '.rb')
|
9
9
|
CATEGORY = 'breakpoints'
|
10
10
|
HELP = <<-EOH
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
**#{NAME}** *global-variable* [**on**]
|
12
|
+
**#{NAME}** *global-variable** **nostop**
|
13
|
+
**#{NAME}** *global-variable* **off**
|
14
14
|
|
15
|
-
Use Kernel.trace_var to trace changes of global variable
|
16
|
-
|
15
|
+
Use *Kernel.trace_var* to trace changes of global variable
|
16
|
+
*global-variable*. If `nostop` is given, then we just print out the
|
17
17
|
location and variable name but do not stop in the debugger.
|
18
18
|
|
19
|
-
To remove a prior trace, add
|
19
|
+
To remove a prior trace, add `off` to the end.
|
20
20
|
|
21
21
|
Note in contrast to other events, stopping for variable tracing occurs
|
22
22
|
*after* the event, not before.
|
23
23
|
|
24
|
-
|
24
|
+
*Note:* this command name will likely change in the future.
|
25
25
|
|
26
26
|
Examples:
|
27
|
-
|
28
|
-
#{NAME} $PROGRAM_NAME on # same as above
|
29
|
-
#{NAME} $PROGRAN_NAME stop # just print places the varaible is set
|
30
|
-
# along with the location
|
31
|
-
#{NAME} $PROGRAN_NAME off # remove watching changes
|
27
|
+
---------
|
32
28
|
|
33
|
-
|
29
|
+
#{NAME} $PROGRAM_NAME # enter debugger if global $PROGRAM_NAME changes
|
30
|
+
#{NAME} $PROGRAM_NAME on # same as above
|
31
|
+
#{NAME} $PROGRAN_NAME stop # just print places the varaible is set
|
32
|
+
# along with the location
|
33
|
+
#{NAME} $PROGRAN_NAME off # remove watching changes
|
34
|
+
|
35
|
+
See also:
|
36
|
+
---------
|
37
|
+
`info breakpoints`
|
34
38
|
EOH
|
35
39
|
|
36
40
|
MAX_ARGS = 3
|
@@ -54,8 +58,8 @@ See also 'info breakpoints'
|
|
54
58
|
return
|
55
59
|
end
|
56
60
|
else
|
57
|
-
Kernel.trace_var(traced_sym,
|
58
|
-
lambda {|val|
|
61
|
+
Kernel.trace_var(traced_sym,
|
62
|
+
lambda {|val|
|
59
63
|
@proc.core.trace_var_processor(traced_var, val)})
|
60
64
|
end
|
61
65
|
@proc.traced_vars[traced_var] = action
|
@@ -111,4 +115,3 @@ if __FILE__ == $0
|
|
111
115
|
$FOO=1
|
112
116
|
cmd.run(%w(variable $FOO off))
|
113
117
|
end
|
114
|
-
|
@@ -0,0 +1,120 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# Copyright (C) 2013 Rocky Bernstein <rockyb@rubyforge.net>
|
3
|
+
|
4
|
+
# Part of Trepan::CmdProcess to handle command completion
|
5
|
+
require_relative '../app/complete'
|
6
|
+
require_relative 'virtual'
|
7
|
+
|
8
|
+
class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
|
9
|
+
|
10
|
+
attr_reader :leading_str # leading part of string. Used in
|
11
|
+
# command completion
|
12
|
+
|
13
|
+
# Handle initial completion. We draw from the commands, aliases,
|
14
|
+
# and macros for completion. However we won't include aliases which
|
15
|
+
# are prefixes of other commands.
|
16
|
+
def complete(str, last_token)
|
17
|
+
@leading_str = str
|
18
|
+
next_blank_pos, token = Trepan::Complete.next_token(str, 0)
|
19
|
+
return [''] if token.empty? && !last_token.empty?
|
20
|
+
match_pairs = Trepan::Complete.complete_token_with_next(@commands,
|
21
|
+
token)
|
22
|
+
match_hash = {}
|
23
|
+
match_pairs.each do |pair|
|
24
|
+
match_hash[pair[0]] = pair[1]
|
25
|
+
end
|
26
|
+
alias_pairs = Trepan::Complete.
|
27
|
+
complete_token_filtered_with_next(@aliases, token, match_hash,
|
28
|
+
@commands)
|
29
|
+
match_pairs += alias_pairs
|
30
|
+
|
31
|
+
macro_pairs = Trepan::Complete.
|
32
|
+
complete_token_filtered_with_next(@macros, token, match_hash,
|
33
|
+
@commands)
|
34
|
+
match_pairs += macro_pairs
|
35
|
+
|
36
|
+
if str[next_blank_pos..-1].empty?
|
37
|
+
return match_pairs.map{|pair| pair[0]}.sort
|
38
|
+
else
|
39
|
+
alias_pairs.each do |pair|
|
40
|
+
match_hash[pair[0]] = pair[1]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
if match_pairs.size > 1
|
44
|
+
# FIXME: figure out what to do here.
|
45
|
+
# Matched multiple items in the middle of the string
|
46
|
+
# We can't handle this so do nothing.
|
47
|
+
return []
|
48
|
+
# return match_pairs.map do |name, cmd|
|
49
|
+
# ["#{name} #{args[1..-1].join(' ')}"]
|
50
|
+
# end
|
51
|
+
end
|
52
|
+
# match_pairs.size == 1
|
53
|
+
next_complete(str, next_blank_pos, match_pairs[0][1], last_token)
|
54
|
+
end
|
55
|
+
|
56
|
+
def next_complete(str, next_blank_pos, cmd, last_token)
|
57
|
+
next_blank_pos, token = Trepan::Complete.next_token(str, next_blank_pos)
|
58
|
+
return [] if token.empty? && !last_token.empty?
|
59
|
+
|
60
|
+
if cmd.respond_to?(:complete_token_with_next)
|
61
|
+
match_pairs = cmd.complete_token_with_next(token)
|
62
|
+
return [] if match_pairs.empty?
|
63
|
+
if str[next_blank_pos..-1].rstrip.empty? &&
|
64
|
+
(token.empty? || token == last_token)
|
65
|
+
return match_pairs.map { |completion, junk| completion }
|
66
|
+
else
|
67
|
+
if match_pairs.size == 1
|
68
|
+
return next_complete(str, next_blank_pos, match_pairs[0][1],
|
69
|
+
last_token)
|
70
|
+
else
|
71
|
+
# FIXME: figure out what to do here.
|
72
|
+
# Matched multiple items in the middle of the string
|
73
|
+
# We can't handle this so do nothing.
|
74
|
+
return []
|
75
|
+
end
|
76
|
+
end
|
77
|
+
elsif cmd.respond_to?(:complete)
|
78
|
+
matches = cmd.complete(token)
|
79
|
+
return [] if matches.empty?
|
80
|
+
if str[next_blank_pos..-1].rstrip.empty? &&
|
81
|
+
(token.empty? || token == last_token)
|
82
|
+
return matches
|
83
|
+
else
|
84
|
+
# FIXME: figure out what to do here.
|
85
|
+
# Matched multiple items in the middle of the string
|
86
|
+
# We can't handle this so do nothing.
|
87
|
+
return []
|
88
|
+
end
|
89
|
+
else
|
90
|
+
return []
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
if __FILE__ == $0
|
96
|
+
|
97
|
+
require_relative 'load_cmds'
|
98
|
+
class Trepan::CmdProcessor
|
99
|
+
def initialize(core, settings={})
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
|
104
|
+
cmdproc = Trepan::CmdProcessor.new(nil)
|
105
|
+
|
106
|
+
def cmdproc.errmsg(mess)
|
107
|
+
puts "** #{mess}"
|
108
|
+
end
|
109
|
+
|
110
|
+
def cmdproc.msg(mess)
|
111
|
+
puts mess
|
112
|
+
end
|
113
|
+
|
114
|
+
cmddir = File.join(File.dirname(__FILE__), 'command')
|
115
|
+
cmdproc.instance_variable_set('@settings', {})
|
116
|
+
cmdproc.load_cmds_initialize
|
117
|
+
p cmdproc.complete("d", 'd')
|
118
|
+
p cmdproc.complete("sho d", 'd')
|
119
|
+
p cmdproc.complete('', '')
|
120
|
+
end
|