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.69';
3 8     8   75876 use strict;
  8         18  
  8         326  
4              
5 8     8   3053 use Inline::Files::Virtual;
  8         18  
  8         58  
6 8     8   5337 use Filter::Util::Call;
  8         6983  
  8         530  
7 8     8   74 use Cwd qw(abs_path);
  8         14  
  8         342  
8 8     8   67 use Carp;
  8         12  
  8         3631  
9              
10             my $SOVFM_pat = qr/^__[A-Z](?:_*[A-Z0-9]+)*__\n/m;
11             my %files;
12              
13             sub import {
14 8     8   58 DEBUG && TRACE(@_);
15 8         141 $DB::single = 1;
16 8         22 my ($class, @args) = @_;
17 8         23 my ($package, $file, $line) = caller;
18              
19 8         15 my $path = './';
20 8         21 $file =~ s|\\|/|g;
21 8 50       118 ($path, $file) = ($1, $2) if $file =~ m|^(.*)/(.*)$|;
22 8         254 $file = abs_path($path) . "/$file";
23 8         24 $files{$package} = $file;
24              
25 8         32 while (@args) {
26 1         2 my $next = shift @args;
27 1 50       5 if ($next eq '-backup') {
28 1   33     8 my $backup = shift(@args)||"$file.bak";
29 1         3 local (*IN, *OUT);
30 1 50 33     283 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         12 my (%symbols, $source);
39 8         56 foreach my $vfile (vf_load($file, $SOVFM_pat)) {
40 12         32 my $symbol = vf_marker($vfile);
41 12         74 $symbol =~ s/^__|__\n//g;
42 12         16 push @{$symbols{$symbol}}, $vfile;
  12         38  
43             }
44              
45 8         29 foreach my $symbol (keys %symbols) {
46 8     8   47 no strict 'refs';
  8         12  
  8         767  
47 8         18 my $fq_symbol = "${package}::${symbol}";
48 8         10 @$fq_symbol = @{$symbols{$symbol}};
  8         46  
49 8         20 $$fq_symbol = $symbols{$symbol}[0];
50 8         238 my $impl = tie *$fq_symbol, $class, $fq_symbol, -w $file;
51 8         44 tie %$fq_symbol, $class."::Data", $impl;
52             }
53              
54 8         18 foreach (qw( open close seek tell truncate write )) {
55 8     8   43 no strict 'refs';
  8         13  
  8         2213  
56 48         47 *{"CORE::GLOBAL::$_"} = \&{"vf_$_"};
  48         196  
  48         88  
57             }
58              
59 8         37 ($source = vf_prefix($file)) =~ s/(.*\n){$line}//;
60             filter_add( sub {
61 16 100   16   12365 return 0 unless $source;
62 8         14 $_ = $source;
63 8         13 $source = "";
64 8         1892 return 1;
65 8         73 } );
66             }
67              
68             sub TIEHANDLE {
69 12     12   15 DEBUG && TRACE(@_);
70 12         24 my ($class, $symbol, $writable) = @_;
71 12         77 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   15 DEBUG && TRACE(@_);
80             }
81              
82             sub AUTOLOAD {
83 6     6   431 DEBUG && TRACE(@_) &&
84             print "AUTOLOAD => $Inline::Files::AUTOLOAD\n";
85 8     8   48 no strict;
  8         14  
  8         1698  
86 6         22 local $^W;
87 6         10 my $impl = shift;
88 6         21 my $symbol = $impl->{symbol};
89 6         26 untie *$symbol;
90 6         18 $$symbol = shift @$symbol;
91 6 100       20 return unless $$symbol;
92 5 100       15 my $open_mode = $impl->{writable} ? "+<" : "<";
93 5 50       27 vf_open $symbol, "$open_mode$$symbol", $symbol or return;
94 5 50       28 croak "Internal error" unless tied *$symbol;
95 5         30 $AUTOLOAD =~ s/.*:://;
96 5         9 local $Carp::CarpLevel = 1;
97 5         37 return tied(*$symbol)->$AUTOLOAD(@_);
98             }
99              
100             sub get_filename {
101 2     2 0 2 DEBUG && TRACE(@_);
102 2 50       9 $files{$_[0]} || "";
103             }
104              
105             package Inline::Files::Data;
106 8     8   43 use Carp;
  8         15  
  8         599  
107             BEGIN {
108 8     8   26 *DEBUG = \&Inline::Files::DEBUG;
109 8         293 *TRACE = \&Inline::Files::TRACE;
110             }
111              
112             sub access {
113 6     6   8 DEBUG && TRACE(@_);
114 8     8   47 no strict 'refs';
  8         12  
  8         3287  
115 6         6 tied(*{$_[0]->{impl}{symbol}});
  6         73  
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         14 my ($class, $impl) = @_;
130 8         42 bless { impl=>$impl, iter=>0 }, $class;
131             }
132              
133             sub FETCH {
134 10     10   868 DEBUG && TRACE(@_);
135 10         16 my ($self, $key) = @_;
136 10 100       96 return undef unless $key =~ $validkey;
137 8         26 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   1 DEBUG && TRACE(@_);
161 1         238 croak "Cannot modify read-only hash";
162             }
163              
164              
165             1;
166              
167             __END__