File Coverage

blib/lib/File/RDir.pm
Criterion Covered Total %
statement 58 59 98.3
branch 24 28 85.7
condition 5 6 83.3
subroutine 6 6 100.0
pod 0 3 0.0
total 93 102 91.1


line stmt bran cond sub pod time code
1             package File::RDir;
2             $File::RDir::VERSION = '0.02';
3 1     1   711 use strict;
  1         2  
  1         28  
4 1     1   5 use warnings;
  1         2  
  1         35  
5              
6 1     1   13 use Carp qw(croak);
  1         1  
  1         859  
7              
8             require Exporter;
9              
10             our @ISA = qw(Exporter);
11             our %EXPORT_TAGS = ( 'all' => [ qw(read_rdir) ] );
12             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
13             our @EXPORT = qw();
14              
15             sub new {
16 3     3 0 4 my $pkg = shift;
17 3         4 my ($root, $opt) = @_;
18 3         6 $root =~ s{\\}'/'xmsg;
19              
20 3         3 my @PList;
21              
22 3 100 66     18 if (ref($opt) eq 'HASH' and defined($opt->{'prune'})) {
23 2         10 for (split m{;}xms, $opt->{'prune'}) {
24 4 100       22 my ($item, $mod) = m{\A ([^:]*) : ([A-Z]*)\z}xmsi ? ($1, $2) : ($_, '');
25              
26 4         7 my $rstring = '';
27              
28 4         11 for my $frag (split m{([\*\?])}xms, $item) {
29 6 100       14 if ($frag eq '*') {
    50          
30 2         4 $rstring .= '.*?';
31             }
32             elsif ($frag eq '?') {
33 0         0 $rstring .= '.';
34             }
35             else {
36 4         9 $rstring .= quotemeta($frag);
37             }
38             }
39              
40 4 100       55 push @PList, $mod =~ m{i}xmsi ? qr{\A $rstring \z}xmsi : qr{\A $rstring \z}xms;
41             }
42             }
43              
44 3 50       95 opendir my $hdl, $root or croak "Can't opendir '$root' because $!";
45              
46 3         15 my $self = { 'root' => $root, 'ndir' => '', 'dlist' => [], 'hdl' => $hdl, 'pl' => \@PList };
47              
48 3         12 bless $self, $pkg;
49             }
50              
51             sub match {
52 22     22 0 34 my $self = shift;
53 22 50       57 return unless $self->{'hdl'};
54              
55 22         22 my $ele;
56 22         38 my $full_dir = $self->{'root'}.$self->{'ndir'};
57              
58             LOOP1: {
59 22         24 $ele = readdir $self->{'hdl'};
  95         302  
60              
61 95 100       216 unless (defined $ele) {
62 19         131 closedir $self->{'hdl'};
63 19         33 $self->{'hdl'} = undef;
64              
65 19         39 my $ndir = shift @{$self->{'dlist'}};
  19         43  
66 19 100       43 last LOOP1 unless defined $ndir;
67              
68 16         29 $self->{'ndir'} = $ndir;
69              
70 16         28 $full_dir = $self->{'root'}.$self->{'ndir'};
71 16 50       274 opendir $self->{'hdl'}, $full_dir or croak "Can't opendir '$full_dir' because $!";
72 16         25 redo LOOP1;
73             }
74              
75 76         132 my $full_ele = $full_dir.'/'.$ele;
76              
77 76 100       1216 if (-d $full_ele) {
78 57 100 100     242 redo LOOP1 if $ele eq '.' or $ele eq '..';
79              
80 19         19 for my $p (@{$self->{'pl'}}) {
  19         42  
81 22 100       191 redo LOOP1 if $ele =~ $p;
82             }
83              
84 16         21 push @{$self->{'dlist'}}, $self->{'ndir'}.'/'.$ele;
  16         48  
85 16         26 redo LOOP1;
86             }
87             }
88              
89 22 100       51 return unless defined $ele;
90              
91 19         76 return $self->{'ndir'}.'/'.$ele;
92             }
93              
94             sub read_rdir {
95 3     3 0 439 my ($root, $opt) = @_;
96              
97 3         4 my @FList;
98              
99 3         13 my $iter = File::RDir->new($root, $opt);
100              
101 3         10 while (defined(my $file = $iter->match)) {
102 19         62 push @FList, $file;
103             }
104              
105 3         58 return @FList;
106             }
107              
108             1;
109              
110             __END__