File Coverage

blib/lib/Inline/Files.pm
Criterion Covered Total %
statement 100 109 91.7
branch 14 20 70.0
condition 5 15 33.3
subroutine 21 26 80.7
pod 0 1 0.0
total 140 171 81.8


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