line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# -*- coding: utf-8 -*- |
2
|
|
|
|
|
|
|
# Copyright (C) 2011-2012, 2014 Rocky Bernstein <rocky@cpan.org> |
3
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
# Part of Devel::Trepan::CmdProcessor that loads up debugger commands from |
5
|
|
|
|
|
|
|
# builtin and user directories. |
6
|
|
|
|
|
|
|
# Sets @commands, @aliases, @macros |
7
|
12
|
|
|
12
|
|
82541
|
use rlib '../../..'; |
|
12
|
|
|
|
|
35
|
|
|
12
|
|
|
|
|
70
|
|
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
package Devel::Trepan::CmdProcessor; |
10
|
|
|
|
|
|
|
$Load_seen = 1; |
11
|
12
|
|
|
12
|
|
7212
|
use warnings; use strict; |
|
12
|
|
|
12
|
|
26
|
|
|
12
|
|
|
|
|
315
|
|
|
12
|
|
|
|
|
98
|
|
|
12
|
|
|
|
|
59
|
|
|
12
|
|
|
|
|
284
|
|
12
|
12
|
|
|
12
|
|
59
|
no warnings 'redefine'; |
|
12
|
|
|
|
|
25
|
|
|
12
|
|
|
|
|
379
|
|
13
|
|
|
|
|
|
|
|
14
|
12
|
|
|
12
|
|
60
|
use File::Spec; |
|
12
|
|
|
|
|
31
|
|
|
12
|
|
|
|
|
405
|
|
15
|
12
|
|
|
12
|
|
71
|
use File::Basename; |
|
12
|
|
|
|
|
21
|
|
|
12
|
|
|
|
|
812
|
|
16
|
12
|
|
|
12
|
|
88
|
use Cwd 'abs_path'; |
|
12
|
|
|
|
|
22
|
|
|
12
|
|
|
|
|
18223
|
|
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
=head2 load_cmds_initialize |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
load_debugger_commands($self) -> undef |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
Loads in our built-in commands. |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
Called from Devel::Trepan::CmdProcessor->new in CmdProcessor.pm |
25
|
|
|
|
|
|
|
=cut |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
sub load_cmds_initialize($) |
28
|
|
|
|
|
|
|
{ |
29
|
13
|
|
|
13
|
0
|
50
|
my $self = shift; |
30
|
13
|
|
|
|
|
59
|
$self->{commands} = {}; |
31
|
13
|
|
|
|
|
73
|
$self->{aliases} = {}; |
32
|
13
|
|
|
|
|
66
|
$self->{macros} = {}; |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
my @cmd_dirs = ( |
35
|
|
|
|
|
|
|
File::Spec->catfile(dirname(__FILE__), 'Command'), |
36
|
13
|
|
|
|
|
1945
|
@{$self->{settings}{cmddir}} |
|
13
|
|
|
|
|
110
|
|
37
|
|
|
|
|
|
|
); |
38
|
13
|
|
|
|
|
93
|
for my $cmd_dir (@cmd_dirs) { |
39
|
13
|
50
|
|
|
|
561
|
$self->load_debugger_commands($cmd_dir) if -d $cmd_dir; |
40
|
|
|
|
|
|
|
} |
41
|
|
|
|
|
|
|
} |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
=head2 load_debugger_commands |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
load_debugger_commands($self, $file_or_dir) -> @errors |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
Loads in debugger commands by require'ing each Perl file in the |
48
|
|
|
|
|
|
|
'command' directory. Then a new instance of each class of the |
49
|
|
|
|
|
|
|
form Trepan::xxCommand is added to @commands and that array |
50
|
|
|
|
|
|
|
is returned. |
51
|
|
|
|
|
|
|
=cut |
52
|
|
|
|
|
|
|
sub load_debugger_commands($$) |
53
|
|
|
|
|
|
|
{ |
54
|
13
|
|
|
13
|
0
|
75
|
my ($self, $file_or_dir) = @_; |
55
|
13
|
|
|
|
|
50
|
my @errors = (); |
56
|
13
|
50
|
|
|
|
206
|
if ( -d $file_or_dir ) { |
|
|
0
|
|
|
|
|
|
57
|
13
|
|
|
|
|
1171
|
my $dir = abs_path($file_or_dir); |
58
|
|
|
|
|
|
|
# change $0 so it doesn't get in the way of __FILE__ eq $0 |
59
|
|
|
|
|
|
|
# old_dollar0 = $0 |
60
|
|
|
|
|
|
|
# $0 = '' |
61
|
13
|
|
|
|
|
7493
|
for my $pm (glob(File::Spec->catfile($dir, '*.pm'))) { |
62
|
494
|
|
|
|
|
1552
|
my $err = $self->load_debugger_command($pm); |
63
|
494
|
50
|
|
|
|
1584
|
push @errors, $err if $err; |
64
|
|
|
|
|
|
|
} |
65
|
|
|
|
|
|
|
# $0 = old_dollar0 |
66
|
|
|
|
|
|
|
} elsif (-r $file_or_dir) { |
67
|
0
|
|
|
|
|
0
|
my $err = $self->load_debugger_command($file_or_dir); |
68
|
0
|
0
|
|
|
|
0
|
push @errors, $err if $err; |
69
|
|
|
|
|
|
|
} |
70
|
13
|
|
|
|
|
155
|
return @errors; |
71
|
|
|
|
|
|
|
} |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
=head2 load_debugger_command |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
load_debugger_command($self, $command_file, [$force]) |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
Loads a debugger command. Returns a string containing the error or '' if no error. |
78
|
|
|
|
|
|
|
=cut |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
sub load_debugger_command($$;$) |
81
|
|
|
|
|
|
|
{ |
82
|
494
|
|
|
494
|
0
|
1298
|
my ($self, $command_file, $force) = @_; |
83
|
494
|
50
|
|
|
|
13965
|
return unless -r $command_file; |
84
|
494
|
|
|
|
|
2819
|
my $rc = ''; |
85
|
494
|
|
|
|
|
907
|
eval { $rc = do $command_file; }; |
|
494
|
|
|
|
|
202766
|
|
86
|
494
|
50
|
33
|
|
|
4092
|
if (!$rc or $rc eq 'Skip me!') { |
|
|
50
|
|
|
|
|
|
87
|
0
|
|
|
|
|
0
|
return 'skipped'; |
88
|
|
|
|
|
|
|
} elsif ($rc) { |
89
|
|
|
|
|
|
|
# Instantiate each Command class found by the above require(s). |
90
|
494
|
|
|
|
|
17778
|
my $name = basename($command_file, '.pm'); |
91
|
494
|
|
|
|
|
2480
|
return $self->setup_command($name); |
92
|
|
|
|
|
|
|
} else { |
93
|
0
|
|
|
|
|
0
|
my $errmsg = "Trouble reading ${command_file}: $@"; |
94
|
0
|
|
|
|
|
0
|
$self->errmsg($errmsg); |
95
|
0
|
|
|
|
|
0
|
return $errmsg; |
96
|
|
|
|
|
|
|
} |
97
|
|
|
|
|
|
|
} |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
=head2 run_cmd |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
run_cmd($self, $cmd_arry) |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
Looks up cmd_array[0] in @commands and runs that. We do lots of |
104
|
|
|
|
|
|
|
validity testing on cmd_array. |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
=cut |
107
|
|
|
|
|
|
|
sub run_cmd($$) |
108
|
|
|
|
|
|
|
{ |
109
|
3
|
|
|
3
|
0
|
2493
|
my ($self, $cmd_array) = @_; |
110
|
3
|
100
|
|
|
|
13
|
unless ('ARRAY' eq ref $cmd_array) { |
111
|
1
|
50
|
|
|
|
5
|
my $ref_msg = ref($cmd_array) ? ", got: " . ref($cmd_array): ''; |
112
|
1
|
|
|
|
|
7
|
$self->errmsg("run_cmd argument should be an Array reference$ref_msg"); |
113
|
1
|
|
|
|
|
19
|
return; |
114
|
|
|
|
|
|
|
} |
115
|
|
|
|
|
|
|
# if ($cmd_array.detect{|item| !item.is_a?(String)}) { |
116
|
|
|
|
|
|
|
# $self ->errmsg("run_cmd argument Array should only contain strings. " . |
117
|
|
|
|
|
|
|
# "Got #{cmd_array.inspect}"); |
118
|
|
|
|
|
|
|
# return; |
119
|
|
|
|
|
|
|
# } |
120
|
2
|
100
|
|
|
|
9
|
if (0 == scalar @$cmd_array) { |
121
|
1
|
|
|
|
|
14
|
$self->errmsg("run_cmd Array should have at least one item"); |
122
|
1
|
|
|
|
|
20
|
return; |
123
|
|
|
|
|
|
|
} |
124
|
1
|
|
|
|
|
4
|
my $cmd_name = $cmd_array->[0]; |
125
|
1
|
50
|
|
|
|
4
|
if (exists($self->{commands}{$cmd_name})) { |
126
|
1
|
|
|
|
|
8
|
$self->{commands}{$cmd_name}->run($cmd_array); |
127
|
|
|
|
|
|
|
} |
128
|
|
|
|
|
|
|
} |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
# sub save_commands(opts) |
131
|
|
|
|
|
|
|
# { |
132
|
|
|
|
|
|
|
# save_filename = opts[:filename] || |
133
|
|
|
|
|
|
|
# File.join(Dir.tmpdir, Dir::Tmpname.make_tmpname(['trepanning-save', '.txt'], nil)) |
134
|
|
|
|
|
|
|
# begin |
135
|
|
|
|
|
|
|
# save_file = File.open(save_filename, 'w') |
136
|
|
|
|
|
|
|
# rescue => exc |
137
|
|
|
|
|
|
|
# errmsg("Can't open #{save_filename} for writing.") |
138
|
|
|
|
|
|
|
# errmsg("System reports: #{exc.inspect}") |
139
|
|
|
|
|
|
|
# return nil |
140
|
|
|
|
|
|
|
# } |
141
|
|
|
|
|
|
|
# save_file.print "#\n# Commands to restore trepanning environment\n#\n" |
142
|
|
|
|
|
|
|
# @commands.each do |cmd_name, cmd_obj| |
143
|
|
|
|
|
|
|
# cmd_obj.save_command if cmd_obj.respond_to?(:save_command) |
144
|
|
|
|
|
|
|
# next unless cmd_obj.is_a?(Trepan::SubcommandMgr) |
145
|
|
|
|
|
|
|
# cmd_obj.subcmds.subcmds.each do |subcmd_name, subcmd_obj| |
146
|
|
|
|
|
|
|
# save_file.print subcmd_obj.save_command if |
147
|
|
|
|
|
|
|
# subcmd_obj.respond_to?(:save_command) |
148
|
|
|
|
|
|
|
# next unless subcmd_obj.is_a?(Trepan::SubSubcommandMgr) |
149
|
|
|
|
|
|
|
# subcmd_obj.subcmds.subcmds.each do |subsubcmd_name, subsubcmd_obj| |
150
|
|
|
|
|
|
|
# save_file.print subsubcmd_obj.save_command if |
151
|
|
|
|
|
|
|
# subsubcmd_obj.respond_to?(:save_command) |
152
|
|
|
|
|
|
|
# } |
153
|
|
|
|
|
|
|
# } |
154
|
|
|
|
|
|
|
# } |
155
|
|
|
|
|
|
|
# save_file.print "!FileUtils.rm #{save_filename.inspect}" if |
156
|
|
|
|
|
|
|
# opts[:erase] |
157
|
|
|
|
|
|
|
# save_file.close |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
# return save_filename |
160
|
|
|
|
|
|
|
# } |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
=head2 setup_command |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
setup_command($self, $name) |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
Instantiate a Devel::Trepan::Command and extract info: the NAME, ALIASES |
167
|
|
|
|
|
|
|
and store the command in @commands. |
168
|
|
|
|
|
|
|
=cut |
169
|
|
|
|
|
|
|
sub setup_command($$) |
170
|
|
|
|
|
|
|
{ |
171
|
494
|
|
|
494
|
0
|
1232
|
my ($self, $name) = @_; |
172
|
494
|
|
|
|
|
781
|
my $cmd_obj; |
173
|
494
|
|
|
|
|
965
|
my $cmd_name = lc $name; |
174
|
494
|
|
|
|
|
1298
|
my $new_cmd = "\$cmd_obj=Devel::Trepan::CmdProcessor::Command::${name}" . |
175
|
|
|
|
|
|
|
"->new(\$self, \$cmd_name); 1"; |
176
|
494
|
50
|
|
|
|
39513
|
if (eval $new_cmd) { |
177
|
|
|
|
|
|
|
# Add to list of commands and aliases. |
178
|
494
|
50
|
|
|
|
4358
|
if ($cmd_obj->{aliases}) { |
179
|
494
|
|
|
|
|
918
|
for my $a (@{$cmd_obj->{aliases}}) { |
|
494
|
|
|
|
|
1514
|
|
180
|
559
|
|
|
|
|
2388
|
$self->{aliases}{$a} = $cmd_name; |
181
|
|
|
|
|
|
|
} |
182
|
|
|
|
|
|
|
} |
183
|
494
|
|
|
|
|
2425
|
$self->{commands}{$cmd_name} = $cmd_obj; |
184
|
494
|
|
|
|
|
3972
|
return ''; |
185
|
|
|
|
|
|
|
} else { |
186
|
0
|
|
|
|
|
|
$self->errmsg("Error instantiating $name"); |
187
|
0
|
|
|
|
|
|
$self->errmsg($@); |
188
|
0
|
|
|
|
|
|
return $@; |
189
|
|
|
|
|
|
|
} |
190
|
|
|
|
|
|
|
} |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
unless (caller) { |
193
|
|
|
|
|
|
|
require Devel::Trepan::CmdProcessor; |
194
|
|
|
|
|
|
|
my $cmdproc = Devel::Trepan::CmdProcessor->new; |
195
|
|
|
|
|
|
|
require Array::Columnize; |
196
|
|
|
|
|
|
|
my @cmds = sort keys(%{$cmdproc->{commands}}); |
197
|
|
|
|
|
|
|
print Array::Columnize::columnize(\@cmds); |
198
|
|
|
|
|
|
|
my $sep = '=' x 20 . "\n"; |
199
|
|
|
|
|
|
|
print $sep; |
200
|
|
|
|
|
|
|
my @aliases = sort keys(%{$cmdproc->{aliases}}); |
201
|
|
|
|
|
|
|
print Array::Columnize::columnize(\@aliases); |
202
|
|
|
|
|
|
|
print $sep; |
203
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
$cmdproc->run_cmd('foo'); # Invalid - not an Array |
205
|
|
|
|
|
|
|
$cmdproc->run_cmd([]); # Invalid - empty Array |
206
|
|
|
|
|
|
|
$cmdproc->run_cmd(['help', '*']); |
207
|
|
|
|
|
|
|
# $cmdproc->run_cmd(['list', 5]); # Invalid - nonstring arg |
208
|
|
|
|
|
|
|
} |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
1; |