File Coverage

blib/lib/File/Grep.pm
Criterion Covered Total %
statement 82 115 71.3
branch 18 30 60.0
condition 0 5 0.0
subroutine 13 18 72.2
pod 3 5 60.0
total 116 173 67.0


line stmt bran cond sub pod time code
1             #!/usr/bin/perl -w
2              
3             package File::Grep;
4              
5 1     1   654 use strict;
  1         2  
  1         37  
6 1     1   9 use Carp;
  1         2  
  1         357  
7              
8             BEGIN {
9 1     1   6 use Exporter ();
  1         5  
  1         22  
10 1     1   6 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
  1         2  
  1         589  
11 1     1   12 $VERSION = sprintf( "%d.%02d", q( $Revision: 0.02 $ ) =~ /\s(\d+)\.(\d+)/ );
12 1         18 @ISA = qw(Exporter);
13 1         2 @EXPORT = qw();
14 1         3 @EXPORT_OK = qw( fgrep fmap fdo );
15 1         1723 %EXPORT_TAGS = ( );
16             }
17              
18             # Remain silent on bad files, else shoutout.
19             our $SILENT = 1;
20              
21             # Internal function; does the actual walk through the files, and calls
22             # out to the coderef to do the work for each line. This gives me a bit
23             # more flexibility with the end interface
24              
25             sub _fgrep_process {
26 10     10   20 my ( $closure, @files ) = @_;
27 10         13 my $openfile = 0;
28 10         14 my $abort = 0;
29 10         10 my $i = 0;
30 10         18 foreach my $file ( @files ) {
31 18         22 my $fh;
32 18 100       63 if ( UNIVERSAL::isa( \$file, "SCALAR" ) ) {
33             # If it's a scalar, assume it's a file and open it
34 14 50 0     467 open FILE, "$file" or
      0        
35             ( !$SILENT and carp "Cannot open file '$file' for fgrep: $!" )
36             and next;
37 14         37 $fh = \*FILE;
38 14         21 $openfile = 1;
39             } else {
40             # Otherwise, we will assume it's a legit filehandle.
41             # If something's
42             # amiss, we'll catch it at <> below.
43 4         6 $fh = $file;
44 4         5 $openfile = 0;
45             }
46 18         22 my $line;
47 18         21 eval { $line = <$fh> };
  18         238  
48             # Fix for perl5.8 - thanks to Benjamin Kram
49 18 100       36 if ( $@ ) {
50 1 50       8 !$SILENT and carp "Cannot use file '$file' for fgrep: $@";
51 1         2 last;
52             } else {
53 17         36 while ( defined( $line ) ) {
54 116         221 my $state = &$closure( $i, $., $line );
55 116 50       266 if ( $state < 0 ) {
    50          
56             # If need to shut down whole process...
57 0         0 $abort = 1;
58 0         0 last; # while!
59             } elsif ( $state == 0 ) {
60             # If need to shut down just this file...
61 0         0 $abort = 0;
62 0         0 last; # while!
63             }
64 116         367 $line = <$fh>;
65             }
66             }
67 17 100       40 if ( $openfile ) { close $fh; }
  14         118  
68 17 50       32 last if ( $abort ); # Fileloop...
69 17         32 $i++; # Increment counter
70             }
71 10         68 return;
72             }
73              
74             sub fgrep (&@) {
75 8     8 1 2997 my ( $coderef, @files ) = @_;
76 8 100       27 if ( wantarray ) {
    50          
77 2         4 my @matches = map { { filename => $_,
  4         20  
78             count => 0,
79             matches => { } } } @files;
80             my $sub = sub {
81 28     28   51 my ( $file, $pos, $line ) = @_;
82 28         45 local $_ = $line;
83 28 100       54 if ( &$coderef( $file, $pos, $_ ) ) {
84 9         52 $matches[$file]->{ count }++;
85 9         24 $matches[$file]->{ matches }->{ $pos } = $line;
86             }
87 28         149 return 1;
88 2         10 };
89              
90 2         5 _fgrep_process( $sub, @files );
91 2         18 return @matches;
92              
93             } elsif ( defined( wantarray ) ) {
94 6         8 my $count = 0;
95             my $sub = sub {
96 60     60   115 my ( $file, $pos, $line ) = @_;
97 60         74 local $_ = $line;
98 60 100       115 if ( &$coderef( $file, $pos, $_ ) ) { $count++ };
  15         90  
99 60         244 return 1;
100 6         26 };
101            
102 6         19 _fgrep_process( $sub, @files );
103 6         29 return $count;
104             } else {
105 0         0 my $found = 0;
106             my $sub = sub {
107 0     0   0 my ( $file, $pos, $line ) = @_;
108 0         0 local $_ = $line;
109 0 0       0 if ( &$coderef( $file, $pos, $_ ) )
110 0         0 { $found=1; return -1; }
  0         0  
111             else
112 0         0 { return 1; }
113 0         0 };
114 0         0 _fgrep_process( $sub, @files );
115 0         0 return $found;
116             }
117             }
118              
119             sub fgrep_flat (&@) {
120 0     0 0 0 my ( $coderef, @files ) = @_;
121 0         0 my @matches;
122             my $sub = sub {
123 0     0   0 my ( $file, $pos, $line ) = @_;
124 0         0 local $_ = $line;
125 0 0       0 if ( &$coderef( $file, $pos, $_ ) ) {
126 0         0 push @matches, $line;
127 0         0 return 1;
128             }
129 0         0 };
130 0         0 _fgrep_process( $sub, @files );
131 0         0 return @matches;
132             }
133              
134             sub fgrep_into ( &$@ ) {
135 0     0 0 0 my ( $coderef, $arrayref, @files ) = @_;
136             my $sub = sub {
137 0     0   0 my ( $file, $pos, $line ) = @_;
138 0         0 local $_ = $line;
139 0 0       0 if ( &$coderef( $file, $pos, $_ ) ) {
140 0         0 push @$arrayref, $line;
141 0         0 return 1;
142             }
143 0         0 };
144 0         0 _fgrep_process( $sub, @files );
145 0         0 return $arrayref;
146             }
147              
148             sub fmap (&@) {
149 1     1 1 327 my ( $mapper, @files ) = @_;
150              
151 1         1 my @mapped;
152             my $sub = sub {
153 14     14   24 my ( $file, $pos, $line ) = @_;
154 14         16 local $_ = $line;
155 14         59 push @mapped, &$mapper( $file, $pos, $_ );
156 14         59 return 1;
157 1         5 };
158 1         4 _fgrep_process( $sub, @files );
159 1         9 return @mapped;
160             }
161              
162             sub fdo (&@) {
163 1     1 1 321 my ( $doer, @files ) = @_;
164             my $sub = sub {
165 14     14   21 my ( $file, $pos, $line ) = @_;
166 14         21 local $_ = $line;
167 14         30 &$doer( $file, $pos, $_ );
168 14         78 return 1;
169 1         6 };
170 1         3 _fgrep_process( $sub, @files );
171             }
172              
173             1;
174             __END__