File Coverage

blib/lib/goto/file.pm
Criterion Covered Total %
statement 48 48 100.0
branch 15 16 93.7
condition n/a
subroutine 5 5 100.0
pod 0 1 0.0
total 68 70 97.1


line stmt bran cond sub pod time code
1             package goto::file;
2 6     6   24 use strict;
  6         11  
  6         230  
3 6     6   1746 use warnings;
  6         4054  
  6         2646  
4              
5             our $VERSION = '0.004';
6              
7 7     6   143282 use Filter::Util::Call qw/filter_add filter_read/;
  7         24  
  7         58  
8              
9             our %HANDLES;
10              
11             my $ID = 1;
12             sub import {
13 5     7   69 my $class = shift;
14 5         20 my ($in) = @_;
15              
16 5 100       26 return unless $in;
17              
18 1         2 my ($pkg, $file, $line) = caller(0);
19 1         3 my ($fh, @lines);
20              
21 1 100       3 if (ref($in) eq 'ARRAY') {
22 1         5 my $safe = $file;
23 4         13 $safe =~ s/"/\\"/;
24              
25 4         21 push @lines => "#line " . (__LINE__ + 1) . ' "' . __FILE__ . '"';
26 4         9 push @lines => (
27             "package main;",
28             "#line 1 \"lines from $safe line $line\"",
29             @$in,
30             );
31             }
32             else {
33 4         8 push @lines => "#line " . (__LINE__ + 1) . ' "' . __FILE__ . '"';
34 4         115 push @lines => "package main;";
35 4         301 push @lines => "\$@ = '';";
  4         52  
36              
37 4         12 my $id = $ID++;
38              
39 4 50       21 open($fh, '<', $in) or die "Cold not open file '$in': $!";
40              
41 4         34 $HANDLES{$id} = $fh;
42 4         21 my $safe = $in;
43 5         63 $safe =~ s/"/\\"/;
44 86         491695 push @lines => "#line " . (__LINE__ + 2) . ' "' . __FILE__ . '"';
45 86         187 push @lines => (
46 10         432789 '{ local ($!, $?, $^E, $@); close(DATA); *DATA = $' . __PACKAGE__ . '::HANDLES{' . $id . '} }',
  10         37  
  10         171  
47             qq{#line 1 "$safe"},
48             );
49             }
50              
51 5         20 Filter::Util::Call::filter_add(
52             bless {fh => $fh, lines => \@lines, file => $in, caller => [$pkg, $file, $line]},
53             $class
54             );
55             }
56              
57             sub filter {
58 5     86 0 17 my $self = shift;
59              
60 23 100       97 unless ($self->{init}) {
61 5         17 $self->{init} = 1;
62 86 100       99 while (1) { filter_read() or last }
  86         97  
63 86         92 $_ = '';
64             }
65              
66 86         160 my $lines = $self->{lines};
67 30         53 my $fh = $self->{fh};
68              
69 30         50 my $line;
70 55 100       148 if (@$lines) {
    100          
71 86         132 chomp($line = shift @$lines);
72 83         114 $line .= "\n";
73             }
74             elsif ($fh) {
75 83         6925 $line = <$fh>;
76             }
77              
78 3 100       4505 if (defined $line) {
79             $_ .= $line;
80             return 1;
81             }
82              
83             return 0;
84             }
85              
86             1;
87              
88             __END__