line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Config::Maker::Path; |
2
|
|
|
|
|
|
|
|
3
|
9
|
|
|
9
|
|
54
|
use utf8; |
|
9
|
|
|
|
|
16
|
|
|
9
|
|
|
|
|
54
|
|
4
|
9
|
|
|
9
|
|
248
|
use warnings; |
|
9
|
|
|
|
|
18
|
|
|
9
|
|
|
|
|
217
|
|
5
|
9
|
|
|
9
|
|
51
|
use strict; |
|
9
|
|
|
|
|
16
|
|
|
9
|
|
|
|
|
350
|
|
6
|
|
|
|
|
|
|
|
7
|
9
|
|
|
9
|
|
50
|
use Carp; |
|
9
|
|
|
|
|
17
|
|
|
9
|
|
|
|
|
1339
|
|
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
require Config::Maker::Path::Root; |
10
|
|
|
|
|
|
|
require Config::Maker::Path::AnyPath; |
11
|
|
|
|
|
|
|
require Config::Maker::Path::This; |
12
|
|
|
|
|
|
|
require Config::Maker::Path::Parent; |
13
|
|
|
|
|
|
|
require Config::Maker::Path::Meta; |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
use overload |
16
|
9
|
|
|
|
|
103
|
'cmp' => \&Config::Maker::truecmp, |
17
|
|
|
|
|
|
|
'<=>' => \&Config::Maker::truecmp, |
18
|
|
|
|
|
|
|
'""' => 'str', |
19
|
9
|
|
|
9
|
|
65
|
fallback => 1; |
|
9
|
|
|
|
|
19
|
|
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
our $parser = $Config::Maker::parser; |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
our %paths; # Cache for paths... |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
our %checks; # For [$if$] directive... |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
# Coversion of expressions to regexes and coderefs: |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
sub _glob_to_re { |
30
|
1976
|
|
|
1976
|
|
4256
|
local $_ = $_[0]; |
31
|
|
|
|
|
|
|
|
32
|
1976
|
100
|
|
|
|
15022
|
/[.+^\-\$]/ ? "\\$_" : |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
33
|
|
|
|
|
|
|
/\{/ ? "(?:" : |
34
|
|
|
|
|
|
|
/\}/ ? ")" : |
35
|
|
|
|
|
|
|
/\*/ ? ".*" : |
36
|
|
|
|
|
|
|
/\?/ ? "." : |
37
|
|
|
|
|
|
|
$_; |
38
|
|
|
|
|
|
|
} |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
sub glob_to_re { |
41
|
596
|
|
|
596
|
0
|
1270
|
my ($self, $patt) = @_; |
42
|
|
|
|
|
|
|
|
43
|
596
|
100
|
|
|
|
2771
|
return qr/.*/ if (!defined $patt); |
44
|
300
|
50
|
|
|
|
1026
|
return qr/$patt/ if ($patt =~ s/^RE://); |
45
|
|
|
|
|
|
|
|
46
|
300
|
50
|
|
|
|
1581
|
$patt =~ s/([^\\])|(\\.)/defined $1 ? _glob_to_re($1) : $2/eg; |
|
1976
|
|
|
|
|
6545
|
|
47
|
300
|
|
|
|
|
6361
|
qr/^$patt$/; |
48
|
|
|
|
|
|
|
} |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
sub code_to_sub { |
51
|
298
|
|
|
298
|
0
|
668
|
my ($self, $code) = @_; |
52
|
|
|
|
|
|
|
|
53
|
298
|
100
|
|
987
|
|
2029
|
return sub { 1; } unless $code; |
|
987
|
|
|
|
|
5274
|
|
54
|
6
|
|
|
|
|
57
|
Config::Maker::DBG("Code-to-sub: qq{$code}"); |
55
|
6
|
|
|
|
|
34
|
$code =~ s/\A\(//; |
56
|
6
|
|
|
|
|
32
|
$code =~ s/\)\Z//; |
57
|
6
|
|
|
|
|
44
|
my $sub = Config::Maker::exe("sub { $code; };"); |
58
|
6
|
|
|
|
|
28
|
return $sub; |
59
|
|
|
|
|
|
|
} |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
# Common argument parsing: |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
sub bhash { |
64
|
361
|
|
|
361
|
0
|
18586
|
my ($class, $keys) = splice @_, 0, 2; |
65
|
361
|
50
|
|
|
|
1729
|
$keys = +{ map { $_ => 1; } @$keys } if(ref($keys) eq 'ARRAY'); |
|
1255
|
|
|
|
|
4112
|
|
66
|
361
|
50
|
|
|
|
1928
|
my %hash = (ref($_[0]) eq 'HASH' ? %{$_[0]} : @_); |
|
0
|
|
|
|
|
0
|
|
67
|
|
|
|
|
|
|
|
68
|
361
|
|
|
|
|
1427
|
for(keys %hash) { |
69
|
336
|
50
|
|
|
|
1291
|
croak "Unknown argument $_" |
70
|
|
|
|
|
|
|
unless $keys->{$_}; |
71
|
|
|
|
|
|
|
} |
72
|
361
|
|
|
|
|
3011
|
bless \%hash, $class; |
73
|
|
|
|
|
|
|
} |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
# Public interface: |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
sub new { |
78
|
298
|
|
|
298
|
0
|
2063
|
my $self = shift->bhash([qw/-type -value -code -tail/], @_); |
79
|
|
|
|
|
|
|
|
80
|
298
|
|
|
|
|
1861
|
$self->{-text} = ''; |
81
|
298
|
100
|
|
|
|
1650
|
$self->{-text} .= $self->{-type} if $self->{-type}; |
82
|
298
|
100
|
|
|
|
1027
|
$self->{-text} .= ':' . $self->{-value} if $self->{-value}; |
83
|
298
|
100
|
|
|
|
1659
|
$self->{-text} .= $self->{-code} if $self->{-code}; |
84
|
|
|
|
|
|
|
|
85
|
298
|
|
|
|
|
1451
|
$self->{-type} = $self->glob_to_re($self->{-type}); |
86
|
298
|
|
|
|
|
1555
|
$self->{-value} = $self->glob_to_re($self->{-value}); |
87
|
298
|
|
|
|
|
1772
|
$self->{-code} = $self->code_to_sub($self->{-code}); |
88
|
|
|
|
|
|
|
|
89
|
298
|
|
|
|
|
1434
|
return $self; |
90
|
|
|
|
|
|
|
} |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
sub make { |
93
|
1303
|
|
|
1303
|
0
|
2679
|
my ($class, $text) = @_; |
94
|
|
|
|
|
|
|
#D# DBG "Making path from `$text'"; |
95
|
1303
|
100
|
|
|
|
9859
|
return $text if UNIVERSAL::isa($text, __PACKAGE__); |
96
|
1183
|
100
|
|
|
|
33136
|
return $paths{$text} if($paths{$text}); |
97
|
269
|
50
|
|
|
|
2607
|
$paths{$text} = $parser->path_whole($text) |
98
|
|
|
|
|
|
|
or croak "Invalid path: $text"; |
99
|
|
|
|
|
|
|
} |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
sub match { |
102
|
2054
|
|
|
2054
|
0
|
3543
|
my ($self, $from) = @_; |
103
|
|
|
|
|
|
|
|
104
|
3990
|
100
|
100
|
|
|
25842
|
grep { |
105
|
|
|
|
|
|
|
# no warnings 'uninitialized'; # NOTEME |
106
|
2054
|
|
|
|
|
6264
|
($_->{-type} =~ /$self->{-type}/) |
107
|
|
|
|
|
|
|
&& ($_->{-value} =~ /$self->{-value}/) |
108
|
|
|
|
|
|
|
&& ($self->{-code}->()) |
109
|
2054
|
|
|
|
|
2521
|
} @{$from->{-children}} |
110
|
|
|
|
|
|
|
} |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
sub find { |
113
|
2197
|
|
|
2197
|
0
|
5371
|
my ($self, $from, $gather) = @_; |
114
|
2197
|
|
100
|
|
|
9394
|
$gather ||= []; |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
#D# DBG "Pattern $self find in ".$from->id; |
117
|
2197
|
100
|
|
|
|
7080
|
if($self->{-tail}) { |
118
|
75
|
|
|
|
|
351
|
$self->{-tail}->find($_, $gather) for $self->match($from); |
119
|
|
|
|
|
|
|
} else { |
120
|
2122
|
|
|
|
|
5597
|
push @$gather, ($self->match($from)); |
121
|
|
|
|
|
|
|
} |
122
|
|
|
|
|
|
|
#D# DBG "Returning: `" . join("', `", map $_->id, @$gather) . "'"; |
123
|
|
|
|
|
|
|
|
124
|
2197
|
|
|
|
|
8429
|
return $gather; |
125
|
|
|
|
|
|
|
} |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
sub text { |
128
|
2866
|
|
|
2866
|
0
|
32856
|
$_[0]->{-text}; |
129
|
|
|
|
|
|
|
} |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
sub str { |
132
|
2903
|
|
|
2903
|
0
|
12075
|
my ($self) = @_; |
133
|
2903
|
100
|
|
|
|
9810
|
$self->text . ($self->{-tail} ? '/' . $self->{-tail}->str : ''); |
134
|
|
|
|
|
|
|
} |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
sub _findtimes { |
137
|
26
|
50
|
|
26
|
|
105
|
confess "$_[1] can't ->find" unless UNIVERSAL::can($_[1], 'find'); |
138
|
26
|
|
|
|
|
63
|
my $r = $_[1]->find($_[0]); |
139
|
26
|
100
|
|
|
|
99
|
return 0 if @$r < $_[2]; |
140
|
13
|
100
|
|
|
|
38
|
return 1 if @_ == 3; |
141
|
9
|
100
|
|
|
|
40
|
return 0 if @$r > $_[3]; |
142
|
4
|
|
|
|
|
17
|
return 1; |
143
|
|
|
|
|
|
|
} |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
BEGIN { # Constants must be done early enough... |
146
|
|
|
|
|
|
|
%checks = ( |
147
|
7
|
|
|
|
|
21
|
none => sub { _findtimes($_, @_, 0,0); }, |
148
|
0
|
|
|
|
|
0
|
unique => sub { _findtimes($_, @_,0,1); }, |
149
|
7
|
|
|
|
|
18
|
one => sub { _findtimes($_, @_,1,1); }, |
150
|
12
|
|
|
|
|
31
|
exists => sub { _findtimes($_, @_,1); }, |
151
|
0
|
|
|
|
|
0
|
any => sub { 1; }, |
152
|
9
|
|
|
9
|
|
23607
|
); |
153
|
|
|
|
|
|
|
} |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
1; |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
__END__ |