line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
|
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
BEGIN { |
6
|
1
|
|
|
1
|
|
3
|
my %fatpacked; |
7
|
|
|
|
|
|
|
|
8
|
1
|
|
|
|
|
11
|
$fatpacked{"App/Perl/Tags.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'APP_PERL_TAGS'; |
9
|
|
|
|
|
|
|
#!/usr/bin/env perl |
10
|
|
|
|
|
|
|
use 5.006; |
11
|
|
|
|
|
|
|
use strict; use warnings; |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
package App::Perl::Tags; |
14
|
|
|
|
|
|
|
use Getopt::Long (); |
15
|
|
|
|
|
|
|
use Pod::Usage qw/pod2usage/; |
16
|
|
|
|
|
|
|
use File::Find::Rule; |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
use Perl::Tags; |
19
|
|
|
|
|
|
|
use Perl::Tags::Hybrid; |
20
|
|
|
|
|
|
|
use Perl::Tags::Naive::Moose; # includes ::Naive |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
our $VERSION = '0.02'; |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
sub run { |
25
|
|
|
|
|
|
|
my $class = shift; |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
my %options = ( |
28
|
|
|
|
|
|
|
outfile => 'perltags', |
29
|
|
|
|
|
|
|
files => undef, |
30
|
|
|
|
|
|
|
depth => 10, |
31
|
|
|
|
|
|
|
variables => 1, |
32
|
|
|
|
|
|
|
ppi => 0, |
33
|
|
|
|
|
|
|
prune => [ ], |
34
|
|
|
|
|
|
|
help => sub { $class->usage() }, |
35
|
|
|
|
|
|
|
version => sub { $class->version() }, |
36
|
|
|
|
|
|
|
); |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
Getopt::Long::GetOptions( |
39
|
|
|
|
|
|
|
\%options, |
40
|
|
|
|
|
|
|
'help|h', |
41
|
|
|
|
|
|
|
'version|v', |
42
|
|
|
|
|
|
|
'outfile|o=s', |
43
|
|
|
|
|
|
|
'files|L=s', |
44
|
|
|
|
|
|
|
'prune=s@', |
45
|
|
|
|
|
|
|
'depth|d=i', |
46
|
|
|
|
|
|
|
'variables|vars!', |
47
|
|
|
|
|
|
|
'ppi|p!', |
48
|
|
|
|
|
|
|
); |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
if (defined $options{files}) { |
51
|
|
|
|
|
|
|
# Do not descend into explicitly specified files. |
52
|
|
|
|
|
|
|
$options{depth} = 1; |
53
|
|
|
|
|
|
|
} else { |
54
|
|
|
|
|
|
|
# If not files are specified via -files options, we expect some |
55
|
|
|
|
|
|
|
# paths after all the options. |
56
|
|
|
|
|
|
|
$class->usage() unless @ARGV |
57
|
|
|
|
|
|
|
} |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
$options{paths} = \@ARGV; |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
my $self = $class->new(%options); |
62
|
|
|
|
|
|
|
$self->main(); |
63
|
|
|
|
|
|
|
exit(); |
64
|
|
|
|
|
|
|
} |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
sub new { |
67
|
|
|
|
|
|
|
my ($class, %options) = @_; |
68
|
|
|
|
|
|
|
$options{prune} = [ '.git', '.svn' ] unless @{ $options{prune} || [] }; |
69
|
|
|
|
|
|
|
return bless \%options, $class; |
70
|
|
|
|
|
|
|
} |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
sub version { |
73
|
|
|
|
|
|
|
print "perl-tags v. $VERSION (Perl Tags v. $Perl::Tags::VERSION)\n"; |
74
|
|
|
|
|
|
|
exit(); |
75
|
|
|
|
|
|
|
} |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
sub usage { |
78
|
|
|
|
|
|
|
pod2usage(0); |
79
|
|
|
|
|
|
|
} |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
sub main { |
82
|
|
|
|
|
|
|
my $self = shift; |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
my %args = ( |
85
|
|
|
|
|
|
|
max_level => $self->{depth}, |
86
|
|
|
|
|
|
|
exts => 1, |
87
|
|
|
|
|
|
|
do_variables => $self->{variables}, |
88
|
|
|
|
|
|
|
); |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
my @taggers = ( Perl::Tags::Naive::Moose->new( %args ) ); |
91
|
|
|
|
|
|
|
if ($self->{ppi}) { |
92
|
|
|
|
|
|
|
require Perl::Tags::PPI; |
93
|
|
|
|
|
|
|
push @taggers, Perl::Tags::PPI->new( %args ); |
94
|
|
|
|
|
|
|
} |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
my $ptag = Perl::Tags::Hybrid->new( %args, \@taggers ); |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
my @files = do { |
99
|
|
|
|
|
|
|
if (defined $self->{files}) { |
100
|
|
|
|
|
|
|
if ('-' eq $self->{files}) { |
101
|
|
|
|
|
|
|
map { chomp; $_ } <STDIN>; |
102
|
|
|
|
|
|
|
} else { |
103
|
|
|
|
|
|
|
my $fh = IO::File->new($self->{files}) |
104
|
|
|
|
|
|
|
or die "cannot open $$self{files} for reading: $!"; |
105
|
|
|
|
|
|
|
map { chomp; $_ } <$fh>; |
106
|
|
|
|
|
|
|
} |
107
|
|
|
|
|
|
|
} else { |
108
|
|
|
|
|
|
|
$self->get_files; |
109
|
|
|
|
|
|
|
} |
110
|
|
|
|
|
|
|
}; |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
$ptag->process(files => \@files); |
113
|
|
|
|
|
|
|
$ptag->output(outfile => $self->{outfile}); |
114
|
|
|
|
|
|
|
return; |
115
|
|
|
|
|
|
|
} |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
sub get_files { |
118
|
|
|
|
|
|
|
my $self = shift; |
119
|
|
|
|
|
|
|
my @prune = @{ $self->{prune} }; |
120
|
|
|
|
|
|
|
my @paths = @{ $self->{paths} }; |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
my $rule = File::Find::Rule->new; |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
my @files = |
125
|
|
|
|
|
|
|
$rule->or( |
126
|
|
|
|
|
|
|
$rule->new |
127
|
|
|
|
|
|
|
->directory |
128
|
|
|
|
|
|
|
->name(@prune) |
129
|
|
|
|
|
|
|
->prune |
130
|
|
|
|
|
|
|
->discard, |
131
|
|
|
|
|
|
|
$rule->new |
132
|
|
|
|
|
|
|
->file, |
133
|
|
|
|
|
|
|
)->in(@paths); |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
return @files; |
136
|
|
|
|
|
|
|
} |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
=head1 AUTHOR |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
Copyright 2009-2014, Steffen Mueller, with contributions from osfameron |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
=cut |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
# vim:ts=2:sw=2 |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
1; |
147
|
|
|
|
|
|
|
APP_PERL_TAGS |
148
|
|
|
|
|
|
|
|
149
|
1
|
|
|
|
|
46
|
$fatpacked{"Carp.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CARP'; |
150
|
|
|
|
|
|
|
package Carp; |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
{ use 5.006; } |
153
|
|
|
|
|
|
|
use strict; |
154
|
|
|
|
|
|
|
use warnings; |
155
|
|
|
|
|
|
|
BEGIN { |
156
|
|
|
|
|
|
|
# Very old versions of warnings.pm load Carp. This can go wrong due |
157
|
|
|
|
|
|
|
# to the circular dependency. If warnings is invoked before Carp, |
158
|
|
|
|
|
|
|
# then warnings starts by loading Carp, then Carp (above) tries to |
159
|
|
|
|
|
|
|
# invoke warnings, and gets nothing because warnings is in the process |
160
|
|
|
|
|
|
|
# of loading and hasn't defined its import method yet. If we were |
161
|
|
|
|
|
|
|
# only turning on warnings ("use warnings" above) this wouldn't be too |
162
|
|
|
|
|
|
|
# bad, because Carp would just gets the state of the -w switch and so |
163
|
|
|
|
|
|
|
# might not get some warnings that it wanted. The real problem is |
164
|
|
|
|
|
|
|
# that we then want to turn off Unicode warnings, but "no warnings |
165
|
|
|
|
|
|
|
# 'utf8'" won't be effective if we're in this circular-dependency |
166
|
|
|
|
|
|
|
# situation. So, if warnings.pm is an affected version, we turn |
167
|
|
|
|
|
|
|
# off all warnings ourselves by directly setting ${^WARNING_BITS}. |
168
|
|
|
|
|
|
|
# On unaffected versions, we turn off just Unicode warnings, via |
169
|
|
|
|
|
|
|
# the proper API. |
170
|
|
|
|
|
|
|
if(!defined($warnings::VERSION) || eval($warnings::VERSION) < 1.06) { |
171
|
|
|
|
|
|
|
${^WARNING_BITS} = ""; |
172
|
|
|
|
|
|
|
} else { |
173
|
|
|
|
|
|
|
"warnings"->unimport("utf8"); |
174
|
|
|
|
|
|
|
} |
175
|
|
|
|
|
|
|
} |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
sub _fetch_sub { # fetch sub without autovivifying |
178
|
|
|
|
|
|
|
my($pack, $sub) = @_; |
179
|
|
|
|
|
|
|
$pack .= '::'; |
180
|
|
|
|
|
|
|
# only works with top-level packages |
181
|
|
|
|
|
|
|
return unless exists($::{$pack}); |
182
|
|
|
|
|
|
|
for ($::{$pack}) { |
183
|
|
|
|
|
|
|
return unless ref \$_ eq 'GLOB' && *$_{HASH} && exists $$_{$sub}; |
184
|
|
|
|
|
|
|
for ($$_{$sub}) { |
185
|
|
|
|
|
|
|
return ref \$_ eq 'GLOB' ? *$_{CODE} : undef |
186
|
|
|
|
|
|
|
} |
187
|
|
|
|
|
|
|
} |
188
|
|
|
|
|
|
|
} |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
# UTF8_REGEXP_PROBLEM is a compile-time constant indicating whether Carp |
191
|
|
|
|
|
|
|
# must avoid applying a regular expression to an upgraded (is_utf8) |
192
|
|
|
|
|
|
|
# string. There are multiple problems, on different Perl versions, |
193
|
|
|
|
|
|
|
# that require this to be avoided. All versions prior to 5.13.8 will |
194
|
|
|
|
|
|
|
# load utf8_heavy.pl for the swash system, even if the regexp doesn't |
195
|
|
|
|
|
|
|
# use character classes. Perl 5.6 and Perls [5.11.2, 5.13.11) exhibit |
196
|
|
|
|
|
|
|
# specific problems when Carp is being invoked in the aftermath of a |
197
|
|
|
|
|
|
|
# syntax error. |
198
|
|
|
|
|
|
|
BEGIN { |
199
|
|
|
|
|
|
|
if("$]" < 5.013011) { |
200
|
|
|
|
|
|
|
*UTF8_REGEXP_PROBLEM = sub () { 1 }; |
201
|
|
|
|
|
|
|
} else { |
202
|
|
|
|
|
|
|
*UTF8_REGEXP_PROBLEM = sub () { 0 }; |
203
|
|
|
|
|
|
|
} |
204
|
|
|
|
|
|
|
} |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
# is_utf8() is essentially the utf8::is_utf8() function, which indicates |
207
|
|
|
|
|
|
|
# whether a string is represented in the upgraded form (using UTF-8 |
208
|
|
|
|
|
|
|
# internally). As utf8::is_utf8() is only available from Perl 5.8 |
209
|
|
|
|
|
|
|
# onwards, extra effort is required here to make it work on Perl 5.6. |
210
|
|
|
|
|
|
|
BEGIN { |
211
|
|
|
|
|
|
|
if(defined(my $sub = _fetch_sub utf8 => 'is_utf8')) { |
212
|
|
|
|
|
|
|
*is_utf8 = $sub; |
213
|
|
|
|
|
|
|
} else { |
214
|
|
|
|
|
|
|
# black magic for perl 5.6 |
215
|
|
|
|
|
|
|
*is_utf8 = sub { unpack("C", "\xaa".$_[0]) != 170 }; |
216
|
|
|
|
|
|
|
} |
217
|
|
|
|
|
|
|
} |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
# The downgrade() function defined here is to be used for attempts to |
220
|
|
|
|
|
|
|
# downgrade where it is acceptable to fail. It must be called with a |
221
|
|
|
|
|
|
|
# second argument that is a true value. |
222
|
|
|
|
|
|
|
BEGIN { |
223
|
|
|
|
|
|
|
if(defined(my $sub = _fetch_sub utf8 => 'downgrade')) { |
224
|
|
|
|
|
|
|
*downgrade = \&{"utf8::downgrade"}; |
225
|
|
|
|
|
|
|
} else { |
226
|
|
|
|
|
|
|
*downgrade = sub { |
227
|
|
|
|
|
|
|
my $r = ""; |
228
|
|
|
|
|
|
|
my $l = length($_[0]); |
229
|
|
|
|
|
|
|
for(my $i = 0; $i != $l; $i++) { |
230
|
|
|
|
|
|
|
my $o = ord(substr($_[0], $i, 1)); |
231
|
|
|
|
|
|
|
return if $o > 255; |
232
|
|
|
|
|
|
|
$r .= chr($o); |
233
|
|
|
|
|
|
|
} |
234
|
|
|
|
|
|
|
$_[0] = $r; |
235
|
|
|
|
|
|
|
}; |
236
|
|
|
|
|
|
|
} |
237
|
|
|
|
|
|
|
} |
238
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
our $VERSION = '1.3301'; |
240
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
our $MaxEvalLen = 0; |
242
|
|
|
|
|
|
|
our $Verbose = 0; |
243
|
|
|
|
|
|
|
our $CarpLevel = 0; |
244
|
|
|
|
|
|
|
our $MaxArgLen = 64; # How much of each argument to print. 0 = all. |
245
|
|
|
|
|
|
|
our $MaxArgNums = 8; # How many arguments to print. 0 = all. |
246
|
|
|
|
|
|
|
our $RefArgFormatter = undef; # allow caller to format reference arguments |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
require Exporter; |
249
|
|
|
|
|
|
|
our @ISA = ('Exporter'); |
250
|
|
|
|
|
|
|
our @EXPORT = qw(confess croak carp); |
251
|
|
|
|
|
|
|
our @EXPORT_OK = qw(cluck verbose longmess shortmess); |
252
|
|
|
|
|
|
|
our @EXPORT_FAIL = qw(verbose); # hook to enable verbose mode |
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
# The members of %Internal are packages that are internal to perl. |
255
|
|
|
|
|
|
|
# Carp will not report errors from within these packages if it |
256
|
|
|
|
|
|
|
# can. The members of %CarpInternal are internal to Perl's warning |
257
|
|
|
|
|
|
|
# system. Carp will not report errors from within these packages |
258
|
|
|
|
|
|
|
# either, and will not report calls *to* these packages for carp and |
259
|
|
|
|
|
|
|
# croak. They replace $CarpLevel, which is deprecated. The |
260
|
|
|
|
|
|
|
# $Max(EvalLen|(Arg(Len|Nums)) variables are used to specify how the eval |
261
|
|
|
|
|
|
|
# text and function arguments should be formatted when printed. |
262
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
our %CarpInternal; |
264
|
|
|
|
|
|
|
our %Internal; |
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
# disable these by default, so they can live w/o require Carp |
267
|
|
|
|
|
|
|
$CarpInternal{Carp}++; |
268
|
|
|
|
|
|
|
$CarpInternal{warnings}++; |
269
|
|
|
|
|
|
|
$Internal{Exporter}++; |
270
|
|
|
|
|
|
|
$Internal{'Exporter::Heavy'}++; |
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
# if the caller specifies verbose usage ("perl -MCarp=verbose script.pl") |
273
|
|
|
|
|
|
|
# then the following method will be called by the Exporter which knows |
274
|
|
|
|
|
|
|
# to do this thanks to @EXPORT_FAIL, above. $_[1] will contain the word |
275
|
|
|
|
|
|
|
# 'verbose'. |
276
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
sub export_fail { shift; $Verbose = shift if $_[0] eq 'verbose'; @_ } |
278
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
sub _cgc { |
280
|
|
|
|
|
|
|
no strict 'refs'; |
281
|
|
|
|
|
|
|
return \&{"CORE::GLOBAL::caller"} if defined &{"CORE::GLOBAL::caller"}; |
282
|
|
|
|
|
|
|
return; |
283
|
|
|
|
|
|
|
} |
284
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
sub longmess { |
286
|
|
|
|
|
|
|
local($!, $^E); |
287
|
|
|
|
|
|
|
# Icky backwards compatibility wrapper. :-( |
288
|
|
|
|
|
|
|
# |
289
|
|
|
|
|
|
|
# The story is that the original implementation hard-coded the |
290
|
|
|
|
|
|
|
# number of call levels to go back, so calls to longmess were off |
291
|
|
|
|
|
|
|
# by one. Other code began calling longmess and expecting this |
292
|
|
|
|
|
|
|
# behaviour, so the replacement has to emulate that behaviour. |
293
|
|
|
|
|
|
|
my $cgc = _cgc(); |
294
|
|
|
|
|
|
|
my $call_pack = $cgc ? $cgc->() : caller(); |
295
|
|
|
|
|
|
|
if ( $Internal{$call_pack} or $CarpInternal{$call_pack} ) { |
296
|
|
|
|
|
|
|
return longmess_heavy(@_); |
297
|
|
|
|
|
|
|
} |
298
|
|
|
|
|
|
|
else { |
299
|
|
|
|
|
|
|
local $CarpLevel = $CarpLevel + 1; |
300
|
|
|
|
|
|
|
return longmess_heavy(@_); |
301
|
|
|
|
|
|
|
} |
302
|
|
|
|
|
|
|
} |
303
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
our @CARP_NOT; |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
sub shortmess { |
307
|
|
|
|
|
|
|
local($!, $^E); |
308
|
|
|
|
|
|
|
my $cgc = _cgc(); |
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
# Icky backwards compatibility wrapper. :-( |
311
|
|
|
|
|
|
|
local @CARP_NOT = $cgc ? $cgc->() : caller(); |
312
|
|
|
|
|
|
|
shortmess_heavy(@_); |
313
|
|
|
|
|
|
|
} |
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
sub croak { die shortmess @_ } |
316
|
|
|
|
|
|
|
sub confess { die longmess @_ } |
317
|
|
|
|
|
|
|
sub carp { warn shortmess @_ } |
318
|
|
|
|
|
|
|
sub cluck { warn longmess @_ } |
319
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
BEGIN { |
321
|
|
|
|
|
|
|
if("$]" >= 5.015002 || ("$]" >= 5.014002 && "$]" < 5.015) || |
322
|
|
|
|
|
|
|
("$]" >= 5.012005 && "$]" < 5.013)) { |
323
|
|
|
|
|
|
|
*CALLER_OVERRIDE_CHECK_OK = sub () { 1 }; |
324
|
|
|
|
|
|
|
} else { |
325
|
|
|
|
|
|
|
*CALLER_OVERRIDE_CHECK_OK = sub () { 0 }; |
326
|
|
|
|
|
|
|
} |
327
|
|
|
|
|
|
|
} |
328
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
sub caller_info { |
330
|
|
|
|
|
|
|
my $i = shift(@_) + 1; |
331
|
|
|
|
|
|
|
my %call_info; |
332
|
|
|
|
|
|
|
my $cgc = _cgc(); |
333
|
|
|
|
|
|
|
{ |
334
|
|
|
|
|
|
|
# Some things override caller() but forget to implement the |
335
|
|
|
|
|
|
|
# @DB::args part of it, which we need. We check for this by |
336
|
|
|
|
|
|
|
# pre-populating @DB::args with a sentinel which no-one else |
337
|
|
|
|
|
|
|
# has the address of, so that we can detect whether @DB::args |
338
|
|
|
|
|
|
|
# has been properly populated. However, on earlier versions |
339
|
|
|
|
|
|
|
# of perl this check tickles a bug in CORE::caller() which |
340
|
|
|
|
|
|
|
# leaks memory. So we only check on fixed perls. |
341
|
|
|
|
|
|
|
@DB::args = \$i if CALLER_OVERRIDE_CHECK_OK; |
342
|
|
|
|
|
|
|
package DB; |
343
|
|
|
|
|
|
|
@call_info{ |
344
|
|
|
|
|
|
|
qw(pack file line sub has_args wantarray evaltext is_require) } |
345
|
|
|
|
|
|
|
= $cgc ? $cgc->($i) : caller($i); |
346
|
|
|
|
|
|
|
} |
347
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
unless ( defined $call_info{file} ) { |
349
|
|
|
|
|
|
|
return (); |
350
|
|
|
|
|
|
|
} |
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
my $sub_name = Carp::get_subname( \%call_info ); |
353
|
|
|
|
|
|
|
if ( $call_info{has_args} ) { |
354
|
|
|
|
|
|
|
my @args; |
355
|
|
|
|
|
|
|
if (CALLER_OVERRIDE_CHECK_OK && @DB::args == 1 |
356
|
|
|
|
|
|
|
&& ref $DB::args[0] eq ref \$i |
357
|
|
|
|
|
|
|
&& $DB::args[0] == \$i ) { |
358
|
|
|
|
|
|
|
@DB::args = (); # Don't let anyone see the address of $i |
359
|
|
|
|
|
|
|
local $@; |
360
|
|
|
|
|
|
|
my $where = eval { |
361
|
|
|
|
|
|
|
my $func = $cgc or return ''; |
362
|
|
|
|
|
|
|
my $gv = |
363
|
|
|
|
|
|
|
(_fetch_sub B => 'svref_2object' or return '') |
364
|
|
|
|
|
|
|
->($func)->GV; |
365
|
|
|
|
|
|
|
my $package = $gv->STASH->NAME; |
366
|
|
|
|
|
|
|
my $subname = $gv->NAME; |
367
|
|
|
|
|
|
|
return unless defined $package && defined $subname; |
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
# returning CORE::GLOBAL::caller isn't useful for tracing the cause: |
370
|
|
|
|
|
|
|
return if $package eq 'CORE::GLOBAL' && $subname eq 'caller'; |
371
|
|
|
|
|
|
|
" in &${package}::$subname"; |
372
|
|
|
|
|
|
|
} || ''; |
373
|
|
|
|
|
|
|
@args |
374
|
|
|
|
|
|
|
= "** Incomplete caller override detected$where; \@DB::args were not set **"; |
375
|
|
|
|
|
|
|
} |
376
|
|
|
|
|
|
|
else { |
377
|
|
|
|
|
|
|
@args = @DB::args; |
378
|
|
|
|
|
|
|
my $overflow; |
379
|
|
|
|
|
|
|
if ( $MaxArgNums and @args > $MaxArgNums ) |
380
|
|
|
|
|
|
|
{ # More than we want to show? |
381
|
|
|
|
|
|
|
$#args = $MaxArgNums; |
382
|
|
|
|
|
|
|
$overflow = 1; |
383
|
|
|
|
|
|
|
} |
384
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
@args = map { Carp::format_arg($_) } @args; |
386
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
if ($overflow) { |
388
|
|
|
|
|
|
|
push @args, '...'; |
389
|
|
|
|
|
|
|
} |
390
|
|
|
|
|
|
|
} |
391
|
|
|
|
|
|
|
|
392
|
|
|
|
|
|
|
# Push the args onto the subroutine |
393
|
|
|
|
|
|
|
$sub_name .= '(' . join( ', ', @args ) . ')'; |
394
|
|
|
|
|
|
|
} |
395
|
|
|
|
|
|
|
$call_info{sub_name} = $sub_name; |
396
|
|
|
|
|
|
|
return wantarray() ? %call_info : \%call_info; |
397
|
|
|
|
|
|
|
} |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
# Transform an argument to a function into a string. |
400
|
|
|
|
|
|
|
our $in_recurse; |
401
|
|
|
|
|
|
|
sub format_arg { |
402
|
|
|
|
|
|
|
my $arg = shift; |
403
|
|
|
|
|
|
|
|
404
|
|
|
|
|
|
|
if ( ref($arg) ) { |
405
|
|
|
|
|
|
|
# legitimate, let's not leak it. |
406
|
|
|
|
|
|
|
if (!$in_recurse && |
407
|
|
|
|
|
|
|
do { |
408
|
|
|
|
|
|
|
local $@; |
409
|
|
|
|
|
|
|
local $in_recurse = 1; |
410
|
|
|
|
|
|
|
local $SIG{__DIE__} = sub{}; |
411
|
|
|
|
|
|
|
eval {$arg->can('CARP_TRACE') } |
412
|
|
|
|
|
|
|
}) |
413
|
|
|
|
|
|
|
{ |
414
|
|
|
|
|
|
|
return $arg->CARP_TRACE(); |
415
|
|
|
|
|
|
|
} |
416
|
|
|
|
|
|
|
elsif (!$in_recurse && |
417
|
|
|
|
|
|
|
defined($RefArgFormatter) && |
418
|
|
|
|
|
|
|
do { |
419
|
|
|
|
|
|
|
local $@; |
420
|
|
|
|
|
|
|
local $in_recurse = 1; |
421
|
|
|
|
|
|
|
local $SIG{__DIE__} = sub{}; |
422
|
|
|
|
|
|
|
eval {$arg = $RefArgFormatter->($arg); 1} |
423
|
|
|
|
|
|
|
}) |
424
|
|
|
|
|
|
|
{ |
425
|
|
|
|
|
|
|
return $arg; |
426
|
|
|
|
|
|
|
} |
427
|
|
|
|
|
|
|
else |
428
|
|
|
|
|
|
|
{ |
429
|
|
|
|
|
|
|
my $sub = _fetch_sub(overload => 'StrVal'); |
430
|
|
|
|
|
|
|
return $sub ? &$sub($arg) : "$arg"; |
431
|
|
|
|
|
|
|
} |
432
|
|
|
|
|
|
|
} |
433
|
|
|
|
|
|
|
return "undef" if !defined($arg); |
434
|
|
|
|
|
|
|
downgrade($arg, 1); |
435
|
|
|
|
|
|
|
return $arg if !(UTF8_REGEXP_PROBLEM && is_utf8($arg)) && |
436
|
|
|
|
|
|
|
$arg =~ /\A-?[0-9]+(?:\.[0-9]*)?(?:[eE][-+]?[0-9]+)?\z/; |
437
|
|
|
|
|
|
|
my $suffix = ""; |
438
|
|
|
|
|
|
|
if ( 2 < $MaxArgLen and $MaxArgLen < length($arg) ) { |
439
|
|
|
|
|
|
|
substr ( $arg, $MaxArgLen - 3 ) = ""; |
440
|
|
|
|
|
|
|
$suffix = "..."; |
441
|
|
|
|
|
|
|
} |
442
|
|
|
|
|
|
|
if(UTF8_REGEXP_PROBLEM && is_utf8($arg)) { |
443
|
|
|
|
|
|
|
for(my $i = length($arg); $i--; ) { |
444
|
|
|
|
|
|
|
my $c = substr($arg, $i, 1); |
445
|
|
|
|
|
|
|
my $x = substr($arg, 0, 0); # work around bug on Perl 5.8.{1,2} |
446
|
|
|
|
|
|
|
if($c eq "\"" || $c eq "\\" || $c eq "\$" || $c eq "\@") { |
447
|
|
|
|
|
|
|
substr $arg, $i, 0, "\\"; |
448
|
|
|
|
|
|
|
next; |
449
|
|
|
|
|
|
|
} |
450
|
|
|
|
|
|
|
my $o = ord($c); |
451
|
|
|
|
|
|
|
substr $arg, $i, 1, sprintf("\\x{%x}", $o) |
452
|
|
|
|
|
|
|
if $o < 0x20 || $o > 0x7f; |
453
|
|
|
|
|
|
|
} |
454
|
|
|
|
|
|
|
} else { |
455
|
|
|
|
|
|
|
$arg =~ s/([\"\\\$\@])/\\$1/g; |
456
|
|
|
|
|
|
|
$arg =~ s/([^ -~])/sprintf("\\x{%x}",ord($1))/eg; |
457
|
|
|
|
|
|
|
} |
458
|
|
|
|
|
|
|
downgrade($arg, 1); |
459
|
|
|
|
|
|
|
return "\"".$arg."\"".$suffix; |
460
|
|
|
|
|
|
|
} |
461
|
|
|
|
|
|
|
|
462
|
|
|
|
|
|
|
sub Regexp::CARP_TRACE { |
463
|
|
|
|
|
|
|
my $arg = "$_[0]"; |
464
|
|
|
|
|
|
|
downgrade($arg, 1); |
465
|
|
|
|
|
|
|
if(UTF8_REGEXP_PROBLEM && is_utf8($arg)) { |
466
|
|
|
|
|
|
|
for(my $i = length($arg); $i--; ) { |
467
|
|
|
|
|
|
|
my $o = ord(substr($arg, $i, 1)); |
468
|
|
|
|
|
|
|
my $x = substr($arg, 0, 0); # work around bug on Perl 5.8.{1,2} |
469
|
|
|
|
|
|
|
substr $arg, $i, 1, sprintf("\\x{%x}", $o) |
470
|
|
|
|
|
|
|
if $o < 0x20 || $o > 0x7f; |
471
|
|
|
|
|
|
|
} |
472
|
|
|
|
|
|
|
} else { |
473
|
|
|
|
|
|
|
$arg =~ s/([^ -~])/sprintf("\\x{%x}",ord($1))/eg; |
474
|
|
|
|
|
|
|
} |
475
|
|
|
|
|
|
|
downgrade($arg, 1); |
476
|
|
|
|
|
|
|
my $suffix = ""; |
477
|
|
|
|
|
|
|
if($arg =~ /\A\(\?\^?([a-z]*)(?:-[a-z]*)?:(.*)\)\z/s) { |
478
|
|
|
|
|
|
|
($suffix, $arg) = ($1, $2); |
479
|
|
|
|
|
|
|
} |
480
|
|
|
|
|
|
|
if ( 2 < $MaxArgLen and $MaxArgLen < length($arg) ) { |
481
|
|
|
|
|
|
|
substr ( $arg, $MaxArgLen - 3 ) = ""; |
482
|
|
|
|
|
|
|
$suffix = "...".$suffix; |
483
|
|
|
|
|
|
|
} |
484
|
|
|
|
|
|
|
return "qr($arg)$suffix"; |
485
|
|
|
|
|
|
|
} |
486
|
|
|
|
|
|
|
|
487
|
|
|
|
|
|
|
# Takes an inheritance cache and a package and returns |
488
|
|
|
|
|
|
|
# an anon hash of known inheritances and anon array of |
489
|
|
|
|
|
|
|
# inheritances which consequences have not been figured |
490
|
|
|
|
|
|
|
# for. |
491
|
|
|
|
|
|
|
sub get_status { |
492
|
|
|
|
|
|
|
my $cache = shift; |
493
|
|
|
|
|
|
|
my $pkg = shift; |
494
|
|
|
|
|
|
|
$cache->{$pkg} ||= [ { $pkg => $pkg }, [ trusts_directly($pkg) ] ]; |
495
|
|
|
|
|
|
|
return @{ $cache->{$pkg} }; |
496
|
|
|
|
|
|
|
} |
497
|
|
|
|
|
|
|
|
498
|
|
|
|
|
|
|
# Takes the info from caller() and figures out the name of |
499
|
|
|
|
|
|
|
# the sub/require/eval |
500
|
|
|
|
|
|
|
sub get_subname { |
501
|
|
|
|
|
|
|
my $info = shift; |
502
|
|
|
|
|
|
|
if ( defined( $info->{evaltext} ) ) { |
503
|
|
|
|
|
|
|
my $eval = $info->{evaltext}; |
504
|
|
|
|
|
|
|
if ( $info->{is_require} ) { |
505
|
|
|
|
|
|
|
return "require $eval"; |
506
|
|
|
|
|
|
|
} |
507
|
|
|
|
|
|
|
else { |
508
|
|
|
|
|
|
|
$eval =~ s/([\\\'])/\\$1/g; |
509
|
|
|
|
|
|
|
return "eval '" . str_len_trim( $eval, $MaxEvalLen ) . "'"; |
510
|
|
|
|
|
|
|
} |
511
|
|
|
|
|
|
|
} |
512
|
|
|
|
|
|
|
|
513
|
|
|
|
|
|
|
# this can happen on older perls when the sub (or the stash containing it) |
514
|
|
|
|
|
|
|
# has been deleted |
515
|
|
|
|
|
|
|
if ( !defined( $info->{sub} ) ) { |
516
|
|
|
|
|
|
|
return '__ANON__::__ANON__'; |
517
|
|
|
|
|
|
|
} |
518
|
|
|
|
|
|
|
|
519
|
|
|
|
|
|
|
return ( $info->{sub} eq '(eval)' ) ? 'eval {...}' : $info->{sub}; |
520
|
|
|
|
|
|
|
} |
521
|
|
|
|
|
|
|
|
522
|
|
|
|
|
|
|
# Figures out what call (from the point of view of the caller) |
523
|
|
|
|
|
|
|
# the long error backtrace should start at. |
524
|
|
|
|
|
|
|
sub long_error_loc { |
525
|
|
|
|
|
|
|
my $i; |
526
|
|
|
|
|
|
|
my $lvl = $CarpLevel; |
527
|
|
|
|
|
|
|
{ |
528
|
|
|
|
|
|
|
++$i; |
529
|
|
|
|
|
|
|
my $cgc = _cgc(); |
530
|
|
|
|
|
|
|
my @caller = $cgc ? $cgc->($i) : caller($i); |
531
|
|
|
|
|
|
|
my $pkg = $caller[0]; |
532
|
|
|
|
|
|
|
unless ( defined($pkg) ) { |
533
|
|
|
|
|
|
|
|
534
|
|
|
|
|
|
|
# This *shouldn't* happen. |
535
|
|
|
|
|
|
|
if (%Internal) { |
536
|
|
|
|
|
|
|
local %Internal; |
537
|
|
|
|
|
|
|
$i = long_error_loc(); |
538
|
|
|
|
|
|
|
last; |
539
|
|
|
|
|
|
|
} |
540
|
|
|
|
|
|
|
elsif (defined $caller[2]) { |
541
|
|
|
|
|
|
|
# this can happen when the stash has been deleted |
542
|
|
|
|
|
|
|
# in that case, just assume that it's a reasonable place to |
543
|
|
|
|
|
|
|
# stop (the file and line data will still be intact in any |
544
|
|
|
|
|
|
|
# case) - the only issue is that we can't detect if the |
545
|
|
|
|
|
|
|
# deleted package was internal (so don't do that then) |
546
|
|
|
|
|
|
|
# -doy |
547
|
|
|
|
|
|
|
redo unless 0 > --$lvl; |
548
|
|
|
|
|
|
|
last; |
549
|
|
|
|
|
|
|
} |
550
|
|
|
|
|
|
|
else { |
551
|
|
|
|
|
|
|
return 2; |
552
|
|
|
|
|
|
|
} |
553
|
|
|
|
|
|
|
} |
554
|
|
|
|
|
|
|
redo if $CarpInternal{$pkg}; |
555
|
|
|
|
|
|
|
redo unless 0 > --$lvl; |
556
|
|
|
|
|
|
|
redo if $Internal{$pkg}; |
557
|
|
|
|
|
|
|
} |
558
|
|
|
|
|
|
|
return $i - 1; |
559
|
|
|
|
|
|
|
} |
560
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
sub longmess_heavy { |
562
|
|
|
|
|
|
|
return @_ if ref( $_[0] ); # don't break references as exceptions |
563
|
|
|
|
|
|
|
my $i = long_error_loc(); |
564
|
|
|
|
|
|
|
return ret_backtrace( $i, @_ ); |
565
|
|
|
|
|
|
|
} |
566
|
|
|
|
|
|
|
|
567
|
|
|
|
|
|
|
# Returns a full stack backtrace starting from where it is |
568
|
|
|
|
|
|
|
# told. |
569
|
|
|
|
|
|
|
sub ret_backtrace { |
570
|
|
|
|
|
|
|
my ( $i, @error ) = @_; |
571
|
|
|
|
|
|
|
my $mess; |
572
|
|
|
|
|
|
|
my $err = join '', @error; |
573
|
|
|
|
|
|
|
$i++; |
574
|
|
|
|
|
|
|
|
575
|
|
|
|
|
|
|
my $tid_msg = ''; |
576
|
|
|
|
|
|
|
if ( defined &threads::tid ) { |
577
|
|
|
|
|
|
|
my $tid = threads->tid; |
578
|
|
|
|
|
|
|
$tid_msg = " thread $tid" if $tid; |
579
|
|
|
|
|
|
|
} |
580
|
|
|
|
|
|
|
|
581
|
|
|
|
|
|
|
my %i = caller_info($i); |
582
|
|
|
|
|
|
|
$mess = "$err at $i{file} line $i{line}$tid_msg"; |
583
|
|
|
|
|
|
|
if( defined $. ) { |
584
|
|
|
|
|
|
|
local $@ = ''; |
585
|
|
|
|
|
|
|
local $SIG{__DIE__}; |
586
|
|
|
|
|
|
|
eval { |
587
|
|
|
|
|
|
|
CORE::die; |
588
|
|
|
|
|
|
|
}; |
589
|
|
|
|
|
|
|
if($@ =~ /^Died at .*(, <.*?> line \d+).$/ ) { |
590
|
|
|
|
|
|
|
$mess .= $1; |
591
|
|
|
|
|
|
|
} |
592
|
|
|
|
|
|
|
} |
593
|
|
|
|
|
|
|
$mess .= "\.\n"; |
594
|
|
|
|
|
|
|
|
595
|
|
|
|
|
|
|
while ( my %i = caller_info( ++$i ) ) { |
596
|
|
|
|
|
|
|
$mess .= "\t$i{sub_name} called at $i{file} line $i{line}$tid_msg\n"; |
597
|
|
|
|
|
|
|
} |
598
|
|
|
|
|
|
|
|
599
|
|
|
|
|
|
|
return $mess; |
600
|
|
|
|
|
|
|
} |
601
|
|
|
|
|
|
|
|
602
|
|
|
|
|
|
|
sub ret_summary { |
603
|
|
|
|
|
|
|
my ( $i, @error ) = @_; |
604
|
|
|
|
|
|
|
my $err = join '', @error; |
605
|
|
|
|
|
|
|
$i++; |
606
|
|
|
|
|
|
|
|
607
|
|
|
|
|
|
|
my $tid_msg = ''; |
608
|
|
|
|
|
|
|
if ( defined &threads::tid ) { |
609
|
|
|
|
|
|
|
my $tid = threads->tid; |
610
|
|
|
|
|
|
|
$tid_msg = " thread $tid" if $tid; |
611
|
|
|
|
|
|
|
} |
612
|
|
|
|
|
|
|
|
613
|
|
|
|
|
|
|
my %i = caller_info($i); |
614
|
|
|
|
|
|
|
return "$err at $i{file} line $i{line}$tid_msg\.\n"; |
615
|
|
|
|
|
|
|
} |
616
|
|
|
|
|
|
|
|
617
|
|
|
|
|
|
|
sub short_error_loc { |
618
|
|
|
|
|
|
|
# You have to create your (hash)ref out here, rather than defaulting it |
619
|
|
|
|
|
|
|
# inside trusts *on a lexical*, as you want it to persist across calls. |
620
|
|
|
|
|
|
|
# (You can default it on $_[2], but that gets messy) |
621
|
|
|
|
|
|
|
my $cache = {}; |
622
|
|
|
|
|
|
|
my $i = 1; |
623
|
|
|
|
|
|
|
my $lvl = $CarpLevel; |
624
|
|
|
|
|
|
|
{ |
625
|
|
|
|
|
|
|
my $cgc = _cgc(); |
626
|
|
|
|
|
|
|
my $called = $cgc ? $cgc->($i) : caller($i); |
627
|
|
|
|
|
|
|
$i++; |
628
|
|
|
|
|
|
|
my $caller = $cgc ? $cgc->($i) : caller($i); |
629
|
|
|
|
|
|
|
|
630
|
|
|
|
|
|
|
if (!defined($caller)) { |
631
|
|
|
|
|
|
|
my @caller = $cgc ? $cgc->($i) : caller($i); |
632
|
|
|
|
|
|
|
if (@caller) { |
633
|
|
|
|
|
|
|
# if there's no package but there is other caller info, then |
634
|
|
|
|
|
|
|
# the package has been deleted - treat this as a valid package |
635
|
|
|
|
|
|
|
# in this case |
636
|
|
|
|
|
|
|
redo if defined($called) && $CarpInternal{$called}; |
637
|
|
|
|
|
|
|
redo unless 0 > --$lvl; |
638
|
|
|
|
|
|
|
last; |
639
|
|
|
|
|
|
|
} |
640
|
|
|
|
|
|
|
else { |
641
|
|
|
|
|
|
|
return 0; |
642
|
|
|
|
|
|
|
} |
643
|
|
|
|
|
|
|
} |
644
|
|
|
|
|
|
|
redo if $Internal{$caller}; |
645
|
|
|
|
|
|
|
redo if $CarpInternal{$caller}; |
646
|
|
|
|
|
|
|
redo if $CarpInternal{$called}; |
647
|
|
|
|
|
|
|
redo if trusts( $called, $caller, $cache ); |
648
|
|
|
|
|
|
|
redo if trusts( $caller, $called, $cache ); |
649
|
|
|
|
|
|
|
redo unless 0 > --$lvl; |
650
|
|
|
|
|
|
|
} |
651
|
|
|
|
|
|
|
return $i - 1; |
652
|
|
|
|
|
|
|
} |
653
|
|
|
|
|
|
|
|
654
|
|
|
|
|
|
|
sub shortmess_heavy { |
655
|
|
|
|
|
|
|
return longmess_heavy(@_) if $Verbose; |
656
|
|
|
|
|
|
|
return @_ if ref( $_[0] ); # don't break references as exceptions |
657
|
|
|
|
|
|
|
my $i = short_error_loc(); |
658
|
|
|
|
|
|
|
if ($i) { |
659
|
|
|
|
|
|
|
ret_summary( $i, @_ ); |
660
|
|
|
|
|
|
|
} |
661
|
|
|
|
|
|
|
else { |
662
|
|
|
|
|
|
|
longmess_heavy(@_); |
663
|
|
|
|
|
|
|
} |
664
|
|
|
|
|
|
|
} |
665
|
|
|
|
|
|
|
|
666
|
|
|
|
|
|
|
# If a string is too long, trims it with ... |
667
|
|
|
|
|
|
|
sub str_len_trim { |
668
|
|
|
|
|
|
|
my $str = shift; |
669
|
|
|
|
|
|
|
my $max = shift || 0; |
670
|
|
|
|
|
|
|
if ( 2 < $max and $max < length($str) ) { |
671
|
|
|
|
|
|
|
substr( $str, $max - 3 ) = '...'; |
672
|
|
|
|
|
|
|
} |
673
|
|
|
|
|
|
|
return $str; |
674
|
|
|
|
|
|
|
} |
675
|
|
|
|
|
|
|
|
676
|
|
|
|
|
|
|
# Takes two packages and an optional cache. Says whether the |
677
|
|
|
|
|
|
|
# first inherits from the second. |
678
|
|
|
|
|
|
|
# |
679
|
|
|
|
|
|
|
# Recursive versions of this have to work to avoid certain |
680
|
|
|
|
|
|
|
# possible endless loops, and when following long chains of |
681
|
|
|
|
|
|
|
# inheritance are less efficient. |
682
|
|
|
|
|
|
|
sub trusts { |
683
|
|
|
|
|
|
|
my $child = shift; |
684
|
|
|
|
|
|
|
my $parent = shift; |
685
|
|
|
|
|
|
|
my $cache = shift; |
686
|
|
|
|
|
|
|
my ( $known, $partial ) = get_status( $cache, $child ); |
687
|
|
|
|
|
|
|
|
688
|
|
|
|
|
|
|
# Figure out consequences until we have an answer |
689
|
|
|
|
|
|
|
while ( @$partial and not exists $known->{$parent} ) { |
690
|
|
|
|
|
|
|
my $anc = shift @$partial; |
691
|
|
|
|
|
|
|
next if exists $known->{$anc}; |
692
|
|
|
|
|
|
|
$known->{$anc}++; |
693
|
|
|
|
|
|
|
my ( $anc_knows, $anc_partial ) = get_status( $cache, $anc ); |
694
|
|
|
|
|
|
|
my @found = keys %$anc_knows; |
695
|
|
|
|
|
|
|
@$known{@found} = (); |
696
|
|
|
|
|
|
|
push @$partial, @$anc_partial; |
697
|
|
|
|
|
|
|
} |
698
|
|
|
|
|
|
|
return exists $known->{$parent}; |
699
|
|
|
|
|
|
|
} |
700
|
|
|
|
|
|
|
|
701
|
|
|
|
|
|
|
# Takes a package and gives a list of those trusted directly |
702
|
|
|
|
|
|
|
sub trusts_directly { |
703
|
|
|
|
|
|
|
my $class = shift; |
704
|
|
|
|
|
|
|
no strict 'refs'; |
705
|
|
|
|
|
|
|
my $stash = \%{"$class\::"}; |
706
|
|
|
|
|
|
|
for my $var (qw/ CARP_NOT ISA /) { |
707
|
|
|
|
|
|
|
# Don't try using the variable until we know it exists, |
708
|
|
|
|
|
|
|
# to avoid polluting the caller's namespace. |
709
|
|
|
|
|
|
|
if ( $stash->{$var} && *{$stash->{$var}}{ARRAY} && @{$stash->{$var}} ) { |
710
|
|
|
|
|
|
|
return @{$stash->{$var}} |
711
|
|
|
|
|
|
|
} |
712
|
|
|
|
|
|
|
} |
713
|
|
|
|
|
|
|
return; |
714
|
|
|
|
|
|
|
} |
715
|
|
|
|
|
|
|
|
716
|
|
|
|
|
|
|
if(!defined($warnings::VERSION) || |
717
|
|
|
|
|
|
|
do { no warnings "numeric"; $warnings::VERSION < 1.03 }) { |
718
|
|
|
|
|
|
|
# Very old versions of warnings.pm import from Carp. This can go |
719
|
|
|
|
|
|
|
# wrong due to the circular dependency. If Carp is invoked before |
720
|
|
|
|
|
|
|
# warnings, then Carp starts by loading warnings, then warnings |
721
|
|
|
|
|
|
|
# tries to import from Carp, and gets nothing because Carp is in |
722
|
|
|
|
|
|
|
# the process of loading and hasn't defined its import method yet. |
723
|
|
|
|
|
|
|
# So we work around that by manually exporting to warnings here. |
724
|
|
|
|
|
|
|
no strict "refs"; |
725
|
|
|
|
|
|
|
*{"warnings::$_"} = \&$_ foreach @EXPORT; |
726
|
|
|
|
|
|
|
} |
727
|
|
|
|
|
|
|
|
728
|
|
|
|
|
|
|
1; |
729
|
|
|
|
|
|
|
|
730
|
|
|
|
|
|
|
__END__ |
731
|
|
|
|
|
|
|
|
732
|
|
|
|
|
|
|
=head1 NAME |
733
|
|
|
|
|
|
|
|
734
|
|
|
|
|
|
|
Carp - alternative warn and die for modules |
735
|
|
|
|
|
|
|
|
736
|
|
|
|
|
|
|
=head1 SYNOPSIS |
737
|
|
|
|
|
|
|
|
738
|
|
|
|
|
|
|
use Carp; |
739
|
|
|
|
|
|
|
|
740
|
|
|
|
|
|
|
# warn user (from perspective of caller) |
741
|
|
|
|
|
|
|
carp "string trimmed to 80 chars"; |
742
|
|
|
|
|
|
|
|
743
|
|
|
|
|
|
|
# die of errors (from perspective of caller) |
744
|
|
|
|
|
|
|
croak "We're outta here!"; |
745
|
|
|
|
|
|
|
|
746
|
|
|
|
|
|
|
# die of errors with stack backtrace |
747
|
|
|
|
|
|
|
confess "not implemented"; |
748
|
|
|
|
|
|
|
|
749
|
|
|
|
|
|
|
# cluck, longmess and shortmess not exported by default |
750
|
|
|
|
|
|
|
use Carp qw(cluck longmess shortmess); |
751
|
|
|
|
|
|
|
cluck "This is how we got here!"; |
752
|
|
|
|
|
|
|
$long_message = longmess( "message from cluck() or confess()" ); |
753
|
|
|
|
|
|
|
$short_message = shortmess( "message from carp() or croak()" ); |
754
|
|
|
|
|
|
|
|
755
|
|
|
|
|
|
|
=head1 DESCRIPTION |
756
|
|
|
|
|
|
|
|
757
|
|
|
|
|
|
|
The Carp routines are useful in your own modules because |
758
|
|
|
|
|
|
|
they act like C<die()> or C<warn()>, but with a message which is more |
759
|
|
|
|
|
|
|
likely to be useful to a user of your module. In the case of |
760
|
|
|
|
|
|
|
C<cluck()> and C<confess()>, that context is a summary of every |
761
|
|
|
|
|
|
|
call in the call-stack; C<longmess()> returns the contents of the error |
762
|
|
|
|
|
|
|
message. |
763
|
|
|
|
|
|
|
|
764
|
|
|
|
|
|
|
For a shorter message you can use C<carp()> or C<croak()> which report the |
765
|
|
|
|
|
|
|
error as being from where your module was called. C<shortmess()> returns the |
766
|
|
|
|
|
|
|
contents of this error message. There is no guarantee that that is where the |
767
|
|
|
|
|
|
|
error was, but it is a good educated guess. |
768
|
|
|
|
|
|
|
|
769
|
|
|
|
|
|
|
C<Carp> takes care not to clobber the status variables C<$!> and C<$^E> |
770
|
|
|
|
|
|
|
in the course of assembling its error messages. This means that a |
771
|
|
|
|
|
|
|
C<$SIG{__DIE__}> or C<$SIG{__WARN__}> handler can capture the error |
772
|
|
|
|
|
|
|
information held in those variables, if it is required to augment the |
773
|
|
|
|
|
|
|
error message, and if the code calling C<Carp> left useful values there. |
774
|
|
|
|
|
|
|
Of course, C<Carp> can't guarantee the latter. |
775
|
|
|
|
|
|
|
|
776
|
|
|
|
|
|
|
You can also alter the way the output and logic of C<Carp> works, by |
777
|
|
|
|
|
|
|
changing some global variables in the C<Carp> namespace. See the |
778
|
|
|
|
|
|
|
section on C<GLOBAL VARIABLES> below. |
779
|
|
|
|
|
|
|
|
780
|
|
|
|
|
|
|
Here is a more complete description of how C<carp> and C<croak> work. |
781
|
|
|
|
|
|
|
What they do is search the call-stack for a function call stack where |
782
|
|
|
|
|
|
|
they have not been told that there shouldn't be an error. If every |
783
|
|
|
|
|
|
|
call is marked safe, they give up and give a full stack backtrace |
784
|
|
|
|
|
|
|
instead. In other words they presume that the first likely looking |
785
|
|
|
|
|
|
|
potential suspect is guilty. Their rules for telling whether |
786
|
|
|
|
|
|
|
a call shouldn't generate errors work as follows: |
787
|
|
|
|
|
|
|
|
788
|
|
|
|
|
|
|
=over 4 |
789
|
|
|
|
|
|
|
|
790
|
|
|
|
|
|
|
=item 1. |
791
|
|
|
|
|
|
|
|
792
|
|
|
|
|
|
|
Any call from a package to itself is safe. |
793
|
|
|
|
|
|
|
|
794
|
|
|
|
|
|
|
=item 2. |
795
|
|
|
|
|
|
|
|
796
|
|
|
|
|
|
|
Packages claim that there won't be errors on calls to or from |
797
|
|
|
|
|
|
|
packages explicitly marked as safe by inclusion in C<@CARP_NOT>, or |
798
|
|
|
|
|
|
|
(if that array is empty) C<@ISA>. The ability to override what |
799
|
|
|
|
|
|
|
@ISA says is new in 5.8. |
800
|
|
|
|
|
|
|
|
801
|
|
|
|
|
|
|
=item 3. |
802
|
|
|
|
|
|
|
|
803
|
|
|
|
|
|
|
The trust in item 2 is transitive. If A trusts B, and B |
804
|
|
|
|
|
|
|
trusts C, then A trusts C. So if you do not override C<@ISA> |
805
|
|
|
|
|
|
|
with C<@CARP_NOT>, then this trust relationship is identical to, |
806
|
|
|
|
|
|
|
"inherits from". |
807
|
|
|
|
|
|
|
|
808
|
|
|
|
|
|
|
=item 4. |
809
|
|
|
|
|
|
|
|
810
|
|
|
|
|
|
|
Any call from an internal Perl module is safe. (Nothing keeps |
811
|
|
|
|
|
|
|
user modules from marking themselves as internal to Perl, but |
812
|
|
|
|
|
|
|
this practice is discouraged.) |
813
|
|
|
|
|
|
|
|
814
|
|
|
|
|
|
|
=item 5. |
815
|
|
|
|
|
|
|
|
816
|
|
|
|
|
|
|
Any call to Perl's warning system (eg Carp itself) is safe. |
817
|
|
|
|
|
|
|
(This rule is what keeps it from reporting the error at the |
818
|
|
|
|
|
|
|
point where you call C<carp> or C<croak>.) |
819
|
|
|
|
|
|
|
|
820
|
|
|
|
|
|
|
=item 6. |
821
|
|
|
|
|
|
|
|
822
|
|
|
|
|
|
|
C<$Carp::CarpLevel> can be set to skip a fixed number of additional |
823
|
|
|
|
|
|
|
call levels. Using this is not recommended because it is very |
824
|
|
|
|
|
|
|
difficult to get it to behave correctly. |
825
|
|
|
|
|
|
|
|
826
|
|
|
|
|
|
|
=back |
827
|
|
|
|
|
|
|
|
828
|
|
|
|
|
|
|
=head2 Forcing a Stack Trace |
829
|
|
|
|
|
|
|
|
830
|
|
|
|
|
|
|
As a debugging aid, you can force Carp to treat a croak as a confess |
831
|
|
|
|
|
|
|
and a carp as a cluck across I<all> modules. In other words, force a |
832
|
|
|
|
|
|
|
detailed stack trace to be given. This can be very helpful when trying |
833
|
|
|
|
|
|
|
to understand why, or from where, a warning or error is being generated. |
834
|
|
|
|
|
|
|
|
835
|
|
|
|
|
|
|
This feature is enabled by 'importing' the non-existent symbol |
836
|
|
|
|
|
|
|
'verbose'. You would typically enable it by saying |
837
|
|
|
|
|
|
|
|
838
|
|
|
|
|
|
|
perl -MCarp=verbose script.pl |
839
|
|
|
|
|
|
|
|
840
|
|
|
|
|
|
|
or by including the string C<-MCarp=verbose> in the PERL5OPT |
841
|
|
|
|
|
|
|
environment variable. |
842
|
|
|
|
|
|
|
|
843
|
|
|
|
|
|
|
Alternately, you can set the global variable C<$Carp::Verbose> to true. |
844
|
|
|
|
|
|
|
See the C<GLOBAL VARIABLES> section below. |
845
|
|
|
|
|
|
|
|
846
|
|
|
|
|
|
|
=head2 Stack Trace formatting |
847
|
|
|
|
|
|
|
|
848
|
|
|
|
|
|
|
At each stack level, the subroutine's name is displayed along with |
849
|
|
|
|
|
|
|
its parameters. For simple scalars, this is sufficient. For complex |
850
|
|
|
|
|
|
|
data types, such as objects and other references, this can simply |
851
|
|
|
|
|
|
|
display C<'HASH(0x1ab36d8)'>. |
852
|
|
|
|
|
|
|
|
853
|
|
|
|
|
|
|
Carp gives two ways to control this. |
854
|
|
|
|
|
|
|
|
855
|
|
|
|
|
|
|
=over 4 |
856
|
|
|
|
|
|
|
|
857
|
|
|
|
|
|
|
=item 1. |
858
|
|
|
|
|
|
|
|
859
|
|
|
|
|
|
|
For objects, a method, C<CARP_TRACE>, will be called, if it exists. If |
860
|
|
|
|
|
|
|
this method doesn't exist, or it recurses into C<Carp>, or it otherwise |
861
|
|
|
|
|
|
|
throws an exception, this is skipped, and Carp moves on to the next option, |
862
|
|
|
|
|
|
|
otherwise checking stops and the string returned is used. It is recommended |
863
|
|
|
|
|
|
|
that the object's type is part of the string to make debugging easier. |
864
|
|
|
|
|
|
|
|
865
|
|
|
|
|
|
|
=item 2. |
866
|
|
|
|
|
|
|
|
867
|
|
|
|
|
|
|
For any type of reference, C<$Carp::RefArgFormatter> is checked (see below). |
868
|
|
|
|
|
|
|
This variable is expected to be a code reference, and the current parameter |
869
|
|
|
|
|
|
|
is passed in. If this function doesn't exist (the variable is undef), or |
870
|
|
|
|
|
|
|
it recurses into C<Carp>, or it otherwise throws an exception, this is |
871
|
|
|
|
|
|
|
skipped, and Carp moves on to the next option, otherwise checking stops |
872
|
|
|
|
|
|
|
and the string returned is used. |
873
|
|
|
|
|
|
|
|
874
|
|
|
|
|
|
|
=item 3. |
875
|
|
|
|
|
|
|
|
876
|
|
|
|
|
|
|
Otherwise, if neither C<CARP_TRACE> nor C<$Carp::RefArgFormatter> is |
877
|
|
|
|
|
|
|
available, stringify the value ignoring any overloading. |
878
|
|
|
|
|
|
|
|
879
|
|
|
|
|
|
|
=back |
880
|
|
|
|
|
|
|
|
881
|
|
|
|
|
|
|
=head1 GLOBAL VARIABLES |
882
|
|
|
|
|
|
|
|
883
|
|
|
|
|
|
|
=head2 $Carp::MaxEvalLen |
884
|
|
|
|
|
|
|
|
885
|
|
|
|
|
|
|
This variable determines how many characters of a string-eval are to |
886
|
|
|
|
|
|
|
be shown in the output. Use a value of C<0> to show all text. |
887
|
|
|
|
|
|
|
|
888
|
|
|
|
|
|
|
Defaults to C<0>. |
889
|
|
|
|
|
|
|
|
890
|
|
|
|
|
|
|
=head2 $Carp::MaxArgLen |
891
|
|
|
|
|
|
|
|
892
|
|
|
|
|
|
|
This variable determines how many characters of each argument to a |
893
|
|
|
|
|
|
|
function to print. Use a value of C<0> to show the full length of the |
894
|
|
|
|
|
|
|
argument. |
895
|
|
|
|
|
|
|
|
896
|
|
|
|
|
|
|
Defaults to C<64>. |
897
|
|
|
|
|
|
|
|
898
|
|
|
|
|
|
|
=head2 $Carp::MaxArgNums |
899
|
|
|
|
|
|
|
|
900
|
|
|
|
|
|
|
This variable determines how many arguments to each function to show. |
901
|
|
|
|
|
|
|
Use a value of C<0> to show all arguments to a function call. |
902
|
|
|
|
|
|
|
|
903
|
|
|
|
|
|
|
Defaults to C<8>. |
904
|
|
|
|
|
|
|
|
905
|
|
|
|
|
|
|
=head2 $Carp::Verbose |
906
|
|
|
|
|
|
|
|
907
|
|
|
|
|
|
|
This variable makes C<carp()> and C<croak()> generate stack backtraces |
908
|
|
|
|
|
|
|
just like C<cluck()> and C<confess()>. This is how C<use Carp 'verbose'> |
909
|
|
|
|
|
|
|
is implemented internally. |
910
|
|
|
|
|
|
|
|
911
|
|
|
|
|
|
|
Defaults to C<0>. |
912
|
|
|
|
|
|
|
|
913
|
|
|
|
|
|
|
=head2 $Carp::RefArgFormatter |
914
|
|
|
|
|
|
|
|
915
|
|
|
|
|
|
|
This variable sets a general argument formatter to display references. |
916
|
|
|
|
|
|
|
Plain scalars and objects that implement C<CARP_TRACE> will not go through |
917
|
|
|
|
|
|
|
this formatter. Calling C<Carp> from within this function is not supported. |
918
|
|
|
|
|
|
|
|
919
|
|
|
|
|
|
|
local $Carp::RefArgFormatter = sub { |
920
|
|
|
|
|
|
|
require Data::Dumper; |
921
|
|
|
|
|
|
|
Data::Dumper::Dump($_[0]); # not necessarily safe |
922
|
|
|
|
|
|
|
}; |
923
|
|
|
|
|
|
|
|
924
|
|
|
|
|
|
|
=head2 @CARP_NOT |
925
|
|
|
|
|
|
|
|
926
|
|
|
|
|
|
|
This variable, I<in your package>, says which packages are I<not> to be |
927
|
|
|
|
|
|
|
considered as the location of an error. The C<carp()> and C<cluck()> |
928
|
|
|
|
|
|
|
functions will skip over callers when reporting where an error occurred. |
929
|
|
|
|
|
|
|
|
930
|
|
|
|
|
|
|
NB: This variable must be in the package's symbol table, thus: |
931
|
|
|
|
|
|
|
|
932
|
|
|
|
|
|
|
# These work |
933
|
|
|
|
|
|
|
our @CARP_NOT; # file scope |
934
|
|
|
|
|
|
|
use vars qw(@CARP_NOT); # package scope |
935
|
|
|
|
|
|
|
@My::Package::CARP_NOT = ... ; # explicit package variable |
936
|
|
|
|
|
|
|
|
937
|
|
|
|
|
|
|
# These don't work |
938
|
|
|
|
|
|
|
sub xyz { ... @CARP_NOT = ... } # w/o declarations above |
939
|
|
|
|
|
|
|
my @CARP_NOT; # even at top-level |
940
|
|
|
|
|
|
|
|
941
|
|
|
|
|
|
|
Example of use: |
942
|
|
|
|
|
|
|
|
943
|
|
|
|
|
|
|
package My::Carping::Package; |
944
|
|
|
|
|
|
|
use Carp; |
945
|
|
|
|
|
|
|
our @CARP_NOT; |
946
|
|
|
|
|
|
|
sub bar { .... or _error('Wrong input') } |
947
|
|
|
|
|
|
|
sub _error { |
948
|
|
|
|
|
|
|
# temporary control of where'ness, __PACKAGE__ is implicit |
949
|
|
|
|
|
|
|
local @CARP_NOT = qw(My::Friendly::Caller); |
950
|
|
|
|
|
|
|
carp(@_) |
951
|
|
|
|
|
|
|
} |
952
|
|
|
|
|
|
|
|
953
|
|
|
|
|
|
|
This would make C<Carp> report the error as coming from a caller not |
954
|
|
|
|
|
|
|
in C<My::Carping::Package>, nor from C<My::Friendly::Caller>. |
955
|
|
|
|
|
|
|
|
956
|
|
|
|
|
|
|
Also read the L</DESCRIPTION> section above, about how C<Carp> decides |
957
|
|
|
|
|
|
|
where the error is reported from. |
958
|
|
|
|
|
|
|
|
959
|
|
|
|
|
|
|
Use C<@CARP_NOT>, instead of C<$Carp::CarpLevel>. |
960
|
|
|
|
|
|
|
|
961
|
|
|
|
|
|
|
Overrides C<Carp>'s use of C<@ISA>. |
962
|
|
|
|
|
|
|
|
963
|
|
|
|
|
|
|
=head2 %Carp::Internal |
964
|
|
|
|
|
|
|
|
965
|
|
|
|
|
|
|
This says what packages are internal to Perl. C<Carp> will never |
966
|
|
|
|
|
|
|
report an error as being from a line in a package that is internal to |
967
|
|
|
|
|
|
|
Perl. For example: |
968
|
|
|
|
|
|
|
|
969
|
|
|
|
|
|
|
$Carp::Internal{ (__PACKAGE__) }++; |
970
|
|
|
|
|
|
|
# time passes... |
971
|
|
|
|
|
|
|
sub foo { ... or confess("whatever") }; |
972
|
|
|
|
|
|
|
|
973
|
|
|
|
|
|
|
would give a full stack backtrace starting from the first caller |
974
|
|
|
|
|
|
|
outside of __PACKAGE__. (Unless that package was also internal to |
975
|
|
|
|
|
|
|
Perl.) |
976
|
|
|
|
|
|
|
|
977
|
|
|
|
|
|
|
=head2 %Carp::CarpInternal |
978
|
|
|
|
|
|
|
|
979
|
|
|
|
|
|
|
This says which packages are internal to Perl's warning system. For |
980
|
|
|
|
|
|
|
generating a full stack backtrace this is the same as being internal |
981
|
|
|
|
|
|
|
to Perl, the stack backtrace will not start inside packages that are |
982
|
|
|
|
|
|
|
listed in C<%Carp::CarpInternal>. But it is slightly different for |
983
|
|
|
|
|
|
|
the summary message generated by C<carp> or C<croak>. There errors |
984
|
|
|
|
|
|
|
will not be reported on any lines that are calling packages in |
985
|
|
|
|
|
|
|
C<%Carp::CarpInternal>. |
986
|
|
|
|
|
|
|
|
987
|
|
|
|
|
|
|
For example C<Carp> itself is listed in C<%Carp::CarpInternal>. |
988
|
|
|
|
|
|
|
Therefore the full stack backtrace from C<confess> will not start |
989
|
|
|
|
|
|
|
inside of C<Carp>, and the short message from calling C<croak> is |
990
|
|
|
|
|
|
|
not placed on the line where C<croak> was called. |
991
|
|
|
|
|
|
|
|
992
|
|
|
|
|
|
|
=head2 $Carp::CarpLevel |
993
|
|
|
|
|
|
|
|
994
|
|
|
|
|
|
|
This variable determines how many additional call frames are to be |
995
|
|
|
|
|
|
|
skipped that would not otherwise be when reporting where an error |
996
|
|
|
|
|
|
|
occurred on a call to one of C<Carp>'s functions. It is fairly easy |
997
|
|
|
|
|
|
|
to count these call frames on calls that generate a full stack |
998
|
|
|
|
|
|
|
backtrace. However it is much harder to do this accounting for calls |
999
|
|
|
|
|
|
|
that generate a short message. Usually people skip too many call |
1000
|
|
|
|
|
|
|
frames. If they are lucky they skip enough that C<Carp> goes all of |
1001
|
|
|
|
|
|
|
the way through the call stack, realizes that something is wrong, and |
1002
|
|
|
|
|
|
|
then generates a full stack backtrace. If they are unlucky then the |
1003
|
|
|
|
|
|
|
error is reported from somewhere misleading very high in the call |
1004
|
|
|
|
|
|
|
stack. |
1005
|
|
|
|
|
|
|
|
1006
|
|
|
|
|
|
|
Therefore it is best to avoid C<$Carp::CarpLevel>. Instead use |
1007
|
|
|
|
|
|
|
C<@CARP_NOT>, C<%Carp::Internal> and C<%Carp::CarpInternal>. |
1008
|
|
|
|
|
|
|
|
1009
|
|
|
|
|
|
|
Defaults to C<0>. |
1010
|
|
|
|
|
|
|
|
1011
|
|
|
|
|
|
|
=head1 BUGS |
1012
|
|
|
|
|
|
|
|
1013
|
|
|
|
|
|
|
The Carp routines don't handle exception objects currently. |
1014
|
|
|
|
|
|
|
If called with a first argument that is a reference, they simply |
1015
|
|
|
|
|
|
|
call die() or warn(), as appropriate. |
1016
|
|
|
|
|
|
|
|
1017
|
|
|
|
|
|
|
Some of the Carp code assumes that Perl's basic character encoding is |
1018
|
|
|
|
|
|
|
ASCII, and will go wrong on an EBCDIC platform. |
1019
|
|
|
|
|
|
|
|
1020
|
|
|
|
|
|
|
=head1 SEE ALSO |
1021
|
|
|
|
|
|
|
|
1022
|
|
|
|
|
|
|
L<Carp::Always>, |
1023
|
|
|
|
|
|
|
L<Carp::Clan> |
1024
|
|
|
|
|
|
|
|
1025
|
|
|
|
|
|
|
=head1 AUTHOR |
1026
|
|
|
|
|
|
|
|
1027
|
|
|
|
|
|
|
The Carp module first appeared in Larry Wall's perl 5.000 distribution. |
1028
|
|
|
|
|
|
|
Since then it has been modified by several of the perl 5 porters. |
1029
|
|
|
|
|
|
|
Andrew Main (Zefram) <zefram@fysh.org> divested Carp into an independent |
1030
|
|
|
|
|
|
|
distribution. |
1031
|
|
|
|
|
|
|
|
1032
|
|
|
|
|
|
|
=head1 COPYRIGHT |
1033
|
|
|
|
|
|
|
|
1034
|
|
|
|
|
|
|
Copyright (C) 1994-2013 Larry Wall |
1035
|
|
|
|
|
|
|
|
1036
|
|
|
|
|
|
|
Copyright (C) 2011, 2012, 2013 Andrew Main (Zefram) <zefram@fysh.org> |
1037
|
|
|
|
|
|
|
|
1038
|
|
|
|
|
|
|
=head1 LICENSE |
1039
|
|
|
|
|
|
|
|
1040
|
|
|
|
|
|
|
This module is free software; you can redistribute it and/or modify it |
1041
|
|
|
|
|
|
|
under the same terms as Perl itself. |
1042
|
|
|
|
|
|
|
CARP |
1043
|
|
|
|
|
|
|
|
1044
|
1
|
|
|
|
|
3
|
$fatpacked{"Carp/Heavy.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CARP_HEAVY'; |
1045
|
|
|
|
|
|
|
package Carp::Heavy; |
1046
|
|
|
|
|
|
|
|
1047
|
|
|
|
|
|
|
use Carp (); |
1048
|
|
|
|
|
|
|
|
1049
|
|
|
|
|
|
|
our $VERSION = '1.3301'; |
1050
|
|
|
|
|
|
|
|
1051
|
|
|
|
|
|
|
my $cv = defined($Carp::VERSION) ? $Carp::VERSION : "undef"; |
1052
|
|
|
|
|
|
|
if($cv ne $VERSION) { |
1053
|
|
|
|
|
|
|
die "Version mismatch between Carp $cv ($INC{q(Carp.pm)}) and Carp::Heavy $VERSION ($INC{q(Carp/Heavy.pm)}). Did you alter \@INC after Carp was loaded?\n"; |
1054
|
|
|
|
|
|
|
} |
1055
|
|
|
|
|
|
|
|
1056
|
|
|
|
|
|
|
1; |
1057
|
|
|
|
|
|
|
|
1058
|
|
|
|
|
|
|
# Most of the machinery of Carp used to be here. |
1059
|
|
|
|
|
|
|
# It has been moved in Carp.pm now, but this placeholder remains for |
1060
|
|
|
|
|
|
|
# the benefit of modules that like to preload Carp::Heavy directly. |
1061
|
|
|
|
|
|
|
# This must load Carp, because some modules rely on the historical |
1062
|
|
|
|
|
|
|
# behaviour of Carp::Heavy loading Carp. |
1063
|
|
|
|
|
|
|
CARP_HEAVY |
1064
|
|
|
|
|
|
|
|
1065
|
1
|
|
|
|
|
14
|
$fatpacked{"Module/Locate.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'MODULE_LOCATE'; |
1066
|
|
|
|
|
|
|
{ |
1067
|
|
|
|
|
|
|
package Module::Locate; |
1068
|
|
|
|
|
|
|
|
1069
|
1
|
|
|
1
|
|
5
|
use warnings; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
23
|
|
1070
|
1
|
|
|
1
|
|
12
|
use 5.8.8; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
544
|
|
1071
|
|
|
|
|
|
|
|
1072
|
|
|
|
|
|
|
our $VERSION = '1.79'; |
1073
|
|
|
|
|
|
|
our $Cache = 0; |
1074
|
|
|
|
|
|
|
our $Global = 1; |
1075
|
|
|
|
|
|
|
|
1076
|
|
|
|
|
|
|
my $ident_re = qr{[_a-z]\w*}i; |
1077
|
|
|
|
|
|
|
my $sep_re = qr{'|::}; |
1078
|
|
|
|
|
|
|
our $PkgRe = qr{\A(?:$ident_re(?:$sep_re$ident_re)*)\z}; |
1079
|
|
|
|
|
|
|
|
1080
|
|
|
|
|
|
|
my @All = qw( |
1081
|
|
|
|
|
|
|
locate get_source acts_like_fh |
1082
|
|
|
|
|
|
|
mod_to_path is_mod_loaded is_pkg_loaded |
1083
|
|
|
|
|
|
|
); |
1084
|
|
|
|
|
|
|
|
1085
|
|
|
|
|
|
|
sub import { |
1086
|
1
|
|
|
1
|
|
3
|
my $pkg = caller; |
1087
|
1
|
|
|
|
|
6
|
my @args = @_[ 1 .. $#_ ]; |
1088
|
|
|
|
|
|
|
|
1089
|
1
|
|
|
|
|
8
|
while(local $_ = shift @args) { |
1090
|
1
|
50
|
50
|
|
|
6
|
*{ "$pkg\::$_" } = \&$_ and next |
|
1
|
|
|
|
|
159
|
|
1091
|
|
|
|
|
|
|
if defined &$_; |
1092
|
|
|
|
|
|
|
|
1093
|
0
|
0
|
|
|
|
|
$Cache = shift @args, next |
1094
|
|
|
|
|
|
|
if /^cache$/i; |
1095
|
|
|
|
|
|
|
|
1096
|
0
|
0
|
|
|
|
|
$Global = shift @args, next |
1097
|
|
|
|
|
|
|
if /^global$/i; |
1098
|
|
|
|
|
|
|
|
1099
|
0
|
0
|
|
|
|
|
if(/^:all$/i) { |
1100
|
0
|
|
|
|
|
|
*{ "$pkg\::$_" } = \&$_ |
1101
|
0
|
|
|
|
|
|
for @All; |
1102
|
0
|
|
|
|
|
|
next; |
1103
|
|
|
|
|
|
|
} |
1104
|
|
|
|
|
|
|
|
1105
|
0
|
|
|
|
|
|
warn("not in ".__PACKAGE__." import list: '$_'"); |
1106
|
|
|
|
|
|
|
} |
1107
|
|
|
|
|
|
|
} |
1108
|
|
|
|
|
|
|
|
1109
|
1
|
|
|
1
|
|
6
|
use strict; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
41
|
|
1110
|
|
|
|
|
|
|
|
1111
|
1
|
|
|
1
|
|
10
|
use IO::File; |
|
1
|
|
|
|
|
5873
|
|
|
1
|
|
|
|
|
200
|
|
1112
|
1
|
|
|
1
|
|
9
|
use overload (); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
19
|
|
1113
|
1
|
|
|
1
|
|
6
|
use Carp 'croak'; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
66
|
|
1114
|
1
|
|
|
1
|
|
13
|
use File::Spec::Functions 'catfile'; |
|
1
|
|
|
|
|
992
|
|
|
1
|
|
|
|
|
754
|
|
1115
|
|
|
|
|
|
|
|
1116
|
|
|
|
|
|
|
sub get_source { |
1117
|
0
|
|
|
0
|
1
|
|
my $pkg = $_[-1]; |
1118
|
|
|
|
|
|
|
|
1119
|
0
|
|
|
|
|
|
my $f = locate($pkg); |
1120
|
|
|
|
|
|
|
|
1121
|
|
|
|
|
|
|
my $fh = ( acts_like_fh($f) ? |
1122
|
|
|
|
|
|
|
$f |
1123
|
|
|
|
|
|
|
: |
1124
|
0
|
0
|
|
|
|
|
do { my $tmp = IO::File->new($f) |
|
0
|
0
|
|
|
|
|
|
1125
|
0
|
|
|
|
|
|
or croak("invalid module '$pkg' [$f] - $!"); $tmp } |
1126
|
|
|
|
|
|
|
); |
1127
|
|
|
|
|
|
|
|
1128
|
0
|
|
|
|
|
|
local $/; |
1129
|
0
|
|
|
|
|
|
return <$fh>; |
1130
|
|
|
|
|
|
|
} |
1131
|
|
|
|
|
|
|
|
1132
|
|
|
|
|
|
|
sub locate { |
1133
|
0
|
|
|
0
|
1
|
|
my $pkg = $_[-1]; |
1134
|
|
|
|
|
|
|
|
1135
|
0
|
0
|
|
|
|
|
croak("Undefined filename provided") |
1136
|
|
|
|
|
|
|
unless defined $pkg; |
1137
|
|
|
|
|
|
|
|
1138
|
0
|
|
|
|
|
|
my $inc_path = mod_to_path($pkg); |
1139
|
|
|
|
|
|
|
|
1140
|
0
|
0
|
0
|
|
|
|
return $INC{$inc_path} if exists($INC{$inc_path}) && !wantarray; |
1141
|
|
|
|
|
|
|
|
1142
|
|
|
|
|
|
|
# On Windows the inc_path will use '/' for directory separator, |
1143
|
|
|
|
|
|
|
# but when looking for a module, we need to use the OS's separator. |
1144
|
0
|
|
|
|
|
|
my $partial_path = _mod_to_partial_path($pkg); |
1145
|
|
|
|
|
|
|
|
1146
|
0
|
|
|
|
|
|
my @paths; |
1147
|
|
|
|
|
|
|
|
1148
|
0
|
|
|
|
|
|
for(@INC) { |
1149
|
0
|
0
|
|
|
|
|
if(ref $_) { |
1150
|
0
|
|
|
|
|
|
my $ret = coderefs_in_INC($_, $inc_path); |
1151
|
|
|
|
|
|
|
|
1152
|
|
|
|
|
|
|
next |
1153
|
0
|
0
|
|
|
|
|
unless defined $ret; |
1154
|
|
|
|
|
|
|
|
1155
|
0
|
0
|
|
|
|
|
croak("invalid \@INC subroutine return $ret") |
1156
|
|
|
|
|
|
|
unless acts_like_fh($ret); |
1157
|
|
|
|
|
|
|
|
1158
|
0
|
|
|
|
|
|
return $ret; |
1159
|
|
|
|
|
|
|
} |
1160
|
|
|
|
|
|
|
|
1161
|
0
|
|
|
|
|
|
my $fullpath = catfile($_, $partial_path); |
1162
|
0
|
0
|
|
|
|
|
push(@paths, $fullpath) if -f $fullpath; |
1163
|
|
|
|
|
|
|
} |
1164
|
|
|
|
|
|
|
|
1165
|
0
|
0
|
|
|
|
|
return unless @paths > 0; |
1166
|
|
|
|
|
|
|
|
1167
|
0
|
0
|
|
|
|
|
return wantarray ? @paths : $paths[0]; |
1168
|
|
|
|
|
|
|
} |
1169
|
|
|
|
|
|
|
|
1170
|
|
|
|
|
|
|
sub mod_to_path { |
1171
|
0
|
|
|
0
|
1
|
|
my $pkg = shift; |
1172
|
0
|
|
|
|
|
|
my $path = $pkg; |
1173
|
|
|
|
|
|
|
|
1174
|
0
|
0
|
|
|
|
|
croak("Invalid package name '$pkg'") |
1175
|
|
|
|
|
|
|
unless $pkg =~ $Module::Locate::PkgRe; |
1176
|
|
|
|
|
|
|
|
1177
|
|
|
|
|
|
|
# %INC always uses / as a directory separator, even on Windows |
1178
|
0
|
|
|
|
|
|
$path =~ s!::!/!g; |
1179
|
0
|
0
|
|
|
|
|
$path .= '.pm' unless $path =~ m!\.pm$!; |
1180
|
|
|
|
|
|
|
|
1181
|
0
|
|
|
|
|
|
return $path; |
1182
|
|
|
|
|
|
|
} |
1183
|
|
|
|
|
|
|
|
1184
|
|
|
|
|
|
|
sub coderefs_in_INC { |
1185
|
0
|
|
|
0
|
0
|
|
my($path, $c) = reverse @_; |
1186
|
|
|
|
|
|
|
|
1187
|
0
|
0
|
|
|
|
|
my $ret = ref($c) eq 'CODE' ? |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1188
|
|
|
|
|
|
|
$c->( $c, $path ) |
1189
|
|
|
|
|
|
|
: |
1190
|
|
|
|
|
|
|
ref($c) eq 'ARRAY' ? |
1191
|
|
|
|
|
|
|
$c->[0]->( $c, $path ) |
1192
|
|
|
|
|
|
|
: |
1193
|
|
|
|
|
|
|
UNIVERSAL::can($c, 'INC') ? |
1194
|
|
|
|
|
|
|
$c->INC( $path ) |
1195
|
|
|
|
|
|
|
: |
1196
|
|
|
|
|
|
|
warn("invalid reference in \@INC '$c'") |
1197
|
|
|
|
|
|
|
; |
1198
|
|
|
|
|
|
|
|
1199
|
0
|
|
|
|
|
|
return $ret; |
1200
|
|
|
|
|
|
|
} |
1201
|
|
|
|
|
|
|
|
1202
|
|
|
|
|
|
|
sub acts_like_fh { |
1203
|
1
|
|
|
1
|
|
6
|
no strict 'refs'; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
487
|
|
1204
|
|
|
|
|
|
|
return ( ref $_[0] and ( |
1205
|
|
|
|
|
|
|
( ref $_[0] eq 'GLOB' and defined *{$_[0]}{IO} ) |
1206
|
|
|
|
|
|
|
or ( UNIVERSAL::isa($_[0], 'IO::Handle') ) |
1207
|
|
|
|
|
|
|
or ( overload::Method($_[0], '<>') ) |
1208
|
0
|
|
0
|
0
|
1
|
|
) or ref \$_[0] eq 'GLOB' and defined *{$_[0]}{IO} ); |
1209
|
|
|
|
|
|
|
} |
1210
|
|
|
|
|
|
|
|
1211
|
|
|
|
|
|
|
sub is_mod_loaded { |
1212
|
0
|
|
|
0
|
1
|
|
my $mod = shift; |
1213
|
|
|
|
|
|
|
|
1214
|
0
|
0
|
|
|
|
|
croak("Invalid package name '$mod'") |
1215
|
|
|
|
|
|
|
unless $mod =~ $Module::Locate::PkgRe; |
1216
|
|
|
|
|
|
|
|
1217
|
|
|
|
|
|
|
## it looks like %INC entries automagically use / as a separator |
1218
|
0
|
|
|
|
|
|
my $path = join '/', split '::' => "$mod.pm"; |
1219
|
|
|
|
|
|
|
|
1220
|
0
|
|
0
|
|
|
|
return (exists $INC{$path} && defined $INC{$path}); |
1221
|
|
|
|
|
|
|
} |
1222
|
|
|
|
|
|
|
|
1223
|
|
|
|
|
|
|
sub _mod_to_partial_path { |
1224
|
0
|
|
|
0
|
|
|
my $package = shift; |
1225
|
|
|
|
|
|
|
|
1226
|
0
|
|
|
|
|
|
return catfile(split(/::/, $package)).'.pm'; |
1227
|
|
|
|
|
|
|
} |
1228
|
|
|
|
|
|
|
|
1229
|
|
|
|
|
|
|
sub is_pkg_loaded { |
1230
|
0
|
|
|
0
|
1
|
|
my $pkg = shift; |
1231
|
|
|
|
|
|
|
|
1232
|
0
|
0
|
|
|
|
|
croak("Invalid package name '$pkg'") |
1233
|
|
|
|
|
|
|
unless $pkg =~ $Module::Locate::PkgRe; |
1234
|
|
|
|
|
|
|
|
1235
|
0
|
|
|
|
|
|
my @tbls = map "${_}::", split('::' => $pkg); |
1236
|
0
|
|
|
|
|
|
my $tbl = \%main::; |
1237
|
|
|
|
|
|
|
|
1238
|
0
|
|
|
|
|
|
for(@tbls) { |
1239
|
0
|
0
|
|
|
|
|
return unless exists $tbl->{$_}; |
1240
|
0
|
|
|
|
|
|
$tbl = $tbl->{$_}; |
1241
|
|
|
|
|
|
|
} |
1242
|
|
|
|
|
|
|
|
1243
|
0
|
|
|
|
|
|
return !!$pkg; |
1244
|
|
|
|
|
|
|
} |
1245
|
|
|
|
|
|
|
} |
1246
|
|
|
|
|
|
|
|
1247
|
|
|
|
|
|
|
q[ That better be make-up, and it better be good ]; |
1248
|
|
|
|
|
|
|
|
1249
|
|
|
|
|
|
|
=pod |
1250
|
|
|
|
|
|
|
|
1251
|
|
|
|
|
|
|
=head1 NAME |
1252
|
|
|
|
|
|
|
|
1253
|
|
|
|
|
|
|
Module::Locate - locate modules in the same fashion as C<require> and C<use> |
1254
|
|
|
|
|
|
|
|
1255
|
|
|
|
|
|
|
=head1 SYNOPSIS |
1256
|
|
|
|
|
|
|
|
1257
|
|
|
|
|
|
|
use Module::Locate qw/ locate get_source /; |
1258
|
|
|
|
|
|
|
|
1259
|
|
|
|
|
|
|
add_plugin( locate "This::Module" ); |
1260
|
|
|
|
|
|
|
eval 'use strict; ' . get_source('legacy_code.plx'); |
1261
|
|
|
|
|
|
|
|
1262
|
|
|
|
|
|
|
=head1 DESCRIPTION |
1263
|
|
|
|
|
|
|
|
1264
|
|
|
|
|
|
|
Using C<locate()>, return the path that C<require> would find for a given |
1265
|
|
|
|
|
|
|
module or filename (it can also return a filehandle if a reference in C<@INC> |
1266
|
|
|
|
|
|
|
has been used). This means you can test for the existence, or find the path |
1267
|
|
|
|
|
|
|
for, modules without having to evaluate the code they contain. |
1268
|
|
|
|
|
|
|
|
1269
|
|
|
|
|
|
|
This module also comes with accompanying utility functions that are used within |
1270
|
|
|
|
|
|
|
the module itself (except for C<get_source>) and are available for import. |
1271
|
|
|
|
|
|
|
|
1272
|
|
|
|
|
|
|
=head1 FUNCTIONS |
1273
|
|
|
|
|
|
|
|
1274
|
|
|
|
|
|
|
=over 4 |
1275
|
|
|
|
|
|
|
|
1276
|
|
|
|
|
|
|
=item C<import> |
1277
|
|
|
|
|
|
|
|
1278
|
|
|
|
|
|
|
Given function names, the appropriate functions will be exported into the |
1279
|
|
|
|
|
|
|
caller's package. |
1280
|
|
|
|
|
|
|
|
1281
|
|
|
|
|
|
|
If C<:all> is passed then all subroutines are exported. |
1282
|
|
|
|
|
|
|
|
1283
|
|
|
|
|
|
|
The B<Global> and B<Cache> options are no longer supported. |
1284
|
|
|
|
|
|
|
See the BUGS section below. |
1285
|
|
|
|
|
|
|
|
1286
|
|
|
|
|
|
|
|
1287
|
|
|
|
|
|
|
=item C<locate($module_name)> |
1288
|
|
|
|
|
|
|
|
1289
|
|
|
|
|
|
|
Given a module name as a string (in standard perl bareword format) locate the |
1290
|
|
|
|
|
|
|
path of the module. If called in a scalar context the first path found will be |
1291
|
|
|
|
|
|
|
returned, if called in a list context a list of paths where the module was |
1292
|
|
|
|
|
|
|
found. Also, if references have been placed in C<@INC> then a filehandle will |
1293
|
|
|
|
|
|
|
be returned, as defined in the C<require> documentation. An empty C<return> is |
1294
|
|
|
|
|
|
|
used if the module couldn't be located. |
1295
|
|
|
|
|
|
|
|
1296
|
|
|
|
|
|
|
As of version C<1.7> a filename can also be provided to further mimic the lookup |
1297
|
|
|
|
|
|
|
behaviour of C<require>/C<use>. |
1298
|
|
|
|
|
|
|
|
1299
|
|
|
|
|
|
|
=item C<get_source($module_name)> |
1300
|
|
|
|
|
|
|
|
1301
|
|
|
|
|
|
|
When provided with a package name, gets the path using C<locate()>. |
1302
|
|
|
|
|
|
|
If C<locate()> returned a path, then the contents of that file are returned |
1303
|
|
|
|
|
|
|
by C<get_source()> in a scalar. |
1304
|
|
|
|
|
|
|
|
1305
|
|
|
|
|
|
|
=item C<acts_like_fh> |
1306
|
|
|
|
|
|
|
|
1307
|
|
|
|
|
|
|
Given a scalar, check if it behaves like a filehandle. Firstly it checks if it |
1308
|
|
|
|
|
|
|
is a bareword filehandle, then if it inherits from C<IO::Handle> and lastly if |
1309
|
|
|
|
|
|
|
it overloads the C<E<lt>E<gt>> operator. If this is missing any other standard |
1310
|
|
|
|
|
|
|
filehandle behaviour, please send me an e-mail. |
1311
|
|
|
|
|
|
|
|
1312
|
|
|
|
|
|
|
=item C<mod_to_path($module_name)> |
1313
|
|
|
|
|
|
|
|
1314
|
|
|
|
|
|
|
Given a module name, |
1315
|
|
|
|
|
|
|
converts it to a relative path e.g C<Foo::Bar> would become C<Foo/Bar.pm>. |
1316
|
|
|
|
|
|
|
|
1317
|
|
|
|
|
|
|
Note that this path will always use '/' for the directory separator, |
1318
|
|
|
|
|
|
|
even on Windows, |
1319
|
|
|
|
|
|
|
as that's the format used in C<%INC>. |
1320
|
|
|
|
|
|
|
|
1321
|
|
|
|
|
|
|
=item C<is_mod_loaded($module_name)> |
1322
|
|
|
|
|
|
|
|
1323
|
|
|
|
|
|
|
Given a module name, return true if the module has been |
1324
|
|
|
|
|
|
|
loaded (i.e exists in the C<%INC> hash). |
1325
|
|
|
|
|
|
|
|
1326
|
|
|
|
|
|
|
=item C<is_pkg_loaded($package_name)> |
1327
|
|
|
|
|
|
|
|
1328
|
|
|
|
|
|
|
Given a package name (like C<locate()>), check if the package has an existing |
1329
|
|
|
|
|
|
|
symbol table loaded (checks by walking the C<%main::> stash). |
1330
|
|
|
|
|
|
|
|
1331
|
|
|
|
|
|
|
=back |
1332
|
|
|
|
|
|
|
|
1333
|
|
|
|
|
|
|
=head1 SEE ALSO |
1334
|
|
|
|
|
|
|
|
1335
|
|
|
|
|
|
|
A review of modules that can be used to get the path (and often other information) |
1336
|
|
|
|
|
|
|
for one or more modules: L<http://neilb.org/reviews/module-path.html>. |
1337
|
|
|
|
|
|
|
|
1338
|
|
|
|
|
|
|
L<App::Module::Locate> and L<mlocate>. |
1339
|
|
|
|
|
|
|
|
1340
|
|
|
|
|
|
|
=head1 REPOSITORY |
1341
|
|
|
|
|
|
|
|
1342
|
|
|
|
|
|
|
L<https://github.com/neilbowers/Module-Locate> |
1343
|
|
|
|
|
|
|
|
1344
|
|
|
|
|
|
|
=head1 BUGS |
1345
|
|
|
|
|
|
|
|
1346
|
|
|
|
|
|
|
In previous versions of this module, if you specified C<Global =E<gt> 1> |
1347
|
|
|
|
|
|
|
when use'ing this module, |
1348
|
|
|
|
|
|
|
then looking up a module's path would update C<%INC>, |
1349
|
|
|
|
|
|
|
even if the module hadn't actually been loaded (yet). |
1350
|
|
|
|
|
|
|
This meant that if you subsequently tried to load the module, |
1351
|
|
|
|
|
|
|
it would wrongly not be loaded. |
1352
|
|
|
|
|
|
|
|
1353
|
|
|
|
|
|
|
Bugs are tracked using RT (bug you can also raise Github issues if you prefer): |
1354
|
|
|
|
|
|
|
|
1355
|
|
|
|
|
|
|
L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Module-Locate> |
1356
|
|
|
|
|
|
|
|
1357
|
|
|
|
|
|
|
=head1 AUTHOR |
1358
|
|
|
|
|
|
|
|
1359
|
|
|
|
|
|
|
Dan Brook C<< <cpan@broquaint.com> >> |
1360
|
|
|
|
|
|
|
|
1361
|
|
|
|
|
|
|
=head1 LICENSE |
1362
|
|
|
|
|
|
|
|
1363
|
|
|
|
|
|
|
This is free software; you can redistribute it and/or modify it under the same terms as |
1364
|
|
|
|
|
|
|
Perl itself. |
1365
|
|
|
|
|
|
|
|
1366
|
|
|
|
|
|
|
=cut |
1367
|
|
|
|
|
|
|
MODULE_LOCATE |
1368
|
|
|
|
|
|
|
|
1369
|
1
|
|
|
|
|
23
|
$fatpacked{"Perl/Tags.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'PERL_TAGS'; |
1370
|
|
|
|
|
|
|
#!/usr/bin/perl |
1371
|
|
|
|
|
|
|
|
1372
|
|
|
|
|
|
|
=head1 NAME |
1373
|
|
|
|
|
|
|
|
1374
|
|
|
|
|
|
|
Perl::Tags - Generate (possibly exuberant) Ctags style tags for Perl sourcecode |
1375
|
|
|
|
|
|
|
|
1376
|
|
|
|
|
|
|
=head1 SYNOPSIS |
1377
|
|
|
|
|
|
|
|
1378
|
|
|
|
|
|
|
=head2 Using Perl::Tags to assist your development |
1379
|
|
|
|
|
|
|
|
1380
|
|
|
|
|
|
|
C<Perl::Tags> is designed to be integrated into your development |
1381
|
|
|
|
|
|
|
environment. Here are a few ways to use it: |
1382
|
|
|
|
|
|
|
|
1383
|
|
|
|
|
|
|
=head3 With Vim |
1384
|
|
|
|
|
|
|
|
1385
|
|
|
|
|
|
|
C<Perl::Tags> was originally designed to be used with vim. See |
1386
|
|
|
|
|
|
|
L<https://github.com/osfameron/perl-tags-vim> for an easily installable Plugin. |
1387
|
|
|
|
|
|
|
|
1388
|
|
|
|
|
|
|
NB: You will need to have a vim with perl compiled in it. Debuntu packages |
1389
|
|
|
|
|
|
|
this as C<vim-perl>. Alternatively you can compile from source (you'll need |
1390
|
|
|
|
|
|
|
Perl + the development headers C<libperl-dev>). |
1391
|
|
|
|
|
|
|
|
1392
|
|
|
|
|
|
|
(Note that C<perl-tags-vim> includes its own copy of C<Perl::Tags> through |
1393
|
|
|
|
|
|
|
the magic of git submodules and L<App::FatPacker>, so you don't need to install |
1394
|
|
|
|
|
|
|
this module from CPAN if you are only intending to use it with Vim as above!) |
1395
|
|
|
|
|
|
|
|
1396
|
|
|
|
|
|
|
=head3 From the Command Line |
1397
|
|
|
|
|
|
|
|
1398
|
|
|
|
|
|
|
See the L<bin/perl-tags> script provided. |
1399
|
|
|
|
|
|
|
|
1400
|
|
|
|
|
|
|
=head3 From other editors |
1401
|
|
|
|
|
|
|
|
1402
|
|
|
|
|
|
|
Any editor that supports ctags should be able to use this output. Documentation |
1403
|
|
|
|
|
|
|
and code patches on how to do this are welcome. |
1404
|
|
|
|
|
|
|
|
1405
|
|
|
|
|
|
|
=head2 Using the Perl::Tags module within your code |
1406
|
|
|
|
|
|
|
|
1407
|
|
|
|
|
|
|
use Perl::Tags; |
1408
|
|
|
|
|
|
|
my $naive_tagger = Perl::Tags::Naive->new( max_level=>2 ); |
1409
|
|
|
|
|
|
|
$naive_tagger->process( |
1410
|
|
|
|
|
|
|
files => ['Foo.pm', 'bar.pl'], |
1411
|
|
|
|
|
|
|
refresh=>1 |
1412
|
|
|
|
|
|
|
); |
1413
|
|
|
|
|
|
|
|
1414
|
|
|
|
|
|
|
print $naive_tagger; # stringifies to ctags file |
1415
|
|
|
|
|
|
|
|
1416
|
|
|
|
|
|
|
Recursively follows C<use> and C<require> statements, up to a maximum |
1417
|
|
|
|
|
|
|
of C<max_level>. |
1418
|
|
|
|
|
|
|
|
1419
|
|
|
|
|
|
|
=head1 DETAILS |
1420
|
|
|
|
|
|
|
|
1421
|
|
|
|
|
|
|
There are several taggers distributed with this distribution, including: |
1422
|
|
|
|
|
|
|
|
1423
|
|
|
|
|
|
|
=over 4 |
1424
|
|
|
|
|
|
|
|
1425
|
|
|
|
|
|
|
=item L<Perl::Tags::Naive> |
1426
|
|
|
|
|
|
|
|
1427
|
|
|
|
|
|
|
This is a more-or-less straight ripoff, slightly updated, of the original |
1428
|
|
|
|
|
|
|
pltags code. This is a "naive" tagger, in that it makes pragmatic assumptions |
1429
|
|
|
|
|
|
|
about what Perl code usually looks like (e.g. it doesn't actually parse the |
1430
|
|
|
|
|
|
|
code.) This is fast, lightweight, and often Good Enough. |
1431
|
|
|
|
|
|
|
|
1432
|
|
|
|
|
|
|
This has additional subclasses such as L<Perl::Tags::Naive::Moose> to parse |
1433
|
|
|
|
|
|
|
Moose declarations, and L<Perl::Tags::Naive::Lib> to parse C<use lib>. |
1434
|
|
|
|
|
|
|
|
1435
|
|
|
|
|
|
|
=item L<Perl::Tags::PPI> |
1436
|
|
|
|
|
|
|
|
1437
|
|
|
|
|
|
|
Uses the L<PPI> module to do a deeper analysis and parsing of your Perl code. |
1438
|
|
|
|
|
|
|
This is more accurate, but slower. |
1439
|
|
|
|
|
|
|
|
1440
|
|
|
|
|
|
|
=item L<Perl::Tags::Hybrid> |
1441
|
|
|
|
|
|
|
|
1442
|
|
|
|
|
|
|
Can run multiple taggers, such as ::Naive and ::PPI, combining the results. |
1443
|
|
|
|
|
|
|
|
1444
|
|
|
|
|
|
|
=back |
1445
|
|
|
|
|
|
|
|
1446
|
|
|
|
|
|
|
=head1 EXTENDING |
1447
|
|
|
|
|
|
|
|
1448
|
|
|
|
|
|
|
Documentation patches are welcome: in the meantime, have a look at |
1449
|
|
|
|
|
|
|
L<Perl::Tags::Naive> and its subclasses for a simple line-by-line method of |
1450
|
|
|
|
|
|
|
tagging files. Alternatively L<Perl::Tags::PPI> uses L<PPI>'s built in |
1451
|
|
|
|
|
|
|
method of parsing Perl documents. |
1452
|
|
|
|
|
|
|
|
1453
|
|
|
|
|
|
|
In general, you will want to override the C<get_tags_for_file> method, |
1454
|
|
|
|
|
|
|
returning a list of C<Perl::Tags::Tag> objects to be registered. |
1455
|
|
|
|
|
|
|
|
1456
|
|
|
|
|
|
|
For recursively checking other modules, return a C<Perl::Tags::Tag::Recurse> |
1457
|
|
|
|
|
|
|
object, which does I<not> create a new tag in the resulting perltags file, |
1458
|
|
|
|
|
|
|
but instead processes the next file recursively. |
1459
|
|
|
|
|
|
|
|
1460
|
|
|
|
|
|
|
=head1 FEATURES |
1461
|
|
|
|
|
|
|
|
1462
|
|
|
|
|
|
|
* Recursive, incremental tagging. |
1463
|
|
|
|
|
|
|
* parses `use_ok`/`require_ok` line from Test::More |
1464
|
|
|
|
|
|
|
|
1465
|
|
|
|
|
|
|
=head1 METHODS |
1466
|
|
|
|
|
|
|
|
1467
|
|
|
|
|
|
|
=cut |
1468
|
|
|
|
|
|
|
|
1469
|
|
|
|
|
|
|
package Perl::Tags; |
1470
|
|
|
|
|
|
|
|
1471
|
1
|
|
|
1
|
|
5
|
use strict; use warnings; |
|
1
|
|
|
1
|
|
3
|
|
|
1
|
|
|
|
|
26
|
|
|
1
|
|
|
|
|
5
|
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
21
|
|
1472
|
|
|
|
|
|
|
|
1473
|
1
|
|
|
1
|
|
10
|
use Perl::Tags::Tag; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
29
|
|
1474
|
1
|
|
|
1
|
|
12
|
use Data::Dumper; |
|
1
|
|
|
|
|
7693
|
|
|
1
|
|
|
|
|
68
|
|
1475
|
1
|
|
|
1
|
|
8
|
use File::Spec; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
71
|
|
1476
|
|
|
|
|
|
|
|
1477
|
1
|
|
|
1
|
|
5
|
use overload q("") => \&to_string; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
11
|
|
1478
|
|
|
|
|
|
|
our $VERSION = 0.28; |
1479
|
|
|
|
|
|
|
|
1480
|
|
|
|
|
|
|
=head2 C<new> |
1481
|
|
|
|
|
|
|
|
1482
|
|
|
|
|
|
|
L<Perl::Tags> is an abstract baseclass. Use a class such as |
1483
|
|
|
|
|
|
|
L<Perl::Tags::Naive> and instantiate it with C<new>. |
1484
|
|
|
|
|
|
|
|
1485
|
|
|
|
|
|
|
$naive_tagger = Perl::Tags::Naive->new( max_level=>2 ); |
1486
|
|
|
|
|
|
|
|
1487
|
|
|
|
|
|
|
Accepts the following parameters |
1488
|
|
|
|
|
|
|
|
1489
|
|
|
|
|
|
|
max_level: levels of "use" statements to descend into, default 2 |
1490
|
|
|
|
|
|
|
do_variables: tag variables? default 1 (true) |
1491
|
|
|
|
|
|
|
exts: use the Exuberant extensions |
1492
|
|
|
|
|
|
|
|
1493
|
|
|
|
|
|
|
=cut |
1494
|
|
|
|
|
|
|
|
1495
|
|
|
|
|
|
|
sub new { |
1496
|
0
|
|
|
0
|
1
|
|
my $class = shift; |
1497
|
0
|
|
|
|
|
|
my %options = ( |
1498
|
|
|
|
|
|
|
max_level => 2, # go into next file, but not down the whole tree |
1499
|
|
|
|
|
|
|
do_variables => 1, |
1500
|
|
|
|
|
|
|
@_); |
1501
|
|
|
|
|
|
|
|
1502
|
0
|
|
|
|
|
|
my $self = \%options; |
1503
|
|
|
|
|
|
|
|
1504
|
0
|
|
|
|
|
|
return bless $self, $class; |
1505
|
|
|
|
|
|
|
} |
1506
|
|
|
|
|
|
|
|
1507
|
|
|
|
|
|
|
=head2 C<to_string> |
1508
|
|
|
|
|
|
|
|
1509
|
|
|
|
|
|
|
A L<Perl::Tags> object will stringify to a textual representation of a ctags |
1510
|
|
|
|
|
|
|
file. |
1511
|
|
|
|
|
|
|
|
1512
|
|
|
|
|
|
|
print $tagger; |
1513
|
|
|
|
|
|
|
|
1514
|
|
|
|
|
|
|
=cut |
1515
|
|
|
|
|
|
|
|
1516
|
|
|
|
|
|
|
sub to_string { |
1517
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
1518
|
0
|
0
|
|
|
|
|
my $tags = $self->{tags} or return ''; |
1519
|
0
|
|
|
|
|
|
my %tags = %$tags; |
1520
|
|
|
|
|
|
|
|
1521
|
0
|
|
|
|
|
|
my $s; # to test |
1522
|
|
|
|
|
|
|
|
1523
|
|
|
|
|
|
|
my @lines; |
1524
|
|
|
|
|
|
|
|
1525
|
|
|
|
|
|
|
# the structure is an HoHoA of |
1526
|
|
|
|
|
|
|
# |
1527
|
|
|
|
|
|
|
# {tag_name} |
1528
|
|
|
|
|
|
|
# {file_name} |
1529
|
|
|
|
|
|
|
# [ tags ] |
1530
|
|
|
|
|
|
|
# |
1531
|
|
|
|
|
|
|
# where the file_name level is to allow us to prioritize tags from |
1532
|
|
|
|
|
|
|
# first-included files (on the basis that they may well be the files we |
1533
|
|
|
|
|
|
|
# want to see first. |
1534
|
|
|
|
|
|
|
|
1535
|
0
|
|
|
|
|
|
my $ord = $self->{order}; |
1536
|
0
|
|
|
|
|
|
my @names = sort keys %$tags; |
1537
|
0
|
|
|
|
|
|
for (@names) { |
1538
|
0
|
|
|
|
|
|
my $files = $tags{$_}; |
1539
|
0
|
|
|
|
|
|
push @lines, map { @{$files->{$_}} } |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
1540
|
0
|
|
|
|
|
|
sort { $ord->{$a} <=> $ord->{$b} } keys %$files; |
1541
|
|
|
|
|
|
|
} |
1542
|
0
|
|
|
|
|
|
return join "\n", @lines; |
1543
|
|
|
|
|
|
|
} |
1544
|
|
|
|
|
|
|
|
1545
|
|
|
|
|
|
|
=head2 C<clean_file> |
1546
|
|
|
|
|
|
|
|
1547
|
|
|
|
|
|
|
Delete all tags, but without touching the "order" seen, that way, if the tags |
1548
|
|
|
|
|
|
|
are recreated, they will remain near the top of the "interestingness" tree |
1549
|
|
|
|
|
|
|
|
1550
|
|
|
|
|
|
|
=cut |
1551
|
|
|
|
|
|
|
|
1552
|
|
|
|
|
|
|
sub clean_file { |
1553
|
0
|
|
|
0
|
1
|
|
my ($self, $file) = @_; |
1554
|
|
|
|
|
|
|
|
1555
|
0
|
0
|
|
|
|
|
my $tags = $self->{tags} or die "Trying to clean '$file', but there's no tags"; |
1556
|
|
|
|
|
|
|
|
1557
|
0
|
|
|
|
|
|
for my $name (keys %$tags) { |
1558
|
0
|
|
|
|
|
|
delete $tags->{$name}{$file}; |
1559
|
|
|
|
|
|
|
} |
1560
|
0
|
|
|
|
|
|
delete $self->{seen}{$file}; |
1561
|
|
|
|
|
|
|
# we don't delete the {order} though |
1562
|
|
|
|
|
|
|
} |
1563
|
|
|
|
|
|
|
|
1564
|
|
|
|
|
|
|
=head2 C<output> |
1565
|
|
|
|
|
|
|
|
1566
|
|
|
|
|
|
|
Save the file to disk if it has changed. (The private C<{is_dirty}> attribute |
1567
|
|
|
|
|
|
|
is used, as the tags object may be made up incrementally and recursively within |
1568
|
|
|
|
|
|
|
your IDE. |
1569
|
|
|
|
|
|
|
|
1570
|
|
|
|
|
|
|
=cut |
1571
|
|
|
|
|
|
|
|
1572
|
|
|
|
|
|
|
sub output { |
1573
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
1574
|
0
|
|
|
|
|
|
my %options = @_; |
1575
|
0
|
0
|
|
|
|
|
my $outfile = $options{outfile} or die "No file to write to"; |
1576
|
|
|
|
|
|
|
|
1577
|
0
|
0
|
0
|
|
|
|
return unless $self->{is_dirty} || ! -e $outfile; |
1578
|
|
|
|
|
|
|
|
1579
|
0
|
0
|
|
|
|
|
open (my $OUT, '>', $outfile) or die "Couldn't open $outfile for write: $!"; |
1580
|
0
|
|
|
|
|
|
binmode STDOUT, ":encoding(UTF-8)"; |
1581
|
0
|
|
|
|
|
|
print $OUT $self; |
1582
|
0
|
0
|
|
|
|
|
close $OUT or die "Couldn't close $outfile for write: $!"; |
1583
|
|
|
|
|
|
|
|
1584
|
0
|
|
|
|
|
|
$self->{is_dirty} = 0; |
1585
|
|
|
|
|
|
|
} |
1586
|
|
|
|
|
|
|
|
1587
|
|
|
|
|
|
|
=head2 C<process> |
1588
|
|
|
|
|
|
|
|
1589
|
|
|
|
|
|
|
Scan one or more Perl file for tags |
1590
|
|
|
|
|
|
|
|
1591
|
|
|
|
|
|
|
$tagger->process( |
1592
|
|
|
|
|
|
|
files => [ 'Module.pm', 'script.pl' ] |
1593
|
|
|
|
|
|
|
); |
1594
|
|
|
|
|
|
|
$tagger->process( |
1595
|
|
|
|
|
|
|
files => 'script.pl', |
1596
|
|
|
|
|
|
|
refresh => 1, |
1597
|
|
|
|
|
|
|
); |
1598
|
|
|
|
|
|
|
|
1599
|
|
|
|
|
|
|
=cut |
1600
|
|
|
|
|
|
|
|
1601
|
|
|
|
|
|
|
sub process { |
1602
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
1603
|
0
|
|
|
|
|
|
my %options = @_; |
1604
|
0
|
|
0
|
|
|
|
my $files = $options{files} || die "No file passed to process"; |
1605
|
0
|
0
|
|
|
|
|
my @files = ref $files ? @$files : ($files); |
1606
|
|
|
|
|
|
|
|
1607
|
0
|
|
|
|
|
|
$self->queue( map { |
1608
|
0
|
|
|
|
|
|
{ file=>$_, level=>1, refresh=>$options{refresh} } |
1609
|
|
|
|
|
|
|
} @files); |
1610
|
|
|
|
|
|
|
|
1611
|
0
|
|
|
|
|
|
while (my $file = $self->popqueue) { |
1612
|
0
|
|
|
|
|
|
$self->process_item( %options, %$file ); |
1613
|
|
|
|
|
|
|
} |
1614
|
0
|
|
|
|
|
|
return 1; |
1615
|
|
|
|
|
|
|
} |
1616
|
|
|
|
|
|
|
|
1617
|
|
|
|
|
|
|
=head2 C<queue>, C<popqueue> |
1618
|
|
|
|
|
|
|
|
1619
|
|
|
|
|
|
|
Internal methods managing the processing |
1620
|
|
|
|
|
|
|
|
1621
|
|
|
|
|
|
|
=cut |
1622
|
|
|
|
|
|
|
|
1623
|
|
|
|
|
|
|
sub queue { |
1624
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
1625
|
0
|
|
|
|
|
|
for (@_) { |
1626
|
0
|
0
|
|
|
|
|
push @{$self->{queue}}, $_ unless $_->{level} > $self->{max_level}; |
|
0
|
|
|
|
|
|
|
1627
|
|
|
|
|
|
|
} |
1628
|
|
|
|
|
|
|
} |
1629
|
|
|
|
|
|
|
|
1630
|
|
|
|
|
|
|
sub popqueue { |
1631
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
1632
|
0
|
|
|
|
|
|
return pop @{$self->{queue}}; |
|
0
|
|
|
|
|
|
|
1633
|
|
|
|
|
|
|
} |
1634
|
|
|
|
|
|
|
|
1635
|
|
|
|
|
|
|
=head2 C<process_item>, C<process_file>, C<get_tags_for_file> |
1636
|
|
|
|
|
|
|
|
1637
|
|
|
|
|
|
|
Do the heavy lifting for C<process> above. |
1638
|
|
|
|
|
|
|
|
1639
|
|
|
|
|
|
|
Taggers I<must> override the abstract method C<get_tags_for_file>. |
1640
|
|
|
|
|
|
|
|
1641
|
|
|
|
|
|
|
=cut |
1642
|
|
|
|
|
|
|
|
1643
|
|
|
|
|
|
|
sub process_item { |
1644
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
1645
|
0
|
|
|
|
|
|
my %options = @_; |
1646
|
0
|
|
0
|
|
|
|
my $file = $options{file} || die "No file passed to proces"; |
1647
|
|
|
|
|
|
|
|
1648
|
|
|
|
|
|
|
# make filename absolute, (this could become an option if appropriately |
1649
|
|
|
|
|
|
|
# refactored) but because of my usage (tags_$PID file in /tmp) I need the |
1650
|
|
|
|
|
|
|
# absolute path anyway, and it prevents the file being included twice under |
1651
|
|
|
|
|
|
|
# slightly different names (unless you have 2 hardlinked copies, as I do |
1652
|
|
|
|
|
|
|
# for my .vim/ directory... bah) |
1653
|
|
|
|
|
|
|
|
1654
|
0
|
|
|
|
|
|
$file = File::Spec->rel2abs( $file ) ; |
1655
|
|
|
|
|
|
|
|
1656
|
0
|
0
|
|
|
|
|
if ($self->{seen}{$file}++) { |
1657
|
0
|
0
|
|
|
|
|
return unless $options{refresh}; |
1658
|
0
|
|
|
|
|
|
$self->clean_file( $file ); |
1659
|
|
|
|
|
|
|
} |
1660
|
|
|
|
|
|
|
|
1661
|
0
|
|
|
|
|
|
$self->{is_dirty}++; # we haven't yet been written out |
1662
|
|
|
|
|
|
|
|
1663
|
0
|
|
0
|
|
|
|
$self->{order}{$file} = $self->{curr_order}++ || 0; |
1664
|
|
|
|
|
|
|
|
1665
|
0
|
|
|
|
|
|
$self->{current} = { |
1666
|
|
|
|
|
|
|
file => $file, |
1667
|
|
|
|
|
|
|
package_name => '', |
1668
|
|
|
|
|
|
|
has_subs => 0, |
1669
|
|
|
|
|
|
|
var_continues => 0, |
1670
|
|
|
|
|
|
|
level => $options{level}, |
1671
|
|
|
|
|
|
|
}; |
1672
|
|
|
|
|
|
|
|
1673
|
0
|
|
|
|
|
|
$self->process_file( $file ); |
1674
|
|
|
|
|
|
|
|
1675
|
0
|
|
|
|
|
|
return $self->{tags}; |
1676
|
|
|
|
|
|
|
} |
1677
|
|
|
|
|
|
|
|
1678
|
|
|
|
|
|
|
sub process_file { |
1679
|
0
|
|
|
0
|
1
|
|
my ($self, $file) = @_; |
1680
|
|
|
|
|
|
|
|
1681
|
0
|
|
|
|
|
|
my @tags = $self->get_tags_for_file( $file ); |
1682
|
|
|
|
|
|
|
|
1683
|
0
|
|
|
|
|
|
$self->register( $file, @tags ); |
1684
|
|
|
|
|
|
|
} |
1685
|
|
|
|
|
|
|
|
1686
|
|
|
|
|
|
|
sub get_tags_for_file { |
1687
|
1
|
|
|
1
|
|
1064
|
use Carp 'confess'; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
409
|
|
1688
|
0
|
|
|
0
|
1
|
|
confess "Abstract method get_tags_for_file called"; |
1689
|
|
|
|
|
|
|
} |
1690
|
|
|
|
|
|
|
|
1691
|
|
|
|
|
|
|
=head2 C<register> |
1692
|
|
|
|
|
|
|
|
1693
|
|
|
|
|
|
|
The parsing is done by a number of lightweight objects (parsers) which look for |
1694
|
|
|
|
|
|
|
subroutine references, variables, module inclusion etc. When they are |
1695
|
|
|
|
|
|
|
successful, they call the C<register> method in the main tags object. |
1696
|
|
|
|
|
|
|
|
1697
|
|
|
|
|
|
|
Note that if your tagger wants to register not a new I<declaration> but rather |
1698
|
|
|
|
|
|
|
a I<usage> of another module, then your tagger should return a |
1699
|
|
|
|
|
|
|
C<Perl::Tags::Tag::Recurse> object. This is a pseudo-tag which causes the linked |
1700
|
|
|
|
|
|
|
module to be scanned in turn. See L<Perl::Tags::Naive>'s handling of C<use> |
1701
|
|
|
|
|
|
|
statements as an example! |
1702
|
|
|
|
|
|
|
|
1703
|
|
|
|
|
|
|
=cut |
1704
|
|
|
|
|
|
|
|
1705
|
|
|
|
|
|
|
sub register { |
1706
|
0
|
|
|
0
|
1
|
|
my ($self, $file, @tags) = @_; |
1707
|
0
|
|
|
|
|
|
for my $tag (@tags) { |
1708
|
0
|
0
|
|
|
|
|
$tag->on_register( $self ) or next; |
1709
|
0
|
|
0
|
|
|
|
$tag->{pkg} ||= $self->{current}{package_name}; |
1710
|
0
|
|
0
|
|
|
|
$tag->{exts} ||= $self->{exts}; |
1711
|
|
|
|
|
|
|
|
1712
|
|
|
|
|
|
|
# and copy absolute file if requested |
1713
|
|
|
|
|
|
|
# $tag->{file} = $file if $self->{absolute}; |
1714
|
|
|
|
|
|
|
|
1715
|
0
|
|
|
|
|
|
my $name = $tag->{name}; |
1716
|
0
|
|
|
|
|
|
push @{ $self->{tags}{$name}{$file} }, $tag; |
|
0
|
|
|
|
|
|
|
1717
|
|
|
|
|
|
|
} |
1718
|
|
|
|
|
|
|
} |
1719
|
|
|
|
|
|
|
|
1720
|
|
|
|
|
|
|
## |
1721
|
|
|
|
|
|
|
1; |
1722
|
|
|
|
|
|
|
|
1723
|
|
|
|
|
|
|
=head1 SEE ALSO |
1724
|
|
|
|
|
|
|
|
1725
|
|
|
|
|
|
|
L<bin/perl-tags> |
1726
|
|
|
|
|
|
|
|
1727
|
|
|
|
|
|
|
=head1 CONTRIBUTIONS |
1728
|
|
|
|
|
|
|
|
1729
|
|
|
|
|
|
|
Contributions are always welcome. The repo is in git: |
1730
|
|
|
|
|
|
|
|
1731
|
|
|
|
|
|
|
http://github.com/osfameron/perl-tags |
1732
|
|
|
|
|
|
|
|
1733
|
|
|
|
|
|
|
Please fork and make pull request. Maint bits available on request. |
1734
|
|
|
|
|
|
|
|
1735
|
|
|
|
|
|
|
=over 4 |
1736
|
|
|
|
|
|
|
|
1737
|
|
|
|
|
|
|
=item wolverian |
1738
|
|
|
|
|
|
|
|
1739
|
|
|
|
|
|
|
::PPI subclass |
1740
|
|
|
|
|
|
|
|
1741
|
|
|
|
|
|
|
=item Ian Tegebo |
1742
|
|
|
|
|
|
|
|
1743
|
|
|
|
|
|
|
patch to use File::Temp |
1744
|
|
|
|
|
|
|
|
1745
|
|
|
|
|
|
|
=item DMITRI |
1746
|
|
|
|
|
|
|
|
1747
|
|
|
|
|
|
|
patch to parse constant and label declarations |
1748
|
|
|
|
|
|
|
|
1749
|
|
|
|
|
|
|
=item drbean |
1750
|
|
|
|
|
|
|
|
1751
|
|
|
|
|
|
|
::Naive::Moose, ::Naive::Spiffy and ::Naive::Lib subclasses |
1752
|
|
|
|
|
|
|
|
1753
|
|
|
|
|
|
|
=item Alias |
1754
|
|
|
|
|
|
|
|
1755
|
|
|
|
|
|
|
prodding me to make repo public |
1756
|
|
|
|
|
|
|
|
1757
|
|
|
|
|
|
|
=item nothingmuch |
1758
|
|
|
|
|
|
|
|
1759
|
|
|
|
|
|
|
::PPI fixes |
1760
|
|
|
|
|
|
|
|
1761
|
|
|
|
|
|
|
=item tsee |
1762
|
|
|
|
|
|
|
|
1763
|
|
|
|
|
|
|
Command line interface, applying patches |
1764
|
|
|
|
|
|
|
|
1765
|
|
|
|
|
|
|
=back |
1766
|
|
|
|
|
|
|
|
1767
|
|
|
|
|
|
|
=head1 AUTHOR and LICENSE |
1768
|
|
|
|
|
|
|
|
1769
|
|
|
|
|
|
|
osfameron (2006-2009) - osfameron@cpan.org |
1770
|
|
|
|
|
|
|
and contributors, as above |
1771
|
|
|
|
|
|
|
|
1772
|
|
|
|
|
|
|
For support, try emailing me or grabbing me on irc #london.pm on irc.perl.org |
1773
|
|
|
|
|
|
|
|
1774
|
|
|
|
|
|
|
This was originally ripped off pltags.pl, as distributed with vim |
1775
|
|
|
|
|
|
|
and available from L<http://www.mscha.com/mscha.html?pltags#tools> |
1776
|
|
|
|
|
|
|
Version 2.3, 28 February 2002 |
1777
|
|
|
|
|
|
|
Written by Michael Schaap <pltags@mscha.com>. |
1778
|
|
|
|
|
|
|
|
1779
|
|
|
|
|
|
|
This is licensed under the same terms as Perl itself. (Or as Vim if you prefer). |
1780
|
|
|
|
|
|
|
|
1781
|
|
|
|
|
|
|
=cut |
1782
|
|
|
|
|
|
|
PERL_TAGS |
1783
|
|
|
|
|
|
|
|
1784
|
1
|
|
|
|
|
3
|
$fatpacked{"Perl/Tags/Hybrid.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'PERL_TAGS_HYBRID'; |
1785
|
|
|
|
|
|
|
package Perl::Tags::Hybrid; |
1786
|
|
|
|
|
|
|
|
1787
|
1
|
|
|
1
|
|
6
|
use strict; use warnings; |
|
1
|
|
|
1
|
|
2
|
|
|
1
|
|
|
|
|
31
|
|
|
1
|
|
|
|
|
5
|
|
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
31
|
|
1788
|
1
|
|
|
1
|
|
15
|
use parent 'Perl::Tags'; |
|
1
|
|
|
|
|
561
|
|
|
1
|
|
|
|
|
6
|
|
1789
|
|
|
|
|
|
|
|
1790
|
|
|
|
|
|
|
=head1 C<Perl::Tags::Hybrid> |
1791
|
|
|
|
|
|
|
|
1792
|
|
|
|
|
|
|
Combine the results of multiple parsers, for example C<Perl::Tags::Naive> |
1793
|
|
|
|
|
|
|
and C<Perl::Tags::PPI>. |
1794
|
|
|
|
|
|
|
|
1795
|
|
|
|
|
|
|
=head1 SYNOPSIS |
1796
|
|
|
|
|
|
|
|
1797
|
|
|
|
|
|
|
my $parser = Perl::Tags::Hybrid->new( |
1798
|
|
|
|
|
|
|
taggers => [ |
1799
|
|
|
|
|
|
|
Perl::Tags::Naive->new, |
1800
|
|
|
|
|
|
|
Perl::Tags::PPI->new, |
1801
|
|
|
|
|
|
|
], |
1802
|
|
|
|
|
|
|
); |
1803
|
|
|
|
|
|
|
|
1804
|
|
|
|
|
|
|
=head2 C<get_tags_for_file> |
1805
|
|
|
|
|
|
|
|
1806
|
|
|
|
|
|
|
Registers the results from running each sub-taggers |
1807
|
|
|
|
|
|
|
|
1808
|
|
|
|
|
|
|
=cut |
1809
|
|
|
|
|
|
|
|
1810
|
|
|
|
|
|
|
sub get_taggers { |
1811
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
1812
|
0
|
0
|
|
|
|
|
return @{ $self->{taggers} || [] }; |
|
0
|
|
|
|
|
|
|
1813
|
|
|
|
|
|
|
} |
1814
|
|
|
|
|
|
|
|
1815
|
|
|
|
|
|
|
sub get_tags_for_file { |
1816
|
0
|
|
|
0
|
1
|
|
my ($self, $file) = @_; |
1817
|
|
|
|
|
|
|
|
1818
|
0
|
|
|
|
|
|
my @taggers = $self->get_taggers; |
1819
|
|
|
|
|
|
|
|
1820
|
0
|
|
|
|
|
|
return map { $_->get_tags_for_file( $file ) } @taggers; |
|
0
|
|
|
|
|
|
|
1821
|
|
|
|
|
|
|
} |
1822
|
|
|
|
|
|
|
|
1823
|
|
|
|
|
|
|
1; |
1824
|
|
|
|
|
|
|
PERL_TAGS_HYBRID |
1825
|
|
|
|
|
|
|
|
1826
|
1
|
|
|
|
|
13
|
$fatpacked{"Perl/Tags/Naive.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'PERL_TAGS_NAIVE'; |
1827
|
|
|
|
|
|
|
package Perl::Tags::Naive; |
1828
|
|
|
|
|
|
|
|
1829
|
1
|
|
|
1
|
|
5
|
use strict; use warnings; |
|
1
|
|
|
1
|
|
2
|
|
|
1
|
|
|
|
|
35
|
|
|
1
|
|
|
|
|
4
|
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
21
|
|
1830
|
1
|
|
|
1
|
|
5
|
use parent 'Perl::Tags'; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
7
|
|
1831
|
|
|
|
|
|
|
|
1832
|
|
|
|
|
|
|
=head1 C<Perl::Tags::Naive> |
1833
|
|
|
|
|
|
|
|
1834
|
|
|
|
|
|
|
A naive implementation. That is to say, it's based on the classic C<pltags.pl> |
1835
|
|
|
|
|
|
|
script distributed with Perl, which is by and large a better bet than the |
1836
|
|
|
|
|
|
|
results produced by C<ctags>. But a "better" approach may be to integrate this |
1837
|
|
|
|
|
|
|
with PPI. |
1838
|
|
|
|
|
|
|
|
1839
|
|
|
|
|
|
|
=head2 Subclassing |
1840
|
|
|
|
|
|
|
|
1841
|
|
|
|
|
|
|
See L<TodoTagger> in the C<t/> directory of the distribution for a fully |
1842
|
|
|
|
|
|
|
working example (tested in <t/02_subclass.t>). You may want to reuse parsers |
1843
|
|
|
|
|
|
|
in the ::Naive package, or use all of the existing parsers and add your own. |
1844
|
|
|
|
|
|
|
|
1845
|
|
|
|
|
|
|
package My::Tagger; |
1846
|
|
|
|
|
|
|
use Perl::Tags; |
1847
|
|
|
|
|
|
|
use parent 'Perl::Tags::Naive'; |
1848
|
|
|
|
|
|
|
|
1849
|
|
|
|
|
|
|
sub get_parsers { |
1850
|
|
|
|
|
|
|
my $self = shift; |
1851
|
|
|
|
|
|
|
return ( |
1852
|
|
|
|
|
|
|
$self->can('todo_line'), # a new parser |
1853
|
|
|
|
|
|
|
$self->SUPER::get_parsers(), # all ::Naive's parsers |
1854
|
|
|
|
|
|
|
# or maybe... |
1855
|
|
|
|
|
|
|
$self->can('variable'), # one of ::Naive's parsers |
1856
|
|
|
|
|
|
|
); |
1857
|
|
|
|
|
|
|
} |
1858
|
|
|
|
|
|
|
|
1859
|
|
|
|
|
|
|
sub todo_line { |
1860
|
|
|
|
|
|
|
# your new parser code here! |
1861
|
|
|
|
|
|
|
} |
1862
|
|
|
|
|
|
|
sub package_line { |
1863
|
|
|
|
|
|
|
# override one of ::Naive's parsers |
1864
|
|
|
|
|
|
|
} |
1865
|
|
|
|
|
|
|
|
1866
|
|
|
|
|
|
|
Because ::Naive uses C<can('parser')> instead of C<\&parser>, you |
1867
|
|
|
|
|
|
|
can just override a particular parser by redefining in the subclass. |
1868
|
|
|
|
|
|
|
|
1869
|
|
|
|
|
|
|
=head2 C<get_tags_for_file> |
1870
|
|
|
|
|
|
|
|
1871
|
|
|
|
|
|
|
::Naive uses a simple line-by-line analysis of Perl code, comparing |
1872
|
|
|
|
|
|
|
each line against an array of parsers returned by the L<get_parsers> method. |
1873
|
|
|
|
|
|
|
|
1874
|
|
|
|
|
|
|
The first of these parsers that matches (if any) will return the |
1875
|
|
|
|
|
|
|
tag/control to be registred by the tagger. |
1876
|
|
|
|
|
|
|
|
1877
|
|
|
|
|
|
|
=cut |
1878
|
|
|
|
|
|
|
|
1879
|
|
|
|
|
|
|
{ |
1880
|
|
|
|
|
|
|
# Tags that start POD: |
1881
|
|
|
|
|
|
|
my @start_tags = qw(pod head1 head2 head3 head4 over item back begin |
1882
|
|
|
|
|
|
|
end for encoding); |
1883
|
|
|
|
|
|
|
my @end_tags = qw(cut); |
1884
|
|
|
|
|
|
|
|
1885
|
|
|
|
|
|
|
my $startpod = '^=(?:' . join('|', @start_tags) . ')\b'; |
1886
|
|
|
|
|
|
|
my $endpod = '^=(?:' . join('|', @end_tags) . ')\b'; |
1887
|
|
|
|
|
|
|
|
1888
|
0
|
|
|
0
|
0
|
|
sub STARTPOD { qr/$startpod/ } |
1889
|
0
|
|
|
0
|
0
|
|
sub ENDPOD { qr/$endpod/ } |
1890
|
|
|
|
|
|
|
} |
1891
|
|
|
|
|
|
|
|
1892
|
|
|
|
|
|
|
sub get_tags_for_file { |
1893
|
0
|
|
|
0
|
1
|
|
my ($self, $file) = @_; |
1894
|
|
|
|
|
|
|
|
1895
|
0
|
|
|
|
|
|
my @parsers = $self->get_parsers(); # function refs |
1896
|
|
|
|
|
|
|
|
1897
|
0
|
0
|
|
|
|
|
open (my $IN, '<', $file) or die "Couldn't open file `$file`: $!\n"; |
1898
|
|
|
|
|
|
|
|
1899
|
0
|
|
|
|
|
|
my $start = STARTPOD(); |
1900
|
0
|
|
|
|
|
|
my $end = ENDPOD(); |
1901
|
|
|
|
|
|
|
|
1902
|
0
|
|
|
|
|
|
my @all_tags; |
1903
|
|
|
|
|
|
|
|
1904
|
0
|
|
|
|
|
|
while (<$IN>) { |
1905
|
0
|
0
|
|
|
|
|
next if (/$start/o .. /$end/o); # Skip over POD. |
1906
|
0
|
|
|
|
|
|
chomp; |
1907
|
0
|
|
|
|
|
|
my $statement = my $line = $_; |
1908
|
0
|
|
|
|
|
|
PARSELOOP: for my $parser (@parsers) { |
1909
|
0
|
|
|
|
|
|
my @tags = $parser->( |
1910
|
|
|
|
|
|
|
$self, |
1911
|
|
|
|
|
|
|
$line, |
1912
|
|
|
|
|
|
|
$statement, |
1913
|
|
|
|
|
|
|
$file |
1914
|
|
|
|
|
|
|
); |
1915
|
0
|
|
|
|
|
|
push @all_tags, @tags; |
1916
|
|
|
|
|
|
|
} |
1917
|
|
|
|
|
|
|
} |
1918
|
0
|
|
|
|
|
|
return @all_tags; |
1919
|
|
|
|
|
|
|
} |
1920
|
|
|
|
|
|
|
|
1921
|
|
|
|
|
|
|
=head2 C<get_parsers> |
1922
|
|
|
|
|
|
|
|
1923
|
|
|
|
|
|
|
The following parsers are defined by this module. |
1924
|
|
|
|
|
|
|
|
1925
|
|
|
|
|
|
|
=over 4 |
1926
|
|
|
|
|
|
|
|
1927
|
|
|
|
|
|
|
=cut |
1928
|
|
|
|
|
|
|
|
1929
|
|
|
|
|
|
|
sub get_parsers { |
1930
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
1931
|
|
|
|
|
|
|
return ( |
1932
|
0
|
|
|
|
|
|
$self->can('trim'), |
1933
|
|
|
|
|
|
|
$self->can('variable'), |
1934
|
|
|
|
|
|
|
$self->can('package_line'), |
1935
|
|
|
|
|
|
|
$self->can('sub_line'), |
1936
|
|
|
|
|
|
|
$self->can('use_constant'), |
1937
|
|
|
|
|
|
|
$self->can('use_line'), |
1938
|
|
|
|
|
|
|
$self->can('label_line'), |
1939
|
|
|
|
|
|
|
); |
1940
|
|
|
|
|
|
|
} |
1941
|
|
|
|
|
|
|
|
1942
|
|
|
|
|
|
|
=item C<trim> |
1943
|
|
|
|
|
|
|
|
1944
|
|
|
|
|
|
|
A filter rather than a parser, removes whitespace and comments. |
1945
|
|
|
|
|
|
|
|
1946
|
|
|
|
|
|
|
=cut |
1947
|
|
|
|
|
|
|
|
1948
|
|
|
|
|
|
|
sub trim { |
1949
|
0
|
|
|
0
|
1
|
|
shift; |
1950
|
|
|
|
|
|
|
# naughtily work on arg inplace |
1951
|
0
|
|
|
|
|
|
$_[1] =~ s/#.*//; # remove comment. Naively |
1952
|
0
|
|
|
|
|
|
$_[1] =~ s/^\s*//; # Trim spaces |
1953
|
0
|
|
|
|
|
|
$_[1] =~ s/\s*$//; |
1954
|
|
|
|
|
|
|
|
1955
|
0
|
|
|
|
|
|
return; |
1956
|
|
|
|
|
|
|
} |
1957
|
|
|
|
|
|
|
|
1958
|
|
|
|
|
|
|
=item C<variable> |
1959
|
|
|
|
|
|
|
|
1960
|
|
|
|
|
|
|
Tags definitions of C<my>, C<our>, and C<local> variables. |
1961
|
|
|
|
|
|
|
|
1962
|
|
|
|
|
|
|
Returns a L<Perl::Tags::Tag::Var> if found |
1963
|
|
|
|
|
|
|
|
1964
|
|
|
|
|
|
|
=cut |
1965
|
|
|
|
|
|
|
|
1966
|
|
|
|
|
|
|
sub variable { |
1967
|
|
|
|
|
|
|
# don't handle continuing thingy for now |
1968
|
0
|
|
|
0
|
1
|
|
my ($self, $line, $statement, $file) = @_; |
1969
|
|
|
|
|
|
|
|
1970
|
0
|
0
|
|
|
|
|
return unless $self->{do_variables}; |
1971
|
|
|
|
|
|
|
# I'm not sure I see this as all that useful |
1972
|
|
|
|
|
|
|
|
1973
|
0
|
0
|
0
|
|
|
|
if ($self->{var_continues} || $statement =~/^(my|our|local)\b/) { |
1974
|
|
|
|
|
|
|
|
1975
|
0
|
|
|
|
|
|
$self->{current}{var_continues} = ! ($statement=~/;$/); |
1976
|
0
|
|
|
|
|
|
$statement =~s/=.*$//; |
1977
|
|
|
|
|
|
|
# remove RHS with extreme prejudice |
1978
|
|
|
|
|
|
|
# and also not accounting for things like |
1979
|
|
|
|
|
|
|
# my $x=my $y=my $z; |
1980
|
|
|
|
|
|
|
|
1981
|
0
|
|
|
|
|
|
my @vars = $statement=~/[\$@%]((?:\w|:)+)\b/g; |
1982
|
|
|
|
|
|
|
|
1983
|
|
|
|
|
|
|
# use Data::Dumper; |
1984
|
|
|
|
|
|
|
# print Dumper({ vars => \@vars, statement => $statement }); |
1985
|
|
|
|
|
|
|
|
1986
|
0
|
|
|
|
|
|
return map { |
1987
|
0
|
|
|
|
|
|
Perl::Tags::Tag::Var->new( |
1988
|
|
|
|
|
|
|
name => $_, |
1989
|
|
|
|
|
|
|
file => $file, |
1990
|
|
|
|
|
|
|
line => $line, |
1991
|
|
|
|
|
|
|
linenum => $., |
1992
|
|
|
|
|
|
|
); |
1993
|
|
|
|
|
|
|
} @vars; |
1994
|
|
|
|
|
|
|
} |
1995
|
0
|
|
|
|
|
|
return; |
1996
|
|
|
|
|
|
|
} |
1997
|
|
|
|
|
|
|
|
1998
|
|
|
|
|
|
|
=item C<package_line> |
1999
|
|
|
|
|
|
|
|
2000
|
|
|
|
|
|
|
Parse a package declaration, returning a L<Perl::Tags::Tag::Package> if found. |
2001
|
|
|
|
|
|
|
|
2002
|
|
|
|
|
|
|
=cut |
2003
|
|
|
|
|
|
|
|
2004
|
|
|
|
|
|
|
sub package_line { |
2005
|
0
|
|
|
0
|
1
|
|
my ($self, $line, $statement, $file) = @_; |
2006
|
|
|
|
|
|
|
|
2007
|
0
|
0
|
|
|
|
|
if ($statement=~/^package\s+((?:\w|:)+)\b/) { |
2008
|
|
|
|
|
|
|
return ( |
2009
|
0
|
|
|
|
|
|
Perl::Tags::Tag::Package->new( |
2010
|
|
|
|
|
|
|
name => $1, |
2011
|
|
|
|
|
|
|
file => $file, |
2012
|
|
|
|
|
|
|
line => $line, |
2013
|
|
|
|
|
|
|
linenum => $., |
2014
|
|
|
|
|
|
|
) |
2015
|
|
|
|
|
|
|
); |
2016
|
|
|
|
|
|
|
} |
2017
|
0
|
|
|
|
|
|
return; |
2018
|
|
|
|
|
|
|
} |
2019
|
|
|
|
|
|
|
|
2020
|
|
|
|
|
|
|
=item C<sub_line> |
2021
|
|
|
|
|
|
|
|
2022
|
|
|
|
|
|
|
Parse the declaration of a subroutine, returning a L<Perl::Tags::Tag::Sub> if found. |
2023
|
|
|
|
|
|
|
|
2024
|
|
|
|
|
|
|
=cut |
2025
|
|
|
|
|
|
|
|
2026
|
|
|
|
|
|
|
sub sub_line { |
2027
|
0
|
|
|
0
|
1
|
|
my ($self, $line, $statement, $file) = @_; |
2028
|
0
|
0
|
|
|
|
|
if ($statement=~/sub\s+(\w+)\b/) { |
2029
|
|
|
|
|
|
|
return ( |
2030
|
0
|
|
|
|
|
|
Perl::Tags::Tag::Sub->new( |
2031
|
|
|
|
|
|
|
name => $1, |
2032
|
|
|
|
|
|
|
file => $file, |
2033
|
|
|
|
|
|
|
line => $line, |
2034
|
|
|
|
|
|
|
linenum => $., |
2035
|
|
|
|
|
|
|
) |
2036
|
|
|
|
|
|
|
); |
2037
|
|
|
|
|
|
|
} |
2038
|
|
|
|
|
|
|
|
2039
|
0
|
|
|
|
|
|
return; |
2040
|
|
|
|
|
|
|
} |
2041
|
|
|
|
|
|
|
|
2042
|
|
|
|
|
|
|
=item C<use_constant> |
2043
|
|
|
|
|
|
|
|
2044
|
|
|
|
|
|
|
Parse a use constant directive |
2045
|
|
|
|
|
|
|
|
2046
|
|
|
|
|
|
|
=cut |
2047
|
|
|
|
|
|
|
|
2048
|
|
|
|
|
|
|
sub use_constant { |
2049
|
0
|
|
|
0
|
1
|
|
my ($self, $line, $statement, $file) = @_; |
2050
|
0
|
0
|
|
|
|
|
if ($statement =~/^\s*use\s+constant\s+([^=[:space:]]+)/) { |
2051
|
|
|
|
|
|
|
return ( |
2052
|
0
|
|
|
|
|
|
Perl::Tags::Tag::Constant->new( |
2053
|
|
|
|
|
|
|
name => $1, |
2054
|
|
|
|
|
|
|
file => $file, |
2055
|
|
|
|
|
|
|
line => $line, |
2056
|
|
|
|
|
|
|
linenum => $., |
2057
|
|
|
|
|
|
|
) |
2058
|
|
|
|
|
|
|
); |
2059
|
|
|
|
|
|
|
} |
2060
|
0
|
|
|
|
|
|
return; |
2061
|
|
|
|
|
|
|
} |
2062
|
|
|
|
|
|
|
|
2063
|
|
|
|
|
|
|
=item C<use_line> |
2064
|
|
|
|
|
|
|
|
2065
|
|
|
|
|
|
|
Parse a use, require, and also a use_ok line (from Test::More). |
2066
|
|
|
|
|
|
|
Uses a dummy tag (L<Perl::Tags::Tag::Recurse> to do so). |
2067
|
|
|
|
|
|
|
|
2068
|
|
|
|
|
|
|
=cut |
2069
|
|
|
|
|
|
|
|
2070
|
|
|
|
|
|
|
sub use_line { |
2071
|
0
|
|
|
0
|
1
|
|
my ($self, $line, $statement, $file) = @_; |
2072
|
|
|
|
|
|
|
|
2073
|
0
|
|
|
|
|
|
my @ret; |
2074
|
0
|
0
|
|
|
|
|
if ($statement=~/^(?:use|require)(_ok\(?)?\s+(.*)/) { |
2075
|
0
|
|
|
|
|
|
my @packages = split /\s+/, $2; # may be more than one if base |
2076
|
0
|
0
|
|
|
|
|
@packages = ($packages[0]) if $1; # if use_ok ecc. from Test::More |
2077
|
|
|
|
|
|
|
|
2078
|
0
|
|
|
|
|
|
for (@packages) { |
2079
|
0
|
|
|
|
|
|
s/^q[wq]?[[:punct:]]//; |
2080
|
0
|
|
|
|
|
|
/((?:\w|:)+)/; |
2081
|
0
|
0
|
|
|
|
|
$1 and push @ret, Perl::Tags::Tag::Recurse->new( |
2082
|
|
|
|
|
|
|
name => $1, |
2083
|
|
|
|
|
|
|
line=>'dummy' ); |
2084
|
|
|
|
|
|
|
} |
2085
|
|
|
|
|
|
|
} |
2086
|
0
|
|
|
|
|
|
return @ret; |
2087
|
|
|
|
|
|
|
} |
2088
|
|
|
|
|
|
|
|
2089
|
|
|
|
|
|
|
=item C<label_line> |
2090
|
|
|
|
|
|
|
|
2091
|
|
|
|
|
|
|
Parse label declaration |
2092
|
|
|
|
|
|
|
|
2093
|
|
|
|
|
|
|
=cut |
2094
|
|
|
|
|
|
|
|
2095
|
|
|
|
|
|
|
sub label_line { |
2096
|
0
|
|
|
0
|
1
|
|
my ($self, $line, $statement, $file) = @_; |
2097
|
0
|
0
|
|
|
|
|
if ($statement=~/^\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*:(?:[^:]|$)/) { |
2098
|
|
|
|
|
|
|
return ( |
2099
|
0
|
|
|
|
|
|
Perl::Tags::Tag::Label->new( |
2100
|
|
|
|
|
|
|
name => $1, |
2101
|
|
|
|
|
|
|
file => $file, |
2102
|
|
|
|
|
|
|
line => $line, |
2103
|
|
|
|
|
|
|
linenum => $., |
2104
|
|
|
|
|
|
|
) |
2105
|
|
|
|
|
|
|
); |
2106
|
|
|
|
|
|
|
} |
2107
|
0
|
|
|
|
|
|
return; |
2108
|
|
|
|
|
|
|
} |
2109
|
|
|
|
|
|
|
|
2110
|
|
|
|
|
|
|
=back |
2111
|
|
|
|
|
|
|
|
2112
|
|
|
|
|
|
|
=cut |
2113
|
|
|
|
|
|
|
|
2114
|
|
|
|
|
|
|
1; |
2115
|
|
|
|
|
|
|
PERL_TAGS_NAIVE |
2116
|
|
|
|
|
|
|
|
2117
|
1
|
|
|
|
|
10
|
$fatpacked{"Perl/Tags/Naive/Lib.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'PERL_TAGS_NAIVE_LIB'; |
2118
|
|
|
|
|
|
|
package Perl::Tags::Naive::Lib; |
2119
|
|
|
|
|
|
|
|
2120
|
|
|
|
|
|
|
use strict; use warnings; |
2121
|
|
|
|
|
|
|
use parent 'Perl::Tags::Naive'; |
2122
|
|
|
|
|
|
|
|
2123
|
|
|
|
|
|
|
=head2 C<get_parsers> |
2124
|
|
|
|
|
|
|
|
2125
|
|
|
|
|
|
|
The following parsers are defined by this module. |
2126
|
|
|
|
|
|
|
|
2127
|
|
|
|
|
|
|
=over 4 |
2128
|
|
|
|
|
|
|
|
2129
|
|
|
|
|
|
|
=cut |
2130
|
|
|
|
|
|
|
|
2131
|
|
|
|
|
|
|
sub get_parsers |
2132
|
|
|
|
|
|
|
{ |
2133
|
|
|
|
|
|
|
my $self = shift; |
2134
|
|
|
|
|
|
|
return ( |
2135
|
|
|
|
|
|
|
$self->SUPER::get_parsers(), |
2136
|
|
|
|
|
|
|
$self->can('uselib_line'), |
2137
|
|
|
|
|
|
|
); |
2138
|
|
|
|
|
|
|
} |
2139
|
|
|
|
|
|
|
|
2140
|
|
|
|
|
|
|
|
2141
|
|
|
|
|
|
|
=item C<uselib_line> |
2142
|
|
|
|
|
|
|
|
2143
|
|
|
|
|
|
|
Parse a use/require lib line |
2144
|
|
|
|
|
|
|
Unshift libraries found onto @INC. |
2145
|
|
|
|
|
|
|
|
2146
|
|
|
|
|
|
|
=cut |
2147
|
|
|
|
|
|
|
|
2148
|
|
|
|
|
|
|
sub uselib_line { |
2149
|
|
|
|
|
|
|
my ($self, $line, $statement, $file) = @_; |
2150
|
|
|
|
|
|
|
|
2151
|
|
|
|
|
|
|
my @ret; |
2152
|
|
|
|
|
|
|
if ($statement=~/^(?:use|require)\s+lib\s+(.*)/) { |
2153
|
|
|
|
|
|
|
my @libraries = split /\s+/, $1; # may be more than one |
2154
|
|
|
|
|
|
|
|
2155
|
|
|
|
|
|
|
for (@libraries) { |
2156
|
|
|
|
|
|
|
s/^q[wq]?[[:punct:]]//; |
2157
|
|
|
|
|
|
|
/((?:\w|:)+)/; |
2158
|
|
|
|
|
|
|
$1 and unshift @INC, $1; |
2159
|
|
|
|
|
|
|
} |
2160
|
|
|
|
|
|
|
} |
2161
|
|
|
|
|
|
|
return @ret; |
2162
|
|
|
|
|
|
|
} |
2163
|
|
|
|
|
|
|
|
2164
|
|
|
|
|
|
|
1; |
2165
|
|
|
|
|
|
|
|
2166
|
|
|
|
|
|
|
=back |
2167
|
|
|
|
|
|
|
|
2168
|
|
|
|
|
|
|
#package Perl::Tags::Tag::Recurse::Lib; |
2169
|
|
|
|
|
|
|
# |
2170
|
|
|
|
|
|
|
#our @ISA = qw/Perl::Tags::Tag::Recurse/; |
2171
|
|
|
|
|
|
|
# |
2172
|
|
|
|
|
|
|
#=head1 C<Perl::Tags::Tag::Recurse::Lib> |
2173
|
|
|
|
|
|
|
# |
2174
|
|
|
|
|
|
|
#=head2 C<type>: dummy |
2175
|
|
|
|
|
|
|
# |
2176
|
|
|
|
|
|
|
#=head2 C<on_register> |
2177
|
|
|
|
|
|
|
# |
2178
|
|
|
|
|
|
|
#Recurse adding this new module accessible from a use lib statement to the queue. |
2179
|
|
|
|
|
|
|
# |
2180
|
|
|
|
|
|
|
#=cut |
2181
|
|
|
|
|
|
|
# |
2182
|
|
|
|
|
|
|
#package Perl::Tags::Tag::Recurse; |
2183
|
|
|
|
|
|
|
# |
2184
|
|
|
|
|
|
|
#sub on_register { |
2185
|
|
|
|
|
|
|
# my ($self, $tags) = @_; |
2186
|
|
|
|
|
|
|
# |
2187
|
|
|
|
|
|
|
# my $name = $self->{name}; |
2188
|
|
|
|
|
|
|
# my $path; |
2189
|
|
|
|
|
|
|
# my @INC_ORIG = @INC; |
2190
|
|
|
|
|
|
|
# my @INC = |
2191
|
|
|
|
|
|
|
# eval { |
2192
|
|
|
|
|
|
|
# $path = locate( $name ); # or warn "Couldn't find path for $module"; |
2193
|
|
|
|
|
|
|
# }; |
2194
|
|
|
|
|
|
|
# # return if $@; |
2195
|
|
|
|
|
|
|
# return unless $path; |
2196
|
|
|
|
|
|
|
# $tags->queue( { file=>$path, level=>$tags->{current}{level}+1 , refresh=>0} +); |
2197
|
|
|
|
|
|
|
# return; # don't get added |
2198
|
|
|
|
|
|
|
#} |
2199
|
|
|
|
|
|
|
|
2200
|
|
|
|
|
|
|
## |
2201
|
|
|
|
|
|
|
|
2202
|
|
|
|
|
|
|
1; |
2203
|
|
|
|
|
|
|
|
2204
|
|
|
|
|
|
|
=head1 AUTHOR and LICENSE |
2205
|
|
|
|
|
|
|
|
2206
|
|
|
|
|
|
|
dr bean - drbean at sign cpan a dot org |
2207
|
|
|
|
|
|
|
osfameron (2006) - osfameron@gmail.com |
2208
|
|
|
|
|
|
|
|
2209
|
|
|
|
|
|
|
For support, try emailing me or grabbing me on irc #london.pm on irc.perl.org |
2210
|
|
|
|
|
|
|
|
2211
|
|
|
|
|
|
|
This was originally ripped off pltags.pl, as distributed with vim |
2212
|
|
|
|
|
|
|
and available from L<http://www.mscha.com/mscha.html?pltags#tools> |
2213
|
|
|
|
|
|
|
Version 2.3, 28 February 2002 |
2214
|
|
|
|
|
|
|
Written by Michael Schaap <pltags@mscha.com>. |
2215
|
|
|
|
|
|
|
|
2216
|
|
|
|
|
|
|
This is licensed under the same terms as Perl itself. (Or as Vim if you +prefer). |
2217
|
|
|
|
|
|
|
|
2218
|
|
|
|
|
|
|
=cut |
2219
|
|
|
|
|
|
|
PERL_TAGS_NAIVE_LIB |
2220
|
|
|
|
|
|
|
|
2221
|
1
|
|
|
|
|
13
|
$fatpacked{"Perl/Tags/Naive/Moose.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'PERL_TAGS_NAIVE_MOOSE'; |
2222
|
1
|
|
|
1
|
|
5
|
use strict; use warnings; |
|
1
|
|
|
1
|
|
2
|
|
|
1
|
|
|
|
|
25
|
|
|
1
|
|
|
|
|
5
|
|
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
54
|
|
2223
|
|
|
|
|
|
|
package Perl::Tags::Naive::Moose; |
2224
|
|
|
|
|
|
|
|
2225
|
1
|
|
|
1
|
|
5
|
use parent 'Perl::Tags::Naive'; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
5
|
|
2226
|
|
|
|
|
|
|
|
2227
|
|
|
|
|
|
|
=head2 C<get_parsers> |
2228
|
|
|
|
|
|
|
|
2229
|
|
|
|
|
|
|
The following parsers are defined by this module. |
2230
|
|
|
|
|
|
|
|
2231
|
|
|
|
|
|
|
=over 4 |
2232
|
|
|
|
|
|
|
|
2233
|
|
|
|
|
|
|
=cut |
2234
|
|
|
|
|
|
|
|
2235
|
|
|
|
|
|
|
sub get_parsers |
2236
|
|
|
|
|
|
|
{ |
2237
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
2238
|
|
|
|
|
|
|
return ( |
2239
|
0
|
|
|
|
|
|
$self->SUPER::get_parsers(), |
2240
|
|
|
|
|
|
|
$self->can('extends_line'), |
2241
|
|
|
|
|
|
|
$self->can('with_line'), |
2242
|
|
|
|
|
|
|
$self->can('has_line'), |
2243
|
|
|
|
|
|
|
$self->can('around_line'), |
2244
|
|
|
|
|
|
|
$self->can('before_line'), |
2245
|
|
|
|
|
|
|
$self->can('after_line'), |
2246
|
|
|
|
|
|
|
$self->can('override_line'), |
2247
|
|
|
|
|
|
|
$self->can('augment_line'), |
2248
|
|
|
|
|
|
|
$self->can('class_line'), |
2249
|
|
|
|
|
|
|
$self->can('method_line'), |
2250
|
|
|
|
|
|
|
$self->can('role_line'), |
2251
|
|
|
|
|
|
|
); |
2252
|
|
|
|
|
|
|
} |
2253
|
|
|
|
|
|
|
|
2254
|
|
|
|
|
|
|
=item C<extends_line> |
2255
|
|
|
|
|
|
|
|
2256
|
|
|
|
|
|
|
Parse the declaration of a 'extends' Moose keyword, returning a L<Perl::Tags::Tag::Extends> if found. |
2257
|
|
|
|
|
|
|
|
2258
|
|
|
|
|
|
|
=cut |
2259
|
|
|
|
|
|
|
|
2260
|
|
|
|
|
|
|
sub extends_line { |
2261
|
0
|
|
|
0
|
1
|
|
my ($self, $line, $statement, $file) = @_; |
2262
|
0
|
0
|
|
|
|
|
if ($statement=~/extends\s+["']?((?:\w+|::)+)\b/) { |
2263
|
0
|
|
|
|
|
|
return Perl::Tags::Tag::Recurse->new( |
2264
|
|
|
|
|
|
|
name => $1, |
2265
|
|
|
|
|
|
|
line => 'dummy', |
2266
|
|
|
|
|
|
|
); |
2267
|
|
|
|
|
|
|
} |
2268
|
0
|
|
|
|
|
|
return; |
2269
|
|
|
|
|
|
|
} |
2270
|
|
|
|
|
|
|
|
2271
|
|
|
|
|
|
|
=item C<with_line> |
2272
|
|
|
|
|
|
|
|
2273
|
|
|
|
|
|
|
Parse the declaration of a 'with' Moose keyword, returning a L<Perl::Tags::Tag::With> tag if found. |
2274
|
|
|
|
|
|
|
|
2275
|
|
|
|
|
|
|
=cut |
2276
|
|
|
|
|
|
|
|
2277
|
|
|
|
|
|
|
sub with_line { |
2278
|
0
|
|
|
0
|
1
|
|
my ( $self, $line, $statement, $file ) = @_; |
2279
|
0
|
0
|
|
|
|
|
if ( $statement =~ m/\bwith\s+(?:qw.)?\W*([a-zA-Z0-9_: ]+)/ ) { |
2280
|
0
|
|
|
|
|
|
my @roles = split /\s+/, $1; |
2281
|
0
|
|
|
|
|
|
my @returns; |
2282
|
0
|
|
|
|
|
|
foreach my $role (@roles) { |
2283
|
0
|
|
|
|
|
|
push @returns, Perl::Tags::Tag::Recurse->new( |
2284
|
|
|
|
|
|
|
name => $role, |
2285
|
|
|
|
|
|
|
line => 'dummy', |
2286
|
|
|
|
|
|
|
); |
2287
|
|
|
|
|
|
|
} |
2288
|
0
|
|
|
|
|
|
return @returns; |
2289
|
|
|
|
|
|
|
} |
2290
|
0
|
|
|
|
|
|
return; |
2291
|
|
|
|
|
|
|
} |
2292
|
|
|
|
|
|
|
|
2293
|
|
|
|
|
|
|
=item C<has_line> |
2294
|
|
|
|
|
|
|
|
2295
|
|
|
|
|
|
|
Parse the declaration of a 'has' Moose keyword, returning a L<Perl::Tags::Tag::Has> if found. |
2296
|
|
|
|
|
|
|
|
2297
|
|
|
|
|
|
|
=cut |
2298
|
|
|
|
|
|
|
|
2299
|
|
|
|
|
|
|
sub has_line { |
2300
|
0
|
|
|
0
|
1
|
|
my ($self, $line, $statement, $file) = @_; |
2301
|
0
|
0
|
|
|
|
|
if ($statement=~/\bhas\s+["']?(\w+)\b/) { |
2302
|
|
|
|
|
|
|
return ( |
2303
|
0
|
|
|
|
|
|
Perl::Tags::Tag::Has->new( |
2304
|
|
|
|
|
|
|
name => $1, |
2305
|
|
|
|
|
|
|
file => $file, |
2306
|
|
|
|
|
|
|
line => $line, |
2307
|
|
|
|
|
|
|
linenum => $., |
2308
|
|
|
|
|
|
|
) |
2309
|
|
|
|
|
|
|
); |
2310
|
|
|
|
|
|
|
} |
2311
|
0
|
|
|
|
|
|
return; |
2312
|
|
|
|
|
|
|
} |
2313
|
|
|
|
|
|
|
|
2314
|
|
|
|
|
|
|
=item C<around_line> |
2315
|
|
|
|
|
|
|
|
2316
|
|
|
|
|
|
|
Parse the declaration of a 'around' Moose keyword, returning a L<Perl::Tags::Tag::Around> tag if found. |
2317
|
|
|
|
|
|
|
|
2318
|
|
|
|
|
|
|
=cut |
2319
|
|
|
|
|
|
|
|
2320
|
|
|
|
|
|
|
sub around_line { |
2321
|
0
|
|
|
0
|
1
|
|
my ($self, $line, $statement, $file) = @_; |
2322
|
0
|
0
|
|
|
|
|
if ($statement=~/around\s+["'](\w+)\b/) { |
2323
|
|
|
|
|
|
|
return ( |
2324
|
0
|
|
|
|
|
|
Perl::Tags::Tag::Around->new( |
2325
|
|
|
|
|
|
|
name => $1, |
2326
|
|
|
|
|
|
|
file => $file, |
2327
|
|
|
|
|
|
|
line => $line, |
2328
|
|
|
|
|
|
|
linenum => $., |
2329
|
|
|
|
|
|
|
) |
2330
|
|
|
|
|
|
|
); |
2331
|
|
|
|
|
|
|
} |
2332
|
0
|
|
|
|
|
|
return; |
2333
|
|
|
|
|
|
|
} |
2334
|
|
|
|
|
|
|
|
2335
|
|
|
|
|
|
|
=item C<before_line> |
2336
|
|
|
|
|
|
|
|
2337
|
|
|
|
|
|
|
Parse the declaration of a 'before' Moose keyword, returning a L<Perl::Tags::Tag::Before> tag if found. |
2338
|
|
|
|
|
|
|
|
2339
|
|
|
|
|
|
|
=cut |
2340
|
|
|
|
|
|
|
|
2341
|
|
|
|
|
|
|
sub before_line { |
2342
|
0
|
|
|
0
|
1
|
|
my ($self, $line, $statement, $file) = @_; |
2343
|
0
|
0
|
|
|
|
|
if ($statement=~/before\s+["'](\w+)\b/) { |
2344
|
|
|
|
|
|
|
return ( |
2345
|
0
|
|
|
|
|
|
Perl::Tags::Tag::Before->new( |
2346
|
|
|
|
|
|
|
name => $1, |
2347
|
|
|
|
|
|
|
file => $file, |
2348
|
|
|
|
|
|
|
line => $line, |
2349
|
|
|
|
|
|
|
linenum => $., |
2350
|
|
|
|
|
|
|
) |
2351
|
|
|
|
|
|
|
); |
2352
|
|
|
|
|
|
|
} |
2353
|
0
|
|
|
|
|
|
return; |
2354
|
|
|
|
|
|
|
} |
2355
|
|
|
|
|
|
|
|
2356
|
|
|
|
|
|
|
=item C<after_line> |
2357
|
|
|
|
|
|
|
|
2358
|
|
|
|
|
|
|
Parse the declaration of a 'after' Moose keyword, returning a L<Perl::Tags::Tag::After> tag if found. |
2359
|
|
|
|
|
|
|
|
2360
|
|
|
|
|
|
|
=cut |
2361
|
|
|
|
|
|
|
|
2362
|
|
|
|
|
|
|
sub after_line { |
2363
|
0
|
|
|
0
|
1
|
|
my ($self, $line, $statement, $file) = @_; |
2364
|
0
|
0
|
|
|
|
|
if ($statement=~/after\s+["'](\w+)\b/) { |
2365
|
|
|
|
|
|
|
return ( |
2366
|
0
|
|
|
|
|
|
Perl::Tags::Tag::After->new( |
2367
|
|
|
|
|
|
|
name => $1, |
2368
|
|
|
|
|
|
|
file => $file, |
2369
|
|
|
|
|
|
|
line => $line, |
2370
|
|
|
|
|
|
|
linenum => $., |
2371
|
|
|
|
|
|
|
) |
2372
|
|
|
|
|
|
|
); |
2373
|
|
|
|
|
|
|
} |
2374
|
0
|
|
|
|
|
|
return; |
2375
|
|
|
|
|
|
|
} |
2376
|
|
|
|
|
|
|
|
2377
|
|
|
|
|
|
|
=item C<override_line> |
2378
|
|
|
|
|
|
|
|
2379
|
|
|
|
|
|
|
Parse the declaration of a 'override' Moose keyword, returning a L<Perl::Tags::Tag::Override> tag if found. |
2380
|
|
|
|
|
|
|
|
2381
|
|
|
|
|
|
|
=cut |
2382
|
|
|
|
|
|
|
|
2383
|
|
|
|
|
|
|
sub override_line { |
2384
|
0
|
|
|
0
|
1
|
|
my ($self, $line, $statement, $file) = @_; |
2385
|
0
|
0
|
|
|
|
|
if ($statement=~/override\s+["'](\w+)\b/) { |
2386
|
|
|
|
|
|
|
return ( |
2387
|
0
|
|
|
|
|
|
Perl::Tags::Tag::Override->new( |
2388
|
|
|
|
|
|
|
name => $1, |
2389
|
|
|
|
|
|
|
file => $file, |
2390
|
|
|
|
|
|
|
line => $line, |
2391
|
|
|
|
|
|
|
linenum => $., |
2392
|
|
|
|
|
|
|
) |
2393
|
|
|
|
|
|
|
); |
2394
|
|
|
|
|
|
|
} |
2395
|
0
|
|
|
|
|
|
return; |
2396
|
|
|
|
|
|
|
} |
2397
|
|
|
|
|
|
|
|
2398
|
|
|
|
|
|
|
=item C<augment_line> |
2399
|
|
|
|
|
|
|
|
2400
|
|
|
|
|
|
|
Parse the declaration of a 'augment' Moose keyword, returning a L<Perl::Tags::Tag::Augment> tag if found. |
2401
|
|
|
|
|
|
|
|
2402
|
|
|
|
|
|
|
=cut |
2403
|
|
|
|
|
|
|
|
2404
|
|
|
|
|
|
|
sub augment_line { |
2405
|
0
|
|
|
0
|
1
|
|
my ($self, $line, $statement, $file) = @_; |
2406
|
0
|
0
|
|
|
|
|
if ($statement=~/augment\s+["']?(\w+)\b/) { |
2407
|
|
|
|
|
|
|
return ( |
2408
|
0
|
|
|
|
|
|
Perl::Tags::Tag::Augment->new( |
2409
|
|
|
|
|
|
|
name => $1, |
2410
|
|
|
|
|
|
|
file => $file, |
2411
|
|
|
|
|
|
|
line => $line, |
2412
|
|
|
|
|
|
|
linenum => $., |
2413
|
|
|
|
|
|
|
) |
2414
|
|
|
|
|
|
|
); |
2415
|
|
|
|
|
|
|
} |
2416
|
0
|
|
|
|
|
|
return; |
2417
|
|
|
|
|
|
|
} |
2418
|
|
|
|
|
|
|
|
2419
|
|
|
|
|
|
|
=item C<class_line> |
2420
|
|
|
|
|
|
|
|
2421
|
|
|
|
|
|
|
Parse the declaration of a 'class' Moose keyword, returning a L<Perl::Tags::Tag::Class> tag if found. |
2422
|
|
|
|
|
|
|
|
2423
|
|
|
|
|
|
|
=cut |
2424
|
|
|
|
|
|
|
|
2425
|
|
|
|
|
|
|
sub class_line { |
2426
|
0
|
|
|
0
|
1
|
|
my ($self, $line, $statement, $file) = @_; |
2427
|
0
|
0
|
|
|
|
|
if ($statement=~/class\s+(\w+)\b/) { |
2428
|
|
|
|
|
|
|
return ( |
2429
|
0
|
|
|
|
|
|
Perl::Tags::Tag::Class->new( |
2430
|
|
|
|
|
|
|
name => $1, |
2431
|
|
|
|
|
|
|
file => $file, |
2432
|
|
|
|
|
|
|
line => $line, |
2433
|
|
|
|
|
|
|
linenum => $., |
2434
|
|
|
|
|
|
|
) |
2435
|
|
|
|
|
|
|
); |
2436
|
|
|
|
|
|
|
} |
2437
|
0
|
|
|
|
|
|
return; |
2438
|
|
|
|
|
|
|
} |
2439
|
|
|
|
|
|
|
|
2440
|
|
|
|
|
|
|
=item C<method_line> |
2441
|
|
|
|
|
|
|
|
2442
|
|
|
|
|
|
|
Parse the declaration of a 'method' Moose keyword, returning a L<Perl::Tags::Tag::Method> tag if found. |
2443
|
|
|
|
|
|
|
|
2444
|
|
|
|
|
|
|
=cut |
2445
|
|
|
|
|
|
|
|
2446
|
|
|
|
|
|
|
sub method_line { |
2447
|
0
|
|
|
0
|
1
|
|
my ($self, $line, $statement, $file) = @_; |
2448
|
0
|
0
|
|
|
|
|
if ($statement=~/method\s+(\w+)\b/) { |
2449
|
|
|
|
|
|
|
return ( |
2450
|
0
|
|
|
|
|
|
Perl::Tags::Tag::Method->new( |
2451
|
|
|
|
|
|
|
name => $1, |
2452
|
|
|
|
|
|
|
file => $file, |
2453
|
|
|
|
|
|
|
line => $line, |
2454
|
|
|
|
|
|
|
linenum => $., |
2455
|
|
|
|
|
|
|
) |
2456
|
|
|
|
|
|
|
); |
2457
|
|
|
|
|
|
|
} |
2458
|
0
|
|
|
|
|
|
return; |
2459
|
|
|
|
|
|
|
} |
2460
|
|
|
|
|
|
|
|
2461
|
|
|
|
|
|
|
=item C<role_line> |
2462
|
|
|
|
|
|
|
|
2463
|
|
|
|
|
|
|
Parse the declaration of a 'role' Moose keyword, returning a L<Perl::Tags::Tag::Role> tag if found. |
2464
|
|
|
|
|
|
|
|
2465
|
|
|
|
|
|
|
=cut |
2466
|
|
|
|
|
|
|
|
2467
|
|
|
|
|
|
|
sub role_line { |
2468
|
0
|
|
|
0
|
1
|
|
my ($self, $line, $statement, $file) = @_; |
2469
|
0
|
0
|
|
|
|
|
if ($statement=~/role\s+(\w+)\b/) { |
2470
|
|
|
|
|
|
|
return ( |
2471
|
0
|
|
|
|
|
|
Perl::Tags::Tag::Role->new( |
2472
|
|
|
|
|
|
|
name => $1, |
2473
|
|
|
|
|
|
|
file => $file, |
2474
|
|
|
|
|
|
|
line => $line, |
2475
|
|
|
|
|
|
|
linenum => $., |
2476
|
|
|
|
|
|
|
) |
2477
|
|
|
|
|
|
|
); |
2478
|
|
|
|
|
|
|
} |
2479
|
0
|
|
|
|
|
|
return; |
2480
|
|
|
|
|
|
|
} |
2481
|
|
|
|
|
|
|
|
2482
|
|
|
|
|
|
|
=head1 C<Perl::Tags::Tag::Method> |
2483
|
|
|
|
|
|
|
|
2484
|
|
|
|
|
|
|
=head2 C<type>: Method |
2485
|
|
|
|
|
|
|
|
2486
|
|
|
|
|
|
|
=cut |
2487
|
|
|
|
|
|
|
|
2488
|
|
|
|
|
|
|
package Perl::Tags::Tag::Method; |
2489
|
|
|
|
|
|
|
our @ISA = qw/Perl::Tags::Tag::Sub/; |
2490
|
|
|
|
|
|
|
|
2491
|
0
|
|
|
0
|
|
|
sub type { 'Method' } |
2492
|
|
|
|
|
|
|
|
2493
|
|
|
|
|
|
|
|
2494
|
|
|
|
|
|
|
=head1 C<Perl::Tags::Tag::Has> |
2495
|
|
|
|
|
|
|
|
2496
|
|
|
|
|
|
|
=head2 C<type>: Has |
2497
|
|
|
|
|
|
|
|
2498
|
|
|
|
|
|
|
=cut |
2499
|
|
|
|
|
|
|
|
2500
|
|
|
|
|
|
|
package Perl::Tags::Tag::Has; |
2501
|
|
|
|
|
|
|
our @ISA = qw/Perl::Tags::Tag::Method/; |
2502
|
|
|
|
|
|
|
|
2503
|
0
|
|
|
0
|
|
|
sub type { 'Has' } |
2504
|
|
|
|
|
|
|
|
2505
|
|
|
|
|
|
|
=head1 C<Perl::Tags::Tag::Around> |
2506
|
|
|
|
|
|
|
|
2507
|
|
|
|
|
|
|
=head2 C<type>: Around |
2508
|
|
|
|
|
|
|
|
2509
|
|
|
|
|
|
|
=cut |
2510
|
|
|
|
|
|
|
|
2511
|
|
|
|
|
|
|
package Perl::Tags::Tag::Around; |
2512
|
|
|
|
|
|
|
our @ISA = qw/Perl::Tags::Tag::Method/; |
2513
|
|
|
|
|
|
|
|
2514
|
0
|
|
|
0
|
|
|
sub type { 'Around' } |
2515
|
|
|
|
|
|
|
|
2516
|
|
|
|
|
|
|
=head1 C<Perl::Tags::Tag::Before> |
2517
|
|
|
|
|
|
|
|
2518
|
|
|
|
|
|
|
=head2 C<type>: Before |
2519
|
|
|
|
|
|
|
|
2520
|
|
|
|
|
|
|
=cut |
2521
|
|
|
|
|
|
|
|
2522
|
|
|
|
|
|
|
package Perl::Tags::Tag::Before; |
2523
|
|
|
|
|
|
|
our @ISA = qw/Perl::Tags::Tag::Method/; |
2524
|
|
|
|
|
|
|
|
2525
|
0
|
|
|
0
|
|
|
sub type { 'Before' } |
2526
|
|
|
|
|
|
|
|
2527
|
|
|
|
|
|
|
=head1 C<Perl::Tags::Tag::After> |
2528
|
|
|
|
|
|
|
|
2529
|
|
|
|
|
|
|
=head2 C<type>: After |
2530
|
|
|
|
|
|
|
|
2531
|
|
|
|
|
|
|
=cut |
2532
|
|
|
|
|
|
|
|
2533
|
|
|
|
|
|
|
package Perl::Tags::Tag::After; |
2534
|
|
|
|
|
|
|
our @ISA = qw/Perl::Tags::Tag::Method/; |
2535
|
|
|
|
|
|
|
|
2536
|
0
|
|
|
0
|
|
|
sub type { 'After' } |
2537
|
|
|
|
|
|
|
|
2538
|
|
|
|
|
|
|
=head1 C<Perl::Tags::Tag::Override> |
2539
|
|
|
|
|
|
|
|
2540
|
|
|
|
|
|
|
=head2 C<type>: Override |
2541
|
|
|
|
|
|
|
|
2542
|
|
|
|
|
|
|
=cut |
2543
|
|
|
|
|
|
|
|
2544
|
|
|
|
|
|
|
package Perl::Tags::Tag::Override; |
2545
|
|
|
|
|
|
|
our @ISA = qw/Perl::Tags::Tag::Method/; |
2546
|
|
|
|
|
|
|
|
2547
|
0
|
|
|
0
|
|
|
sub type { 'Override' } |
2548
|
|
|
|
|
|
|
|
2549
|
|
|
|
|
|
|
=head1 C<Perl::Tags::Tag::Augment> |
2550
|
|
|
|
|
|
|
|
2551
|
|
|
|
|
|
|
=head2 C<type>: Augment |
2552
|
|
|
|
|
|
|
|
2553
|
|
|
|
|
|
|
=cut |
2554
|
|
|
|
|
|
|
|
2555
|
|
|
|
|
|
|
package Perl::Tags::Tag::Augment; |
2556
|
|
|
|
|
|
|
our @ISA = qw/Perl::Tags::Tag::Method/; |
2557
|
|
|
|
|
|
|
|
2558
|
0
|
|
|
0
|
|
|
sub type { 'Augment' } |
2559
|
|
|
|
|
|
|
|
2560
|
|
|
|
|
|
|
=head1 C<Perl::Tags::Tag::Class> |
2561
|
|
|
|
|
|
|
|
2562
|
|
|
|
|
|
|
=head2 C<type>: Class |
2563
|
|
|
|
|
|
|
|
2564
|
|
|
|
|
|
|
=cut |
2565
|
|
|
|
|
|
|
|
2566
|
|
|
|
|
|
|
package Perl::Tags::Tag::Class; |
2567
|
|
|
|
|
|
|
our @ISA = qw/Perl::Tags::Tag::Package/; |
2568
|
|
|
|
|
|
|
|
2569
|
0
|
|
|
0
|
|
|
sub type { 'Class' } |
2570
|
|
|
|
|
|
|
|
2571
|
|
|
|
|
|
|
=head1 C<Perl::Tags::Tag::Role> |
2572
|
|
|
|
|
|
|
|
2573
|
|
|
|
|
|
|
=head2 C<type>: Role |
2574
|
|
|
|
|
|
|
|
2575
|
|
|
|
|
|
|
=cut |
2576
|
|
|
|
|
|
|
|
2577
|
|
|
|
|
|
|
package Perl::Tags::Tag::Role; |
2578
|
|
|
|
|
|
|
our @ISA = qw/Perl::Tags::Tag::Package/; |
2579
|
|
|
|
|
|
|
|
2580
|
0
|
|
|
0
|
|
|
sub type { 'Role' } |
2581
|
|
|
|
|
|
|
|
2582
|
|
|
|
|
|
|
1; |
2583
|
|
|
|
|
|
|
|
2584
|
|
|
|
|
|
|
=head1 AUTHOR and LICENSE |
2585
|
|
|
|
|
|
|
|
2586
|
|
|
|
|
|
|
dr bean - drbean at sign cpan a dot org |
2587
|
|
|
|
|
|
|
|
2588
|
|
|
|
|
|
|
This is licensed under the same terms as Perl itself. (Or as Vim if you +prefer). |
2589
|
|
|
|
|
|
|
|
2590
|
|
|
|
|
|
|
=cut |
2591
|
|
|
|
|
|
|
|
2592
|
|
|
|
|
|
|
# vim: set ts=8 sts=4 sw=4 noet: |
2593
|
|
|
|
|
|
|
PERL_TAGS_NAIVE_MOOSE |
2594
|
|
|
|
|
|
|
|
2595
|
1
|
|
|
|
|
7
|
$fatpacked{"Perl/Tags/Naive/Spiffy.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'PERL_TAGS_NAIVE_SPIFFY'; |
2596
|
|
|
|
|
|
|
package Perl::Tags::Naive::Spiffy; |
2597
|
|
|
|
|
|
|
|
2598
|
|
|
|
|
|
|
use strict; use warnings; |
2599
|
|
|
|
|
|
|
use parent 'Perl::Tags::Naive'; |
2600
|
|
|
|
|
|
|
|
2601
|
|
|
|
|
|
|
=head2 C<get_parsers> |
2602
|
|
|
|
|
|
|
|
2603
|
|
|
|
|
|
|
The following parsers are defined by this module. |
2604
|
|
|
|
|
|
|
|
2605
|
|
|
|
|
|
|
=over 4 |
2606
|
|
|
|
|
|
|
|
2607
|
|
|
|
|
|
|
=cut |
2608
|
|
|
|
|
|
|
|
2609
|
|
|
|
|
|
|
sub get_parsers |
2610
|
|
|
|
|
|
|
{ |
2611
|
|
|
|
|
|
|
my $self = shift; |
2612
|
|
|
|
|
|
|
return ( |
2613
|
|
|
|
|
|
|
$self->SUPER::get_parsers(), |
2614
|
|
|
|
|
|
|
$self->can('field_line'), |
2615
|
|
|
|
|
|
|
$self->can('stub_line'), |
2616
|
|
|
|
|
|
|
); |
2617
|
|
|
|
|
|
|
} |
2618
|
|
|
|
|
|
|
|
2619
|
|
|
|
|
|
|
=item C<field_line> |
2620
|
|
|
|
|
|
|
|
2621
|
|
|
|
|
|
|
Parse the declaration of a Spiffy class accessor method, returning a L<Perl::Tags::Tag::Field> if found. |
2622
|
|
|
|
|
|
|
|
2623
|
|
|
|
|
|
|
=cut |
2624
|
|
|
|
|
|
|
|
2625
|
|
|
|
|
|
|
sub field_line { |
2626
|
|
|
|
|
|
|
my ($self, $line, $statement, $file) = @_; |
2627
|
|
|
|
|
|
|
if ($statement=~/field\s+["']?(\w+)\b/) { |
2628
|
|
|
|
|
|
|
return ( |
2629
|
|
|
|
|
|
|
Perl::Tags::Tag::Field->new( |
2630
|
|
|
|
|
|
|
name => $1, |
2631
|
|
|
|
|
|
|
file => $file, |
2632
|
|
|
|
|
|
|
line => $line, |
2633
|
|
|
|
|
|
|
linenum => $., |
2634
|
|
|
|
|
|
|
) |
2635
|
|
|
|
|
|
|
); |
2636
|
|
|
|
|
|
|
} |
2637
|
|
|
|
|
|
|
return; |
2638
|
|
|
|
|
|
|
} |
2639
|
|
|
|
|
|
|
|
2640
|
|
|
|
|
|
|
=item C<stub_line> |
2641
|
|
|
|
|
|
|
|
2642
|
|
|
|
|
|
|
Parse the declaration of a Spiffy stub method, returning a L<Perl::Tags::Tag::Stub> if found. |
2643
|
|
|
|
|
|
|
|
2644
|
|
|
|
|
|
|
=cut |
2645
|
|
|
|
|
|
|
|
2646
|
|
|
|
|
|
|
sub stub_line { |
2647
|
|
|
|
|
|
|
my ($self, $line, $statement, $file) = @_; |
2648
|
|
|
|
|
|
|
if ($statement=~/stub\s+["']?(\w+)\b/) { |
2649
|
|
|
|
|
|
|
return ( |
2650
|
|
|
|
|
|
|
Perl::Tags::Tag::Stub->new( |
2651
|
|
|
|
|
|
|
name => $1, |
2652
|
|
|
|
|
|
|
file => $file, |
2653
|
|
|
|
|
|
|
line => $line, |
2654
|
|
|
|
|
|
|
linenum => $., |
2655
|
|
|
|
|
|
|
) |
2656
|
|
|
|
|
|
|
); |
2657
|
|
|
|
|
|
|
} |
2658
|
|
|
|
|
|
|
return; |
2659
|
|
|
|
|
|
|
} |
2660
|
|
|
|
|
|
|
|
2661
|
|
|
|
|
|
|
=back |
2662
|
|
|
|
|
|
|
|
2663
|
|
|
|
|
|
|
=head1 C<Perl::Tags::Tag::Field> |
2664
|
|
|
|
|
|
|
|
2665
|
|
|
|
|
|
|
=head2 C<type>: Field |
2666
|
|
|
|
|
|
|
|
2667
|
|
|
|
|
|
|
=cut |
2668
|
|
|
|
|
|
|
|
2669
|
|
|
|
|
|
|
package Perl::Tags::Tag::Field; |
2670
|
|
|
|
|
|
|
our @ISA = qw/Perl::Tags::Tag/; |
2671
|
|
|
|
|
|
|
|
2672
|
|
|
|
|
|
|
sub type { 'Field' } |
2673
|
|
|
|
|
|
|
|
2674
|
|
|
|
|
|
|
=head1 C<Perl::Tags::Tag::Stub> |
2675
|
|
|
|
|
|
|
|
2676
|
|
|
|
|
|
|
=head2 C<type>: Stub |
2677
|
|
|
|
|
|
|
|
2678
|
|
|
|
|
|
|
=cut |
2679
|
|
|
|
|
|
|
|
2680
|
|
|
|
|
|
|
package Perl::Tags::Tag::Stub; |
2681
|
|
|
|
|
|
|
our @ISA = qw/Perl::Tags::Tag/; |
2682
|
|
|
|
|
|
|
|
2683
|
|
|
|
|
|
|
sub type { 'Stub' } |
2684
|
|
|
|
|
|
|
|
2685
|
|
|
|
|
|
|
1; |
2686
|
|
|
|
|
|
|
|
2687
|
|
|
|
|
|
|
=head1 AUTHOR and LICENSE |
2688
|
|
|
|
|
|
|
|
2689
|
|
|
|
|
|
|
dr bean - drbean at sign cpan a dot org |
2690
|
|
|
|
|
|
|
osfameron (2006) - osfameron@gmail.com |
2691
|
|
|
|
|
|
|
|
2692
|
|
|
|
|
|
|
For support, try emailing me or grabbing me on irc #london.pm on irc.perl.org |
2693
|
|
|
|
|
|
|
|
2694
|
|
|
|
|
|
|
This was originally ripped off pltags.pl, as distributed with vim |
2695
|
|
|
|
|
|
|
and available from L<http://www.mscha.com/mscha.html?pltags#tools> |
2696
|
|
|
|
|
|
|
Version 2.3, 28 February 2002 |
2697
|
|
|
|
|
|
|
Written by Michael Schaap <pltags@mscha.com>. |
2698
|
|
|
|
|
|
|
|
2699
|
|
|
|
|
|
|
This is licensed under the same terms as Perl itself. (Or as Vim if you +prefer). |
2700
|
|
|
|
|
|
|
|
2701
|
|
|
|
|
|
|
=cut |
2702
|
|
|
|
|
|
|
PERL_TAGS_NAIVE_SPIFFY |
2703
|
|
|
|
|
|
|
|
2704
|
1
|
|
|
|
|
3
|
$fatpacked{"Perl/Tags/PPI.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'PERL_TAGS_PPI'; |
2705
|
|
|
|
|
|
|
package Perl::Tags::PPI; |
2706
|
|
|
|
|
|
|
|
2707
|
|
|
|
|
|
|
use strict; use warnings; |
2708
|
|
|
|
|
|
|
|
2709
|
|
|
|
|
|
|
use base qw(Perl::Tags); |
2710
|
|
|
|
|
|
|
|
2711
|
|
|
|
|
|
|
use PPI; |
2712
|
|
|
|
|
|
|
|
2713
|
|
|
|
|
|
|
sub ppi_all { |
2714
|
|
|
|
|
|
|
my ( $self, $file ) = @_; |
2715
|
|
|
|
|
|
|
|
2716
|
|
|
|
|
|
|
my $doc = PPI::Document->new($file) || return; |
2717
|
|
|
|
|
|
|
|
2718
|
|
|
|
|
|
|
$doc->index_locations; |
2719
|
|
|
|
|
|
|
|
2720
|
|
|
|
|
|
|
return map { $self->_tagify( $_, "$file" ) } |
2721
|
|
|
|
|
|
|
@{ $doc->find(sub { $_[1]->isa("PPI::Statement") }) || [] } |
2722
|
|
|
|
|
|
|
} |
2723
|
|
|
|
|
|
|
|
2724
|
|
|
|
|
|
|
sub get_tags_for_file { |
2725
|
|
|
|
|
|
|
my ( $self, $file, @parsers ) = @_; |
2726
|
|
|
|
|
|
|
|
2727
|
|
|
|
|
|
|
my @tags = $self->ppi_all( $file ); |
2728
|
|
|
|
|
|
|
|
2729
|
|
|
|
|
|
|
return @tags; |
2730
|
|
|
|
|
|
|
} |
2731
|
|
|
|
|
|
|
|
2732
|
|
|
|
|
|
|
sub _tagify { |
2733
|
|
|
|
|
|
|
my ( $self, $thing, $file ) = @_; |
2734
|
|
|
|
|
|
|
|
2735
|
|
|
|
|
|
|
my $class = $thing->class; |
2736
|
|
|
|
|
|
|
|
2737
|
|
|
|
|
|
|
my ( $first_line ) = split /\n/, $thing; |
2738
|
|
|
|
|
|
|
|
2739
|
|
|
|
|
|
|
if ( my ( $subtype ) = ( $class =~ /^PPI::Statement::(.*)$/ ) ) { |
2740
|
|
|
|
|
|
|
|
2741
|
|
|
|
|
|
|
my $method = "_tagify_" . lc($subtype); |
2742
|
|
|
|
|
|
|
|
2743
|
|
|
|
|
|
|
if ( $self->can($method) ) { |
2744
|
|
|
|
|
|
|
return $self->$method( $thing, $file, $first_line ); |
2745
|
|
|
|
|
|
|
} |
2746
|
|
|
|
|
|
|
} |
2747
|
|
|
|
|
|
|
|
2748
|
|
|
|
|
|
|
return $self->_tagify_statement($thing, $file, $first_line); |
2749
|
|
|
|
|
|
|
} |
2750
|
|
|
|
|
|
|
|
2751
|
|
|
|
|
|
|
# catch all |
2752
|
|
|
|
|
|
|
sub _tagify_statement { |
2753
|
|
|
|
|
|
|
my ( $self, $thing, $file, $first_line ) = @_; |
2754
|
|
|
|
|
|
|
|
2755
|
|
|
|
|
|
|
return; |
2756
|
|
|
|
|
|
|
} |
2757
|
|
|
|
|
|
|
|
2758
|
|
|
|
|
|
|
sub _tagify_sub { |
2759
|
|
|
|
|
|
|
my ( $self, $thing, $file, $line ) = @_; |
2760
|
|
|
|
|
|
|
|
2761
|
|
|
|
|
|
|
return Perl::Tags::Tag::Sub->new( |
2762
|
|
|
|
|
|
|
name => $thing->name, |
2763
|
|
|
|
|
|
|
file => $file, |
2764
|
|
|
|
|
|
|
line => $line, |
2765
|
|
|
|
|
|
|
linenum => $thing->location->[0], |
2766
|
|
|
|
|
|
|
pkg => $thing->guess_package |
2767
|
|
|
|
|
|
|
); |
2768
|
|
|
|
|
|
|
} |
2769
|
|
|
|
|
|
|
|
2770
|
|
|
|
|
|
|
sub _tagify_variable { |
2771
|
|
|
|
|
|
|
my ( $self, $thing, $file, $line ) = @_; |
2772
|
|
|
|
|
|
|
return map { |
2773
|
|
|
|
|
|
|
Perl::Tags::Tag::Var->new( |
2774
|
|
|
|
|
|
|
name => $_, |
2775
|
|
|
|
|
|
|
file => $file, |
2776
|
|
|
|
|
|
|
line => $line, |
2777
|
|
|
|
|
|
|
linenum => $thing->location->[0], |
2778
|
|
|
|
|
|
|
) |
2779
|
|
|
|
|
|
|
} $thing->variables; |
2780
|
|
|
|
|
|
|
} |
2781
|
|
|
|
|
|
|
|
2782
|
|
|
|
|
|
|
sub _tagify_package { |
2783
|
|
|
|
|
|
|
my ( $self, $thing, $file, $line ) = @_; |
2784
|
|
|
|
|
|
|
|
2785
|
|
|
|
|
|
|
return Perl::Tags::Tag::Package->new( |
2786
|
|
|
|
|
|
|
name => $thing->namespace, |
2787
|
|
|
|
|
|
|
file => $file, |
2788
|
|
|
|
|
|
|
line => $line, |
2789
|
|
|
|
|
|
|
linenum => $thing->location->[0], |
2790
|
|
|
|
|
|
|
); |
2791
|
|
|
|
|
|
|
} |
2792
|
|
|
|
|
|
|
|
2793
|
|
|
|
|
|
|
sub _tagify_include { |
2794
|
|
|
|
|
|
|
my ( $self, $thing, $file ) = @_; |
2795
|
|
|
|
|
|
|
|
2796
|
|
|
|
|
|
|
if ( my $module = $thing->module ) { |
2797
|
|
|
|
|
|
|
return Perl::Tags::Tag::Recurse->new( |
2798
|
|
|
|
|
|
|
name => $module, |
2799
|
|
|
|
|
|
|
line => "dummy", |
2800
|
|
|
|
|
|
|
); |
2801
|
|
|
|
|
|
|
} |
2802
|
|
|
|
|
|
|
|
2803
|
|
|
|
|
|
|
return; |
2804
|
|
|
|
|
|
|
} |
2805
|
|
|
|
|
|
|
|
2806
|
|
|
|
|
|
|
sub PPI::Statement::Sub::guess_package { |
2807
|
|
|
|
|
|
|
my ($self) = @_; |
2808
|
|
|
|
|
|
|
|
2809
|
|
|
|
|
|
|
my $temp = $self; |
2810
|
|
|
|
|
|
|
my $package; |
2811
|
|
|
|
|
|
|
|
2812
|
|
|
|
|
|
|
while (1) { |
2813
|
|
|
|
|
|
|
$temp = $temp->sprevious_sibling |
2814
|
|
|
|
|
|
|
or last; |
2815
|
|
|
|
|
|
|
|
2816
|
|
|
|
|
|
|
if ( $temp->class eq 'PPI::Statement::Package' ) { |
2817
|
|
|
|
|
|
|
$package = $temp; |
2818
|
|
|
|
|
|
|
last; |
2819
|
|
|
|
|
|
|
} |
2820
|
|
|
|
|
|
|
} |
2821
|
|
|
|
|
|
|
|
2822
|
|
|
|
|
|
|
return $package; |
2823
|
|
|
|
|
|
|
} |
2824
|
|
|
|
|
|
|
|
2825
|
|
|
|
|
|
|
=head1 NAME |
2826
|
|
|
|
|
|
|
|
2827
|
|
|
|
|
|
|
Perl::Tags::PPI - use PPI to parse |
2828
|
|
|
|
|
|
|
|
2829
|
|
|
|
|
|
|
=head1 DESCRIPTION |
2830
|
|
|
|
|
|
|
|
2831
|
|
|
|
|
|
|
This is a drop-in replacement for the basic L<Perl::Tags> parser. Please see that module's |
2832
|
|
|
|
|
|
|
perldoc, and test C<t/04_ppi.t> for details. |
2833
|
|
|
|
|
|
|
|
2834
|
|
|
|
|
|
|
(Doc patches very welcome!) |
2835
|
|
|
|
|
|
|
|
2836
|
|
|
|
|
|
|
=head1 AUTHOR |
2837
|
|
|
|
|
|
|
|
2838
|
|
|
|
|
|
|
(c) Wolverian 2006 |
2839
|
|
|
|
|
|
|
|
2840
|
|
|
|
|
|
|
Modifications by nothingmuch |
2841
|
|
|
|
|
|
|
|
2842
|
|
|
|
|
|
|
=cut |
2843
|
|
|
|
|
|
|
|
2844
|
|
|
|
|
|
|
1; |
2845
|
|
|
|
|
|
|
PERL_TAGS_PPI |
2846
|
|
|
|
|
|
|
|
2847
|
1
|
|
|
|
|
14
|
$fatpacked{"Perl/Tags/Tag.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'PERL_TAGS_TAG'; |
2848
|
|
|
|
|
|
|
package Perl::Tags::Tag; |
2849
|
1
|
|
|
1
|
|
4
|
use strict; use warnings; |
|
1
|
|
|
1
|
|
2
|
|
|
1
|
|
|
|
|
28
|
|
|
1
|
|
|
|
|
5
|
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
35
|
|
2850
|
|
|
|
|
|
|
|
2851
|
1
|
|
|
1
|
|
5
|
use overload q("") => \&to_string; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
10
|
|
2852
|
|
|
|
|
|
|
|
2853
|
|
|
|
|
|
|
=head2 C<new> |
2854
|
|
|
|
|
|
|
|
2855
|
|
|
|
|
|
|
Returns a new tag object |
2856
|
|
|
|
|
|
|
|
2857
|
|
|
|
|
|
|
=cut |
2858
|
|
|
|
|
|
|
|
2859
|
|
|
|
|
|
|
sub new { |
2860
|
0
|
|
|
0
|
1
|
|
my $class = shift; |
2861
|
0
|
|
|
|
|
|
my %options = @_; |
2862
|
|
|
|
|
|
|
|
2863
|
0
|
|
|
|
|
|
$options{type} = $class->type; |
2864
|
|
|
|
|
|
|
|
2865
|
|
|
|
|
|
|
# chomp and escape line |
2866
|
0
|
|
|
|
|
|
chomp (my $line = $options{line}); |
2867
|
|
|
|
|
|
|
|
2868
|
0
|
|
|
|
|
|
$line =~ s{\\}{\\\\}g; |
2869
|
0
|
|
|
|
|
|
$line =~ s{/}{\\/}g; |
2870
|
|
|
|
|
|
|
# $line =~ s{\$}{\\\$}g; |
2871
|
|
|
|
|
|
|
|
2872
|
0
|
|
|
|
|
|
my $self = bless { |
2873
|
|
|
|
|
|
|
name => $options{name}, |
2874
|
|
|
|
|
|
|
file => $options{file}, |
2875
|
|
|
|
|
|
|
type => $options{type}, |
2876
|
|
|
|
|
|
|
is_static => $options{is_static}, |
2877
|
|
|
|
|
|
|
line => $line, |
2878
|
|
|
|
|
|
|
linenum => $options{linenum}, |
2879
|
|
|
|
|
|
|
exts => $options{exts}, # exuberant? |
2880
|
|
|
|
|
|
|
pkg => $options{pkg}, # package name |
2881
|
|
|
|
|
|
|
}, $class; |
2882
|
|
|
|
|
|
|
|
2883
|
0
|
|
|
|
|
|
$self->modify_options(); |
2884
|
0
|
|
|
|
|
|
return $self; |
2885
|
|
|
|
|
|
|
} |
2886
|
|
|
|
|
|
|
|
2887
|
|
|
|
|
|
|
=head2 C<type>, C<modify_options> |
2888
|
|
|
|
|
|
|
|
2889
|
|
|
|
|
|
|
Abstract methods |
2890
|
|
|
|
|
|
|
|
2891
|
|
|
|
|
|
|
=cut |
2892
|
|
|
|
|
|
|
|
2893
|
|
|
|
|
|
|
sub type { |
2894
|
0
|
|
|
0
|
1
|
|
die "Tried to call 'type' on virtual superclass"; |
2895
|
|
|
|
|
|
|
} |
2896
|
|
|
|
|
|
|
|
2897
|
0
|
|
|
0
|
1
|
|
sub modify_options { return } # no change |
2898
|
|
|
|
|
|
|
|
2899
|
|
|
|
|
|
|
=head2 C<to_string> |
2900
|
|
|
|
|
|
|
|
2901
|
|
|
|
|
|
|
A tag stringifies to an appropriate line in a ctags file. |
2902
|
|
|
|
|
|
|
|
2903
|
|
|
|
|
|
|
=cut |
2904
|
|
|
|
|
|
|
|
2905
|
|
|
|
|
|
|
sub to_string { |
2906
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
2907
|
|
|
|
|
|
|
|
2908
|
0
|
0
|
|
|
|
|
my $name = $self->{name} or die; |
2909
|
0
|
0
|
|
|
|
|
my $file = $self->{file} or die; |
2910
|
0
|
0
|
|
|
|
|
my $line = $self->{line} or die; |
2911
|
0
|
|
|
|
|
|
my $linenum = $self->{linenum}; |
2912
|
0
|
|
0
|
|
|
|
my $pkg = $self->{pkg} || ''; |
2913
|
|
|
|
|
|
|
|
2914
|
0
|
|
|
|
|
|
my $tagline = "$name\t$file\t/$line/"; |
2915
|
|
|
|
|
|
|
|
2916
|
|
|
|
|
|
|
# Exuberant extensions |
2917
|
0
|
0
|
|
|
|
|
if ($self->{exts}) { |
2918
|
0
|
|
|
|
|
|
$tagline .= qq(;"\t$self->{type}); |
2919
|
0
|
|
|
|
|
|
$tagline .= "\tline:$linenum"; |
2920
|
0
|
0
|
|
|
|
|
$tagline .= ($self->{is_static} ? "\tfile:" : ''); |
2921
|
0
|
0
|
|
|
|
|
$tagline .= ($self->{pkg} ? "\tclass:$self->{pkg}" : ''); |
2922
|
|
|
|
|
|
|
} |
2923
|
0
|
|
|
|
|
|
return $tagline; |
2924
|
|
|
|
|
|
|
} |
2925
|
|
|
|
|
|
|
|
2926
|
|
|
|
|
|
|
=head2 C<on_register> |
2927
|
|
|
|
|
|
|
|
2928
|
|
|
|
|
|
|
Allows tag to meddle with process when registered with the main tagger object. |
2929
|
|
|
|
|
|
|
Return false if want to prevent registration (e.g. for control tags such as |
2930
|
|
|
|
|
|
|
C<Perl::Tags::Tag::Recurse>.) |
2931
|
|
|
|
|
|
|
|
2932
|
|
|
|
|
|
|
=cut |
2933
|
|
|
|
|
|
|
|
2934
|
|
|
|
|
|
|
sub on_register { |
2935
|
|
|
|
|
|
|
# my $self = shift; |
2936
|
|
|
|
|
|
|
# my $tags = shift; |
2937
|
|
|
|
|
|
|
# .... do stuff in subclasses |
2938
|
|
|
|
|
|
|
|
2939
|
0
|
|
|
0
|
1
|
|
return 1; # or undef to prevent registration |
2940
|
|
|
|
|
|
|
} |
2941
|
|
|
|
|
|
|
|
2942
|
|
|
|
|
|
|
=head1 C<Perl::Tags::Tag::Package> |
2943
|
|
|
|
|
|
|
|
2944
|
|
|
|
|
|
|
=head2 C<type>: p |
2945
|
|
|
|
|
|
|
|
2946
|
|
|
|
|
|
|
=head2 C<modify_options> |
2947
|
|
|
|
|
|
|
|
2948
|
|
|
|
|
|
|
Sets static=0 |
2949
|
|
|
|
|
|
|
|
2950
|
|
|
|
|
|
|
=head2 C<on_register> |
2951
|
|
|
|
|
|
|
|
2952
|
|
|
|
|
|
|
Sets the package name |
2953
|
|
|
|
|
|
|
|
2954
|
|
|
|
|
|
|
=cut |
2955
|
|
|
|
|
|
|
|
2956
|
|
|
|
|
|
|
package Perl::Tags::Tag::Package; |
2957
|
|
|
|
|
|
|
our @ISA = qw/Perl::Tags::Tag/; |
2958
|
|
|
|
|
|
|
|
2959
|
|
|
|
|
|
|
# QUOTE: |
2960
|
|
|
|
|
|
|
# Make a tag for this package unless we're told not to. A |
2961
|
|
|
|
|
|
|
# package is never static. |
2962
|
|
|
|
|
|
|
|
2963
|
0
|
|
|
0
|
|
|
sub type { 'p' } |
2964
|
|
|
|
|
|
|
|
2965
|
|
|
|
|
|
|
sub modify_options { |
2966
|
0
|
|
|
0
|
|
|
my $self = shift; |
2967
|
0
|
|
|
|
|
|
$self->{is_static} = 0; |
2968
|
|
|
|
|
|
|
} |
2969
|
|
|
|
|
|
|
|
2970
|
|
|
|
|
|
|
sub on_register { |
2971
|
0
|
|
|
0
|
|
|
my ($self, $tags) = @_; |
2972
|
0
|
|
|
|
|
|
$tags->{current}{package_name} = $self->{name}; |
2973
|
|
|
|
|
|
|
} |
2974
|
|
|
|
|
|
|
|
2975
|
|
|
|
|
|
|
=head1 C<Perl::Tags::Tag::Var> |
2976
|
|
|
|
|
|
|
|
2977
|
|
|
|
|
|
|
=head2 C<type>: v |
2978
|
|
|
|
|
|
|
|
2979
|
|
|
|
|
|
|
=head2 C<on_register> |
2980
|
|
|
|
|
|
|
|
2981
|
|
|
|
|
|
|
Make a tag for this variable unless we're told not to. We |
2982
|
|
|
|
|
|
|
assume that a variable is always static, unless it appears |
2983
|
|
|
|
|
|
|
in a package before any sub. (Not necessarily true, but |
2984
|
|
|
|
|
|
|
it's ok for most purposes and Vim works fine even if it is |
2985
|
|
|
|
|
|
|
incorrect) |
2986
|
|
|
|
|
|
|
- pltags.pl comments |
2987
|
|
|
|
|
|
|
|
2988
|
|
|
|
|
|
|
=cut |
2989
|
|
|
|
|
|
|
|
2990
|
|
|
|
|
|
|
package Perl::Tags::Tag::Var; |
2991
|
|
|
|
|
|
|
our @ISA = qw/Perl::Tags::Tag/; |
2992
|
|
|
|
|
|
|
|
2993
|
0
|
|
|
0
|
|
|
sub type { 'v' } |
2994
|
|
|
|
|
|
|
|
2995
|
|
|
|
|
|
|
# QUOTE: |
2996
|
|
|
|
|
|
|
|
2997
|
|
|
|
|
|
|
sub on_register { |
2998
|
0
|
|
|
0
|
|
|
my ($self, $tags) = @_; |
2999
|
0
|
0
|
0
|
|
|
|
$self->{is_static} = ( $tags->{current}{package_name} || $tags->{current}{has_subs} ) ? 1 : 0; |
3000
|
|
|
|
|
|
|
|
3001
|
0
|
|
|
|
|
|
return 1; |
3002
|
|
|
|
|
|
|
} |
3003
|
|
|
|
|
|
|
=head1 C<Perl::Tags::Tag::Sub> |
3004
|
|
|
|
|
|
|
|
3005
|
|
|
|
|
|
|
=head2 C<type>: s |
3006
|
|
|
|
|
|
|
|
3007
|
|
|
|
|
|
|
=head2 C<on_register> |
3008
|
|
|
|
|
|
|
|
3009
|
|
|
|
|
|
|
Make a tag for this sub unless we're told not to. We assume |
3010
|
|
|
|
|
|
|
that a sub is static, unless it appears in a package. (Not |
3011
|
|
|
|
|
|
|
necessarily true, but it's ok for most purposes and Vim works |
3012
|
|
|
|
|
|
|
fine even if it is incorrect) |
3013
|
|
|
|
|
|
|
- pltags comments |
3014
|
|
|
|
|
|
|
|
3015
|
|
|
|
|
|
|
=cut |
3016
|
|
|
|
|
|
|
|
3017
|
|
|
|
|
|
|
package Perl::Tags::Tag::Sub; |
3018
|
|
|
|
|
|
|
our @ISA = qw/Perl::Tags::Tag/; |
3019
|
|
|
|
|
|
|
|
3020
|
0
|
|
|
0
|
|
|
sub type { 's' } |
3021
|
|
|
|
|
|
|
|
3022
|
|
|
|
|
|
|
sub on_register { |
3023
|
0
|
|
|
0
|
|
|
my ($self, $tags) = @_; |
3024
|
0
|
|
|
|
|
|
$tags->{current}{has_subs}++ ; |
3025
|
0
|
0
|
|
|
|
|
$self->{is_static}++ unless $tags->{current}{package_name}; |
3026
|
|
|
|
|
|
|
|
3027
|
0
|
|
|
|
|
|
return 1; |
3028
|
|
|
|
|
|
|
} |
3029
|
|
|
|
|
|
|
|
3030
|
|
|
|
|
|
|
=head1 C<Perl::Tags::Tag::Constant> |
3031
|
|
|
|
|
|
|
|
3032
|
|
|
|
|
|
|
=head2 C<type>: c |
3033
|
|
|
|
|
|
|
|
3034
|
|
|
|
|
|
|
=cut |
3035
|
|
|
|
|
|
|
|
3036
|
|
|
|
|
|
|
package Perl::Tags::Tag::Constant; |
3037
|
|
|
|
|
|
|
our @ISA = qw/Perl::Tags::Tag/; |
3038
|
|
|
|
|
|
|
|
3039
|
0
|
|
|
0
|
|
|
sub type { 'c' } |
3040
|
|
|
|
|
|
|
|
3041
|
|
|
|
|
|
|
=head1 C<Perl::Tags::Tag::Label> |
3042
|
|
|
|
|
|
|
|
3043
|
|
|
|
|
|
|
=head2 C<type>: l |
3044
|
|
|
|
|
|
|
|
3045
|
|
|
|
|
|
|
=cut |
3046
|
|
|
|
|
|
|
|
3047
|
|
|
|
|
|
|
package Perl::Tags::Tag::Label; |
3048
|
|
|
|
|
|
|
our @ISA = qw/Perl::Tags::Tag/; |
3049
|
|
|
|
|
|
|
|
3050
|
0
|
|
|
0
|
|
|
sub type { 'l' } |
3051
|
|
|
|
|
|
|
|
3052
|
|
|
|
|
|
|
=head1 C<Perl::Tags::Tag::Recurse> |
3053
|
|
|
|
|
|
|
|
3054
|
|
|
|
|
|
|
=head2 C<type>: dummy |
3055
|
|
|
|
|
|
|
|
3056
|
|
|
|
|
|
|
This is a pseudo-tag, see L<Perl::Tags/register>. |
3057
|
|
|
|
|
|
|
|
3058
|
|
|
|
|
|
|
=head2 C<on_register> |
3059
|
|
|
|
|
|
|
|
3060
|
|
|
|
|
|
|
Recurse adding this new module to the queue. |
3061
|
|
|
|
|
|
|
|
3062
|
|
|
|
|
|
|
=cut |
3063
|
|
|
|
|
|
|
|
3064
|
|
|
|
|
|
|
package Perl::Tags::Tag::Recurse; |
3065
|
|
|
|
|
|
|
our @ISA = qw/Perl::Tags::Tag/; |
3066
|
|
|
|
|
|
|
|
3067
|
1
|
|
|
1
|
|
950
|
use Module::Locate qw/locate/; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
6
|
|
3068
|
|
|
|
|
|
|
|
3069
|
0
|
|
|
0
|
|
|
sub type { 'dummy' } |
3070
|
|
|
|
|
|
|
|
3071
|
|
|
|
|
|
|
sub on_register { |
3072
|
0
|
|
|
0
|
|
|
my ($self, $tags) = @_; |
3073
|
|
|
|
|
|
|
|
3074
|
0
|
|
|
|
|
|
my $name = $self->{name}; |
3075
|
0
|
|
|
|
|
|
my $path; |
3076
|
0
|
|
|
|
|
|
eval { |
3077
|
0
|
|
|
|
|
|
$path = locate( $name ); # or warn "Couldn't find path for $name"; |
3078
|
|
|
|
|
|
|
}; |
3079
|
|
|
|
|
|
|
# return if $@; |
3080
|
0
|
0
|
|
|
|
|
return unless $path; |
3081
|
0
|
|
|
|
|
|
$tags->queue( { file=>$path, level=>$tags->{current}{level}+1 , refresh=>0} ); |
3082
|
0
|
|
|
|
|
|
return; # don't get added |
3083
|
|
|
|
|
|
|
} |
3084
|
|
|
|
|
|
|
|
3085
|
|
|
|
|
|
|
1; |
3086
|
|
|
|
|
|
|
PERL_TAGS_TAG |
3087
|
|
|
|
|
|
|
|
3088
|
1
|
|
|
|
|
2
|
$fatpacked{"Test/Perl/Tags.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'TEST_PERL_TAGS'; |
3089
|
|
|
|
|
|
|
package Test::Perl::Tags; |
3090
|
|
|
|
|
|
|
|
3091
|
|
|
|
|
|
|
use strict; use warnings; |
3092
|
|
|
|
|
|
|
use parent 'Test::Builder::Module'; |
3093
|
|
|
|
|
|
|
|
3094
|
|
|
|
|
|
|
use Path::Tiny 'path'; |
3095
|
|
|
|
|
|
|
|
3096
|
|
|
|
|
|
|
our @EXPORT = qw(tag_ok); |
3097
|
|
|
|
|
|
|
|
3098
|
|
|
|
|
|
|
=head1 NAME |
3099
|
|
|
|
|
|
|
|
3100
|
|
|
|
|
|
|
Test::Perl::Tags - testing output of L<Perl::Tags> |
3101
|
|
|
|
|
|
|
|
3102
|
|
|
|
|
|
|
=head1 SYNOPSIS |
3103
|
|
|
|
|
|
|
|
3104
|
|
|
|
|
|
|
use Test::Perl::Tags; |
3105
|
|
|
|
|
|
|
|
3106
|
|
|
|
|
|
|
# do some tagging |
3107
|
|
|
|
|
|
|
|
3108
|
|
|
|
|
|
|
tag_ok $tagger, |
3109
|
|
|
|
|
|
|
SYMBOL => 'path/to/file.pm' => 'searchable bookmark', |
3110
|
|
|
|
|
|
|
'Description of this test'; |
3111
|
|
|
|
|
|
|
|
3112
|
|
|
|
|
|
|
tag_ok $tagger, |
3113
|
|
|
|
|
|
|
SYMBOL => 'path/to/file.pm' => 'searchable bookmark' => 'p' => 'line:3' => 'class:Test', |
3114
|
|
|
|
|
|
|
'Add additional parameters for exuberant extension'; |
3115
|
|
|
|
|
|
|
|
3116
|
|
|
|
|
|
|
=cut |
3117
|
|
|
|
|
|
|
|
3118
|
|
|
|
|
|
|
sub tag_ok { |
3119
|
|
|
|
|
|
|
my ($tagger, $symbol, $path, $bookmark) = splice(@_, 0, 4); |
3120
|
|
|
|
|
|
|
my $description = pop; |
3121
|
|
|
|
|
|
|
|
3122
|
|
|
|
|
|
|
my $canonpath = path($path)->absolute->canonpath; |
3123
|
|
|
|
|
|
|
|
3124
|
|
|
|
|
|
|
my $tag = join "\t", |
3125
|
|
|
|
|
|
|
$symbol, |
3126
|
|
|
|
|
|
|
$canonpath, |
3127
|
|
|
|
|
|
|
"/$bookmark/"; |
3128
|
|
|
|
|
|
|
|
3129
|
|
|
|
|
|
|
# exuberant extensions |
3130
|
|
|
|
|
|
|
if (@_) { |
3131
|
|
|
|
|
|
|
$tag .= join "\t", |
3132
|
|
|
|
|
|
|
q<;">, |
3133
|
|
|
|
|
|
|
@_; |
3134
|
|
|
|
|
|
|
} |
3135
|
|
|
|
|
|
|
|
3136
|
|
|
|
|
|
|
my $ok = $tagger =~ / |
3137
|
|
|
|
|
|
|
^ |
3138
|
|
|
|
|
|
|
\Q$tag\E |
3139
|
|
|
|
|
|
|
$ |
3140
|
|
|
|
|
|
|
/mx; |
3141
|
|
|
|
|
|
|
my $builder = __PACKAGE__->builder; |
3142
|
|
|
|
|
|
|
|
3143
|
|
|
|
|
|
|
$builder->ok( $ok, $description ) |
3144
|
|
|
|
|
|
|
or $builder->diag( "Tags did not match:\n$tag" ); |
3145
|
|
|
|
|
|
|
} |
3146
|
|
|
|
|
|
|
|
3147
|
|
|
|
|
|
|
1; |
3148
|
|
|
|
|
|
|
TEST_PERL_TAGS |
3149
|
|
|
|
|
|
|
|
3150
|
1
|
|
|
|
|
1849
|
s/^ //mg for values %fatpacked; |
3151
|
|
|
|
|
|
|
|
3152
|
1
|
|
|
|
|
5
|
my $class = 'FatPacked::'.(0+\%fatpacked); |
3153
|
1
|
|
|
1
|
|
2798
|
no strict 'refs'; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
339
|
|
3154
|
1
|
|
|
0
|
|
6
|
*{"${class}::files"} = sub { keys %{$_[0]} }; |
|
1
|
|
|
|
|
13
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
3155
|
|
|
|
|
|
|
|
3156
|
1
|
50
|
|
|
|
6
|
if ($] < 5.008) { |
3157
|
0
|
|
|
|
|
0
|
*{"${class}::INC"} = sub { |
3158
|
0
|
0
|
|
|
|
0
|
if (my $fat = $_[0]{$_[1]}) { |
3159
|
|
|
|
|
|
|
return sub { |
3160
|
0
|
0
|
|
|
|
0
|
return 0 unless length $fat; |
3161
|
0
|
|
|
|
|
0
|
$fat =~ s/^([^\n]*\n?)//; |
3162
|
0
|
|
|
|
|
0
|
$_ = $1; |
3163
|
0
|
|
|
|
|
0
|
return 1; |
3164
|
0
|
|
|
|
|
0
|
}; |
3165
|
|
|
|
|
|
|
} |
3166
|
0
|
|
|
|
|
0
|
return; |
3167
|
0
|
|
|
|
|
0
|
}; |
3168
|
|
|
|
|
|
|
} |
3169
|
|
|
|
|
|
|
|
3170
|
|
|
|
|
|
|
else { |
3171
|
1
|
|
|
|
|
5
|
*{"${class}::INC"} = sub { |
3172
|
16
|
100
|
|
16
|
|
2607
|
if (my $fat = $_[0]{$_[1]}) { |
3173
|
6
|
50
|
|
1
|
|
78
|
open my $fh, '<', \$fat |
|
1
|
|
|
|
|
5
|
|
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
8
|
|
3174
|
|
|
|
|
|
|
or die "FatPacker error loading $_[1] (could be a perl installation issue?)"; |
3175
|
6
|
|
|
|
|
744
|
return $fh; |
3176
|
|
|
|
|
|
|
} |
3177
|
10
|
|
|
|
|
10096
|
return; |
3178
|
1
|
|
|
|
|
4
|
}; |
3179
|
|
|
|
|
|
|
} |
3180
|
|
|
|
|
|
|
|
3181
|
1
|
|
|
|
|
23
|
unshift @INC, bless \%fatpacked, $class; |
3182
|
|
|
|
|
|
|
} |
3183
|
|
|
|
|
|
|
|
3184
|
1
|
|
|
1
|
|
29
|
use 5.006; |
|
1
|
|
|
|
|
4
|
|
|
1
|
|
|
|
|
36
|
|
3185
|
1
|
|
|
1
|
|
6
|
use strict; use warnings; |
|
1
|
|
|
1
|
|
2
|
|
|
1
|
|
|
|
|
28
|
|
|
1
|
|
|
|
|
5
|
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
33
|
|
3186
|
|
|
|
|
|
|
|
3187
|
1
|
|
|
1
|
|
13
|
use Perl::Tags; |
|
1
|
|
|
|
|
4
|
|
|
1
|
|
|
|
|
29
|
|
3188
|
1
|
|
|
1
|
|
12
|
use Perl::Tags::Hybrid; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
28
|
|
3189
|
1
|
|
|
1
|
|
11
|
use Perl::Tags::Naive::Moose; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
39
|
|
3190
|
|
|
|
|
|
|
|
3191
|
|
|
|
|
|
|
|
3192
|
|
|
|
|
|
|
|
3193
|
|
|
|
|
|
|
|
3194
|
|
|
|
|
|
|
|
3195
|
|
|
|
|
|
|
|
3196
|
|
|
|
|
|
|
|
3197
|
|
|
|
|
|
|
|
3198
|
|
|
|
|
|
|
|
3199
|
|
|
|
|
|
|
1; |
3200
|
|
|
|
|
|
|
|