File Coverage

blib/lib/Regexp/Common.pm
Criterion Covered Total %
statement 142 161 88.2
branch 42 64 65.6
condition 10 17 58.8
subroutine 25 30 83.3
pod 3 8 37.5
total 222 280 79.2


line stmt bran cond sub pod time code
1             package Regexp::Common;
2              
3 73     73   81522 use 5.10.0;
  73         279  
4 73     73   407 use strict;
  73         157  
  73         1527  
5              
6 73     73   373 use warnings;
  73         150  
  73         1875  
7 73     73   371 no warnings 'syntax';
  73         154  
  73         19450  
8              
9             our $VERSION = '2017060201';
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 42137 my ($class, @data) = @_;
27 16593         23761 my %self;
28 16593         43126 tie %self, $class, @data;
29 16593         74976 return \%self;
30             }
31              
32             sub TIEHASH {
33 18787     18787   46373 my ($class, @data) = @_;
34 18787         52731 bless \@data, $class;
35             }
36              
37             sub FETCH {
38 16593     16593   1237564 my ($self, $extra) = @_;
39 16593         48879 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   209315 shift; # Shift off the class.
49 2194         8141 tie %RE, __PACKAGE__;
50             {
51 73     73   484 no strict 'refs';
  73         144  
  73         7008  
  2194         4005  
52 2194         4058 *{caller() . "::RE"} = \%RE;
  2194         12741  
53             }
54              
55 2194         6555 my $saw_import;
56             my $no_defaults;
57 2194         0 my %exclude;
58 2194         4490 foreach my $entry (grep {!/^RE_/} @_) {
  6278         16738  
59 6266 100       15359 if ($entry eq 'pattern') {
60 73     73   431 no strict 'refs';
  73         156  
  73         23507  
61 2089         3954 *{caller() . "::pattern"} = \&pattern;
  2089         9906  
62 2089         4800 next;
63             }
64             # This used to prevent $; from being set. We still recognize it,
65             # but we won't do anything.
66 4177 100       9035 if ($entry eq 'clean') {
67 2088         3530 next;
68             }
69 2089 50       4861 if ($entry eq 'no_defaults') {
70 2089         3614 $no_defaults ++;
71 2089         3861 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     10881 unless ($saw_import || $no_defaults) {
92 105         425 foreach my $module (values %imports) {
93 1365 50       3891 next if $exclude {$module};
94 1365         75335 eval "require $module;";
95 1365 50       6779 die $@ if $@;
96             }
97             }
98              
99 2194         3738 my %exported;
100 2194         40663 foreach my $entry (grep {/^RE_/} @_) {
  6278         934219  
101 12 100       77 if ($entry =~ /^RE_(\w+_)?ALL$/) {
102 6 100       42 my $m = defined $1 ? $1 : "";
103 6         124 my $re = qr /^RE_${m}.*$/;
104 6         66 while (my ($sub, $interface) = each %sub_interface) {
105 1038 50       2011 next if $exported {$sub};
106 1038 100       4084 next unless $sub =~ /$re/;
107             {
108 73     73   477 no strict 'refs';
  73         167  
  73         5451  
  730         1023  
109 730         857 *{caller() . "::$sub"} = $interface;
  730         2747  
110             }
111 730         4372 $exported {$sub} ++;
112             }
113             }
114             else {
115 6 50       25 next if $exported {$entry};
116             _croak "Can't export unknown subroutine &$entry"
117 6 50       23 unless $sub_interface {$entry};
118             {
119 73     73   410 no strict 'refs';
  73         148  
  73         27640  
  6         9  
120 6         13 *{caller() . "::$entry"} = $sub_interface {$entry};
  6         38  
121             }
122 6         1265 $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   1064493250 my @args = @{tied %{$_[0]}};
  1564278         2581072  
  1564278         6107608  
137 1564278         3445672 my @nonflags = grep {!/$fpat/} @args;
  3964842         16500838  
138 1564278         4042373 my $cache = get_cache(@nonflags);
139             _croak "Can't create unknown regex: \$RE{"
140             . join("}{",@args) . "}"
141 1564278 50       4028975 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     7952162 unless ($cache->{__VAL__}{version}||0) <= $];
146 1564278         4413117 my %flags = ( %{$cache->{__VAL__}{default}},
147 1564278 100       2496444 map { /$fpat\Q$;\E(.*)/ ? ($1 => $2)
  3964842 100       25671618  
148             : /$fpat/ ? ($1 => undef)
149             : ()
150             } @args);
151 1564278         5340697 $cache->{__VAL__}->_clone_with(\@args, \%flags);
152             }
153              
154 73     73   74937 use overload q{""} => \&_decache;
  73         72732  
  73         594  
155              
156              
157             sub get_cache {
158 1576808     1576808 0 2972469 my $cache = \%cache;
159 1576808         3319782 foreach (@_) {
160             $cache = $cache->{$_}
161 3160711   100     9381814 || ($cache->{$_} = {});
162             }
163 1576808         3105711 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 39143 my %spec = @_;
172             _croak 'pattern() requires argument: name => [ @list ]'
173 12530 50 33     62232 unless $spec{name} && ref $spec{name} eq 'ARRAY';
174             _croak 'pattern() requires argument: create => $sub_ref_or_string'
175 12530 50       28156 unless $spec{create};
176              
177 12530 100       28853 if (ref $spec{create} ne "CODE") {
178 7704         16985 my $fixed_str = "$spec{create}";
179 109369     109369   193506 $spec{create} = sub { $fixed_str }
180 7704         26935 }
181              
182 12530         21702 my @nonflags;
183             my %default;
184 12530         18071 foreach ( @{$spec{name}} ) {
  12530         26928  
185 34708 100       154079 if (/$fpat=(.*)/) {
    100          
186 8568         29442 $default{$1} = $2;
187             }
188             elsif (/$fpat\s*$/) {
189 72         315 $default{$1} = undef;
190             }
191             else {
192 26068         63909 push @nonflags, $_;
193             }
194             }
195              
196 12530         28152 my $entry = get_cache(@nonflags);
197              
198 12530 50       28091 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     98825 default => \%default,
      100        
210             }, 'Regexp::Common::Entry';
211              
212 12530         25679 foreach (@nonflags) {s/\W/X/g}
  26068         55593  
213 12530         30965 my $subname = "RE_" . join ("_", @nonflags);
214             $sub_interface{$subname} = sub {
215 35555 100   35555   1552104 push @_ => undef if @_ % 2;
216 35555         61291 my %flags = @_;
217             my $pat = $spec{create}->($entry->{__VAL__},
218 35555         106696 {%default, %flags}, \@nonflags);
219 35555 50       90870 if (exists $flags{-keep}) { $pat =~ s/\Q(?k:/(/g; }
  0         0  
220 35555         122430 else { $pat =~ s/\Q(?k:/(?:/g; }
221 35555 100       256735 return exists $flags {-i} ? qr /(?i:$pat)/ : qr/$pat/;
222 12530         68801 };
223              
224 12530         42269 return 1;
225             }
226              
227 3320     3320 0 7803 sub generic_match {$_ [1] =~ /$_[0]/}
228 3316     3316 0 7683 sub generic_subs {$_ [1] =~ s/$_[0]/$_[2]/}
229              
230             sub matches {
231 3320     3320 0 156111 my ($self, $str) = @_;
232 3320         6863 my $entry = $self -> _decache;
233 3320         7693 $entry -> {match} -> ($entry, $str);
234             }
235              
236             sub subs {
237 3328     3328 1 135878 my ($self, $str, $newstr) = @_;
238 3328         6683 my $entry = $self -> _decache;
239 3328         8958 $entry -> {subs} -> ($entry, $str, $newstr);
240 3328         15631 return $str;
241             }
242              
243              
244             package Regexp::Common::Entry;
245             # use Carp;
246              
247             use overload
248             q{""} => sub {
249 1564267     1564267   3144734 my ($self) = @_;
250 1564267         5203290 my $pat = $self->{create}->($self, $self->{flags}, $self->{args});
251 1564263 100       4635508 if (exists $self->{flags}{-keep}) {
252 742319         8778552 $pat =~ s/\Q(?k:/(/g;
253             }
254             else {
255 821944         9062412 $pat =~ s/\Q(?k:/(?:/g;
256             }
257 1564263 100       4855796 if (exists $self->{flags}{-i}) { $pat = "(?i)$pat" }
  32         67  
258 1564263         54711724 return $pat;
259 73     73   62088 };
  73         195  
  73         555  
260              
261             sub _clone_with {
262 1564278     1564278   3205673 my ($self, $args, $flags) = @_;
263 1564278         11019307 bless { %$self, args=>$args, flags=>$flags }, ref $self;
264             }
265              
266             1;
267              
268             __END__