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 72     72   52642 use 5.10.0;
  72         161  
4 72     72   252 use strict;
  72         74  
  72         1153  
5              
6 72     72   209 use warnings;
  72         94  
  72         1666  
7 72     72   210 no warnings 'syntax';
  72         67  
  72         16951  
8              
9             our $VERSION = '2016060801';
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 16185     16185 1 23016 my ($class, @data) = @_;
27 16185         11570 my %self;
28 16185         29231 tie %self, $class, @data;
29 16185         49568 return \%self;
30             }
31              
32             sub TIEHASH {
33 18348     18348   24800 my ($class, @data) = @_;
34 18348         31725 bless \@data, $class;
35             }
36              
37             sub FETCH {
38 16185     16185   721456 my ($self, $extra) = @_;
39 16185         31286 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 2163     2163   192191 shift; # Shift off the class.
49 2163         5301 tie %RE, __PACKAGE__;
50             {
51 72     72   284 no strict 'refs';
  72         89  
  72         6143  
  2163         1786  
52 2163         1942 *{caller() . "::RE"} = \%RE;
  2163         9892  
53             }
54              
55 2163         1956 my $saw_import;
56             my $no_defaults;
57 0         0 my %exclude;
58 2163         2434 foreach my $entry (grep {!/^RE_/} @_) {
  6189         9832  
59 6178 100       9070 if ($entry eq 'pattern') {
60 72     72   251 no strict 'refs';
  72         74  
  72         19693  
61 2059         1997 *{caller() . "::pattern"} = \&pattern;
  2059         7128  
62 2059         2783 next;
63             }
64             # This used to prevent $; from being set. We still recognize it,
65             # but we won't do anything.
66 4119 100       5225 if ($entry eq 'clean') {
67 2059         1719 next;
68             }
69 2060 50       2836 if ($entry eq 'no_defaults') {
70 2060         1931 $no_defaults ++;
71 2060         2174 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 2163 100 66     7761 unless ($saw_import || $no_defaults) {
92 103         269 foreach my $module (values %imports) {
93 1339 50       2225 next if $exclude {$module};
94 1339         63415 eval "require $module;";
95 1339 50       4355 die $@ if $@;
96             }
97             }
98              
99 2163         1800 my %exported;
100 2163         34033 foreach my $entry (grep {/^RE_/} @_) {
  6189         778163  
101 11 100       51 if ($entry =~ /^RE_(\w+_)?ALL$/) {
102 5 100       67 my $m = defined $1 ? $1 : "";
103 5         73 my $re = qr /^RE_${m}.*$/;
104 5         38 while (my ($sub, $interface) = each %sub_interface) {
105 865 50       938 next if $exported {$sub};
106 865 100       2386 next unless $sub =~ /$re/;
107             {
108 72     72   276 no strict 'refs';
  72         72  
  72         4547  
  634         386  
109 634         356 *{caller() . "::$sub"} = $interface;
  634         1614  
110             }
111 634         2712 $exported {$sub} ++;
112             }
113             }
114             else {
115 6 50       17 next if $exported {$entry};
116             _croak "Can't export unknown subroutine &$entry"
117 6 50       21 unless $sub_interface {$entry};
118             {
119 72     72   233 no strict 'refs';
  72         77  
  72         23530  
  6         8  
120 6         9 *{caller() . "::$entry"} = $sub_interface {$entry};
  6         38  
121             }
122 6         1100 $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 1558657     1558657   600572674 my @args = @{tied %{$_[0]}};
  1558657         1259676  
  1558657         4056084  
137 1558657         1966972 my @nonflags = grep {!/$fpat/} @args;
  3952838         11144000  
138 1558657         2097232 my $cache = get_cache(@nonflags);
139             _croak "Can't create unknown regex: \$RE{"
140             . join("}{",@args) . "}"
141 1558657 50       2399843 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 1558657 50 100     5763954 unless ($cache->{__VAL__}{version}||0) <= $];
146 1558657         2889817 my %flags = ( %{$cache->{__VAL__}{default}},
147 1558657 100       1075189 map { /$fpat\Q$;\E(.*)/ ? ($1 => $2)
  3952838 100       18093029  
148             : /$fpat/ ? ($1 => undef)
149             : ()
150             } @args);
151 1558657         3263700 $cache->{__VAL__}->_clone_with(\@args, \%flags);
152             }
153              
154 72     72   66157 use overload q{""} => \&_decache;
  72         55239  
  72         412  
155              
156              
157             sub get_cache {
158 1571011     1571011 0 1563465 my $cache = \%cache;
159 1571011         2134281 foreach (@_) {
160             $cache = $cache->{$_}
161 3149103   100     6216930 || ($cache->{$_} = {});
162             }
163 1571011         1609967 return $cache;
164             }
165              
166             sub croak_version {
167 0     0 0 0 my ($entry, @args) = @_;
168             }
169              
170             sub pattern {
171 12354     12354 1 21445 my %spec = @_;
172             _croak 'pattern() requires argument: name => [ @list ]'
173 12354 50 33     43427 unless $spec{name} && ref $spec{name} eq 'ARRAY';
174             _croak 'pattern() requires argument: create => $sub_ref_or_string'
175 12354 50       15231 unless $spec{create};
176              
177 12354 100       16612 if (ref $spec{create} ne "CODE") {
178 7597         9016 my $fixed_str = "$spec{create}";
179 109369     109369   110712 $spec{create} = sub { $fixed_str }
180 7597         16684 }
181              
182 12354         8757 my @nonflags;
183             my %default;
184 12354         8114 foreach ( @{$spec{name}} ) {
  12354         17287  
185 34222 100       101383 if (/$fpat=(.*)/) {
    100          
186 8449         18108 $default{$1} = $2;
187             }
188             elsif (/$fpat\s*$/) {
189 71         837 $default{$1} = undef;
190             }
191             else {
192 25702         34495 push @nonflags, $_;
193             }
194             }
195              
196 12354         14820 my $entry = get_cache(@nonflags);
197              
198 12354 50       16359 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 12354   50     73143 default => \%default,
      100        
210             }, 'Regexp::Common::Entry';
211              
212 12354         13405 foreach (@nonflags) {s/\W/X/g}
  25702         30322  
213 12354         17283 my $subname = "RE_" . join ("_", @nonflags);
214             $sub_interface{$subname} = sub {
215 31990 100   31990   764699 push @_ => undef if @_ % 2;
216 31990         30413 my %flags = @_;
217             my $pat = $spec{create}->($entry->{__VAL__},
218 31990         62488 {%default, %flags}, \@nonflags);
219 31990 50       49545 if (exists $flags{-keep}) { $pat =~ s/\Q(?k:/(/g; }
  0         0  
220 31990         75775 else { $pat =~ s/\Q(?k:/(?:/g; }
221 31990 100       139664 return exists $flags {-i} ? qr /(?i:$pat)/ : qr/$pat/;
222 12354         44417 };
223              
224 12354         25913 return 1;
225             }
226              
227 2939     2939 0 4631 sub generic_match {$_ [1] =~ /$_[0]/}
228 2935     2935 0 4552 sub generic_subs {$_ [1] =~ s/$_[0]/$_[2]/}
229              
230             sub matches {
231 2939     2939 0 77725 my ($self, $str) = @_;
232 2939         3860 my $entry = $self -> _decache;
233 2939         4638 $entry -> {match} -> ($entry, $str);
234             }
235              
236             sub subs {
237 2947     2947 1 69447 my ($self, $str, $newstr) = @_;
238 2947         3925 my $entry = $self -> _decache;
239 2947         4789 $entry -> {subs} -> ($entry, $str, $newstr);
240 2947         8971 return $str;
241             }
242              
243              
244             package Regexp::Common::Entry;
245             # use Carp;
246              
247             use overload
248             q{""} => sub {
249 1558646     1558646   1270364 my ($self) = @_;
250 1558646         3309224 my $pat = $self->{create}->($self, $self->{flags}, $self->{args});
251 1558642 100       2651615 if (exists $self->{flags}{-keep}) {
252 741938         11411717 $pat =~ s/\Q(?k:/(/g;
253             }
254             else {
255 816704         11517833 $pat =~ s/\Q(?k:/(?:/g;
256             }
257 1558642 100       2783360 if (exists $self->{flags}{-i}) { $pat = "(?i)$pat" }
  32         40  
258 1558642         45188006 return $pat;
259 72     72   48210 };
  72         110  
  72         395  
260              
261             sub _clone_with {
262 1558657     1558657   1492682 my ($self, $args, $flags) = @_;
263 1558657         7708902 bless { %$self, args=>$args, flags=>$flags }, ref $self;
264             }
265              
266             1;
267              
268             __END__