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 |
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 |
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. With the C parameter this
568
string can be configured.
569
570
=head2 The C parameter to C and C
571
572
Normally C calls C each time to evaluate a piece
573
of Perl code. This can be a performance killer if the same piece is
574
evaluated over and over again.
575
576
One solution could be to wrap the piece of code into a subroutine, have
577
Perl compile that routine only once and use it many times.
578
579
If C is given C does exactly that. A piece of
580
perl code is wrapped as a subroutine, compiled and the resulting code
581
references are saved in the C with the actual perl text as key.
582
583
C does not currently work if the C option is used.
584
585
There are a few pitfalls with that method that have to be looked out by the
586
template programmer. Suppose you have that piece of code in a template:
587
588
my $var = 5;
589
sub function {
590
return $var++;
591
}
592
$OUT.=function() for( 1..3 );
593
594
That piece will producess the string C<567> in
595
C<$OUT> each time it is evaluated. But if it is wrapped into a subroutine
596
it looks like:
597
598
sub {
599
my $var = 5;
600
sub function {
601
return $var++;
602
}
603
$OUT.=function() for( 1..3 );
604
};
605
606
If that anonymous function is called several times it produces C<012>,
607
C<345> and so on. The problem is that named functions (like C)
608
are created at compile time while anonymous functions (like the outer sub)
609
at run time. Hence, the C<$var> my-variable is not available in
610
C. Perl solves thar conflict by creating a separate variable
611
C<$var> at compile time that is initially C. Evaluated in numerical
612
context is gives C<0>.
613
614
So, how can the code fragment be converted so that the function is created
615
at runtime. There are 2 ways. Firstly, you can use function references:
616
617
sub {
618
my $var = 5;
619
my $function = sub {
620
return $var++;
621
};
622
$OUT.=$function->() for( 1..3 );
623
};
624
625
Now both the inner and the outer functions are anomymous and both are created
626
at runtime. But calling C as C<< $function->() >> may not be
627
convenient. So, the second way uses a Cized symbol:
628
629
sub {
630
my $var = 5;
631
local *function = sub {
632
return $var++;
633
};
634
$OUT.=function() for( 1..3 );
635
};
636
637
For more information see L
638
639
=head2 The C<#line> directive in templates
640
641
Correct line numbers are crucial for debugging. If a template is fetched
642
from a larger file and passed to C as string
643
C doesn't know at which line of the larger file the
644
template starts. Hence, it cannot produce correct error messages.
645
646
The solution is to prepend the template string (assuming default
647
delimiters are used) with
648
649
{#line NUMBER}
650
651
where C is the actual line number where the template starts.
652
653
If custom delimiters are used replace the braces by them. Assuming C<[%>
654
and C<%]> as delimiters that directive should look:
655
656
[%#line NUMBER%]
657
658
Note that there must not be any other character between the opening
659
delimiter and the C<#line> and between the C and the closing
660
delimiter not even spaces. Also, there must be only one space between
661
C<#line> and C.
662
663
The C<#line> directive works not only at the beginning of a template.
664
Suppose you have a larger template and have cut out some parts prior
665
to passing it to C as a string. Replace these parts with
666
correct C<#line> directives and your error messages are correct.
667
668
=head1 AUTHOR
669
670
Torsten Foertsch, Etorsten.foertsch@gmx.netE
671
672
Most of this module is borrowed from
673
L by Mark-Jason Dominus, Plover Systems
674
675
=cut
|