File Coverage

blib/lib/Parse/PMFile.pm
Criterion Covered Total %
statement 324 487 66.5
branch 149 248 60.0
condition 54 143 37.7
subroutine 32 41 78.0
pod 2 2 100.0
total 561 921 60.9


line stmt bran cond sub pod time code
1             package Parse::PMFile;
2              
3 134     134   21773 sub __clean_eval { eval $_[0] } # needs to be here (RT#101273)
4              
5 63     63   7490762 use strict;
  63         145  
  63         2572  
6 63     63   745 use warnings;
  63         136  
  63         3436  
7 63     63   35581 use Safe;
  63         775187  
  63         2247  
8 63     63   47206 use JSON::PP ();
  63         1432934  
  63         2099  
9 63     63   31423 use Dumpvalue;
  63         365931  
  63         2609  
10 63     63   27807 use version ();
  63         132725  
  63         2080  
11 63     63   418 use File::Spec ();
  63         100  
  63         100307  
12              
13             our $VERSION = '0.47';
14             our $VERBOSE = 0;
15             our $ALLOW_DEV_VERSION = 0;
16             our $FORK = 0;
17             our $UNSAFE = $] < 5.010000 ? 1 : 0;
18              
19             sub new {
20 237     237 1 11543543 my ($class, $meta, $opts) = @_;
21 237 100       628 bless {%{ $opts || {} }, META_CONTENT => $meta}, $class;
  237         3299  
22             }
23              
24             # from PAUSE::pmfile::examine_fio
25             sub parse {
26 238     238 1 10216 my ($self, $pmfile) = @_;
27              
28 238         787 $pmfile =~ s|\\|/|g;
29              
30 238         5730 my($filemtime) = (stat $pmfile)[9];
31 238         1189 $self->{MTIME} = $filemtime;
32 238         794 $self->{PMFILE} = $pmfile;
33              
34 238 100       926 unless ($self->_version_from_meta_ok) {
35 232         526 my $version;
36 232 50       569 unless (eval { $version = $self->_parse_version; 1 }) {
  232         957  
  195         1187  
37 0         0 $self->_verbose(1, "error with version in $pmfile: $@");
38 0         0 return;
39             }
40              
41 195         1072 $self->{VERSION} = $version;
42 195 50 66     2722 if ($self->{VERSION} =~ /^\{.*\}$/) {
    100 100        
43             # JSON error message
44             } elsif ($self->{VERSION} =~ /[_\s]/ && !$self->{ALLOW_DEV_VERSION} && !$ALLOW_DEV_VERSION){ # ignore developer releases and "You suck!"
45 5         91 return;
46             }
47             }
48              
49 196         1678 my($ppp) = $self->_packages_per_pmfile;
50 196         1612 my @keys_ppp = $self->_filter_ppps(sort keys %$ppp);
51 196         1036 $self->_verbose(1,"Will check keys_ppp[@keys_ppp]\n");
52              
53             #
54             # Immediately after each package (pmfile) examined contact
55             # the database
56             #
57              
58 196         578 my ($package, %errors);
59 196         0 my %checked_in;
60 196         461 DBPACK: foreach $package (@keys_ppp) {
61             # this part is taken from PAUSE::package::examine_pkg
62             # and PAUSE::package::_pkg_name_insane
63 196 50 33     6070 if ($package !~ /^\w[\w\:\']*\w?\z/
      33        
      33        
      33        
      33        
64             || $package !~ /\w\z/
65             || $package =~ /:/ && $package !~ /::/
66             || $package =~ /\w:\w/
67             || $package =~ /:::/
68             ){
69 0         0 $self->_verbose(1,"Package[$package] did not pass the ultimate sanity check");
70 0         0 delete $ppp->{$package};
71 0         0 next;
72             }
73              
74 196 0 33     712 if ($self->{USERID} && $self->{PERMISSIONS} && !$self->_perm_check($package)) {
      0        
75 0         0 delete $ppp->{$package};
76 0         0 next;
77             }
78              
79             # Check that package name matches case of file name
80             {
81 196         299 my (undef, $module) = split m{/lib/}, $self->{PMFILE}, 2;
  196         1225  
82 196 100       585 if ($module) {
83 6         32 $module =~ s{\.pm\z}{};
84 6         19 $module =~ s{/}{::}g;
85              
86 6 50 33     84 if (lc $module eq lc $package && $module ne $package) {
87             # warn "/// $self->{PMFILE} vs. $module vs. $package\n";
88             $errors{$package} = {
89             indexing_warning => "Capitalization of package ($package) does not match filename!",
90             infile => $self->{PMFILE},
91 0         0 };
92             }
93             }
94             }
95              
96 196         585 my $pp = $ppp->{$package};
97 196 50 66     1783 if ($pp->{version} && $pp->{version} =~ /^\{.*\}$/) { # JSON parser error
98 0         0 my $err = JSON::PP::decode_json($pp->{version});
99 0 0       0 if ($err->{x_normalize}) {
    0          
100             $errors{$package} = {
101             normalize => $err->{version},
102             infile => $pp->{infile},
103 0         0 };
104 0         0 $pp->{version} = "undef";
105             } elsif ($err->{openerr}) {
106 0         0 $pp->{version} = "undef";
107 0         0 $self->_verbose(1,
108             qq{Parse::PMFile was not able to
109             read the file. It issued the following error: C< $err->{r} >},
110             );
111             $errors{$package} = {
112             open => $err->{r},
113             infile => $pp->{infile},
114 0         0 };
115             } else {
116 0         0 $pp->{version} = "undef";
117 0         0 $self->_verbose(1,
118             qq{Parse::PMFile was not able to
119             parse the following line in that file: C< $err->{line} >
120              
121             Note: the indexer is running in a Safe compartement and cannot
122             provide the full functionality of perl in the VERSION line. It
123             is trying hard, but sometime it fails. As a workaround, please
124             consider writing a META.yml that contains a 'provides'
125             attribute or contact the CPAN admins to investigate (yet
126             another) workaround against "Safe" limitations.)},
127              
128             );
129             $errors{$package} = {
130             parse_version => $err->{line},
131             infile => $err->{file},
132 0         0 };
133             }
134             }
135              
136             # Sanity checks
137              
138 196         567 for (
139             $package,
140             $pp->{version},
141             ) {
142 392 50 66     3494 if (!defined || /^\s*$/ || /\s/){ # for whatever reason I come here
      66        
143 4         10 delete $ppp->{$package};
144 4         6 next; # don't screw up 02packages
145             }
146             }
147 196 100       1007 unless ($self->_version_ok($pp)) {
148             $errors{$package} = {
149             long_version => qq{Version string exceeds maximum allowed length of 16b: "$pp->{version}"},
150             infile => $pp->{infile},
151 3         24 };
152 3         10 next;
153             }
154 193         744 $checked_in{$package} = $ppp->{$package};
155             } # end foreach package
156              
157 196 100 66     2042 return (wantarray && %errors) ? (\%checked_in, \%errors) : \%checked_in;
158             }
159              
160             sub _version_ok {
161 196     196   631 my ($self, $pp) = @_;
162 196 100 100     943 return if length($pp->{version} || 0) > 16;
163 193         731 return 1
164             }
165              
166             sub _perm_check {
167 0     0   0 my ($self, $package) = @_;
168 0         0 my $userid = $self->{USERID};
169 0         0 my $module = $self->{PERMISSIONS}->module_permissions($package);
170 0 0       0 return 1 if !$module; # not listed yet
171 0 0 0     0 return 1 if defined $module->m && $module->m eq $userid;
172 0 0 0     0 return 1 if defined $module->f && $module->f eq $userid;
173 0 0 0     0 return 1 if defined $module->c && grep {$_ eq $userid} @{$module->c};
  0         0  
  0         0  
174 0         0 return;
175             }
176              
177             # from PAUSE::pmfile;
178             sub _parse_version {
179 232     232   462 my $self = shift;
180              
181 63     63   629 use strict;
  63         150  
  63         24545  
182              
183 232         563 my $pmfile = $self->{PMFILE};
184 232         15011 my $tmpfile = File::Spec->catfile(File::Spec->tmpdir, "ParsePMFile$$" . rand(1000));
185              
186 232         847 my $pmcp = $pmfile;
187 232         816 for ($pmcp) {
188 232         849 s/([^\\](\\\\)*)@/$1\\@/g; # thanks to Raphael Manfredi for the
189             # solution to escape @s and \
190             }
191 232         392 my($v);
192             {
193              
194 232         349 package main; # seems necessary
195              
196             # XXX: do we need to fork as PAUSE does?
197             # or, is alarm() just fine?
198 232         359 my $pid;
199 232 100 66     1815 if ($self->{FORK} || $FORK) {
200 115         321000 $pid = fork();
201 115 50       14188 die "Can't fork: $!" unless defined $pid;
202             }
203 232 100       3308 if ($pid) {
204 78         47068728 waitpid($pid, 0);
205 78 50       16548 if (open my $fh, '<', $tmpfile) {
206 78         11149 $v = <$fh>;
207             }
208             } else {
209             # XXX Limit Resources too
210              
211 154         1322 my $comp;
212 154         1774 my $eval = qq{
213             local(\$^W) = 0;
214             Parse::PMFile::_parse_version_safely("$pmcp");
215             };
216 154 50 33     3799 unless ($self->{UNSAFE} || $UNSAFE) {
217 154         9147 $comp = Safe->new;
218 154         335217 $comp->permit("entereval"); # for MBARBON/Module-Info-0.30.tar.gz
219 154         2426 $comp->share("*Parse::PMFile::_parse_version_safely");
220 154         19335 $comp->share("*version::new");
221 154         9273 $comp->share("*version::numify");
222 154         9815 $comp->share_from('main', ['*version::',
223             '*charstar::',
224             '*Exporter::',
225             '*DynaLoader::']);
226 154         194588 $comp->share_from('version', ['&qv']);
227 154         9198 $comp->permit(":base_math"); # atan2 (Acme-Pi)
228             # $comp->permit("require"); # no strict!
229 154         1854 $comp->deny(qw/enteriter iter unstack goto/); # minimum protection against Acme::BadExample
230             }
231              
232 154 50 33     5227 version->import('qv') if $self->{UNSAFE} || $UNSAFE;
233             {
234 63     63   446 no strict;
  63         111  
  63         32720  
  154         957  
235 154 50       2361 $v = $comp ? $comp->reval($eval) : eval $eval;
236             }
237 154 100       201079 if ($@){ # still in the child process, out of Safe::reval
238 21         117 my $err = $@;
239             # warn ">>>>>>>err[$err]<<<<<<<<";
240 21 50       182 if (ref $err) {
241 21 50       390 if ($err->{line} =~ /([\$*])([\w\:\']*)\bVERSION\b.*?\=(.*)/) {
242 21         129 local($^W) = 0;
243 21         213 my ($sigil, $vstr) = ($1, $3);
244 21 50       457 $self->_restore_overloaded_stuff(1) if $err->{line} =~ /use\s+version\b|version\->|qv\(/;
245 21 50       121 $v = $comp ? $comp->reval($vstr) : eval $vstr;
246 21 50 33     24735 $v = $$v if $sigil eq '*' && ref $v;
247             }
248 21 50 33     552 if ($@ or !$v) {
249 0         0 $self->_verbose(1, sprintf("reval failed: err[%s] for eval[%s]",
250             JSON::PP::encode_json($err),
251             $eval,
252             ));
253 0         0 $v = JSON::PP::encode_json($err);
254             }
255             } else {
256 0         0 $v = JSON::PP::encode_json({ openerr => $err });
257             }
258             }
259 154 50       1093 if (defined $v) {
260 63     63   474 no warnings;
  63         131  
  63         21080  
261 154 100       2133 $v = $v->numify if ref($v) =~ /^version(::vpp)?$/;
262             } else {
263 0         0 $v = "";
264             }
265 154 100 66     3317 if ($self->{FORK} || $FORK) {
266 37         12114 open my $fh, '>:utf8', $tmpfile;
267 37         783 print $fh $v;
268 37         3473 exit 0;
269             } else {
270 117         638 utf8::encode($v);
271             # undefine empty $v as if read from the tmpfile
272 117 50 33     732 $v = undef if defined $v && !length $v;
273 117 50       848 $comp->erase if ($comp);
274 117         122725 $self->_restore_overloaded_stuff;
275             }
276             }
277             }
278 195 100 66     32294 unlink $tmpfile if ($self->{FORK} || $FORK) && -e $tmpfile;
      66        
279              
280 195         2502 return $self->_normalize_version($v);
281             }
282              
283             sub _restore_overloaded_stuff {
284 138     138   895 my ($self, $used_version_in_safe) = @_;
285 138 50 33     1077 return if $self->{UNSAFE} || $UNSAFE;
286              
287 63     63   442 no strict 'refs';
  63         173  
  63         2273  
288 63     63   330 no warnings 'redefine';
  63         100  
  63         102715  
289              
290             # version XS in CPAN
291 138         303 my $restored;
292 138 50       591 if ($INC{'version/vxs.pm'}) {
293 0         0 *{'version::(""'} = \&version::vxs::stringify;
  0         0  
294 0         0 *{'version::(0+'} = \&version::vxs::numify;
  0         0  
295 0         0 *{'version::(cmp'} = \&version::vxs::VCMP;
  0         0  
296 0         0 *{'version::(<=>'} = \&version::vxs::VCMP;
  0         0  
297 0         0 *{'version::(bool'} = \&version::vxs::boolean;
  0         0  
298 0         0 $restored = 1;
299             }
300             # version PP in CPAN
301 138 50       554 if ($INC{'version/vpp.pm'}) {
302             {
303 0         0 package # hide from PAUSE
304             charstar;
305 0         0 overload->import;
306             }
307 0 0       0 if (!$used_version_in_safe) {
308             package # hide from PAUSE
309             version::vpp;
310 0         0 overload->import;
311             }
312 0 0       0 unless ($restored) {
313 0         0 *{'version::(""'} = \&version::vpp::stringify;
  0         0  
314 0         0 *{'version::(0+'} = \&version::vpp::numify;
  0         0  
315 0         0 *{'version::(cmp'} = \&version::vpp::vcmp;
  0         0  
316 0         0 *{'version::(<=>'} = \&version::vpp::vcmp;
  0         0  
317 0         0 *{'version::(bool'} = \&version::vpp::vbool;
  0         0  
318             }
319 0         0 *{'version::vpp::(""'} = \&version::vpp::stringify;
  0         0  
320 0         0 *{'version::vpp::(0+'} = \&version::vpp::numify;
  0         0  
321 0         0 *{'version::vpp::(cmp'} = \&version::vpp::vcmp;
  0         0  
322 0         0 *{'version::vpp::(<=>'} = \&version::vpp::vcmp;
  0         0  
323 0         0 *{'version::vpp::(bool'} = \&version::vpp::vbool;
  0         0  
324 0         0 *{'charstar::(""'} = \&charstar::thischar;
  0         0  
325 0         0 *{'charstar::(0+'} = \&charstar::thischar;
  0         0  
326 0         0 *{'charstar::(++'} = \&charstar::increment;
  0         0  
327 0         0 *{'charstar::(--'} = \&charstar::decrement;
  0         0  
328 0         0 *{'charstar::(+'} = \&charstar::plus;
  0         0  
329 0         0 *{'charstar::(-'} = \&charstar::minus;
  0         0  
330 0         0 *{'charstar::(*'} = \&charstar::multiply;
  0         0  
331 0         0 *{'charstar::(cmp'} = \&charstar::cmp;
  0         0  
332 0         0 *{'charstar::(<=>'} = \&charstar::spaceship;
  0         0  
333 0         0 *{'charstar::(bool'} = \&charstar::thischar;
  0         0  
334 0         0 *{'charstar::(='} = \&charstar::clone;
  0         0  
335 0         0 $restored = 1;
336             }
337             # version in core
338 138 50       390 if (!$restored) {
339 138         320 *{'version::(""'} = \&version::stringify;
  138         551  
340 138         419 *{'version::(0+'} = \&version::numify;
  138         419  
341 138         1427 *{'version::(cmp'} = \&version::vcmp;
  138         382  
342 138         260 *{'version::(<=>'} = \&version::vcmp;
  138         343  
343 138         278 *{'version::(bool'} = \&version::boolean;
  138         915  
344             }
345             }
346              
347             # from PAUSE::pmfile;
348             sub _packages_per_pmfile {
349 196     196   448 my $self = shift;
350              
351 196         428 my $ppp = {};
352 196         489 my $pmfile = $self->{PMFILE};
353 196         446 my $filemtime = $self->{MTIME};
354 196         742 my $version = $self->{VERSION};
355              
356 196 50       11670 open my $fh, "<", "$pmfile" or return $ppp;
357              
358 196         2167 local $/ = "\n";
359 196         424 my $inpod = 0;
360              
361 196         626 my $package_or_class = 'package';
362 196         394 my $checked_bom;
363 196         4904 PLINE: while (<$fh>) {
364 5988         7241 chomp;
365 5988         8830 my($pline) = $_;
366 5988 100       9576 $pline =~ s/\A(?:\x00\x00\xfe\xff|\xff\xfe\x00\x00|\xfe\xff|\xff\xfe|\xef\xbb\xbf)// unless $checked_bom;
367 5988         6859 $checked_bom = 1;
368 5988 100       11107 $inpod = $pline =~ /^=(?!cut)/ ? 1 :
    100          
369             $pline =~ /^=cut/ ? 0 : $inpod;
370 5988 100       8722 next if $inpod;
371 5928 100       9877 next if substr($pline,0,4) eq "=cut";
372              
373 5922         8336 $pline =~ s/\#.*//;
374 5922 100       14952 next if $pline =~ /^\s*$/;
375 4684 100 66     8536 if ($pline =~ /^__(?:END|DATA)__\b/
376             and $pmfile !~ /\.PL$/ # PL files may well have code after __DATA__
377             ){
378 9         33 last PLINE;
379             }
380              
381             =pod
382             # hide in the pod block until 'class' is added to a version bundle
383             if ($pline =~ /^[\s\{;]*use\s(+v?5\.[0-9]+)/) {
384             my $version = $1;
385             my $version_bundle_for_class = version->parse("v5.xx.xx");
386             if (eval { version->parse($version) >= $version_bundle_for_class) {
387             $package_or_class = 'package|class|role';
388             }
389             next PLINE;
390             }
391             =cut
392              
393             # use feature 'class'; enabels class (and role, though not implemented yet)
394 4675 100       8129 if ($pline =~ /^[\s\{;]*use\s+(?:feature|experimental)\s+[^;]+\b(?:class|all)[^;]*;/) {
395 48         142 $package_or_class = 'package|class';
396             }
397              
398             # some modules also enables class and role
399             # XXX: what to do with MooseX::Declare and a few minor experiments)
400 4675 50       7400 if ($pline =~ /^[\s\{;]*use\s+(?:Feature::Compat::Class)[^;]*;/) {
401 0         0 $package_or_class = 'package|class';
402             }
403 4675 100       7709 if ($pline =~ /^[\s\{;]*use\s+(?:Object::Pad)[^;]*;/) {
404 48         162 $package_or_class = 'package|class|role';
405             }
406              
407 4675         5519 my $pkg;
408             my $strict_version;
409              
410 4675 100       36609 if (
411             $pline =~ m{
412             # (.*) # takes too much time if $pline is long
413             #(?
414             ^[\s\{;]*
415             \b(?:$package_or_class)\s+
416             ([\w\:\']+)
417             \s*
418             (?: $ | [\}\;] | \{ | \s+($version::STRICT) )
419             }x) {
420 205         992 $pkg = $1;
421 205         487 $strict_version = $2;
422 205 50       635 if ($pkg eq "DB"){
423             # XXX if pumpkin and perl make him comaintainer! I
424             # think I always made the pumpkins comaint on DB
425             # without further ado (?)
426 0         0 next PLINE;
427             }
428             }
429              
430 4675 100       11152 if ($pkg) {
431             # Found something
432              
433             # from package
434 205         597 $pkg =~ s/\'/::/g;
435 205 50       1089 next PLINE unless $pkg =~ /^[A-Za-z]/;
436 205 50       1065 next PLINE unless $pkg =~ /\w$/;
437 205 100       565 next PLINE if $pkg eq "main";
438             # Perl::Critic::Policy::TestingAndDebugging::ProhibitShebangWarningsArg
439             # database for modid in mods, package in packages, package in perms
440             # alter table mods modify modid varchar(128) binary NOT NULL default '';
441             # alter table packages modify package varchar(128) binary NOT NULL default '';
442 199 50       653 next PLINE if length($pkg) > 128;
443             #restriction
444 199         1453 $ppp->{$pkg}{parsed}++;
445 199         787 $ppp->{$pkg}{infile} = $pmfile;
446 199 100       1022 if ($self->_simile($pmfile,$pkg)) {
447 193         797 $ppp->{$pkg}{simile} = $pmfile;
448 193 100       806 if ($self->_version_from_meta_ok) {
449 6         23 my $provides = $self->{META_CONTENT}{provides};
450 6 50       21 if (exists $provides->{$pkg}) {
451 6 50       16 if (defined $provides->{$pkg}{version}) {
452 6         17 my $v = $provides->{$pkg}{version};
453 6 100 33     80 if ($v =~ /[_\s]/ && !$self->{ALLOW_DEV_VERSION} && !$ALLOW_DEV_VERSION){ # ignore developer releases and "You suck!"
      66        
454 4         28 next PLINE;
455             }
456              
457 2 50       10 unless (eval { $version = $self->_normalize_version($v); 1 }) {
  2         11  
  2         23  
458 0         0 $self->_verbose(1, "error with version in $pmfile: $@");
459 0         0 next;
460              
461             }
462 2         11 $ppp->{$pkg}{version} = $version;
463             } else {
464 0         0 $ppp->{$pkg}{version} = "undef";
465             }
466             }
467             } else {
468 187 100       685 if (defined $strict_version){
469 19         111 $ppp->{$pkg}{version} = $strict_version ;
470             } else {
471 168 50       642 $ppp->{$pkg}{version} = defined $version ? $version : "";
472             }
473 63     63   514 no warnings;
  63         106  
  63         18732  
474 187 100       683 if ($version eq 'undef') {
475 19 50       87 $ppp->{$pkg}{version} = $version unless defined $ppp->{$pkg}{version};
476             } else {
477             $ppp->{$pkg}{version} =
478             $version
479             if $version
480             > $ppp->{$pkg}{version} ||
481             $version
482 168 50 33     1566 gt $ppp->{$pkg}{version};
483             }
484             }
485             } else { # not simile
486             #### it comes later, it would be nonsense
487             #### to set to "undef". MM_Unix gives us
488             #### the best we can reasonably consider
489             $ppp->{$pkg}{version} =
490             $version
491             unless defined $ppp->{$pkg}{version} &&
492 6 50 33     27 length($ppp->{$pkg}{version});
493             }
494 195         699 $ppp->{$pkg}{filemtime} = $filemtime;
495 195         955 $ppp->{$pkg}{version} .= ""; # make sure to stringify version
496             } else {
497             # $self->_verbose(2,"no pkg found");
498             }
499             }
500              
501 196         2663 close $fh;
502 196         2623 $ppp;
503             }
504              
505             # from PAUSE::pmfile;
506             {
507 63     63   444 no strict;
  63         100  
  63         49254  
508             sub _parse_version_safely {
509 154     154   71397 my($parsefile) = @_;
510 154         755 my $result;
511 154         1310 local *FH;
512 154         2083 local $/ = "\n";
513 154 50       12001 open(FH,$parsefile) or die "Could not open '$parsefile': $!";
514 154         1552 my $inpod = 0;
515 154         7240 while () {
516 503 50       3389 $inpod = /^=(?!cut)/ ? 1 : /^=cut/ ? 0 : $inpod;
    50          
517 503 50 33     3985 next if $inpod || /^\s*#/;
518 503 100       1827 last if /^__(?:END|DATA)__\b/; # fails on quoted __END__ but this is rare -> __END__ in the middle of a line is rarer
519 500         1335 chop;
520              
521 500 100       2310 if (my ($ver) = /package \s+ \S+ \s+ (\S+) \s* [;{]/x) {
522             # XXX: should handle this better if version is bogus -- rjbs,
523             # 2014-03-16
524 6 100       87 return $ver if version::is_lax($ver);
525             }
526              
527             # next unless /\$(([\w\:\']*)\bVERSION)\b.*\=/;
528 497 100       4467 next unless /(?<=])\=(?![=>])/;
529 134         451 my $current_parsed_line = $_;
530 134         2638 my $eval = qq{
531             package #
532             ExtUtils::MakeMaker::_version;
533              
534             local $1$2;
535             \$$2=undef; do {
536             $_
537             }; \$$2
538             };
539 134         1609 local $^W = 0;
540 134     0   2708 local $SIG{__WARN__} = sub {};
541 134         1245 $result = __clean_eval($eval);
542             # warn "current_parsed_line[$current_parsed_line]\$\@[$@]";
543 134 100 66     1657 if ($@ or !defined $result){
544 21         1441 die +{
545             eval => $eval,
546             line => $current_parsed_line,
547             file => $parsefile,
548             err => $@,
549             };
550             }
551 113         729 last;
552             } #;
553 130         3309 close FH;
554              
555 130 100       643 $result = "undef" unless defined $result;
556 130 100       514 if ((ref $result) =~ /^version(?:::vpp)?\b/) {
557 63     63   635 no warnings;
  63         211  
  63         57008  
558 6         46 $result = $result->numify;
559             }
560 130         4147 return $result;
561             }
562             }
563              
564             # from PAUSE::pmfile;
565             sub _filter_ppps {
566 196     196   892 my($self,@ppps) = @_;
567 196         362 my @res;
568              
569             # very similar code is in PAUSE::dist::filter_pms
570 196         551 MANI: for my $ppp ( @ppps ) {
571 199 100       765 if ($self->{META_CONTENT}){
572             my $no_index = $self->{META_CONTENT}{no_index}
573 9   66     51 || $self->{META_CONTENT}{private}; # backward compat
574 9 100       34 if (ref($no_index) eq 'HASH') {
575 3         31 my %map = (
576             package => qr{\z},
577             namespace => qr{::},
578             );
579 3         8 for my $k (qw(package namespace)) {
580 3 50       13 next unless my $v = $no_index->{$k};
581 3         5 my $rest = $map{$k};
582 3 50       10 if (ref $v eq "ARRAY") {
583 3         7 for my $ve (@$v) {
584 3         8 $ve =~ s|::$||;
585 3 50       54 if ($ppp =~ /^$ve$rest/){
586 3         19 $self->_verbose(1,"Skipping ppp[$ppp] due to ve[$ve]");
587 3         19 next MANI;
588             } else {
589 0         0 $self->_verbose(1,"NOT skipping ppp[$ppp] due to ve[$ve]");
590             }
591             }
592             } else {
593 0         0 $v =~ s|::$||;
594 0 0       0 if ($ppp =~ /^$v$rest/){
595 0         0 $self->_verbose(1,"Skipping ppp[$ppp] due to v[$v]");
596 0         0 next MANI;
597             } else {
598 0         0 $self->_verbose(1,"NOT skipping ppp[$ppp] due to v[$v]");
599             }
600             }
601             }
602             } else {
603 6         19 $self->_verbose(1,"No keyword 'no_index' or 'private' in META_CONTENT");
604             }
605             } else {
606             # $self->_verbose(1,"no META_CONTENT"); # too noisy
607             }
608 196         728 push @res, $ppp;
609             }
610 196         1282 $self->_verbose(1,"Result of filter_ppps: res[@res]");
611 196         727 @res;
612             }
613              
614             # from PAUSE::pmfile;
615             sub _simile {
616 199     199   1057 my($self,$file,$package) = @_;
617             # MakeMaker gives them the chance to have the file Simple.pm in
618             # this directory but have the package HTML::Simple in it.
619             # Afaik, they wouldn't be able to do so with deeper nested packages
620 199         1761 $file =~ s|.*/||;
621 199         1292 $file =~ s|\.pm(?:\.PL)?||;
622 199         2499 my $ret = $package =~ m/\b\Q$file\E$/;
623 199   100     667 $ret ||= 0;
624 199 100       536 unless ($ret) {
625             # Apache::mod_perl_guide stuffs it into Version.pm
626 6 50       18 $ret = 1 if lc $file eq 'version';
627             }
628 199         1432 $self->_verbose(1,"Result of simile(): file[$file] package[$package] ret[$ret]\n");
629 199         678 $ret;
630             }
631              
632             # from PAUSE::pmfile
633             sub _normalize_version {
634 197     197   1024 my($self,$v) = @_;
635 197 50       763 $v = "undef" unless defined $v;
636 197         3825 my $dv = Dumpvalue->new;
637 197         14479 my $sdv = $dv->stringify($v,1); # second argument prevents ticks
638 197         10526 $self->_verbose(1,"Result of normalize_version: sdv[$sdv]\n");
639              
640 197 100       1303 return $v if $v eq "undef";
641 178 50       1329 return $v if $v =~ /^\{.*\}$/; # JSON object
642 178         1017 $v =~ s/^\s+//;
643 178         764 $v =~ s/\s+\z//;
644 178 100       1025 if ($v =~ /_/) {
645             # XXX should pass something like EDEVELOPERRELEASE up e.g.
646             # SIXTEASE/XML-Entities-0.0306.tar.gz had nothing but one
647             # such modules and the mesage was not helpful that "nothing
648             # was found".
649 10         122 return $v ;
650             }
651 168 50       1484 if (!version::is_lax($v)) {
652 0         0 return JSON::PP::encode_json({ x_normalize => 'version::is_lax failed', version => $v });
653             }
654             # may warn "Integer overflow"
655 63     63   586 my $vv = eval { no warnings; version->new($v)->numify };
  63         217  
  63         10360  
  168         12162  
  168         5118  
656 168 50       1053 if ($@) {
657             # warn "$v: $@";
658 0         0 return JSON::PP::encode_json({ x_normalize => $@, version => $v });
659             # return "undef";
660             }
661 168 100       852 if ($vv eq $v) {
662             # the boring 3.14
663             } else {
664 141         901 my $forced = $self->_force_numeric($v);
665 141 50       855 if ($forced eq $vv) {
    50          
666             } elsif ($forced =~ /^v(.+)/) {
667             # rare case where a v1.0.23 slipped in (JANL/w3mir-1.0.10.tar.gz)
668 63     63   443 no warnings;
  63         560  
  63         123743  
669 0         0 $vv = version->new($1)->numify;
670             } else {
671             # warn "Unequal forced[$forced] and vv[$vv]";
672 141 50       1526 if ($forced == $vv) {
673             # the trailing zeroes would cause unnecessary havoc
674 141         306 $vv = $forced;
675             }
676             }
677             }
678 168         2924 return $vv;
679             }
680              
681             # from PAUSE::pmfile;
682             sub _force_numeric {
683 141     141   771 my($self,$v) = @_;
684 141         940 $v = $self->_readable($v);
685              
686 141 50 33     2426 if (
      33        
687             $v =~
688             /^(\+?)(\d*)(\.(\d*))?/ &&
689             # "$2$4" ne ''
690             (
691             defined $2 && length $2
692             ||
693             defined $4 && length $4
694             )
695             ) {
696 141 50       678 my $two = defined $2 ? $2 : "";
697 141 50       1168 my $three = defined $3 ? $3 : "";
698 141         503 $v = "$two$three";
699             }
700             # no else branch! We simply say, everything else is a string.
701 141         421 $v;
702             }
703              
704             # from PAUSE::dist
705             sub _version_from_meta_ok {
706 431     431   1094 my($self) = @_;
707 431 100       1972 return $self->{VERSION_FROM_META_OK} if exists $self->{VERSION_FROM_META_OK};
708 237         547 my $c = $self->{META_CONTENT};
709              
710             # If there's no provides hash, we can't get our module versions from the
711             # provides hash! -- rjbs, 2012-03-31
712 237 100       2202 return($self->{VERSION_FROM_META_OK} = 0) unless $c->{provides};
713              
714             # Some versions of Module::Build geneated an empty provides hash. If we're
715             # *not* looking at a Module::Build-generated metafile, then it's okay.
716 6 50       45 my ($mb_v) = (defined $c->{generated_by} ? $c->{generated_by} : '') =~ /Module::Build version ([\d\.]+)/;
717 6 50       40 return($self->{VERSION_FROM_META_OK} = 1) unless $mb_v;
718              
719             # ??? I don't know why this is here.
720 0 0       0 return($self->{VERSION_FROM_META_OK} = 1) if $mb_v eq '0.250.0';
721              
722 0 0 0     0 if ($mb_v >= 0.19 && $mb_v < 0.26 && ! keys %{$c->{provides}}) {
  0   0     0  
723             # RSAVAGE/Javascript-SHA1-1.01.tgz had an empty provides hash. Ron
724             # did not find the reason why this happened, but let's not go
725             # overboard, 0.26 seems a good threshold from the statistics: there
726             # are not many empty provides hashes from 0.26 up.
727 0         0 return($self->{VERSION_FROM_META_OK} = 0);
728             }
729              
730             # We're not in the suspect range of M::B versions. It's good to go.
731 0         0 return($self->{VERSION_FROM_META_OK} = 1);
732             }
733              
734             sub _verbose {
735 797     797   2039 my($self,$level,@what) = @_;
736 797 50 33     7841 warn @what if $level <= ((ref $self && $self->{VERBOSE}) || $VERBOSE);
737             }
738              
739             # all of the following methods are stripped from CPAN::Version
740             # (as of version 5.5001, bundled in CPAN 2.03), and slightly
741             # modified (ie. made private, as well as CPAN->debug(...) are
742             # replaced with $self->_verbose(9, ...).)
743              
744             # CPAN::Version::vcmp courtesy Jost Krieger
745             sub _vcmp {
746 0     0   0 my($self,$l,$r) = @_;
747 0         0 local($^W) = 0;
748 0         0 $self->_verbose(9, "l[$l] r[$r]");
749              
750 0 0       0 return 0 if $l eq $r; # short circuit for quicker success
751              
752 0         0 for ($l,$r) {
753 0         0 s/_//g;
754             }
755 0         0 $self->_verbose(9, "l[$l] r[$r]");
756 0         0 for ($l,$r) {
757 0 0 0     0 next unless tr/.// > 1 || /^v/;
758 0         0 s/^v?/v/;
759 0         0 1 while s/\.0+(\d)/.$1/; # remove leading zeroes per group
760             }
761 0         0 $self->_verbose(9, "l[$l] r[$r]");
762 0 0       0 if ($l=~/^v/ <=> $r=~/^v/) {
763 0         0 for ($l,$r) {
764 0 0       0 next if /^v/;
765 0         0 $_ = $self->_float2vv($_);
766             }
767             }
768 0         0 $self->_verbose(9, "l[$l] r[$r]");
769 0         0 my $lvstring = "v0";
770 0         0 my $rvstring = "v0";
771 0 0 0     0 if ($] >= 5.006
      0        
772             && $l =~ /^v/
773             && $r =~ /^v/) {
774 0         0 $lvstring = $self->_vstring($l);
775 0         0 $rvstring = $self->_vstring($r);
776 0         0 $self->_verbose(9, sprintf "lv[%vd] rv[%vd]", $lvstring, $rvstring);
777             }
778              
779             return (
780 0   0     0 ($l ne "undef") <=> ($r ne "undef")
781             ||
782             $lvstring cmp $rvstring
783             ||
784             $l <=> $r
785             ||
786             $l cmp $r
787             );
788             }
789              
790             sub _vgt {
791 0     0   0 my($self,$l,$r) = @_;
792 0         0 $self->_vcmp($l,$r) > 0;
793             }
794              
795             sub _vlt {
796 0     0   0 my($self,$l,$r) = @_;
797 0         0 $self->_vcmp($l,$r) < 0;
798             }
799              
800             sub _vge {
801 0     0   0 my($self,$l,$r) = @_;
802 0         0 $self->_vcmp($l,$r) >= 0;
803             }
804              
805             sub _vle {
806 0     0   0 my($self,$l,$r) = @_;
807 0         0 $self->_vcmp($l,$r) <= 0;
808             }
809              
810             sub _vstring {
811 0     0   0 my($self,$n) = @_;
812 0 0       0 $n =~ s/^v// or die "Parse::PMFile::_vstring() called with invalid arg [$n]";
813 0         0 pack "U*", split /\./, $n;
814             }
815              
816             # vv => visible vstring
817             sub _float2vv {
818 0     0   0 my($self,$n) = @_;
819 0         0 my($rev) = int($n);
820 0   0     0 $rev ||= 0;
821 0         0 my($mantissa) = $n =~ /\.(\d{1,12})/; # limit to 12 digits to limit
822             # architecture influence
823 0   0     0 $mantissa ||= 0;
824 0         0 $mantissa .= "0" while length($mantissa)%3;
825 0         0 my $ret = "v" . $rev;
826 0         0 while ($mantissa) {
827 0 0       0 $mantissa =~ s/(\d{1,3})// or
828             die "Panic: length>0 but not a digit? mantissa[$mantissa]";
829 0         0 $ret .= ".".int($1);
830             }
831             # warn "n[$n]ret[$ret]";
832 0         0 $ret =~ s/(\.0)+/.0/; # v1.0.0 => v1.0
833 0         0 $ret;
834             }
835              
836             sub _readable {
837 141     141   780 my($self,$n) = @_;
838 141         1167 $n =~ /^([\w\-\+\.]+)/;
839              
840 141 50 33     2431 return $1 if defined $1 && length($1)>0;
841             # if the first user reaches version v43, he will be treated as "+".
842             # We'll have to decide about a new rule here then, depending on what
843             # will be the prevailing versioning behavior then.
844              
845 0 0         if ($] < 5.006) { # or whenever v-strings were introduced
846             # we get them wrong anyway, whatever we do, because 5.005 will
847             # have already interpreted 0.2.4 to be "0.24". So even if he
848             # indexer sends us something like "v0.2.4" we compare wrongly.
849              
850             # And if they say v1.2, then the old perl takes it as "v12"
851              
852 0           $self->_verbose(9, "Suspicious version string seen [$n]\n");
853 0           return $n;
854             }
855 0           my $better = sprintf "v%vd", $n;
856 0           $self->_verbose(9, "n[$n] better[$better]");
857 0           return $better;
858             }
859              
860             1;
861              
862             __END__