File Coverage

blib/lib/Text/Template/Base.pm
Criterion Covered Total %
statement 203 299 67.8
branch 78 140 55.7
condition 16 26 61.5
subroutine 20 31 64.5
pod 2 11 18.1
total 319 507 62.9


line stmt bran cond sub pod time code
1             # -*- perl -*-
2             #
3             # Fill in `templates'
4             #
5             # Copyright 1996, 1997, 1999, 2001, 2002, 2003, 2008 M-J. Dominus.
6             # You may copy and distribute this program under the
7             # same terms as Perl iteself
8             # If in doubt, write to mjd-perl-template+@plover.com for a license.
9             #
10             # This is a slightly enhanced version of M-J. Dominus' Text::Templates 1.45
11             # I have tried to reach M-J. to get my patches into Text::Template
12             # but never got an answer.
13             #
14             # Version 1.45
15              
16             package Text::Template::Base;
17 1     1   5 use Exporter;
  1         2  
  1         66  
18             @ISA = qw(Exporter);
19             @EXPORT_OK = qw(fill_in_file fill_in_string TTerror);
20 1     1   5 use strict;
  1         2  
  1         222  
21              
22             our $VERSION='1.45';
23              
24             our $ERROR;
25              
26             my %GLOBAL_PREPEND = ('Text::Template::Base' => '');
27              
28             sub _param {
29 1124     1124   1165 my $kk;
30 1124         2639 my ($k, %h) = @_;
31 1124         3947 for $kk ($k, "\u$k", "\U$k", "-$k", "-\u$k", "-\U$k") {
32 5730 100       14083 return $h{$kk} if exists $h{$kk};
33             }
34 786         3064 return;
35             }
36              
37             sub always_prepend
38             {
39 0     0 0 0 my $pack = shift;
40 0         0 my $old = $GLOBAL_PREPEND{$pack};
41 0         0 $GLOBAL_PREPEND{$pack} = shift;
42 0         0 $old;
43             }
44              
45             {
46             my %LEGAL_TYPE;
47             BEGIN {
48 1     1   2 %LEGAL_TYPE = map {$_=>1} qw(FILE FILEHANDLE STRING ARRAY);
  4         1660  
49             }
50             sub new {
51 23     23 1 4248 my $pack = shift;
52 23         121 my %a = @_;
53 23   50     89 my $stype = uc(_param('type', %a)) || 'FILE';
54 23         100 my $source = _param('source', %a);
55 23         65 my $untaint = _param('untaint', %a);
56 23         85 my $prepend = _param('prepend', %a);
57 23         69 my $alt_delim = _param('delimiters', %a);
58 23         75 my $broken = _param('broken', %a);
59 23         64 my $filename = _param('filename', %a);
60 23         77 my $evalcache = _param('evalcache', %a);
61 23 50       227 unless (defined $source) {
62 0         0 require Carp;
63 0         0 Carp::croak("Usage: $ {pack}::new(TYPE => ..., SOURCE => ...)");
64             }
65 23 50       67 unless ($LEGAL_TYPE{$stype}) {
66 0         0 require Carp;
67 0         0 Carp::croak("Illegal value `$stype' for TYPE parameter");
68             }
69 23 100       177 my $self = {TYPE => $stype,
70             PREPEND => $prepend,
71             UNTAINT => $untaint,
72             BROKEN => $broken,
73             FILENAME => $filename,
74             EVALCACHE => $evalcache,
75             (defined $alt_delim ? (DELIM => $alt_delim) : ()),
76             };
77             # Under 5.005_03, if any of $stype, $prepend, $untaint, or $broken
78             # are tainted, all the others become tainted too as a result of
79             # sharing the expression with them. We install $source separately
80             # to prevent it from acquiring a spurious taint.
81 23         69 $self->{SOURCE} = $source;
82              
83 23         52 bless $self => $pack;
84 23 50       93 return unless $self->_acquire_data;
85            
86 23         160 $self;
87             }
88             }
89              
90             # Convert template objects of various types to type STRING,
91             # in which the template data is embedded in the object itself.
92             sub _acquire_data {
93 37     37   47 my ($self) = @_;
94 37         74 my $type = $self->{TYPE};
95 37 50       96 if ($type eq 'STRING') {
    0          
    0          
    0          
96             # nothing necessary
97             } elsif ($type eq 'FILE') {
98 0         0 my $data = _load_text($self->{SOURCE});
99 0 0       0 unless (defined $data) {
100             # _load_text already set $ERROR
101 0         0 return undef;
102             }
103 0 0 0     0 if ($self->{UNTAINT} && _is_clean($self->{SOURCE})) {
104 0         0 _unconditionally_untaint($data);
105             }
106 0         0 $self->{TYPE} = 'STRING';
107 0         0 $self->{FILENAME} = $self->{SOURCE};
108 0         0 $self->{SOURCE} = $data;
109             } elsif ($type eq 'ARRAY') {
110 0         0 $self->{TYPE} = 'STRING';
111 0         0 $self->{SOURCE} = join '', @{$self->{SOURCE}};
  0         0  
112             } elsif ($type eq 'FILEHANDLE') {
113 0         0 $self->{TYPE} = 'STRING';
114 0         0 local $/;
115 0         0 my $fh = $self->{SOURCE};
116 0         0 my $data = <$fh>; # Extra assignment avoids bug in Solaris perl5.00[45].
117 0 0       0 if ($self->{UNTAINT}) {
118 0         0 _unconditionally_untaint($data);
119             }
120 0         0 $self->{SOURCE} = $data;
121             } else {
122             # This should have been caught long ago, so it represents a
123             # drastic `can't-happen' sort of failure
124 0         0 my $pack = ref $self;
125 0         0 die "Can only acquire data for $pack objects of subtype STRING, but this is $type; aborting";
126             }
127 37         280 $self->{DATA_ACQUIRED} = 1;
128             }
129              
130             sub source {
131 0     0 0 0 my ($self) = @_;
132 0 0       0 $self->_acquire_data unless $self->{DATA_ACQUIRED};
133 0         0 return $self->{SOURCE};
134             }
135              
136             sub set_source_data {
137 0     0 0 0 my ($self, $newdata) = @_;
138 0         0 $self->{SOURCE} = $newdata;
139 0         0 $self->{DATA_ACQUIRED} = 1;
140 0         0 $self->{TYPE} = 'STRING';
141 0         0 1;
142             }
143              
144             sub compile {
145 23     23 0 41 my $self = shift;
146              
147 23 50       68 return 1 if $self->{TYPE} eq 'PREPARSED';
148              
149 23 50       52 return undef unless $self->_acquire_data;
150 23 50       64 unless ($self->{TYPE} eq 'STRING') {
151 0         0 my $pack = ref $self;
152             # This should have been caught long ago, so it represents a
153             # drastic `can't-happen' sort of failure
154 0         0 die "Can only compile $pack objects of subtype STRING, but this is $self->{TYPE}; aborting";
155             }
156              
157 23         30 my @tokens;
158 23   66     106 my $delim_pats = shift() || $self->{DELIM};
159              
160            
161              
162 23         40 my ($t_open, $t_close) = ('{', '}');
163 23         34 my ($t_open_nl, $t_close_nl) = (0, 0); # number of newlines per delimiter
164 23         27 my $DELIM; # Regex matches a delimiter if $delim_pats
165 23 100       48 if (defined $delim_pats) {
166 20         47 ($t_open, $t_close) = @$delim_pats;
167 20         59 $DELIM = "(?:(?:\Q$t_open\E)|(?:\Q$t_close\E))";
168 20         39 ($t_open_nl, $t_close_nl) = map {tr/\n//} $t_open, $t_close;
  40         84  
169 20         710 @tokens = split /($DELIM|\n)/, $self->{SOURCE};
170             } else {
171 3         107 @tokens = split /(\\\\(?=\\*[{}])|\\[{}]|[{}\n])/, $self->{SOURCE};
172             }
173 23         56 my $state = 'TEXT';
174 23         38 my $depth = 0;
175 23         26 my $lineno = 1;
176 23         24 my @content;
177 23         36 my $cur_item = '';
178 23         30 my $prog_start;
179 23         52 while (@tokens) {
180 442         591 my $t = shift @tokens;
181 442 100       1672 next if $t eq '';
182 359 100 66     1529 if ($t eq $t_open) { # Brace or other opening delimiter
    100 66        
    50          
    50          
    100          
183 57 100       98 if ($depth == 0) {
184 56 100       186 push @content, [$state, $cur_item, $lineno] if $cur_item ne '';
185 56         87 $lineno += $t_open_nl;
186 56         60 $cur_item = '';
187 56         80 $state = 'PROG';
188 56         66 $prog_start = $lineno;
189             } else {
190 1         2 $lineno += $t_open_nl;
191 1         3 $cur_item .= $t;
192             }
193 57         124 $depth++;
194             } elsif ($t eq $t_close) { # Brace or other closing delimiter
195 57         53 $depth--;
196 57 50       131 if ($depth < 0) {
    100          
197 0         0 $ERROR = "Unmatched close brace at line $lineno";
198 0         0 return undef;
199             } elsif ($depth == 0) {
200 56         68 $lineno += $t_close_nl;
201 56 100       205 if ($cur_item =~ /^#line (\d+)$/) {
    50          
202 28         64 $lineno = $1;
203             } elsif ($cur_item ne '') {
204 28         77 push @content, [$state, $cur_item, $prog_start];
205             }
206 56         73 $state = 'TEXT';
207 56         126 $cur_item = '';
208             } else {
209 1         4 $cur_item .= $t;
210             }
211             } elsif (!$delim_pats && $t eq '\\\\') { # precedes \\\..\\\{ or \\\..\\\}
212 0         0 $cur_item .= '\\';
213             } elsif (!$delim_pats && $t =~ /^\\([{}])$/) { # Escaped (literal) brace?
214 0         0 $cur_item .= $1;
215             } elsif ($t eq "\n") { # Newline
216 104         106 $lineno++;
217 104         239 $cur_item .= $t;
218             } else { # Anything else
219 141         361 $cur_item .= $t;
220             }
221             }
222              
223 23 50       65 if ($state eq 'PROG') {
    50          
224 0         0 $ERROR = "End of data inside program text that began at line $prog_start";
225 0         0 return undef;
226             } elsif ($state eq 'TEXT') {
227 23 50       114 push @content, [$state, $cur_item, $lineno] if $cur_item ne '';
228             } else {
229 0         0 die "Can't happen error #1";
230             }
231            
232 23         54 $self->{TYPE} = 'PREPARSED';
233 23         45 $self->{SOURCE} = \@content;
234 23         123 1;
235             }
236              
237             sub prepend_text {
238 90     90 0 8909 my ($self) = @_;
239 90         144 my $t = $self->{PREPEND};
240 90 50       185 unless (defined $t) {
241 90         151 $t = $GLOBAL_PREPEND{ref $self};
242 90 100       193 unless (defined $t) {
243 13         26 $t = $GLOBAL_PREPEND{'Text::Template::Base'};
244             }
245             }
246 90 50       206 $self->{PREPEND} = $_[1] if $#_ >= 1;
247 90         225 return $t;
248             }
249              
250             sub fill_in {
251 90     90 1 120 my $fi_self = shift;
252 90         280 my %fi_a = @_;
253              
254 90 50       244 unless ($fi_self->{TYPE} eq 'PREPARSED') {
255 0         0 my $delims = _param('delimiters', %fi_a);
256 0 0       0 my @delim_arg = (defined $delims ? ($delims) : ());
257 0 0       0 $fi_self->compile(@delim_arg)
258             or return undef;
259             }
260              
261 90         232 my $fi_varhash = _param('hash', %fi_a);
262 90         241 my $fi_package = _param('package', %fi_a) ;
263 90   50     229 my $fi_broken =
264             _param('broken', %fi_a) || $fi_self->{BROKEN} || \&_default_broken;
265 90   50     261 my $fi_broken_arg = _param('broken_arg', %fi_a) || [];
266 90         267 my $fi_safe = _param('safe', %fi_a);
267 90         235 my $fi_ofh = _param('output', %fi_a);
268 90         125 my $fi_eval_package;
269 90         113 my $fi_scrub_package = 0;
270 90   100     188 my $fi_filename = _param('filename', %fi_a) || $fi_self->{FILENAME} || 'template';
271 90   100     253 my $fi_evalcache = _param('evalcache', %fi_a) || $fi_self->{EVALCACHE};
272              
273 90         235 my $fi_prepend = _param('prepend', %fi_a);
274 90 50       211 unless (defined $fi_prepend) {
275 90         221 $fi_prepend = $fi_self->prepend_text;
276             }
277              
278 90 50       232 if (defined $fi_safe) {
    100          
    50          
279 0         0 $fi_eval_package = 'main';
280             } elsif (defined $fi_package) {
281 89         110 $fi_eval_package = $fi_package;
282             } elsif (defined $fi_varhash) {
283 1         6 $fi_eval_package = _gensym();
284 1         4 $fi_scrub_package = 1;
285             } else {
286 0         0 $fi_eval_package = caller;
287             }
288              
289 90         90 my $fi_install_package;
290 90 100       163 if (defined $fi_varhash) {
291 8 100       328 if (defined $fi_package) {
    50          
292 7         10 $fi_install_package = $fi_package;
293             } elsif (defined $fi_safe) {
294 0         0 $fi_install_package = $fi_safe->root;
295             } else {
296 1         3 $fi_install_package = $fi_eval_package; # The gensymmed one
297             }
298 8         25 _install_hash($fi_varhash => $fi_install_package);
299             }
300              
301 90 50 66     339 if (defined $fi_package && defined $fi_safe) {
302 1     1   6 no strict 'refs';
  1         1  
  1         286  
303             # Big fat magic here: Fix it so that the user-specified package
304             # is the default one available in the safe compartment.
305 0         0 *{$fi_safe->root . '::'} = \%{$fi_package . '::'}; # LOD
  0         0  
  0         0  
306             }
307              
308 90         111 my $fi_r = '';
309 90         75 my $fi_ofn;
310 90 100       148 if(defined $fi_ofh) {
311 5 50       12 if(ref $fi_ofh eq 'CODE') {
312 5     16   19 $fi_ofn = sub {&$fi_ofh; return};
  16         30  
  16         73  
313             } else {
314 0     0   0 $fi_ofn = sub {print $fi_ofh $_[0]; return};
  0         0  
  0         0  
315             }
316             } else {
317 85     366   337 $fi_ofn = sub {$fi_r .= $_[0]; return};
  366         691  
  366         897  
318             }
319 90         112 my $fi_item;
320 90         99 foreach $fi_item (@{$fi_self->{SOURCE}}) {
  90         270  
321 290         521 my ($fi_type, $fi_text, $fi_lineno) = @$fi_item;
322 290 100       624 if ($fi_type eq 'TEXT') {
    50          
323 195         363 &$fi_ofn($fi_text);
324             } elsif ($fi_type eq 'PROG') {
325 1     1   5 no strict;
  1         2  
  1         166  
326 95         193 my $fi_lcomment = "#line $fi_lineno $fi_filename";
327 95         233 my $fi_progtext =
328             "package $fi_eval_package; $fi_prepend;\n$fi_lcomment\n$fi_text;";
329 95         108 my $fi_res;
330 95         108 my $fi_eval_err = '';
331 95 50       152 if ($fi_safe) {
332 0         0 $fi_safe->reval(q{undef $OUT});
333 0         0 $fi_res = $fi_safe->reval($fi_progtext);
334 0         0 $fi_eval_err = $@;
335 0         0 my $OUT = $fi_safe->reval('$OUT');
336 0 0       0 $fi_res = $OUT if defined $OUT;
337             } else {
338 1     1   5 no warnings 'redefine';
  1         1  
  1         757  
339 95         110 local *{$fi_eval_package.'::OUT'}=$fi_ofn;
  95         307  
340 95 100       202 if( ref $fi_evalcache eq 'HASH' ) {
341 69         146 my $fn = $fi_evalcache->{$fi_progtext};
342 69 100       145 unless(defined $fn) {
343 25         4510 $fn = $fi_evalcache->{$fi_progtext} =
344             eval "sub {my \$OUT;my \$x=do{\n$fi_progtext\n};".
345             "defined \$OUT ? \$OUT : \$x}";
346             }
347 69 50       560 $fi_res = eval {&$fn} if $fn;
  69         2494  
348             } else {
349 26         27 my $OUT;
350 26         1788 $fi_res = eval $fi_progtext;
351 26 50       164 $fi_res = $OUT if defined $OUT;
352             }
353 95         657 $fi_eval_err = $@;
354             }
355              
356             # If the value of the filled-in text really was undef,
357             # change it to an explicit empty string to avoid undefined
358             # value warnings later.
359 95 100       213 $fi_res = '' unless defined $fi_res;
360              
361 95 100       153 if ($fi_eval_err) {
362 14         33 $fi_res = $fi_broken->(text => $fi_text,
363             error => $fi_eval_err,
364             lineno => $fi_lineno,
365             arg => $fi_broken_arg,
366             );
367 14 50       30 if (defined $fi_res) {
368 14         23 &$fi_ofn($fi_res);
369             } else {
370 0         0 return $fi_res; # Undefined means abort processing
371             }
372             } else {
373 81         136 &$fi_ofn($fi_res);
374             }
375             } else {
376 0         0 die "Can't happen error #2";
377             }
378             }
379              
380 90 100       214 _scrubpkg($fi_eval_package) if $fi_scrub_package;
381 90 100       5745 defined $fi_ofh ? 1 : $fi_r;
382             }
383              
384             sub fill_this_in {
385 0     0 0 0 my $pack = shift;
386 0         0 my $text = shift;
387 0 0       0 my $templ = $pack->new(TYPE => 'STRING', SOURCE => $text, @_)
388             or return undef;
389 0 0       0 $templ->compile or return undef;
390 0         0 my $result = $templ->fill_in(@_);
391 0         0 $result;
392             }
393              
394             sub fill_in_string {
395 0     0 0 0 my $string = shift;
396 0         0 my $package = _param('package', @_);
397 0 0       0 push @_, 'package' => scalar(caller) unless defined $package;
398 0         0 Text::Template::Base->fill_this_in($string, @_);
399             }
400              
401             sub fill_in_file {
402 0     0 0 0 my $fn = shift;
403 0 0       0 my $templ = Text::Template::Base->new(TYPE => 'FILE', SOURCE => $fn, @_)
404             or return undef;
405 0 0       0 $templ->compile or return undef;
406 0         0 my $text = $templ->fill_in(@_);
407 0         0 $text;
408             }
409              
410             sub _default_broken {
411 14     14   66 my %a = @_;
412 14         23 my $prog_text = $a{text};
413 14         21 my $err = $a{error};
414 14         22 my $lineno = $a{lineno};
415 14         20 chomp $err;
416             # $err =~ s/\s+at .*//s;
417 14         60 "Program fragment delivered error ``$err''";
418             }
419              
420             sub _load_text {
421 0     0   0 my $fn = shift;
422 0         0 local *F;
423 0 0       0 unless (open F, $fn) {
424 0         0 $ERROR = "Couldn't open file $fn: $!";
425 0         0 return undef;
426             }
427 0         0 local $/;
428 0         0 ;
429             }
430              
431             sub _is_clean {
432 0     0   0 my $z;
433 0         0 eval { ($z = join('', @_)), eval '#' . substr($z,0,0); 1 } # LOD
  0         0  
  0         0  
434             }
435              
436             sub _unconditionally_untaint {
437 0     0   0 local $_;
438 0         0 for (@_) {
439 0         0 ($_) = /(.*)/s;
440             }
441             }
442              
443             {
444             my $seqno = 0;
445             sub _gensym {
446 1     1   5 __PACKAGE__ . '::GEN' . $seqno++;
447             }
448             sub _scrubpkg {
449 1     1   2 my $s = shift;
450 1         7 $s =~ s/^Text::Template::Base:://;
451 1     1   6 no strict 'refs';
  1         1  
  1         146  
452 1         5 my $hash = $Text::Template::Base::{$s."::"};
453 1         4 foreach my $key (keys %$hash) {
454 2         8 undef $hash->{$key};
455             }
456             }
457             }
458              
459             # Given a hashful of variables (or a list of such hashes)
460             # install the variables into the specified package,
461             # overwriting whatever variables were there before.
462             sub _install_hash {
463 8     8   14 my $hashlist = shift;
464 8         13 my $dest = shift;
465 8 50       30 if (UNIVERSAL::isa($hashlist, 'HASH')) {
466 8         19 $hashlist = [$hashlist];
467             }
468 8         14 my $hash;
469 8         17 foreach $hash (@$hashlist) {
470 8         13 my $name;
471 8         27 foreach $name (keys %$hash) {
472 9         19 my $val = $hash->{$name};
473 1     1   6 no strict 'refs';
  1         2  
  1         216  
474 9         12 local *SYM = *{"$ {dest}::$name"};
  9         61  
475 9 50       35 if (! defined $val) {
    100          
476 0         0 delete ${"$ {dest}::"}{$name};
  0         0  
477             } elsif (ref $val) {
478 5         38 *SYM = $val;
479             } else {
480 4         31 *SYM = \$val;
481             }
482             }
483             }
484             }
485              
486 0     0 0   sub TTerror { $ERROR }
487              
488             1;
489              
490              
491             =head1 NAME
492              
493             Text::Template::Base - Expand template text with embedded Perl
494              
495             =head1 SYNOPSIS
496              
497             use Text::Template::Base;
498              
499             =head1 DESCRIPTION
500              
501             This module is an enhanced version of M-J. Dominus' L
502             version 1.45.
503              
504             I have tried to contact M-J. to get my patches (included in this distribution
505             in the C directory) into L but
506             never got an answer.
507              
508             For usage information see L.
509              
510             =head1 DIFFERENCES COMPARED TO Text::Template 1.45
511              
512             =head2 The C function (to be used within templates)
513              
514             The C function serves a similar purpose as C<$OUT>. It is
515             automatically installed in the package the template is evaluated in.
516             Hence a template can look like this:
517              
518             Here is a list of the things I have got for you since 1907:
519             { foreach $i (@items) {
520             OUT " * $i\n";
521             }
522             }
523              
524             The advantage of the function over C<$OUT> is that it wastes less memory.
525             Suppose you have a very long list of items. Using C<$OUT> it is first
526             accumulated in that variable and then appended to the resulting string.
527             That means it uses twice the memory (for a short time). With the C
528             function each piece of generated text is immediately appended to the
529             resulting string.
530              
531             But the main advantage lies in using the C function in combination
532             with the C option to C. Now a piece of output is directly
533             put out and nothing at all accumulated.
534              
535             There is also a drawback. C<$OUT> is an ordinary variable and can be used
536             as such. This template cannot be easily converted to using C:
537              
538             Here is a list of the things I have got for you since 1907:
539             { foreach $i (@items) {
540             $OUT .= " * $i\n";
541             if( some_error ) {
542             # forget the output so far
543             $OUT = "An error has occurred";
544             last;
545             }
546             }
547             }
548              
549             NOTE, the C function doesn't work with the L> option.
550              
551             =head2 The C parameter to C and C
552              
553             C allows for a file handle to be passed as C
554             parameter. Each chunk of output will be written directly to this handle.
555              
556             With this module a subroutine can be passed instead of the file handle.
557             Each chunk of output will be passed to this function as the only
558             parameter.
559              
560             $template->fill_in(OUTPUT => sub { print $_[0] }, ...);
561              
562             =head2 The C parameter to C and C
563              
564             When C generates error messages it tries to include
565             the file name and line number where the error has happened. But for some
566             template types the file name is not known. In such cases C
567             simply uses the string C