line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package File::Find::Rule::Filesys::Virtual; |
2
|
1
|
|
|
1
|
|
43636
|
use strict; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
39
|
|
3
|
1
|
|
|
1
|
|
6
|
use warnings; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
170
|
|
4
|
1
|
|
|
1
|
|
6
|
use File::Find::Rule 0.28; |
|
1
|
|
|
|
|
44
|
|
|
1
|
|
|
|
|
8
|
|
5
|
1
|
|
|
1
|
|
49
|
use base qw( File::Find::Rule ); |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
158
|
|
6
|
|
|
|
|
|
|
our $VERSION = 1.22; |
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
=head1 NAME |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
File::Find::Rule::Filesys::Virtual - File::Find::Rule adapted to Filesys::Virtual |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
=head1 SYNOPSIS |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
use File::Find::Rule::Filesys::Virtual; |
15
|
|
|
|
|
|
|
use Filesys::Virtual::Ninja; |
16
|
|
|
|
|
|
|
my $vfs = Filesys::Virtual::Ninja->new; |
17
|
|
|
|
|
|
|
my @virtual_ninja_foos = File::Find::Rule::Filesys::Virtual |
18
|
|
|
|
|
|
|
->virtual( $vfs ) |
19
|
|
|
|
|
|
|
->name( "foo.*' ) |
20
|
|
|
|
|
|
|
->in( '/' ); |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
=head1 DESCRIPTION |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
This module allows you to use File::Find::Rule file finding semantics |
25
|
|
|
|
|
|
|
to Filesys::Virtual derived filesystems. |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
=cut |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
|
30
|
1
|
|
|
1
|
|
193
|
BEGIN { *_force_object = \&File::Find::Rule::_force_object } |
31
|
|
|
|
|
|
|
sub virtual { |
32
|
9
|
|
|
9
|
0
|
13152
|
my $self = _force_object shift; |
33
|
9
|
|
|
|
|
60
|
$self->{_virtual} = shift; |
34
|
9
|
|
|
|
|
130
|
return $self; |
35
|
|
|
|
|
|
|
} |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
our %X_tests; |
38
|
|
|
|
|
|
|
*X_tests = \%File::Find::Rule::X_tests; |
39
|
|
|
|
|
|
|
for my $test (keys %X_tests) { |
40
|
|
|
|
|
|
|
$test =~ s/^-//; |
41
|
0
|
|
|
0
|
|
0
|
my $sub = eval 'sub () { |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
2
|
|
|
|
|
8
|
|
|
2
|
|
|
|
|
75
|
|
|
2
|
|
|
|
|
35
|
|
|
2
|
|
|
|
|
18
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
42
|
|
|
|
|
|
|
my $self = _force_object shift; |
43
|
|
|
|
|
|
|
push @{ $self->{rules} }, { |
44
|
|
|
|
|
|
|
code => "\$File::Find::vfs->test(q{' . $test . '}, \$_)", |
45
|
|
|
|
|
|
|
rule => "'.$X_tests{"-$test"}.'", |
46
|
|
|
|
|
|
|
}; |
47
|
|
|
|
|
|
|
return $self; |
48
|
|
|
|
|
|
|
} '; |
49
|
1
|
|
|
1
|
|
6
|
no strict 'refs'; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
243
|
|
50
|
|
|
|
|
|
|
*{ $X_tests{"-$test"} } = $sub; |
51
|
|
|
|
|
|
|
} |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
{ |
54
|
|
|
|
|
|
|
our @stat_tests; |
55
|
|
|
|
|
|
|
*stat_tests = \@File::Find::Rule::stat_tests; |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
my $i = 0; |
58
|
|
|
|
|
|
|
for my $test (@stat_tests) { |
59
|
|
|
|
|
|
|
my $index = $i++; # to close over |
60
|
|
|
|
|
|
|
my $sub = sub { |
61
|
3
|
|
|
3
|
|
10
|
my $self = _force_object shift; |
62
|
|
|
|
|
|
|
|
63
|
3
|
|
|
|
|
21
|
my @tests = map { Number::Compare->parse_to_perl($_) } @_; |
|
3
|
|
|
|
|
21
|
|
64
|
|
|
|
|
|
|
|
65
|
3
|
|
|
|
|
18
|
push @{ $self->{rules} }, { |
|
3
|
|
|
|
|
120
|
|
66
|
|
|
|
|
|
|
rule => $test, |
67
|
|
|
|
|
|
|
args => \@_, |
68
|
|
|
|
|
|
|
code => 'do { my $val = ($File::Find::vfs->stat($_))['.$index.'] || 0;'. |
69
|
3
|
|
|
|
|
86
|
join ('||', map { "(\$val $_)" } @tests ).' }', |
70
|
|
|
|
|
|
|
}; |
71
|
3
|
|
|
|
|
21
|
return $self; |
72
|
|
|
|
|
|
|
}; |
73
|
1
|
|
|
1
|
|
5
|
no strict 'refs'; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
813
|
|
74
|
|
|
|
|
|
|
*$test = $sub; |
75
|
|
|
|
|
|
|
} |
76
|
|
|
|
|
|
|
} |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
sub grep { |
79
|
1
|
|
|
1
|
1
|
4
|
my $self = _force_object shift; |
80
|
0
|
0
|
|
|
|
0
|
my @pattern = map { |
81
|
1
|
|
|
|
|
6
|
ref $_ |
82
|
|
|
|
|
|
|
? ref $_ eq 'ARRAY' |
83
|
1
|
50
|
|
|
|
9
|
? map { [ ( ref $_ ? $_ : qr/$_/ ) => 0 ] } @$_ |
|
|
50
|
|
|
|
|
|
84
|
|
|
|
|
|
|
: [ $_ => 1 ] |
85
|
|
|
|
|
|
|
: [ qr/$_/ => 1 ] |
86
|
|
|
|
|
|
|
} @_; |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
$self->exec( sub { |
89
|
7
|
|
|
7
|
|
148
|
my $vfs = $File::Find::vfs; |
90
|
7
|
50
|
|
|
|
32
|
my $fh = $vfs->open_read($_) or return; |
91
|
7
|
|
|
|
|
868
|
local ($_, $.); |
92
|
7
|
|
|
|
|
605
|
while (<$fh>) { |
93
|
40
|
|
|
|
|
51
|
for my $p (@pattern) { |
94
|
40
|
|
|
|
|
49
|
my ($rule, $ret) = @$p; |
95
|
40
|
50
|
|
|
|
266
|
if (ref $rule eq 'Regexp' ? /$rule/ : $rule->(@_)) { |
|
|
100
|
|
|
|
|
|
96
|
2
|
|
|
|
|
10
|
$vfs->close_read($fh); |
97
|
2
|
|
|
|
|
104
|
return $ret; |
98
|
|
|
|
|
|
|
} |
99
|
|
|
|
|
|
|
} |
100
|
|
|
|
|
|
|
} |
101
|
5
|
|
|
|
|
17
|
$vfs->close_read($fh); |
102
|
5
|
|
|
|
|
229
|
return; |
103
|
1
|
|
|
|
|
26
|
} ); |
104
|
|
|
|
|
|
|
} |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
sub _call_find { |
108
|
7
|
|
|
7
|
|
6709
|
my $self = shift; |
109
|
7
|
|
|
|
|
11
|
my %args = %{ shift() }; |
|
7
|
|
|
|
|
25
|
|
110
|
7
|
|
|
|
|
17
|
my $path = shift; |
111
|
7
|
|
|
|
|
15
|
my $vfs = local $File::Find::vfs = $self->{_virtual}; |
112
|
7
|
|
|
|
|
28
|
my $cwd = $vfs->cwd; |
113
|
7
|
|
|
|
|
100
|
__inner_find( $args{wanted}, $path, "" ); |
114
|
7
|
|
|
|
|
486
|
$vfs->chdir( $cwd ); |
115
|
|
|
|
|
|
|
} |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
# fake the behaviour of File::Find. It burns! |
118
|
|
|
|
|
|
|
sub __inner_find { |
119
|
11
|
|
|
11
|
|
18
|
my $wanted = shift; |
120
|
11
|
|
|
|
|
15
|
my $path = shift; |
121
|
11
|
|
|
|
|
14
|
my $parent = shift; |
122
|
11
|
|
|
|
|
13
|
my $vfs = $File::Find::vfs; |
123
|
|
|
|
|
|
|
|
124
|
11
|
100
|
|
|
|
37
|
unless ( $vfs->chdir( $path ) ) { |
125
|
|
|
|
|
|
|
# Couldn't chdir into it, so we see if it's a file. |
126
|
|
|
|
|
|
|
# Actually because there are many forms of "file" (plain, |
127
|
|
|
|
|
|
|
# symlink, socket, block, character) we just check if it |
128
|
|
|
|
|
|
|
# exists and that it's not a directory. |
129
|
2
|
50
|
33
|
|
|
195
|
if ($vfs->test('e', $path) && !$vfs->test('d', $path)) { |
130
|
2
|
|
|
|
|
524
|
my ($dir, $name) = $path =~ m{^(.*/)(.*)}; |
131
|
2
|
|
|
|
|
4
|
local $_ = $name; |
132
|
2
|
|
|
|
|
4
|
local $File::Find::dir = $dir; |
133
|
2
|
|
|
|
|
4
|
local $File::Find::name = $path; |
134
|
2
|
|
|
|
|
3
|
local $File::Find::prune; |
135
|
2
|
|
|
|
|
7
|
$vfs->chdir($dir); |
136
|
2
|
|
|
|
|
385
|
$wanted->(); |
137
|
|
|
|
|
|
|
} |
138
|
2
|
|
|
|
|
252
|
return; # I have no clue - bail |
139
|
|
|
|
|
|
|
} |
140
|
9
|
100
|
|
|
|
849
|
local $File::Find::dir = $parent ? "$parent/$path" : $path; |
141
|
9
|
|
|
|
|
35
|
for my $name ($vfs->list) { |
142
|
31
|
|
|
|
|
3935
|
local $_ = $name; |
143
|
31
|
|
|
|
|
69
|
local $File::Find::name = "$File::Find::dir/$name"; |
144
|
31
|
|
|
|
|
32
|
local $File::Find::prune; |
145
|
|
|
|
|
|
|
#print "_: $_\n"; |
146
|
|
|
|
|
|
|
#print "dir: $File::Find::dir\n"; |
147
|
|
|
|
|
|
|
#print "name: $File::Find::name\n"; |
148
|
|
|
|
|
|
|
|
149
|
31
|
|
|
|
|
809
|
$wanted->(); |
150
|
|
|
|
|
|
|
|
151
|
31
|
100
|
66
|
|
|
3464
|
if ($vfs->test("d", $name ) && !$File::Find::prune && $name !~ /^\..?$/) { |
|
|
|
100
|
|
|
|
|
152
|
4
|
|
|
|
|
485
|
my $cwd = $vfs->cwd; |
153
|
4
|
|
|
|
|
40
|
__inner_find( $wanted, $name, $File::Find::dir ); |
154
|
4
|
|
|
|
|
536
|
$vfs->chdir( $cwd ); |
155
|
|
|
|
|
|
|
} |
156
|
|
|
|
|
|
|
} |
157
|
|
|
|
|
|
|
} |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
1; |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
__END__ |