File Coverage

blib/lib/Mail/Box/Search/Grep.pm
Criterion Covered Total %
statement 86 90 95.5
branch 27 46 58.7
condition 9 13 69.2
subroutine 18 20 90.0
pod 6 7 85.7
total 146 176 82.9


line stmt bran cond sub pod time code
1             # Copyrights 2001-2019 by [Mark Overmeer].
2             # For other contributors see ChangeLog.
3             # See the manual pages for details on the licensing terms.
4             # Pod stripped from pm file by OODoc 2.02.
5             # This code is part of distribution Mail-Box. Meta-POD processed with
6             # OODoc into POD and HTML manual-pages. See README.md
7             # Copyright Mark Overmeer. Licensed under the same terms as Perl itself.
8              
9             package Mail::Box::Search::Grep;
10 2     2   1468 use vars '$VERSION';
  2         5  
  2         99  
11             $VERSION = '3.008';
12              
13 2     2   11 use base 'Mail::Box::Search';
  2         2  
  2         793  
14              
15 2     2   22 use strict;
  2         4  
  2         32  
16 2     2   8 use warnings;
  2         4  
  2         35  
17              
18 2     2   9 use Carp;
  2         2  
  2         520  
19              
20             #-------------------------------------------
21              
22              
23             sub init($)
24 12     12 0 9809 { my ($self, $args) = @_;
25              
26 12 0 33     41 $args->{in} ||= ($args->{field} ? 'HEAD' : 'BODY');
27              
28 12   66     40 my $deliver = $args->{deliver} || $args->{details}; # details is old name
29             $args->{deliver}
30             = !defined $deliver ? $deliver
31             : ref $deliver eq 'CODE' ? $deliver
32 14     14   33 : $deliver eq 'PRINT' ? sub { $_[0]->printMatch($_[1]) }
33 504     504   865 : ref $deliver eq 'ARRAY' ? sub { push @$deliver, $_[1] }
34 12 50       110 : $deliver;
    100          
    50          
    100          
35              
36 12         65 $self->SUPER::init($args);
37              
38 12         23 my $take = $args->{field};
39             $self->{MBSG_field_check}
40 3865     3865   14618 = !defined $take ? sub {1}
41 0     0   0 : !ref $take ? do {$take = lc $take; sub { $_[1] eq $take }}
  0         0  
  0         0  
42 0     0   0 : ref $take eq 'Regexp' ? sub { $_[1] =~ $take }
43 12 0       50 : ref $take eq 'CODE' ? $take
    0          
    0          
    50          
44             : croak "Illegal field selector $take.";
45              
46             my $match = $args->{match}
47 12 50       39 or croak "No match pattern specified.\n";
48             $self->{MBSG_match_check}
49 2     2   858 = !ref $match ? sub { index("$_[1]", $match) >= $[ }
  2     2245   523  
  2         1453  
  2245         5823  
50 14921     14921   57869 : ref $match eq 'Regexp' ? sub { "$_[1]" =~ $match }
51 12 0       70 : ref $match eq 'CODE' ? $match
    50          
    100          
52             : croak "Illegal match pattern $match.";
53              
54 12         35 $self;
55             }
56              
57             sub search(@)
58 14     14 1 1605 { my ($self, $object, %args) = @_;
59 14         29 delete $self->{MBSG_last_printed};
60 14         50 $self->SUPER::search($object, %args);
61             }
62              
63             sub inHead(@)
64 231     231 1 1120 { my ($self, $part, $head, $args) = @_;
65              
66 231         460 my @details = (message => $part->toplevel, part => $part);
67             my ($field_check, $match_check, $deliver)
68 231         1106 = @$self{ qw/MBSG_field_check MBSG_match_check MBS_deliver/ };
69              
70 231         421 my $matched = 0;
71             LINES:
72 231         554 foreach my $field ($head->orderedFields)
73 3865 100 66     74440 { next unless $field_check->($head, $field->name)
74             && $match_check->($head, $field);
75              
76 122         2589 $matched++;
77 122 50       213 last LINES unless $deliver; # no deliver: only one match needed
78 122         373 $deliver->( {@details, field => $field} );
79             }
80              
81 231         4383 $matched;
82             }
83              
84             sub inBody(@)
85 302     302 1 724 { my ($self, $part, $body, $args) = @_;
86              
87 302         814 my @details = (message => $part->toplevel, part => $part);
88             my ($field_check, $match_check, $deliver)
89 302         1455 = @$self{ qw/MBSG_field_check MBSG_match_check MBS_deliver/ };
90              
91 302         379 my $matched = 0;
92 302         343 my $linenr = 0;
93              
94             LINES:
95 302         628 foreach my $line ($body->lines)
96 13301         18273 { $linenr++;
97 13301 100       15924 next unless $match_check->($body, $line);
98              
99 397         605 $matched++;
100 397 100       625 last LINES unless $deliver; # no deliver: only one match needed
101 396         1291 $deliver->( {@details, linenr => $linenr, line => $line} );
102             }
103              
104 302         1206 $matched;
105             }
106              
107             #-------------------------------------------
108              
109              
110             sub printMatch($;$)
111 14     14 1 19 { my $self = shift;
112 14 50       45 my ($out, $match) = @_==2 ? @_ : (select, shift);
113              
114             $match->{field}
115 14 100       45 ? $self->printMatchedHead($out, $match)
116             : $self->printMatchedBody($out, $match)
117             }
118              
119              
120             sub printMatchedHead($$)
121 5     5 1 27 { my ($self, $out, $match) = @_;
122 5         11 my $message = $match->{message};
123 5         11 my $msgnr = $message->seqnr;
124 5         11 my $folder = $message->folder->name;
125 5   100     15 my $lp = $self->{MBSG_last_printed} || '';
126              
127 5 100       14 unless($lp eq "$folder $msgnr") # match in new message
128 4         8 { my $subject = $message->subject;
129 4         184 $out->print("$folder, message $msgnr: $subject\n");
130 4         68 $self->{MBSG_last_printed} = "$folder $msgnr";
131             }
132              
133 5         17 my @lines = $match->{field}->string;
134 5 50       100 my $inpart = $match->{part}->isPart ? 'p ' : ' ';
135 5         19 $out->print($inpart, join $inpart, @lines);
136 5         74 $self;
137             }
138              
139              
140             sub printMatchedBody($$)
141 9     9 1 19 { my ($self, $out, $match) = @_;
142 9         14 my $message = $match->{message};
143 9         35 my $msgnr = $message->seqnr;
144 9         25 my $folder = $message->folder->name;
145 9   100     30 my $lp = $self->{MBSG_last_printed} || '';
146              
147 9 50       31 unless($lp eq "$folder $msgnr") # match in new message
148 9         26 { my $subject = $message->subject;
149 9         430 $out->print("$folder, message $msgnr: $subject\n");
150 9         205 $self->{MBSG_last_printed} = "$folder $msgnr";
151             }
152              
153 9 100       31 my $inpart = $match->{part}->isPart ? 'p ' : ' ';
154 9         50 $out->print(sprintf "$inpart %2d: %s", $match->{linenr}, $match->{line});
155 9         154 $self;
156             }
157              
158             1;