File Coverage

blib/lib/Regexp/Common.pm
Criterion Covered Total %
statement 141 161 87.5
branch 42 64 65.6
condition 10 17 58.8
subroutine 25 30 83.3
pod 3 8 37.5
total 221 280 78.9


line stmt bran cond sub pod time code
1             package Regexp::Common;
2              
3 73     73   54194 use 5.10.0;
  73         163  
4 73     73   243 use strict;
  73         73  
  73         1196  
5              
6 73     73   209 use warnings;
  73         63  
  73         1523  
7 73     73   202 no warnings 'syntax';
  73         65  
  73         17121  
8              
9             our $VERSION = '2017040401';
10             our %RE;
11             our %sub_interface;
12             our $AUTOLOAD;
13              
14              
15             sub _croak {
16 0     0   0 require Carp;
17 0         0 goto &Carp::croak;
18             }
19              
20             sub _carp {
21 0     0   0 require Carp;
22 0         0 goto &Carp::carp;
23             }
24              
25             sub new {
26 16593     16593 1 25537 my ($class, @data) = @_;
27 16593         12775 my %self;
28 16593         29934 tie %self, $class, @data;
29 16593         53849 return \%self;
30             }
31              
32             sub TIEHASH {
33 18787     18787   26854 my ($class, @data) = @_;
34 18787         34423 bless \@data, $class;
35             }
36              
37             sub FETCH {
38 16593     16593   771656 my ($self, $extra) = @_;
39 16593         36993 return bless ref($self)->new(@$self, $extra), ref($self);
40             }
41              
42             my %imports = map {$_ => "Regexp::Common::$_"}
43             qw /balanced CC comment delimited lingua list
44             net number profanity SEN URI whitespace
45             zip/;
46              
47             sub import {
48 2194     2194   207617 shift; # Shift off the class.
49 2194         5836 tie %RE, __PACKAGE__;
50             {
51 73     73   286 no strict 'refs';
  73         92  
  73         6235  
  2194         2005  
52 2194         2018 *{caller() . "::RE"} = \%RE;
  2194         9689  
53             }
54              
55 2194         2117 my $saw_import;
56             my $no_defaults;
57 0         0 my %exclude;
58 2194         2572 foreach my $entry (grep {!/^RE_/} @_) {
  6278         9940  
59 6266 100       9189 if ($entry eq 'pattern') {
60 73     73   259 no strict 'refs';
  73         69  
  73         20698  
61 2089         2116 *{caller() . "::pattern"} = \&pattern;
  2089         6827  
62 2089         2749 next;
63             }
64             # This used to prevent $; from being set. We still recognize it,
65             # but we won't do anything.
66 4177 100       5352 if ($entry eq 'clean') {
67 2088         1791 next;
68             }
69 2089 50       3017 if ($entry eq 'no_defaults') {
70 2089         1852 $no_defaults ++;
71 2089         2049 next;
72             }
73 0 0       0 if (my $module = $imports {$entry}) {
74 0         0 $saw_import ++;
75 0         0 eval "require $module;";
76 0 0       0 die $@ if $@;
77 0         0 next;
78             }
79 0 0 0     0 if ($entry =~ /^!(.*)/ && $imports {$1}) {
80 0         0 $exclude {$1} ++;
81 0         0 next;
82             }
83             # As a last resort, try to load the argument.
84 0 0       0 my $module = $entry =~ /^Regexp::Common/
85             ? $entry
86             : "Regexp::Common::" . $entry;
87 0         0 eval "require $module;";
88 0 0       0 die $@ if $@;
89             }
90              
91 2194 100 66     8126 unless ($saw_import || $no_defaults) {
92 105         300 foreach my $module (values %imports) {
93 1365 50       2350 next if $exclude {$module};
94 1365         65561 eval "require $module;";
95 1365 50       4710 die $@ if $@;
96             }
97             }
98              
99 2194         1910 my %exported;
100 2194         36577 foreach my $entry (grep {/^RE_/} @_) {
  6278         823166  
101 12 100       55 if ($entry =~ /^RE_(\w+_)?ALL$/) {
102 6 100       30 my $m = defined $1 ? $1 : "";
103 6         102 my $re = qr /^RE_${m}.*$/;
104 6         48 while (my ($sub, $interface) = each %sub_interface) {
105 1038 50       1124 next if $exported {$sub};
106 1038 100       2780 next unless $sub =~ /$re/;
107             {
108 73     73   294 no strict 'refs';
  73         85  
  73         4689  
  730         408  
109 730         427 *{caller() . "::$sub"} = $interface;
  730         1920  
110             }
111 730         3268 $exported {$sub} ++;
112             }
113             }
114             else {
115 6 50       19 next if $exported {$entry};
116             _croak "Can't export unknown subroutine &$entry"
117 6 50       25 unless $sub_interface {$entry};
118             {
119 73     73   257 no strict 'refs';
  73         79  
  73         24173  
  6         9  
120 6         11 *{caller() . "::$entry"} = $sub_interface {$entry};
  6         45  
121             }
122 6         1485 $exported {$entry} ++;
123             }
124             }
125             }
126              
127 0     0   0 sub AUTOLOAD { _croak "Can't $AUTOLOAD" }
128              
129       0     sub DESTROY {}
130              
131             my %cache;
132              
133             my $fpat = qr/^(-\w+)/;
134              
135             sub _decache {
136 1564278     1564278   622072911 my @args = @{tied %{$_[0]}};
  1564278         1341577  
  1564278         4324332  
137 1564278         1930421 my @nonflags = grep {!/$fpat/} @args;
  3964842         11319216  
138 1564278         2268280 my $cache = get_cache(@nonflags);
139             _croak "Can't create unknown regex: \$RE{"
140             . join("}{",@args) . "}"
141 1564278 50       2474400 unless exists $cache->{__VAL__};
142             _croak "Perl $] does not support the pattern "
143             . "\$RE{" . join("}{",@args)
144             . "}.\nYou need Perl $cache->{__VAL__}{version} or later"
145 1564278 50 100     5957607 unless ($cache->{__VAL__}{version}||0) <= $];
146 1564278         2942005 my %flags = ( %{$cache->{__VAL__}{default}},
147 1564278 100       1109151 map { /$fpat\Q$;\E(.*)/ ? ($1 => $2)
  3964842 100       19190704  
148             : /$fpat/ ? ($1 => undef)
149             : ()
150             } @args);
151 1564278         3436786 $cache->{__VAL__}->_clone_with(\@args, \%flags);
152             }
153              
154 73     73   67381 use overload q{""} => \&_decache;
  73         57860  
  73         452  
