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 134     134   2697 use v5.24;
  134         569  
4 134     134   836 use warnings;
  134         280  
  134         7854  
5              
6 134     134   889 use Exporter 'import';
  134         305  
  134         12767  
7             our @EXPORT = ();
8             our %EXPORT_TAGS = ();
9             our @EXPORT_OK = qw();
10              
11 134     134   1397 use Getopt::EX::Func qw(parse_func);
  134         7713  
  134         9107  
12 134     134   1008 use App::Greple::Common qw(%debug &FILELABEL);
  134         537  
  134         72182  
13              
14              
15             sub new {
16 129     129 0 370 my $class = shift;
17 129         410 my $obj = bless [], $class;
18              
19 129 50       624 $obj->append(@_) if @_;
20              
21 129         849 $obj;
22             }
23              
24             sub parse {
25 129     129 0 331 my $obj = shift;
26 129 50       1055 push @$obj, map { /([^:]+):(.*)/ ? [ $1, $2 ] : $_ } @_;
  2         52  
27 129         452 $obj;
28             }
29              
30             sub append {
31 129     129 0 318 my $obj = shift;
32 129         478 push @$obj, @_;
33 129         444 $obj;
34             }
35              
36             sub get_filters {
37 130     130 0 466 my $obj = shift;
38 130         437 my $filename = shift;
39              
40 130         318 my @f;
41 130         440 local $_ = $filename;
42 130         793 for (my $remember = ""; $remember ne $_; ) {
43 130         359 $remember = $_;
44 130         426 for my $p (@$obj) {
45 522 100       1476 if (ref $p eq 'ARRAY') {
46 520         1281 my($exp, $command) = @$p;
47 520 50       1632 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 130         918 @f;
58             }
59              
60 134     134   1611 use POSIX();
  134         6391  
  134         90396  
61              
62             push @EXPORT, qw(push_output_filter);
63             sub push_output_filter {
64 7 100   7 0 30 my %arg = ref $_[0] eq 'HASH' ? %{+shift} : ();
  5         18  
65 7         11 my $fh = shift;
66 7         41 my $pkg = caller;
67 7         19 for my $filter (reverse @_) {
68 7 50       24 $debug{F} and warn "Push output Filter: \"$filter\"\n";
69 7   50     37816 my $pid = open($fh, '|-') // die "$filter: $!\n";
70 7 100       1104 if ($pid == 0) {
71 3 50 33     444 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         75 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 8 my %arg = ref $_[0] eq 'HASH' ? %{+shift} : ();
  2         12  
90 2         6 my $pkg = caller;
91 2         6 for my $filter (@_) {
92 2 50       8 $debug{F} and warn "Push input Filter: \"$filter\"\n";
93 2 50 33     32 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     7809 my $pid = open(STDIN, '-|') // die "$filter: $!\n";
104 2 100       1113 if ($pid == 0) {
105 1         17 do { exec $filter } ;
  1            
106 0 0         warn $@ if $@;
107 0           POSIX::_exit(0);
108             }
109             }
110             }
111             }
112              
113             1;