File Coverage

blib/lib/App/Greple/Filter.pm
Criterion Covered Total %
statement 61 76 80.2
branch 17 36 47.2
condition 4 10 40.0
subroutine 12 12 100.0
pod 0 6 0.0
total 94 140 67.1


line stmt bran cond sub pod time code
1             package App::Greple::Filter;
2              
3 171     171   2692 use v5.24;
  171         526  
4 171     171   797 use warnings;
  171         279  
  171         7614  
5              
6 171     171   699 use Exporter 'import';
  171         293  
  171         11003  
7             our @EXPORT = ();
8             our %EXPORT_TAGS = ();
9             our @EXPORT_OK = qw();
10              
11 171     171   1248 use Getopt::EX::Func qw(parse_func);
  171         8200  
  171         8189  
12 171     171   674 use App::Greple::Common qw(%debug &FILELABEL);
  171         227  
  171         66120  
13              
14              
15             sub new {
16 166     166 0 410 my $class = shift;
17 166         460 my $obj = bless [], $class;
18              
19 166 50       588 $obj->append(@_) if @_;
20              
21 166         655 $obj;
22             }
23              
24             sub parse {
25 166     166 0 295 my $obj = shift;
26 166 50       1018 push @$obj, map { /([^:]+):(.*)/ ? [ $1, $2 ] : $_ } @_;
  2         32  
27 166         529 $obj;
28             }
29              
30             sub append {
31 166     166 0 355 my $obj = shift;
32 166         438 push @$obj, @_;
33 166         359 $obj;
34             }
35              
36             sub get_filters {
37 167     167 0 332 my $obj = shift;
38 167         471 my $filename = shift;
39              
40 167         308 my @f;
41 167         444 local $_ = $filename;
42 167         728 for (my $remember = ""; $remember ne $_; ) {
43 167         497 $remember = $_;
44 167         520 for my $p (@$obj) {
45 670 100       1496 if (ref $p eq 'ARRAY') {
46 668         1159 my($exp, $command) = @$p;
47 668 50       2335 if (ref $exp eq 'CODE' ? &$exp : eval $exp) {
    50          
48 0         0 $command =~ s/{}/$filename/g;
49 0         0 push @f, $command;
50 0 0       0 last if $_ ne $remember;
51             }
52             } else {
53 2         6 push @f, $p;
54             }
55             }
56             }
57 167         1112 @f;
58             }
59              
60 171     171   1455 use POSIX();
  171         5760  
  171         79781  
61              
62             push @EXPORT, qw(push_output_filter);
63             sub push_output_filter {
64 7 100   7 0 21 my %arg = ref $_[0] eq 'HASH' ? %{+shift} : ();
  5         16  
65 7         9 my $fh = shift;
66 7         18 my $pkg = caller;
67 7         17 for my $filter (reverse @_) {
68 7 50       21 $debug{F} and warn "Push output Filter: \"$filter\"\n";
69 7   50     28300 my $pid = open($fh, '|-') // die "$filter: $!\n";
70 7 100       1009 if ($pid == 0) {
71 3 50 33     425 if ($filter =~ /^&/ and
72             my $f = parse_func({ PACKAGE => $pkg }, $filter)) {
73 0         0 local @ARGV;
74 0 0       0 open STDIN, '<&', 0 if eof STDIN;
75 0         0 $f->call;
76             } else {
77 3         53 do { exec $filter } ;
  3         0  
78 0 0       0 warn $@ if $@;
79             }
80 0         0 STDOUT->flush();
81 0         0 STDERR->flush();
82 0         0 POSIX::_exit(0);
83             }
84             }
85             }
86              
87             push @EXPORT, qw(push_input_filter);
88             sub push_input_filter {
89 2 50   2 0 4 my %arg = ref $_[0] eq 'HASH' ? %{+shift} : ();
  2         6  
90 2         22 my $pkg = caller;
91 2         6 for my $filter (@_) {
92 2 50       4 $debug{F} and warn "Push input Filter: \"$filter\"\n";
93 2 50 33     8 if ($filter =~ /^&/ and
94             my $f = parse_func({ PACKAGE => $pkg }, $filter)) {
95 0 0       0 if ($arg{&FILELABEL}) {
96 0         0 $f->append(&FILELABEL => $arg{&FILELABEL});
97             }
98             ##
99             ## intput filter function is responsible for process fork
100             ##
101 0         0 $f->call;
102             } else {
103 2   50     5532 my $pid = open(STDIN, '-|') // die "$filter: $!\n";
104 2 100       368 if ($pid == 0) {
105 1         19 do { exec $filter } ;
  1            
106 0 0         warn $@ if $@;
107 0           POSIX::_exit(0);
108             }
109             }
110             }
111             }
112              
113             1;