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
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
|