line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# Number::Range::Regex |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
# |
4
|
|
|
|
|
|
|
# Copyright 2012 Brian Szymanski. All rights reserved. This module is |
5
|
|
|
|
|
|
|
# free software; you can redistribute it and/or modify it under the same |
6
|
|
|
|
|
|
|
# terms as Perl itself. |
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
package Number::Range::Regex; |
9
|
|
|
|
|
|
|
|
10
|
14
|
|
|
14
|
|
556266
|
use strict; |
|
14
|
|
|
|
|
38
|
|
|
14
|
|
|
|
|
1582
|
|
11
|
14
|
|
|
14
|
|
10276
|
use Number::Range::Regex::Range; |
|
14
|
|
|
|
|
57
|
|
|
14
|
|
|
|
|
1112
|
|
12
|
14
|
|
|
14
|
|
9661
|
use Number::Range::Regex::Iterator; |
|
14
|
|
|
|
|
43
|
|
|
14
|
|
|
|
|
790
|
|
13
|
14
|
|
|
14
|
|
90
|
use Number::Range::Regex::Util; |
|
14
|
|
|
|
|
34
|
|
|
14
|
|
|
|
|
1851
|
|
14
|
14
|
|
|
14
|
|
88
|
use Number::Range::Regex::Util::inf qw( neg_inf pos_inf ); |
|
14
|
|
|
|
|
23
|
|
|
14
|
|
|
|
|
855
|
|
15
|
14
|
|
|
14
|
|
150
|
use vars qw ( @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $VERSION ); |
|
14
|
|
|
|
|
27
|
|
|
14
|
|
|
|
|
1428
|
|
16
|
|
|
|
|
|
|
eval { require warnings; }; #it's ok if we can't load warnings |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
require Exporter; |
19
|
14
|
|
|
14
|
|
75
|
use base 'Exporter'; |
|
14
|
|
|
|
|
25
|
|
|
14
|
|
|
|
|
17785
|
|
20
|
|
|
|
|
|
|
@ISA = qw( Exporter ); |
21
|
|
|
|
|
|
|
@EXPORT = qw( range rangespec ); |
22
|
|
|
|
|
|
|
@EXPORT_OK = qw ( init regex_range ) ; |
23
|
|
|
|
|
|
|
%EXPORT_TAGS = ( all => [ @EXPORT, @EXPORT_OK ] ); |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
$VERSION = '0.32'; |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
my $init_opts = $Number::Range::Regex::Range::default_opts; |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
sub init { |
30
|
4
|
|
|
4
|
0
|
3414
|
my ($self, @opts) = @_; |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
# vestigial limb: init( foo => "bar" ) == init( { foo => "bar" } ); |
33
|
4
|
50
|
|
|
|
24
|
my %opts = (@opts == 1) ? %{$opts[0]} : |
|
1
|
100
|
|
|
|
4
|
|
34
|
|
|
|
|
|
|
(@opts % 2 == 0) ? @opts : |
35
|
|
|
|
|
|
|
die 'usage: init( $options_ref )'; |
36
|
|
|
|
|
|
|
|
37
|
4
|
|
|
|
|
6
|
$init_opts = $Number::Range::Regex::Range::default_opts; |
38
|
|
|
|
|
|
|
# override any values of init_opts that were passed to init |
39
|
4
|
|
|
|
|
19
|
while (my ($key, $value) = each %opts) { |
40
|
3
|
|
|
|
|
19
|
$init_opts->{$key} = $value; |
41
|
|
|
|
|
|
|
} |
42
|
|
|
|
|
|
|
} |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
# regex_range( $min, $max ); #undef = no limit, so. e.g. |
45
|
|
|
|
|
|
|
# regex_range(3, undef) yields the equivalent of qr/[+]?[3-9]|\d+/; |
46
|
|
|
|
|
|
|
sub regex_range { |
47
|
271
|
|
|
271
|
1
|
444273
|
my ($min, $max, $passed_opts) = @_; |
48
|
271
|
|
|
|
|
961
|
my $opts = option_mangler( $init_opts, $passed_opts ); |
49
|
270
|
|
|
|
|
844
|
return range($min, $max, $opts)->regex(); |
50
|
|
|
|
|
|
|
} |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
sub range { |
53
|
345
|
100
|
|
345
|
1
|
26102
|
my $opts = option_mangler( ref $_[-1] eq 'HASH' ? pop : undef ); |
54
|
345
|
|
|
|
|
1109
|
my ($min, $max) = @_; |
55
|
345
|
100
|
66
|
|
|
887
|
if(!defined $min && !defined $max) { |
56
|
3
|
100
|
|
|
|
36
|
die "for the set of all integers, you must specify min as '-inf' and max as '+inf', or use the allow_wildcard argument" if !$opts->{allow_wildcard}; |
57
|
|
|
|
|
|
|
} |
58
|
344
|
100
|
|
|
|
828
|
$min = neg_inf if !defined $min; |
59
|
344
|
100
|
|
|
|
764
|
$max = pos_inf if !defined $max; |
60
|
344
|
|
|
|
|
1328
|
return rangespec( "$min..$max", $opts ); |
61
|
|
|
|
|
|
|
} |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
sub rangespec { |
64
|
491
|
100
|
|
491
|
1
|
30161
|
my $opts = option_mangler( ref $_[-1] eq 'HASH' ? pop : undef ); |
65
|
|
|
|
|
|
|
# we allow (but do not like) e.g. rangespec(5,7,10..18); |
66
|
|
|
|
|
|
|
# we don't like it because it can make us run out of memory for |
67
|
|
|
|
|
|
|
# large ranges. preferred: rangespec('5,7,10..18'); |
68
|
491
|
|
|
|
|
720
|
my $spec; |
69
|
491
|
100
|
|
|
|
1202
|
if(@_ > 1) { |
70
|
1
|
|
|
|
|
5
|
warn "passed literal range to rangespec!\n"; |
71
|
1
|
|
|
|
|
10
|
$spec = join $opts->{range_separator}, @_; |
72
|
|
|
|
|
|
|
} else { |
73
|
490
|
|
|
|
|
993
|
$spec = $_[0]; |
74
|
|
|
|
|
|
|
} |
75
|
|
|
|
|
|
|
|
76
|
491
|
|
|
|
|
954
|
my $base = $opts->{base}; |
77
|
491
|
|
|
|
|
1569
|
my $base_digits = base_digits($base); |
78
|
491
|
|
|
|
|
2104
|
my $base_max = substr($base_digits, -1); |
79
|
|
|
|
|
|
|
|
80
|
491
|
|
|
|
|
1163
|
my $digits_validate = "[$base_digits]+"; |
81
|
491
|
|
|
|
|
1615
|
my $range_operator = '\s*'.quotemeta( $opts->{range_operator} ).'\s*'; |
82
|
491
|
|
|
|
|
1263
|
my $range_separator = '\s*'.quotemeta( $opts->{range_separator} ).'\s*'; |
83
|
491
|
|
|
|
|
5490
|
my $section_validate = qr/(?:-?$digits_validate|(?:-?$digits_validate|-inf)$range_operator(?:\+?inf|-?$digits_validate))/; |
84
|
491
|
|
|
|
|
5050
|
my $range_validate = qr/(?:|$section_validate(?:$range_separator$section_validate)*)/; |
85
|
491
|
100
|
|
|
|
7932
|
die "invalid rangespec '$spec' !~ /$range_validate/" unless $spec =~ /^$range_validate$/; |
86
|
|
|
|
|
|
|
|
87
|
487
|
|
|
|
|
3039
|
my @sections = split /$range_separator/, $spec; |
88
|
487
|
|
|
|
|
771
|
my @ranges; |
89
|
487
|
|
|
|
|
822
|
foreach my $section (@sections) { |
90
|
617
|
100
|
|
|
|
5094
|
if($section =~ /^(-?$digits_validate)$/) { |
91
|
64
|
|
|
|
|
288
|
push @ranges, Number::Range::Regex::SimpleRange->new( $1, $1, $opts ); |
92
|
|
|
|
|
|
|
} else { |
93
|
553
|
|
|
|
|
3727
|
my ($min, $max) = map { s/^\s+//; s/\s+$//; $_ } split /$range_operator/, $section, 2; |
|
1106
|
|
|
|
|
2290
|
|
|
1106
|
|
|
|
|
2366
|
|
|
1106
|
|
|
|
|
17043
|
|
94
|
553
|
|
|
|
|
3205
|
push @ranges, Number::Range::Regex::SimpleRange->new( $min, $max, $opts ); |
95
|
|
|
|
|
|
|
} |
96
|
|
|
|
|
|
|
} |
97
|
485
|
50
|
|
|
|
1975
|
my $warn_overlap = defined $opts->{warn_overlap} ? |
98
|
|
|
|
|
|
|
$opts->{warn_overlap} : 'rangespec'; |
99
|
|
|
|
|
|
|
# note: multi_union() will have the side effect of sorting |
100
|
|
|
|
|
|
|
# and de-overlap-ify-ing the input ranges |
101
|
485
|
|
|
|
|
2534
|
return multi_union( @ranges, { warn_overlap => $warn_overlap } ); |
102
|
|
|
|
|
|
|
} |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
1; |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
__END__ |