155              
156              
157             sub get_cache {
158 1576808     1576808 0 1638780 my $cache = \%cache;
159 1576808         1958895 foreach (@_) {
160             $cache = $cache->{$_}
161 3160711   100     6197327 || ($cache->{$_} = {});
162             }
163 1576808         1613439 return $cache;
164             }
165              
166             sub croak_version {
167 0     0 0 0 my ($entry, @args) = @_;
168             }
169              
170             sub pattern {
171 12530     12530 1 21999 my %spec = @_;
172             _croak 'pattern() requires argument: name => [ @list ]'
173 12530 50 33     44664 unless $spec{name} && ref $spec{name} eq 'ARRAY';
174             _croak 'pattern() requires argument: create => $sub_ref_or_string'
175 12530 50       15539 unless $spec{create};
176              
177 12530 100       17413 if (ref $spec{create} ne "CODE") {
178 7704         9212 my $fixed_str = "$spec{create}";
179 109369     109369   104968 $spec{create} = sub { $fixed_str }
180 7704         17355 }
181              
182 12530         9005 my @nonflags;
183             my %default;
184 12530         8475 foreach ( @{$spec{name}} ) {
  12530         15854  
185 34708 100       104573 if (/$fpat=(.*)/) {
    100          
186 8568         19326 $default{$1} = $2;
187             }
188             elsif (/$fpat\s*$/) {
189 72         182 $default{$1} = undef;
190             }
191             else {
192 26068         33551 push @nonflags, $_;
193             }
194             }
195              
196 12530         15618 my $entry = get_cache(@nonflags);
197              
198 12530 50       16410 if ($entry->{__VAL__}) {
199 0         0 _carp "Overriding \$RE{"
200             . join("}{",@nonflags)
201             . "}";
202             }
203              
204             $entry->{__VAL__} = bless {
205             create => $spec{create},
206             match => $spec{match} || \&generic_match,
207             subs => $spec{subs} || \&generic_subs,
208             version => $spec{version},
209 12530   50     75280 default => \%default,
      100        
210             }, 'Regexp::Common::Entry';
211              
212 12530         12808 foreach (@nonflags) {s/\W/X/g}
  26068         30310  
213 12530         17739 my $subname = "RE_" . join ("_", @nonflags);
214             $sub_interface{$subname} = sub {
215 35555 100   35555   920439 push @_ => undef if @_ % 2;
216 35555         35572 my %flags = @_;
217             my $pat = $spec{create}->($entry->{__VAL__},
218 35555         78261 {%default, %flags}, \@nonflags);
219 35555 50       60579 if (exists $flags{-keep}) { $pat =~ s/\Q(?k:/(/g; }
  0         0  
220 35555         90717 else { $pat =~ s/\Q(?k:/(?:/g; }
221 35555 100       197583 return exists $flags {-i} ? qr /(?i:$pat)/ : qr/$pat/;
222 12530         46392 };
223              
224 12530         26546 return 1;
225             }
226              
227 3320     3320 0 5089 sub generic_match {$_ [1] =~ /$_[0]/}
228 3316     3316 0 5050 sub generic_subs {$_ [1] =~ s/$_[0]/$_[2]/}
229              
230             sub matches {
231 3320     3320 0 95237 my ($self, $str) = @_;
232 3320         4627 my $entry = $self -> _decache;
233 3320         4694 $entry -> {match} -> ($entry, $str);
234             }
235              
236             sub subs {
237 3328     3328 1 81945 my ($self, $str, $newstr) = @_;
238 3328         4396 my $entry = $self -> _decache;
239 3328         4994 $entry -> {subs} -> ($entry, $str, $newstr);
240 3328         10744 return $str;
241             }
242              
243              
244             package Regexp::Common::Entry;
245             # use Carp;
246              
247             use overload
248             q{""} => sub {
249 1564267     1564267   1350359 my ($self) = @_;
250 1564267         3488100 my $pat = $self->{create}->($self, $self->{flags}, $self->{args});
251 1564263 100       2851000 if (exists $self->{flags}{-keep}) {
252 742319         7657816 $pat =~ s/\Q(?k:/(/g;
253             }
254             else {
255 821944         7858330 $pat =~ s/\Q(?k:/(?:/g;
256             }
257 1564263 100       2901996 if (exists $self->{flags}{-i}) { $pat = "(?i)$pat" }
  32         50  
258 1564263         49434872 return $pat;
259 73     73   51348 };
  73         98  
  73         403  
260              
261             sub _clone_with {
262 1564278     1564278   1489698 my ($self, $args, $flags) = @_;
263 1564278         8571022 bless { %$self, args=>$args, flags=>$flags }, ref $self;
264             }
265              
266             1;
267              
268             __END__