File Coverage

blib/lib/Inline/Files.pm
Criterion Covered Total %
statement 101 110 91.8
branch 14 20 70.0
condition 5 15 33.3
subroutine 21 26 80.7
pod 0 1 0.0
total 141 172 81.9


line stmt bran cond sub pod time code
1             package Inline::Files;
2             $VERSION = '0.70';
3 8     8   106605 use strict;
  8         78  
  8         267  
4              
5 8     8   3437 use Inline::Files::Virtual;
  8         20  
  8         54  
6 8     8   4448 use Filter::Util::Call;
  8         7288  
  8         588  
7 8     8   58 use Cwd qw(abs_path);
  8         14  
  8         309  
8 8     8   44 use Carp;
  8         66  
  8         3257  
9              
10             my $SOVFM_pat = qr/^__[A-Z](?:_*[A-Z0-9]+)*__\n/m;
11             my %files;
12              
13             sub import {
14 8     8   71 DEBUG && TRACE(@_);
15 8         25 $DB::single = 1;
16 8         21 my ($class, @args) = @_;
17 8         27 my ($package, $file, $line) = caller;
18              
19 8         15 my $path = './';
20 8         23 $file =~ s|\\|/|g;
21 8 50       97 ($path, $file) = ($1, $2) if $file =~ m|^(.*)/(.*)$|;
22 8         232 $file = abs_path($path) . "/$file";
23 8         32 $files{$package} = $file;
24              
25 8         46 while (@args) {
26 1         2 my $next = shift @args;
27 1 50       4 if ($next eq '-backup') {
28 1   33     7 my $backup = shift(@args)||"$file.bak";
29 1         4 local (*IN, *OUT);
30 1 50 33     284 open IN, $file and open OUT, ">$backup" and
      33        
      33        
      33        
31             print OUT and
32             close IN and close OUT
33             or croak "Cannot make backup of '$file'\n($!)";
34             }
35 0         0 else { croak "usage: use $class [-backup [=> 'filename']]" }
36             }
37              
38 8         22 my (%symbols, $source);
39 8         35 foreach my $vfile (vf_load($file, $SOVFM_pat)) {
40 12         40 my $symbol = vf_marker($vfile);
41 12         61 $symbol =~ s/^__|__\n//g;
42 12         19 push @{$symbols{$symbol}}, $vfile;
  12         34  
43             }
44              
45 8         27 foreach my $symbol (keys %symbols) {
46 8     8   178 no strict 'refs';
  8         24  
  8         1011  
47 8         20 my $fq_symbol = "${package}::${symbol}";
48 8         11 @$fq_symbol = @{$symbols{$symbol}};
  8         41  
49 8         21 $$fq_symbol = $symbols{$symbol}[0];
50 8         185 my $impl = tie *$fq_symbol, $class, $fq_symbol, -w $file;
51 8         51 tie %$fq_symbol, $class."::Data", $impl;
52             }
53              
54 8         17 foreach (qw( open close seek tell truncate write )) {
55 8     8   54 no strict 'refs';
  8         16  
  8         2527  
56 48         66 *{"CORE::GLOBAL::$_"} = \&{"vf_$_"};
  48         297  
  48         94  
57             }
58              
59 8         38 ($source = vf_prefix($file)) =~ s/(.*\n){$line}//;
60             filter_add( sub {
61 16 100   16   11839 return 0 unless $source;
62 8         72 $_ = $source;
63 8         20 $source = "";
64 8         1885 return 1;
65 8         83 } );
66             }
67              
68             sub TIEHANDLE {
69 12     12   25 DEBUG && TRACE(@_);
70 12         28 my ($class, $symbol, $writable) = @_;
71 12         65 bless { symbol => $symbol, writable => $writable }, $class;
72             }
73              
74             sub STORE {
75 0     0   0 DEBUG && TRACE(@_);
76             }
77              
78             sub DESTROY {
79 4     4   14 DEBUG && TRACE(@_);
80             }
81              
82             sub AUTOLOAD {
83 6     6   135 DEBUG && TRACE(@_) &&
84             print "AUTOLOAD => $Inline::Files::AUTOLOAD\n";
85 8     8   66 no strict;
  8         16  
  8         1625  
86 6         46 local $^W;
87 6         13 my $impl = shift;
88 6         15 my $symbol = $impl->{symbol};
89 6         25 untie *$symbol;
90 6         17 $$symbol = shift @$symbol;
91 6 100       22 return unless $$symbol;
92 5 100       13 my $open_mode = $impl->{writable} ? "+<" : "<";
93 5 50       26 vf_open $symbol, "$open_mode$$symbol", $symbol or return;
94 5 50       25 croak "Internal error" unless tied *$symbol;
95 5         26 $AUTOLOAD =~ s/.*:://;
96 5         9 local $Carp::CarpLevel = 1;
97 5         25 return tied(*$symbol)->$AUTOLOAD(@_);
98             }
99              
100             sub get_filename {
101 2     2 0 3 DEBUG && TRACE(@_);
102 2 50       12 $files{$_[0]} || "";
103             }
104              
105             package Inline::Files::Data;
106 8     8   59 use Carp;
  8         14  
  8         712  
107             BEGIN {
108 8     8   42 *DEBUG = \&Inline::Files::DEBUG;
109 8         405 *TRACE = \&Inline::Files::TRACE;
110             }
111              
112             sub access {
113 6     6   6 DEBUG && TRACE(@_);
114 8     8   51 no strict 'refs';
  8         13  
  8         4187  
115 6         7 tied(*{$_[0]->{impl}{symbol}});
  6         63  
116             }
117             my %fetch = (
118             file => sub { access($_[0])->{afile} },
119             line => sub { access($_[0])->{vfile}{line}},
120             offset => sub { access($_[0])->{vfile}{offset}},
121             writable => sub { $_[0]->{impl}{writable} },
122             );
123              
124             my @validkeys = keys %fetch;
125             my $validkey = qr/${\join '|', @validkeys}/;
126              
127             sub TIEHASH {
128 8     8   11 DEBUG && TRACE(@_);
129 8         16 my ($class, $impl) = @_;
130 8         31 bless { impl=>$impl, iter=>0 }, $class;
131             }
132              
133             sub FETCH {
134 10     10   511 DEBUG && TRACE(@_);
135 10         30 my ($self, $key) = @_;
136 10 100       86 return undef unless $key =~ $validkey;
137 8         20 return $fetch{$key}->($self);
138             }
139              
140             sub FIRSTKEY {
141 0     0   0 DEBUG && TRACE(@_);
142 0         0 return $validkeys[$_[0]->{iter} = 0];
143             }
144              
145             sub NEXTKEY {
146 0     0   0 DEBUG && TRACE(@_);
147 0         0 return $validkeys[++$_[0]->{iter}];
148             }
149              
150             sub EXISTS {
151 0     0   0 DEBUG && TRACE(@_);
152 0         0 return $_[1] =~ $validkey;
153             }
154              
155             sub DESTROY {
156 0     0   0 DEBUG && TRACE(@_);
157             }
158              
159             sub AUTOLOAD {
160 1     1   2 DEBUG && TRACE(@_);
161 1         145 croak "Cannot modify read-only hash";
162             }
163              
164              
165             1;
166              
167             __END__