File Coverage

blib/lib/Path/Find.pm
Criterion Covered Total %
statement 57 57 100.0
branch 22 26 84.6
condition 3 3 100.0
subroutine 15 15 100.0
pod 2 2 100.0
total 99 103 96.1


line stmt bran cond sub pod time code
1             package Path::Find;
2              
3             # $Id: Find.pm 2590 2024-02-23 17:36:47Z fil $
4              
5 1     1   194196 use 5.00405;
  1         4  
6 1     1   11 use strict;
  1         3  
  1         37  
7 1     1   6 use vars qw($VERSION @ISA);
  1         2  
  1         118  
8             @ISA = qw();
9              
10             $VERSION = '0.04';
11              
12 1     1   7 use Carp;
  1         2  
  1         90  
13 1     1   6 use File::Spec;
  1         2  
  1         36  
14 1     1   1958 use IO::Dir;
  1         29834  
  1         69  
15 1     1   9 use Scalar::Util qw( blessed );
  1         3  
  1         61  
16 1     1   670 use Text::Glob qw( glob_to_regex );
  1         1144  
  1         81  
17              
18 1     1   8 use Exporter qw( import );
  1         2  
  1         654  
19             our @EXPORT = qw( path_find );
20             our @EXPORT_OK = qw( path_find matchable );
21              
22             sub path_find
23             {
24 10     10 1 5842 my( $dir, $dirglob, $fileglob ) = @_;
25 10 100       28 if( 2==@_ ) {
26 6         10 $fileglob = $dirglob;
27 6         10 $dirglob = "*";
28             }
29              
30 10         42 __path_find( $dir, matchable( $dirglob ), matchable( $fileglob ), 0 );
31             }
32              
33             sub __path_find
34             {
35 53     53   171 my( $dir, $dirmatch, $filematch, $depth ) = @_;
36              
37 53         62 my @ret;
38              
39 53         206 my $dh = IO::Dir->new( $dir );
40 53 50       3524 $dh or return;
41 53         73 my $entry;
42 53         143 while( defined( $entry = $dh->read ) ) {
43 209 100 100     2781 next if $entry eq '.' or $entry eq '..';
44 103         966 my $full = File::Spec->catfile( $dir, $entry );
45 103 100       1571 if( -d $full ) {
    100          
46 44 100       98 push @ret, __path_find( $full, $dirmatch, $filematch, $depth+1 ) if $dirmatch->( $entry, $dir, $full, $depth );
47             }
48             elsif( $filematch->( $entry, $dir, $full, $depth ) ) {
49 26         95 push @ret, $full;
50             }
51             }
52 53         1481 return @ret;
53             }
54              
55             # Turn a glob into a coderef
56             sub matchable
57             {
58 25     25 1 224915 my( $glob ) = @_;
59 25 100       63 $glob = '*' unless defined $glob;
60 25 100       59 return $glob if 'CODE' eq ref $glob;
61 21 100   20   43 return sub { $_[0] =~ $glob } if 'Regexp' eq ref $glob;
  20         203  
62 17 100       26 if( blessed $glob ) {
63 3 50       20 confess ref( $glob ), " object doesn't have method 'match'" unless $glob->can( 'match' );
64 3     7   11 return sub { $glob->match( @_ ) };
  7         16  
65             }
66 14 50       22 confess "Can't convert $glob into a matchable" if ref $glob;
67 14 50       24 $glob = '*' unless defined $glob;
68 14         33 my $re = glob_to_regex( $glob );
69             # warn "glob=$glob re=$re";
70 14     59   920 return sub { $_[0] =~ $re };
  59         631  
71             }
72              
73             1;
74              
75             __END__