File Coverage

blib/lib/Regexp/Common/net.pm
Criterion Covered Total %
statement 16 16 100.0
branch n/a
condition n/a
subroutine 7 7 100.0
pod 0 2 0.0
total 23 25 92.0


line stmt bran cond sub pod time code
1             package Regexp::Common::net;
2              
3 71     71   678 use 5.10.0;
  71         147  
4              
5 71     71   225 use strict;
  71         77  
  71         1131  
6 71     71   220 use warnings;
  71         68  
  71         1570  
7 71     71   205 no warnings 'syntax';
  71         104  
  71         1985  
8              
9 71     71   227 use Regexp::Common qw /pattern clean no_defaults/;
  71         76  
  71         385  
10              
11             our $VERSION = '2016060801';
12              
13              
14             my %IPunit = (
15             dec => q{(?k:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})},
16             oct => q{(?k:[0-3]?[0-7]{1,2})},
17             hex => q{(?k:[0-9a-fA-F]{1,2})},
18             bin => q{(?k:[0-1]{1,8})},
19             strict => q{(?k:2(?:5[0-5]?|[0-4][0-9]?|[6-9]?)|1[0-9]{0,2}|[3-9][0-9]?|0)},
20             );
21             my %MACunit = (
22             %IPunit,
23             hex => q{(?k:[0-9a-fA-F]{1,2})},
24             );
25              
26             my %IPv6unit = (
27             hex => q {(?k:[0-9a-f]{1,4})},
28             HEX => q {(?k:[0-9A-F]{1,4})},
29             HeX => q {(?k:[0-9a-fA-F]{1,4})},
30             );
31              
32 6     6 0 45 sub dec {$_};
33 6     6 0 40 sub bin {oct "0b$_"}
34              
35             my $IPdefsep = '[.]';
36             my $MACdefsep = ':';
37             my $IPv6defsep = ':';
38              
39             pattern name => [qw (net IPv4)],
40             create => "(?k:$IPunit{dec}$IPdefsep$IPunit{dec}$IPdefsep" .
41             "$IPunit{dec}$IPdefsep$IPunit{dec})",
42             ;
43              
44             pattern name => [qw (net MAC)],
45             create => "(?k:" . join ($MACdefsep => ($MACunit{hex}) x 6) . ")",
46             subs => sub {
47             $_ [1] = join ":" => map {sprintf "%02x" => hex}
48             split /$MACdefsep/ => $_ [1]
49             if $_ [1] =~ /$_[0]/
50             },
51             ;
52              
53             foreach my $type (qw /dec oct hex bin strict/) {
54             pattern name => [qw (net IPv4), $type, "-sep=$IPdefsep"],
55             create => sub {my $sep = $_ [1] -> {-sep};
56             "(?k:$IPunit{$type}$sep$IPunit{$type}$sep" .
57             "$IPunit{$type}$sep$IPunit{$type})"
58             },
59             ;
60              
61             pattern name => [qw (net MAC), $type, "-sep=$MACdefsep"],
62             create => sub {my $sep = $_ [1] -> {-sep};
63             "(?k:" . join ($sep => ($MACunit{$type}) x 6) . ")",
64             },
65             subs => sub {
66             return if $] < 5.006 and $type eq 'bin';
67             $_ [1] = join ":" => map {sprintf "%02x" => eval $type}
68             $2, $3, $4, $5, $6, $7
69             if $_ [1] =~ $RE {net} {MAC} {$type}
70             {-sep => $_ [0] -> {flags} {-sep}}
71             {-keep};
72             },
73             ;
74              
75             }
76              
77              
78             my %cache6;
79             pattern name => [qw (net IPv6), "-sep=$IPv6defsep", "-style=HeX"],
80             create => sub {
81             my $style = $_ [1] {-style};
82             my $sep = $_ [1] {-sep};
83              
84             return $cache6 {$style, $sep} if $cache6 {$style, $sep};
85              
86             my @re;
87              
88             die "Impossible style '$style'\n" unless exists $IPv6unit {$style};
89              
90             #
91             # Nothing missing
92             #
93             push @re => join $sep => ($IPv6unit {$style}) x 8;
94              
95             #
96             # For "double colon" representations, at least 2 units must
97             # be omitted, leaving us with at most 6 units. 0 units is also
98             # possible. Note we can have at most one double colon.
99             #
100             for (my $l = 0; $l <= 6; $l ++) {
101             #
102             # We prefer to do longest match, so larger $r gets priority
103             #
104             for (my $r = 6 - $l; $r >= 0; $r --) {
105             #
106             # $l is the number of blocks left of the double colon,
107             # $r is the number of blocks left of the double colon,
108             # $m is the number of omitted blocks
109             #
110             my $m = 8 - $l - $r;
111             my $patl = $l ? ($IPv6unit {$style} . $sep) x $l : $sep;
112             my $patr = $r ? ($sep . $IPv6unit {$style}) x $r : $sep;
113             my $patm = "(?k:)" x $m;
114             my $pat = $patl . $patm . $patr;
115             push @re => "(?:$pat)";
116             }
117             }
118             local $" = "|";
119             $cache6 {$style, $sep} = qq /(?k:(?|@re))/;
120             },
121             ;
122              
123              
124             my $letter = "[A-Za-z]";
125             my $let_dig = "[A-Za-z0-9]";
126             my $let_dig_hyp = "[-A-Za-z0-9]";
127              
128             # Domain names, from RFC 1035.
129             pattern name => [qw (net domain -nospace= -rfc1101=)],
130             create => sub {
131             my $rfc1101 = exists $_ [1] {-rfc1101} &&
132             !defined $_ [1] {-rfc1101};
133              
134             my $lead = $rfc1101 ? "(?!$RE{net}{IPv4}(?:[.]|\$))$let_dig"
135             : $letter;
136              
137             if (exists $_ [1] {-nospace} && !defined $_ [1] {-nospace}) {
138             return "(?k:$lead(?:(?:$let_dig_hyp){0,61}$let_dig)?" .
139             "(?:\\.$lead(?:(?:$let_dig_hyp){0,61}$let_dig)?)*)"
140             }
141             else {
142             return "(?k: |(?:$lead(?:(?:$let_dig_hyp){0,61}$let_dig)?" .
143             "(?:\\.$lead(?:(?:$let_dig_hyp){0,61}$let_dig)?)*))"
144             }
145             },
146             ;
147              
148              
149              
150             1;
151              
152             __END__