File Coverage

blib/lib/ExtUtils/PerlPP.pm
Criterion Covered Total %
statement 9 131 6.8
branch 0 74 0.0
condition 0 21 0.0
subroutine 3 9 33.3
pod 1 3 33.3
total 13 238 5.4


line stmt bran cond sub pod time code
1             # -*- perl -*-
2             #
3             #
4             # ExtUtils::PerlPP - A Perl Preprocessor
5             #
6             #
7             # This module is Copyright (C) 1998 by
8             #
9             # Jochen Wiedmann
10             # Am Eisteich 9
11             # 72555 Metzingen
12             # Germany
13             #
14             # Email: joe@ispsoft.de
15             # Phone: +49 7123 14887
16             #
17             # All rights reserved.
18             #
19             # You may distribute this module under the terms of either the GNU
20             # General Public License or the Artistic License, as specified in
21             # the Perl README file.
22             #
23              
24 1     1   1055 use strict;
  1         3  
  1         54  
25 1     1   7 use Exporter;
  1         1  
  1         68  
26              
27              
28             package ExtUtils::PerlPP;
29              
30 1     1   26 use vars qw($VERSION @ISA @EXPORT);
  1         4  
  1         1957  
31              
32             @ISA = qw(Exporter);
33             @EXPORT = qw(ppp);
34             $VERSION = '0.03';
35              
36              
37             sub new {
38 0     0 1   my $proto = shift;
39 0           my $self = { @_ };
40 0   0       bless ($self, (ref($proto) || $proto));
41 0           $self;
42             }
43              
44              
45             sub ppp {
46 0 0   0 0   my($in, $out, $config) = @_ ? @_ : @ARGV;
47 0           my $parser = ExtUtils::PerlPP->new('in_fh' => $in,
48             'out_fh' => $out,
49             'config' => $config);
50 0           $parser->parse();
51             }
52              
53              
54             sub _ParseVar {
55 0     0     my($self, $config, $var, $subvar) = @_;
56 0 0         my($text) = sprintf("%s%s", $var, (defined($subvar) ? $subvar : ""));
57 0           my $result;
58 0 0         if (!exists($config->{$var})) {
59 0 0         if ($self->{'no_config_default'}) {
60 0           return '';
61             }
62 0           $result = $Config::Config{$var};
63             } else {
64 0           $result = $config->{$var};
65             }
66              
67 0   0       while (defined($result) && $subvar && $subvar =~ /^\-\>(\w+)/) {
      0        
68 0           $var = $1;
69 0           $subvar = $';
70 0 0         if ($var =~ /^\d+$/) {
71 0 0         if (ref($result) ne 'ARRAY') {
72 0           return '';
73             }
74 0           $result = $result->[$var];
75             } else {
76 0 0         if (ref($result) ne 'HASH') {
77 0           return '';
78             }
79 0           $result = $result->{$var};
80             }
81             }
82              
83 0 0         if (!defined($result)) {
    0          
84 0           $result = '';
85             } elsif (ref($result) eq 'CODE') {
86 0           $result = &$result($self, $text);
87 0 0         if (!defined($result)) {
88 0           $result = '';
89             }
90             }
91              
92 0           $result;
93             }
94              
95              
96             sub _ParseVars {
97 0     0     my($self, $config, $line) = @_;
98 0           $line =~ s/\~\~(\w+)((\-\>\w+)*)\~\~/$self->_ParseVar($config, $1, $2)/eg;
  0            
99 0           $line;
100             }
101              
102              
103             sub _Condition {
104 0     0     my($self, $lineNum, $config, $line) = @_;
105 0           $line = $self->_ParseVars($config, $line);
106 0           my $result = eval $line;
107 0 0         if ($@) {
108 0           die "Error while evaluating condition at line $lineNum: $@";
109             }
110 0           $result;
111             }
112              
113              
114             sub parse {
115 0     0 0   my $line;
116 0           my $self = shift;
117 0           my $in = $self->{'in_fh'};
118 0           my $out = $self->{'out_fh'};
119 0           my $config = $self->{'config'};
120 0           my $defaultConfig = !$self->{'no_config_default'};
121 0           my $makeDirs = !$self->{'no_makedirs'};
122 0           my @if_stack;
123 0           my $if_state = 1;
124              
125 0 0         if (!ref($in)) {
126 0           require IO::File;
127 0           my $fh = IO::File->new($in, "r");
128 0 0         if (!$fh) {
129 0           die "Error while opening $in: $!";
130             }
131 0           $in = $fh;
132             }
133 0 0         if (!ref($out)) {
134             # Create directories, if desired
135 0 0         if ($makeDirs) {
136 0           require File::Basename;
137 0           my $base = File::Basename::dirname($out);
138 0 0         if (! -d $base) {
139 0           require File::Path;
140 0           File::Path::mkpath([$base], 0, 0755);
141             }
142             }
143              
144 0           require IO::File;
145 0           my $fh = IO::File->new($out, "w");
146 0 0         if (!$fh) {
147 0           die "Error while opening $out: $!";
148             }
149 0           $out = $fh;
150             }
151 0 0         if (!ref($config)) {
152 0           require IO::File;
153 0           my $fh = IO::File->new($config, "r");
154 0 0         if (!$fh) {
155 0           die "Error while opening $config: $!";
156             }
157 0           local($/) = undef;
158 0           my $code = $fh->getline();
159 0 0         if (!defined($code)) {
160 0           die "Error while reading $config: $!";
161             }
162 0           my $result = eval $code;
163 0 0         if ($@) {
164 0           die "Error while evaluating $config: $!";
165             }
166 0           $config = $result;
167             }
168              
169 0 0         if ($defaultConfig) {
170 0           require Config;
171             }
172              
173 0           my $lineNum = 0;
174 0           while (defined($line = $in->getline())) {
175 0           ++$lineNum;
176 0 0         if ($line =~ /^\s*\~\#if\#\~/) {
    0          
    0          
    0          
    0          
    0          
177 0   0       my $new_state = $if_state &&
178             $self->_Condition($lineNum, $config, $');
179 0           unshift(@if_stack, [$new_state, $if_state, $lineNum]);
180 0           $if_state = $new_state;
181             } elsif ($line =~ /^\s*\~\#elsif\#\~/) {
182 0 0         if (!@if_stack) {
183 0           die "~#elsif#~ without ~#if#~ at line $lineNum";
184             }
185 0           my $if_elem = $if_stack[0];
186 0   0       $if_state = $if_elem->[1] && !$if_elem->[0] &&
187             $self->_Condition($lineNum, $config, $');
188 0 0         if ($if_state) {
189 0           $if_elem->[0] = 1;
190             }
191             } elsif ($line =~ /^\s*\~\#else\#\~/) {
192 0 0         if (!@if_stack) {
193 0           die "~#else#~ without ~#if#~ at line $lineNum";
194             }
195 0           my $if_elem = $if_stack[0];
196 0   0       $if_state = $if_elem->[1] && !$if_elem->[0];
197 0 0         if ($if_state) {
198 0           $if_elem->[0] = 1;
199             }
200             } elsif ($line =~ /^\s*\~\#endif\#\~/) {
201 0 0         if (!@if_stack) {
202 0           die "~#endif#~ without ~#if#~ at line $lineNum";
203             }
204 0           my $if_elem = shift @if_stack;
205 0           $if_state = $if_elem->[1];
206             } elsif ($line =~ /^\s*\~\&([a-zA-Z_]\w*)\&\~/) {
207 0           $line = $';
208 0           my $var = $1;
209 0           my $code = '';
210 0           my $oldLineNum = $lineNum;
211              
212 0   0       while (defined($line) && $line !~ /\~\&\&\~/) {
213 0           $code .= $line;
214 0           $line = $in->getline();
215             }
216 0 0         if (!defined($line)) {
217 0           die "~&$var&~ without ~&&~ at line $oldLineNum";
218             }
219 0 0         if ($line =~ /\~\&\&\~/) {
220 0           $code .= $`;
221             }
222 0           $self->{'config'}->{$var} = eval "sub { $code }";
223 0 0         if ($@) {
224 0           die "Error while defining method $var at line $oldLineNum: $@";
225             }
226             } elsif ($if_state) {
227 0 0         if (!$out->print($self->_ParseVars($config, $line))) {
228 0           die "Error while writing: $!";
229             }
230             }
231             }
232             }
233              
234              
235             1;
236              
237             __END__