File Coverage

blib/lib/Text/BasicTemplate.pm
Criterion Covered Total %
statement 523 669 78.1
branch 343 554 61.9
condition 142 275 51.6
subroutine 33 44 75.0
pod 34 36 94.4
total 1075 1578 68.1


line stmt bran cond sub pod time code
1             #!/usr/bin/perl -w
2             # $Id: BasicTemplate.pm,v 1.31 2000/02/22 01:55:52 aqua Exp $
3              
4             package Text::BasicTemplate;
5              
6 7     7   8135 use strict;
  7         14  
  7         597  
7 7     7   36 use re 'taint';
  7         12  
  7         461  
8             require 5;
9              
10             require Exporter;
11             require AutoLoader;
12              
13 7     7   195 use vars qw($VERSION);
  7         22  
  7         492  
14             $VERSION = "2.006.1";
15              
16 7     7   36 use Fcntl qw(:DEFAULT :flock);
  7         10  
  7         71605  
17              
18             =head1 NAME
19              
20             Text::BasicTemplate -- Simple lexical text/html/etc template parser
21              
22             =cut
23              
24             =head1 SYNOPSIS
25              
26             use Text::BasicTemplate;
27             $bt = Text::BasicTemplate->new;
28             my %dict = (
29             name => 'John',
30             location => sub { hostname() },
31             condiments => [ 'Salt', 'Pepper', 'Catsup' ],
32             sideeffects => { 'Salt' => 'causes high blood pressure',
33             'Pepper' => 'causes mariachi music',
34             'Catsup' => 'brings on warner bros. cartoons' },
35             new => int rand 2
36             );
37              
38             $tmpl = "Hello, %name%; your mail is in %$MAIL%. Welcome to %location%!";
39             print $bt->parse(\$tmpl,\%dict);
40              
41             $tmpl = "%if new%First time, %name%?%fi%".
42             " Care for some %condiments%? ".
43             " They are bad for you. %sideeffects%."
44             $bt->{hash_specifier}->{condiments} = ' ';
45             print $bt->parse(\$tmpl,\%dict);
46              
47             =head1 DESCRIPTION
48              
49             B is a relatively straightforward template
50             parsing module. Its overall function is to permit the separation
51             of format-dependent output from code.
52              
53             This module provides standard key/value substitutions, lexical
54             evaluation/parsing, customizable formatting of perl datatypes,
55             and assorted utility functions.
56              
57             Templates may be structured by the use of arbitrarily nestable
58             if-conditions (including elsif and else), and by the use of
59             subroutine substitutions to provide list parsing. In general,
60             the syntax for conditionals is that of perl itself.
61              
62             Text::BasicTemplate attempts to be as fast and as secure as
63             possible. It may be safely used upon tainted templates and
64             with tainted substitutions without fear of execution of any
65             malicious code.
66              
67             =head1 GETTING STARTED
68              
69             If you have previously used Text::BasicTemplate v0.x, it is
70             important to read the COMPATIBILITY section -- many things
71             have changed, and compatibility is not guaranteed to be
72             preserved in future versions.
73              
74             In general, start with the SYNTAX section, and be sure to
75             at least skim the new() section (for configuration settings)
76             and parse() section (for an explanation of the dictionary).
77              
78             =head1 SYNTAX
79              
80             One of the difficulties in employing a new template parser is
81             picking up the apropriate syntax. Text::BasicTemplate does
82             not spare you that, but it does adhere fairly closely to
83             the syntax of perl itself with respect to operators,
84             conditional operations, template subroutine calls, etc.
85              
86             Anything to which Text::BasicTemplate should pay attention in
87             a template is enclosed in percentage signs (%) -- any such
88             segments will be interpreted as identifiers, operations,
89             conditionals, or apropriate combinations thereof.
90              
91             The simplest of these are variable substitutions; if parse()
92             was passed a dictionary containing the pair (foo => "bar"), any instances
93             of %foo% in the template will be evaluated as "bar." Other
94             variable substitutions are available for lists and hashes,
95             passed by reference in the parse() dictionary, as in
96             (bar => \@r, snaf => \%h). In such a case %bar% will be
97             evaluated to the contents of @r, and %snaf% to the contents
98             of %h. Both will be formatted according to the configured
99             delimiters (see B). Subroutine
100             references may also be included in the dictionary; in their
101             simple form, given ( subref => \&myfunction ), %subref% in
102             the template will be evaluated to whatever is returned from
103             &myfunction(). For more detail and features in subroutine
104             handling, see B.
105              
106             In v0.9.7, BasicTemplate introduced simple conditional
107             evaluation, providing one-level equality/inequality
108             comparisons. In 2.0, after a total rewrite, the conditional
109             evaluation was replaced with a lexically parsed scoping
110             evaluation, providing arbitrarily deep nesting, most major
111             unary and binary perl comparison operators, arbitrary
112             combination of operations, nonconditional evaluation, etc.
113             For the full explanation, read on:
114              
115             =head2 SCOPING
116              
117             Scoped evaluation is available to arbitrary depths, following
118             the usual if/elsif/else pattern. B conditions are terminated
119             by a B. By example:
120              
121             # single if
122             %if %
123            
124             %fi%
125              
126             # if-else
127             %if %
128            
129             %else%
130            
131             %fi%
132              
133             # if-elsif
134             %if %
135            
136             %elsif %
137            
138             %fi%
139              
140             # if-else-elsif
141             %if %
142            
143             %elsif %
144            
145             %else%
146            
147             %fi%
148              
149             A B above is some amount of further template contents, including
150             none (%if %%fi% is perfectly valid, albeit not generally
151             useful). A block may contain further conditions. Dictionary variables
152             used in a conditional will only be evaluated if they come into scope --
153             for example, an elsif will not be evaluated unless its preceeding if or
154             elsif evaluted false -- the principal consequence of this is that
155             subroutines referenced in a conditional will be called only if they
156             come into scope per the above.
157              
158             =head2 IDENTIFIERS
159              
160             Numeric literals may be given without alteration, e.g. %123%.
161              
162             String literals should be given in double quotes, e.g. %"hello"%,
163             or in single quotes, e.g. %'goodbye'%. Either sort may contain
164             quotes of the other sort.
165              
166             Scalar, list and hash variables should be given by name,
167             e.g. %foo%.
168              
169             %% gives a literal % sign and is considered normal text.
170              
171             Environment variables may be used as %$PATH%.
172              
173             Subroutine references should generally be referenced as %&foo%,
174             or %&foo(arg1,arg2,...)% as apropriate. %foo% may be used for
175             subroutines that return a scalar and will not require further
176             parsing of their output -- see B.
177              
178              
179             =head2 EVALUATION
180              
181             Statements, conditional or otherwise, may be used outside of if/else
182             contexts, and will have the results of the evaluation inserted at
183             the point in which they occurred in the template. If used in an
184             if/else statement, they will be evaluated, but the apropriate block
185             will be output instead (pretty much the usual, IOW).
186              
187             I
188             %1 || 2% will evaluate both 1 and 2 (and return 2). Evaluation order
189             is not guaranteed. For all matters requiring precedence, parentheses
190             should be employed (e.g. %1 && (0 || 3)%).
191              
192             Most of the perl unary and binary operators are supported; the trinary
193             conditional is not. Operators presently provided are as follows:
194              
195             B -- identical to their perl equivalents. Return
196             1 or false.
197              
198             B<=~ !~> -- also equivalent to the perl versions, but must be enabled
199             by setting B true (see new()), as a malformed
200             pattern may kill the script -- so do not use them if you think you might
201             be evaluating untrusted untrusted templates. The form for these is
202             =~ pattern, not =~ /pattern/.
203              
204             B<== != E E= E E= E=E> -- perl equivalent
205              
206             B<&& and || or> -- the two ands and the two ors are considered
207             equivalent, as there is no operator precedence in BasicTemplate.
208             && and and return the value of the last operand.
209              
210             B<. x> -- perl equivalent; operand for x must be numeric.
211              
212             B<+ - * / **> -- perl equivalent, divide-by-zero will be checked.
213              
214             B
-- equivalent to int(x/y) and x % y respectively.
215              
216             B<^ & | EE EE> -- perl equivalent
217              
218             B -- perl equivalent.
219              
220             Examples:
221             %foo + bar% -- evaluates to result of foo+bar, where foo and bar
222             are variables given in the dictionary.
223              
224             %if foo && (bar || snaf)%
225            
226             %fi% -- evaluates foo, bar and snaf, outputs the block if the
227             foo and one or more of bar and snaf were true.
228              
229             %"your name: " . &yourname% -- outputs the string "your name: ",
230             followed by whatever was returned by the subroutine referenced
231             by the dictionary entry for yourname.
232              
233             %if $MAIL =~ Maildir%
234             Bernstein would be proud.
235             %else%
236             Eric Allman wants you for a sunbeam.
237             %fi% -- evaluates according to whether the environment variable
238             $MAIL contains the pattern 'Maildir.'
239              
240             Note that blocks inside conditional statements begin immediately
241             following the closing %, so in the above examples, the newline
242             and spaces would be considered part of the block and output if
243             the condition evaluated true. This is acceptable for most
244             whitespace-independent usages, but you should not include whitespace
245             in a conditional block if you do not want it in the output.
246              
247             =head2 LIST/HASH FORMATTING
248              
249             List references will be parsed and delimited according to
250             $obj->{list_delimiter}->{listname} if supplied, and
251             $obj->{list_delimiter}->{__default} if not (the latter is
252             set with the default_list_delimiter argument to new()). The default
253             is ", ".
254              
255             Hash references will be delimited using $obj->{hash_delimiter}->{hashname}
256             between pairs, and $obj->{hash_specifier}->{hashname} between key and
257             value. As above, __default will be used if a delimiter has not
258             been specified for the specific variable. The defaults are ", " and
259             "=" respectively.
260              
261             Example:
262              
263             $bt = Text::BasicTemplate->new(default_list_delimiter => ' and');
264              
265             $ss = "path: %path%" . "\n" . "env: %env%";
266             $bt->{hash_specifier}->{env} = " is ";
267             $bt->{hash_delimiter}->{env} = ", ";
268             print $bt->parse(\$ss, { path => [ split(/:/,$ENV{PATH}) ],
269             env => \%ENV });
270              
271             Output from the above would be of the form:
272              
273             /bin and /usr/bin and /usr/local/bin
274             SHELL is bash, VISUAL is emacs, RSYNC_RSH is ssh
275              
276             =head2 SUBROUTINE SUBSTITUTIONS
277              
278             Subroutine references are something of a special-case in Text::BasicTemplate.
279             In a simple form, they can be used thusly:
280              
281             sub heart_of_oak {
282             return "me lads, 'tis to glory we steer";
283             }
284             $bt = Text::BasicTemplate->new();
285             $ss = "come cheer up %&rest_of_verse%";
286             %ov = ( rest_of_verse => \&heart_of_oak );
287             print $bt->parse(\$ss,\%ov);
288              
289             This would output "come cheer up me lads, 'tis to glory we steer," by calling
290             &heart_of_oak() and inserting its return value into the template.
291              
292             You can pass literals and variables defined in the template to a subroutine, as follows:
293              
294             sub heart_of_oak {
295             my @lines = ( "come cheer up me lads",
296             "'tis to glory we steer",
297             "to find something new in this wonderful year" );
298             my $which = shift;
299             my $loud = shift || 0;
300             return $loud ? uc $lines[$which] : $lines[$which];
301             }
302             $bt = Text::BasicTemplate->new();
303             $ss = "song: %&song(1,$loud)%, %&song(2,$loud)%, %&song(3,$loud)%";
304             print $bt->parse(\$ss, { song => \&heart_of_oak, loud => 1 });
305              
306             This would produce the lines of the song, separated by ", "; as
307             written above (with loud == 1 in the dictionary), it will be
308             shouted (inserted in capitals, as per the call to uc()) -- in
309             the template, the use of $variable in a subroutine call indicates
310             that $variable should be gotten from the dictionary rather than
311             interpreted literally. Use of $ is not the normal BasicTemplate
312             syntax -- %variable% would be more proper, but introduces a nasty
313             parsing mess until the re engine gains balancing abilities
314             (scheduled for perl5.6 as of this writing).
315              
316             The argument $_bt_dict has special meaning, and will be replaced
317             with the hashref being used as the active substitution dictionary,
318             thus giving your routines access to it -- it will be passed in
319             the form of a hashref, which you are free to alter during the call,
320             so long as you keep the effects of your caching options in mind.
321              
322             The available formatting of arguments passed to these subroutines
323             is any combination of:
324              
325             word, word,
326             word => word, word
327             word => "word \"word\" 'word'"
328             word => 'word "word"'
329             word => "word\nword",
330              
331             # as in:
332             %&mysubroutine(foo,bar,snaf => 3,str => "foo bar", word => 'k"ib"o', flap => "\"ing\"")%
333              
334             In the first case, each word argument may contain anything but [,=>]
335             (that is, a comma, an = or a >; yes, that is not entirely proper).
336             If you need to use any of those characters, put the arguments in
337             quotes. Parsing with quotations is more accurate, but depends on
338             lookbehind assertions and is accordingly slow (the parse
339             results are cached, so this is mostly an issue in repetitive
340             executions rather than use of many instances in one template).
341              
342             When performing database queries, which may return in increments and
343             have separate beginning and ending operations, you can use three code
344             references in a single list reference, for beginning, middle and end.
345             The first will be called once at the beginning, the second repeatedly
346             until it returns false, and the third once afterward. For example:
347              
348              
349             sub $number_count = 10;
350             sub numbers_start { "Countdown, kinda like BASIC: " }
351             sub numbers_list { $number_count-- }
352             sub numbers_end { "\"blastoff. whee.\"" }
353             my %ov = (
354             numbers => [ \&numbers_start, \&numbers_list, \&numbers_end ]
355             );
356             $bt = Text::BasicTemplate->new();
357             $ss = '%numbers%';
358             print $bt->parse(\$ss,\%ov);
359              
360             This would call &numbers_start and insert the result, then call and
361             insert &numbers_list until it $number_count reached zero, then call
362             &numbers_end once and insert that. This may easily be applied, for
363             example, to an execute, fetch, fetch, fetch, ..., finish sequence in
364             DBI. If you need only part of these three functions (e.g. a routine
365             that does not need a finish function), you can pass any one as an
366             empty code reference (e.g. \ sub { }).
367              
368             The real use of subroutine references becomes apparent when you need
369             the output from a function parsed into a template of its own. As noted
370             above in the song() example, you can pass arguments to a subroutine via
371             the template. This extends to passing hashes, e.g. %&foo(name => value)%,
372             in which (name,value) will be passed to the subroutine referenced as foo
373             in the parse() dictionary. You may also pass an argument (bt_template => filename),
374             in which case the output from the coderef will be assumed to be a hashref;
375             this hashref will then be added to the current parse() dictionary (where
376             duplication occurs, the hashref will take precedence) and used as the
377             dictionary given to a recursive call of parse() on the file specified by
378             bt_template. So...
379              
380              
381             sub start {
382             return "hello, ";
383             }
384             my $pcount = 0;
385             sub getname {
386             my @people = ( { firstname => 'John', lastname => 'Doe' },
387             { firstname => 'Susan', lastname => 'Smith' }
388             );
389             return $people[$pcount++];
390             }
391             sub end {
392             return "Nice to see you.";
393             }
394             # assume that /path/hello-template contains
395             # The Esteemed %firstname% %lastname%, Lord of All You Survey
396             $bt = Text::BasicTemplate->new();
397             $ss = "Greeting: \"%&greeting(bt_template => /path/hello-template)%\"";
398             print $bt->parse(\$ss, { greeting => [ \&start, \&getname, \&end ] });
399              
400             In this instance, the return values of &start and &end will be used as-is.
401             &getname will be called until it reaches undef (on the third call); the
402             hashrefs returned will be parsed into two copies of /tmp/hello-template.
403             The final output would therefore be:
404              
405             hello, The Esteemed John Doe, Lord of All You Survey
406             The Esteemed Susan Smith, Lord of All You Survey
407             Nice to see you.
408              
409             This has obvious usefulness in terms of taking database output and
410             making presentable (e.g. HTML) output from it, amongst other uses.
411              
412             =head1 PRAGMA/PREPROCESS FUNCTIONS
413              
414             Some basic pragma functions are provided for use in templates. These
415             follow the same syntactical conventions as subroutine substitutions,
416             but correspond to programs internal to Text::BasicTemplate rather
417             than supplied by calling code. Pragmas should not be used on untrusted
418             templates -- when templates are not trustworthy, they should be disabled
419             by setting $object->{pragma_enable}->{name_of_pragma} to false, or more
420             simply disabling all pragmas by setting $object->{pragma_enable} = {}.
421             If an option pragma_enable is passed to new(), it will be taken as
422             a substitute for the enabled list and not overridden.
423              
424             Individual pragmas may be added or overridden with code of your own by
425             setting $object->{pragma_functions}->{name_of_pragma} to a CODE reference.
426             The referenced routine should expect to be passed a list containing
427             a reference to the Text::BasicTemplate object, a hashref to the active
428             dictionary (which may be {}), followed by any arguments passed in
429             the template. Pragma routines must match ^bt_, or they will not be
430             interpreted as pragmas.
431              
432             Pragmas provided are as follows. Note that they follow, to a reasonable
433             extent, the format given by the Apache 1.3 mod_include specification, with
434             a few additions. Options in [ square brackets ] are optional.
435              
436             =head2 bt_include({ file | virtual }, filename, [ noparse ])
437              
438             Includes a file in the given location in the template. The first option
439             specifies from where the file should be loaded, equivalent to the Apache
440             mod_include form. B means any regular path and filename.
441             B is interpreted as relative to $object->{include_document_root}
442             or $ENV{DOCUMENT_ROOT} in that order of precedence; if no document root is
443             specified, no include is done. B is a restricted form of the
444             B form, in which files must match \w[\w\-.]{0,254} to be included
445             (this means, generally, that the included files must be in the working
446             directory, unless you chdir() or something).
447              
448             If B is supplied, the included file will be inserted as-is
449             without further adjustment. Otherwise it will be run through parse()
450             as would any normal template. You should use the noparse option when
451             including an untrusted template from a trusted one.
452              
453             bt_include() will only include readable regular files (that is, those
454             passing C<-e>, C<-f> and C<-r>). Note that this is suceptible to race conditions,
455             so it does not confer any security where a race could be exploited by
456             the usual file/symlink swapping.
457              
458             Examples:
459              
460             %&bt_include(file,templates/boxscores.html)%
461             Includes the file, parses according to the active dictionary
462             %&bt_include(file,orders/summary.txt,noparse)%
463             Includes the file but without any parsing on the way
464             %&bt_include(virtual,index.html)%
465             Includes the file index.html from the document_root directory,
466             with parsing.
467              
468             bt_include() is one the user might want to override if template files
469             are stored in a database or other non-file mechanism.
470              
471             =head2 bt_exec({ cmd | cgi }, command, parse)
472              
473             Analogous to the Apache mod_include 'exec' directive. Executes the
474             specified command and inserts its stdout output into the template
475             in place of the directive. If B is specified, this output
476             will be handed to parse() as if it were a template file.
477              
478             If B is given, the command will be read, parsed if selected,
479             and inserted as-is without validation on the command. If B
480             is given, the output will be skipped up and including the first
481             blank line to remove HTTP headers.
482              
483             bt_exec() is not secure and should not be used except with trusted
484             templates and on trusted binaries. For this reason it is disabled
485             by default and must be manually enabled by setting $object->{pragma_enable}->{bt_exec} true either when calling new() or subsequently.
486              
487              
488             =head1 COMPATIBILITY
489              
490             Text::BasicTemplate 2.0 is a major rewrite from v0.9.8 and previous
491             versions. Compatibility has been preserved to a degree, enough that
492             with compatibility mode enabled, there should be no difference in
493             either output or calling conventions.
494              
495             I
496             will be disabled in some future version, possibly without notice.>
497              
498             Backwards compatibility is a concern in two respects, that of template
499             format and calling conventions.
500              
501             =head2 TEMPLATE FORMAT
502              
503             The BasicTemplate 2.0 template format is only minimally compatible
504             with the older form. If your templates include conditionals or
505             simple_ssi HTML-style include directives, you will need to update
506             your templates and/or use compatibility mode. A template that uses
507             only variable substitution (e.g. "Hello %name%") will not need
508             compatibility mode.
509              
510             Compatibility mode is enabled by passing 'compatibility_mode_0x => 1'
511             to new() (see the POD for new()). Note that compatibility mode is
512             slower than standard mode, because of conversion overhead.
513              
514             The convert_template_0x_2x() function can convert a 0.x template to
515             a 2.0 template -- see the POD for that function for the details.
516             This function can easily be placed in a script to convert your
517             templates in place, and it is likely that such a script will be
518             provided with Text::BasicTemplate releases.
519              
520             =head2 CALLING CONVENTIONS
521              
522             In general, there should be no necessary change between 0.x calls
523             and 2.x calls. All the old calls have been replaced with stubs
524             which call the new versions. These are roughly as follows:
525              
526             push(), parse_push() -- replaced by parse()
527             print(), parse_print() -- replaced by print parse()
528             list_cache() -- replaced by list_lexicon_cache()
529             purge_cache() -- replaced by purge_*_cache()
530             uncache() -- replaced by purge_lexicon_cache(), purge_file_cache()
531              
532             =cut
533              
534              
535             my $errstr;
536             my $debug = 0;
537              
538             my %reserved_words = (
539             'if' => 1, '%if%' => 1,
540             'else' => 1, '%else%' => 1,
541             'elsif' => 1, '%elsif%' => 1,
542             'fi' => 1, '%fi%' => 1,
543             );
544              
545             my %lexeme_types = (
546             0 => 'plain',
547             1 => 'condi',
548             2 => 'ident',
549             3 => 'liter',
550             4 => 'uoper',
551             5 => 'boper',
552             6 => 'coper',
553             );
554              
555             =head1 USEFUL FUNCTIONS
556              
557             =item B
558              
559             Make a Text::BasicTemplate object. Syntax is as follows:
560              
561             $bt = Text::BasicTemplate->new(
562             max_parse_recursion => 32,
563             use_file_cache => 0,
564             use_lexicon_cache => 1,
565             use_scalarref_lexicon_cache => 0,
566             use_full_cond_cache => 1,
567             use_cond2rpn_cache => 1,
568             use_dynroutine_arg_cache => 1,
569             use_flock => 1,
570             default_list_delimiter => ", ",
571             default_hash_delimiter => ", ",
572             default_hash_specifier => "=",
573             default_undef_identifier => "",
574             compatibility_mode_0x => 1,
575             eval_subroutine_refs => 1,
576             strip_html_comments => 0,
577             strip_c_comments => 0,
578             strip_cpp_comments => 0,
579             strip_perl_comments => 0,
580             condense_whitespace => 0,
581             simple_ssi => 1
582             );
583              
584             All explicit arguments to new() are optional; the values shown above are
585             the defaults.
586              
587             Configuration arguments given to new() have the following meanings:
588              
589             =over 4
590              
591             =item B:
592             When performing a recursive parse() on a template, as
593             in the case of a subroutine substitution with a bt_template parameter (see
594             the B section), parsing will stop if recursion goes more than this
595             depth -- the typical cause would be a template A that included a subroutine
596             reference that used a template B, which used a C, which used A again.
597              
598             =item B:
599             Templates specified to parse() by filename are read into
600             memory before being given to the lexer. If this option is set, the contents
601             of the file will be cached in a hash after being read. This is largely
602             unnecessary if (as per default) lexicon caching is enabled. Do not turn this
603             on unless you have disabled lexicon caching, or are doing something dubious
604             to the cache yourself.
605              
606             =item B:
607             If true, the lexicon generated from an input template
608             will be cached prior to parsing. This is the normal form of caching, and
609             enables subsequent calls to parse() to skip over the lexical parsing of
610             templates, generally the most expensive part of the process.
611              
612             =item B:
613             If true, the above lexicon caching applies
614             to templates given to parse() via scalar reference, as well as by filename.
615             This is generally fine, but if you pass the contents of multiple templates
616             by a reference to the same scalar, you may get cache mismatching.
617              
618             =item B:
619             Controls caching of the results of evaluation of conditionals. Has three
620             settings, off (0), normal (1), and persistent (2). If set off, every
621             conditional will be reevaluated every time it is executed (this is not
622             very expensive unless use_cond2rpn_cache is set off also; see documentation
623             for that option). This is necessary only if you intend to change the
624             values in the dictionary during a parse(), as in the case of a
625             template-referenced subroutine calling a method that changes the dictionary.
626             This cache adds some speed; the operation normally requires O(n) where n is
627             the number of operators in the conditional, plus the cond2rpn conversion
628             overhead, if applicable. When use_full_cond_cache is set to 1 (on, as per
629             normal), conditionals are cached only for the span of one parse() call; if
630             a template-referenced routine changes the dictionary for a variable already
631             used in a conditional, the change will have no effect until the next call
632             to parse(). When set to 2 (persistent), the conditional cache does not
633             expire when parse() completes a single template, and indeed will not expire
634             at all unless you call purge_fullcond_cache() manually. This setting can
635             be useful for fast repeated parsing of the same data into multiple
636             templates, but is not suitable when the dictionary is changing.
637              
638             =item B:
639             Subroutine substitutions in templates may be
640             passed arguments; these arguments are parsed into a suitable list before
641             being handed to the subroutine in question. If this is enabled, the results
642             of that parsing will be cached to speed future use. This does not incur
643             cache mismatches; leave enabled unless you have a good reason not to.
644              
645             =item B:
646             If set true, template files will be flock()ed with a LOCK_SH
647             while being read. Otherwise, they will be read blindly. Win32 afflictees
648             might wish to disable this; in general, leave it alone. Note that files
649             generally will need to be read only once each if either lexicon or file
650             caching is enabled (see above).
651              
652             =item B:
653             When listrefs are substituted into a template,
654             they will be join()ed with the contents of $self->{list_delimiter}->{name}
655             if defined, or with this default value otherwise. If you wish your listrefs
656             contatenated with no delimiting, set this to ''. Default is ', '.
657              
658             =item B:
659             As above, but separates key/value pairs in hashref
660             substitution. If %x = (y => z, x => p), this delimiter will be placed
661             between y=z and x=p. Overridden by $self->{hash_delimiter}->{name}. Deault ', '.
662              
663             =item B:
664             As above, separating keys and values in hashref
665             substitution. In the above %x, this delimiter goes between y and z, and
666             between x and p. Overriden by $self->{hash_specifier}->{name}. Default '='.
667              
668             =item B:
669             When a template calls for a substitution key
670             which is undefined in the dictionary, this value will be substituted instead.
671             Default is ''. Something obvious like '**undefined**' might be a good choice
672             for debugging purposes.
673              
674             =item B:
675             This option enables evaluation of subroutine reference
676             substitutions, e.g. %&myroutine()%. Generally a safe option, but you might
677             want to disable it if parsing untrustworthy templates.
678              
679             =item B:
680             Enables compatibility with templates written
681             for Text::BasicTemplate v0.x. See B section.
682              
683             =item B:
684             If set true, HTML comments (E!-- ... --E) will be
685             removed from the parse results. Note that nested comments are not properly
686             stripped. Default off.
687              
688             =item B:
689             If true, C comments (/* ... */) will be removed from
690             parse results. Default off.
691              
692             =item B:
693             If true, C and C++ comments (/* ... */ and // ...\n) will
694             be removed from parse results. Default off.
695              
696             =item B:
697             If true, perl and similar style comments (# ... \n) will
698             be removed from parse results. Default off.
699              
700             =item B:
701             If true, whitespace in parse results will be condensed to
702             the first byte of each, as would be done by most web browsers. Useful for
703             tightening bandwidth usage on HTML templates without making the input templates
704             themselves unreadable. Default off.
705              
706             =item B:
707             If true, server-parsed HTML directives of the #include persuasion
708             will have the file referenced in their file="" or virtual="" arguments inserted
709             in their place. The form is . This usage is deprecated
710             in favor of the %&bt_include()% function -- see the B section. Default off;
711             this should not be enabled when using untrusted templates.
712              
713             =back
714              
715             =cut
716              
717             sub new {
718 7     7 1 1337 my $class = shift;
719 7         24 my %params = @_;
720 7         33 my $self = { %params };
721 7         27 bless $self, $class;
722              
723 7   50     104 $self->{max_parse_recursion} ||= 32;
724 7   50     53 $self->{reserved_words} ||= \%reserved_words;
725 7 50       240 !defined $self->{use_full_cond_cache} and $self->{use_full_cond_cache} = 1;
726 7 50       670 !defined $self->{use_cond2rpn_cache} and $self->{use_cond2rpn_cache}=1;
727 7 50       46 !defined $self->{use_dynroutine_arg_cache} and $self->{use_dynroutine_arg_cache}=1;
728              
729 7 50       57 !defined $self->{taint_enabled} and
730             $self->{taint_enabled} = $self->taint_enabled();
731              
732             # the file cache should be enabled if the lexicon cache isn't,
733             # but we don't need to cache files if the lexicons themselves are
734             # being cached, since the file cache would never be used anyway.
735              
736 7 50       38 if (!defined $self->{use_file_cache}) {
737 7         36 $self->{use_file_cache} = !$self->{use_lexicon_cache};
738             }
739 7   50     56 $self->{use_scalarref_lexicon_cache} ||= 0;
740              
741 7 50       33 !defined $self->{use_flock} and $self->{use_flock} = 1;
742              
743             # caches conversions of conditionals into their RPN conversions
744             # for cond_evaluate()
745 7         17 $self->{cond2rpn_cache} = ();
746              
747             # caches the actual returns from cond_evaluate();
748 7         25 $self->{fullcond_cache} = ();
749              
750             # caches argument lists passed to subrefs (saves reparsing)
751 7         16 $self->{dynroutine_arg_cache} = ();
752              
753             # caches lexicons
754 7         21 $self->{lexicon_cache} = ();
755              
756             # caches files in the absence of lexicon caching
757 7         21 $self->{file_cache} = ();
758              
759 7         24 $self->{enable_pattern_operator} = !$self->{taint_enabled};
760              
761 7 50 50     97 !defined $self->{list_delimiter}->{__default} and
762             $self->{list_delimiter}->{__default} = $self->{default_list_delimiter} || ', ';
763 7 50 50     86 !defined $self->{hash_delimiter}->{__default} and
764             $self->{hash_delimiter}->{__default} = $self->{default_hash_delimiter} || ', ';
765 7 50 50     231 !defined $self->{hash_specifier}->{__default} and
766             $self->{hash_specifier}->{__default} = $self->{default_hash_specifier} || '=';
767              
768 7         22 $self->{default_undef_identifier} = '';
769 7         19 $self->{disabled_pragma_identifier} = '[pragma not enabled]';
770 7         27 $self->{disabled_subref_identifier} = '[subroutine not enabled]';
771 7         14 $self->{tainted_content_identififer} = '[tainted template contents]';
772              
773 7 50       107 $self->{pragma_enable} = {} unless ref $self->{pragma_enable} eq 'HASH';
774 7 50       35 $self->{pragma_functions} = {} unless ref $self->{pragma_functions} eq 'HASH';
775              
776             # v0.x backwards-compatibility settings
777 7 50       32 !defined $self->{compatibility_mode_0x}
778             and $self->{compatibility_mode_0x} = 1;
779              
780 7 50       47 if ($self->{compatibility_mode_0x}) {
781 7         14 $self->{taint_enabled} = 0;
782            
783 7 100       32 !defined $self->{simple_ssi} and $self->{simple_ssi} = 1;
784 7 50       29 if ($self->{simple_ssi}) {
785 7         47 $self->{pragma_enable}->{bt_include} = 1;
786             }
787             }
788              
789              
790 7   50     53 $self->{bt_include_allow_tainted} ||= 0;
791 7 50       27 if (!defined $self->{pragma_enable}->{bt_include}) {
792 0 0       0 if (!$self->{taint_enabled}) {
793             # if taint checking is enabled, we can't safely
794             # do include.
795 0         0 $self->{pragma_enable}->{bt_include} = 1;
796             }
797             }
798 7         33 $self->{pragma_functions}->{bt_include} = \&bt_include;
799 7         39 $self->{pragma_functions}->{bt_exec} = \&bt_exec;
800              
801              
802 7         26 $self->{eval_subroutine_refs} = 1;
803 7         21 for ('strip_html_comments','strip_c_comments','strip_cpp_comments',
804             'strip_perl_comments','condense_whitespace','simple_ssi') {
805 42   100     195 $self->{$_} ||= 0;
806             }
807 7         33 $self;
808             }
809              
810             =item B
811              
812             Given a source template in SOURCE_TEMPLATE, parses that template according
813             to the key/value hash referenced by $ovr, then returns the result.
814              
815             If SOURCE_TEMPLATE is given as a scalar, it will be interpreted as a filename,
816             and the contents of that file will be read, parsed, and returned. If given as
817             a scalar reference, it will be interpreted as a reference to a buffer
818             containing the template (the referenced template will not be modified, and
819             copies of the relevant parts will be used to build the lexicon). If
820             SOURCE_TEMPLATE contains an array reference, that array will be used instead
821             of generating a new lexicon.
822              
823             If use_file_template_cache is true and the source template is loaded from a
824             file, or if use_scalarref_lexicon_cache is true and the source template is
825             given in a scalar reference, the lexicon will be cached to accelerate future
826             parsing of the template. If the contents of either the file or the
827             referenced buffer changes during the lifespan of the Text::BasicTemplate
828             object, the code will not notice -- if you need to change the templates in
829             this fashion, use B to delete the cached lexicon. Lexicon
830             references are not cached, since the code assumes if you make your own
831             templates you are capable of caching them, too.
832              
833             For templates stored in and loaded from files, note that they will be
834             read and parsed in core, so you probably should not try to parse templates
835             that would occupy a significant amount of your available memory. For
836             large seldom-used templates, also consider disabling lexicon caching or
837             calling B afterwards.
838              
839             B is a euphemism for some arbitrary combination of lists, scalar paris,
840             hashrefs and listrefs. These should cumulatively amount to the substitution
841             dictionary -- the simple form is { x => 'y' }, in which all %x% in the
842             template will be replaced with y. (x,y) will work also (and by extension,
843             you may pass lists of these, or raw hashes). The dictionary is parsed
844             once, start-to-finish, so in the event of duplicated entries, the last
845             entry of a given name will be the only one retained.
846              
847             Note on backwards-compatibility: in v0.x, it was possible to pass scalars
848             of the form "x=y". This is deprecated, and is only available if
849             B is set true. Further, as references are now legal
850             fodder for substitutions, ("x",\%y) means that %x% will parse to the
851             contents of %y -- if %y contains part of your substitution dictionary,
852             then the above will present an error in any case, and ("x","y",\%y) is likely
853             what you intended.
854              
855             =cut
856              
857             sub parse {
858 145     145 1 263700 my $self = shift;
859 145   50     446 my $isrc = shift || return undef;
860 145         342 my @dict = (@_);
861 145         258 my $ovr = {};
862 145         200 my $L;
863             my $ss;
864 0         0 my ($d,$e,$src,$tsrc); ##
865              
866              
867 145         415 while ($d = shift @dict) {
868 732 100       2240 if (ref $d eq 'HASH') {
    50          
    50          
869 145         190 unshift @dict, map { ($_,$d->{$_}) } keys %{$d};
  580         1834  
  145         577  
870             } elsif (ref $d eq 'ARRAY') {
871 0         0 unshift @dict,@{$d};
  0         0  
872             } elsif (!ref $d) {
873 587 100 66     2844 if ($self->{compatibility_mode_0x} and $d =~ /^([\w\.\-]+)=(.*)/s) {
874 2         10 $ovr->{$1} = $2;
875 2         5 next;
876             }
877 585 50       926 if (@dict) {
878 585         773 $e = shift @dict;
879 585         2864 $ovr->{$d} = $e;
880             } else {
881 0         0 print STDERR "Text::BasicTemplate::parse($isrc): Stack underflow while flattening dictionary; odd number of elements, last was '$d'";
882             }
883             }
884             }
885 145   100     1098 $ovr->{_bt_recurse_count} ||= 0;
886              
887             # horrible hack
888 145 50       334 if ($self->{compatibility_mode_0x}) {
889 145         282 $self->{compat_0x_ovr} = $ovr;
890             }
891              
892 145 50 33     715 return '[Text::BasicTemplate::parse() recursion limit exceeded]'
893             if $self->{max_parse_recursion} and
894             $ovr->{_bt_recurse_count} > $self->{max_parse_recursion};
895             # print STDERR "ovr = {".join(',',map { "$_=$ovr->{$_}" } keys %{$ovr})."}";
896 145 50       21304 if (ref $isrc eq 'ARRAY') {
    100          
    50          
897 0         0 $L = $isrc;
898             } elsif (ref $isrc eq 'SCALAR') {
899 97 50 33     326 if ($self->{use_scalarref_lexicon_cache} and
900             defined $self->{lexicon_cache}{$isrc}) {
901 0 0       0 $debug && print STDERR "]using lexicon cache for $isrc]";
902 0         0 $L = $self->{lexicon_cache}{$isrc};
903             } else {
904 97         321 $L = $self->lex($src = $isrc);
905 97 50       292 if ($self->{use_scalarref_lexicon_cache}) {
906 0         0 $self->{lexicon_cache}{$isrc} = $L;
907             }
908             }
909             } elsif (!ref $isrc) {
910 48 50 33     139 if ($self->{use_scalarref_lexicon_cache} and
911             defined $self->{lexicon_cache}{$isrc}) {
912 0         0 $L = $self->{lexicon_cache}{$isrc};
913             } else {
914 48 50       186 unless ($tsrc = $self->load_from_file($isrc)) {
915 0         0 warn "Text::BasicTemplate::parse($isrc): File not available";
916 0         0 return undef;
917             }
918 48         146 $L = $self->lex($isrc = $tsrc);
919 48 100       123 if ($self->{use_scalarref_template_cache}) {
920 4         15 $self->{lexicon_cache}{$isrc} = $L;
921             }
922             }
923             }
924              
925             # horrible hack
926 145 50       369 if ($self->{compatibility_mode_0x}) {
927 145         919 delete $self->{compat_0x_ovr};
928             }
929              
930 145         209 $ss = $self->parse_range($L,0,$#{$L},$ovr);
  145         634  
931 145 100       409 $$ss =~ s///mg if $self->{strip_html_comments};
932 145 100 66     700 $$ss =~ s/\/\*.*?\*\///mg if $self->{strip_c_comments} or
933             $self->{strip_cpp_comments};
934 145 100       324 $$ss =~ s/\/\/.*?\n/\n/mg if $self->{strip_cpp_comments};
935 145 100       360 $$ss =~ s/\#.*?\n/\n/mg if $self->{strip_perl_comments};
936 145 100       369 $$ss =~ s/(\s)\s+/$1/mg if $self->{condense_whitespace};
937 145 50       335 if ($self->{use_full_cond_cache} == 1) {
938 145         382 $self->purge_fullcond_cache;
939             }
940 145         3834 $$ss;
941             }
942              
943              
944             =item parse_range \@lexicon $start $end [ \@ov ]
945              
946             Parses and returns the relevant parts of the specified lexicon
947             over the given range. This has the happy side effect of eliminating
948             the obnoxious passing around of chunks of the lexicon. Instead one
949             need only pass references to a single lexicon and the range over which
950             it should be parsed. This routine does the actual work of parse(),
951             but is really only useful internally.
952              
953             =cut
954              
955             sub parse_range {
956 174     174 1 256 my $self = shift;
957 174         186 my $L = shift;
958 174         315 my ($start_pos,$end_pos,$ovr) = @_;
959 174         205 my ($lexeme);
960             my $out;
961 0         0 my ($i,$i1,$i2,$s);
962 0         0 my ($cond,$subcond,$rcond);
963              
964 7     7   101 use re 'taint';
  7         12  
  7         82064  
965 174 50       465 ref $ovr eq 'HASH' or $ovr = {};
966 174 50       388 ref $L eq 'ARRAY' or $L = [];
967 174 50 33     1035 return \ '' unless defined $start_pos and defined $end_pos and $end_pos >= $start_pos;
      33        
968 174 50 33     383 return \ '' if ($end_pos<0 || !@{$L});
  174         585  
969              
970 174 50       393 $debug and print STDERR "\nlexicon[$start_pos,$end_pos, #L=$#{$L}]:\n";
  0         0  
971 174 50       348 $debug and
972             print STDERR $self->dump_lexicon($L,$start_pos,$end_pos);
973              
974 174   66     2994 for ($i=$start_pos; $i<=$end_pos && $i<=$#{$L}; $i++) {
  366         2641  
975             # print " start loop iteration, \$i=$i, end_pos=$end_pos, #L=$#{$L}\n";
976 366         805 $lexeme = $L->[$i];
977 366 50       865 next if ($lexeme->[0] > $self->{max_parse_recursion});
978              
979 366 50       1310 $debug and print STDERR "[L$lexeme->[0]] $lexeme->[1]";
980 366 100 50     984 $debug and print STDERR " -- op" if $lexeme->[2];
981 366 100       680 if (!$lexeme->[2]) {
982 195         563 $out .= $lexeme->[1];
983 195 50       365 $debug and print STDERR "\n";
984 195         745 next;
985             }
986              
987 171 100       494 if ($lexeme->[2] == 2) { # is_identifier
    100          
988 38 50       69 $debug and print STDERR " [ $lexeme->[1] is identifier, passing $lexeme->[3]/$lexeme->[4] ]";
989 38         261 $out .= $self->identifier_evaluate($lexeme->[1],
990             $ovr,$lexeme->[3],$lexeme->[4]);
991 38         144 next;
992             } elsif ($lexeme->[2] == 6) { #is_nonconditional_operation
993 84 50       172 $debug and print STDERR "[ nco lexeme: ".join(',',@{$lexeme}),"]";
  0         0  
994 84         328 $out .= $self->cond_evaluate($lexeme->[1],$ovr);
995             }
996              
997             # For these purposes, if and elsif are roughly equivalent, and
998             #
999 133 100 100     1243 if ($lexeme->[2] == 1 and
1000             $lexeme->[1] =~ /^%(else|(if|elsif)\s+([^%]+))%$/) {
1001 45         73 $cond = $3;
1002 45 100       100 $1 eq 'else' and $cond = 1;
1003 45 50       72 $debug and print STDERR " [if '$cond' from $lexeme->[1]]";
1004 45 100       127 if ($self->cond_evaluate($cond,$ovr)) {
1005 29 50       55 $debug and print STDERR " [eval true]";
1006            
1007             # find end of block, and skip over else/elsifs; if we drop down a level,
1008             # there's likely something wrong with the lexer.
1009 29   66     48 BLOCKLEXEME: for ($i1=$i+1, $i2 = 0;
  78   66     482  
1010             $i1<=$#{$L} &&
1011             $L->[$i1]->[0] >= $lexeme->[0] &&
1012             $i1<=$end_pos; $i1++) {
1013            
1014             # conditional components are a matter for concern iff they're on the
1015             # same level as the if we started from; if we find them from higher
1016             # levels, the recursive call will handle them, and we should not be
1017             # able to get to a lower level by loop conditions immediately above.
1018 77 100 100     627 if ($L->[$i1]->[0] == $L->[$i]->[0] &&
    100 100        
      100        
1019             $L->[$i1]->[1] eq '%fi%') {
1020 17         24 last BLOCKLEXEME;
1021             } elsif ($L->[$i1]->[0] == $L->[$i]->[0] and
1022             $L->[$i1]->[1] eq '%else%' or
1023             substr($L->[$i1]->[1],0,7) eq '%elsif ') {
1024            
1025             # if we actually find an else or elsif, we can skip to the end of
1026             # the block, since the condition from which we started was true,
1027             # and everything including and after an else/elsif is not going
1028             # to get parsed this trip anyway.
1029              
1030 11   33     36 for ($i2=0; $i1+$i2 <= $end_pos &&
  41   66     426  
      100        
1031             $i1+$i2 <= $#{$L} &&
1032             defined $L->[$i1+$i2+1]->[0] &&
1033             $L->[$i1+$i2+1]->[0] >= $L->[$i1]->[0]; $i2++) {
1034             # print STDERR "\ni1=$i1 i2=$i2 end_pos=$end_pos #L=$#{$L}",
1035             # " L->[".($i1+$i2+1)."]->[0]=".$L->[$i1+$i2+1]->[0],
1036             # " L->[$i1]->[0]=".$L->[$i1]->[0],"\n";
1037             }
1038 11         18 last BLOCKLEXEME;
1039             }
1040             }
1041             # $debug and print STDERR " [recurs over ".($i+1)."..".($i1-1).", then skip $i2]";
1042             # $debug and print STDERR " lexdump passed on: ".$self->dump_lexicon($L,$i+1,$i1-1);
1043            
1044 29         130 $s = $self->parse_range($L,$i+1,$i1-1,$ovr);
1045 29 50 33     136 $s and ref $s eq 'SCALAR' and $out .= $$s;
1046             # $debug and print STDERR " back from recursion, i=$i i1=$i1 i2=$i2";
1047             # $out .= ${ $self->parse([ $L->[($i+1)..$i1] ]) };
1048            
1049             # adjust parse position to the end of the if {} block plus the
1050             # distance from that position to the end of the else/elsifs.
1051 29         37 $i = $i1 + $i2;
1052             } else {
1053 16 50       30 $debug and print STDERR " [eval false]";
1054             # if the condition didn't pass, just advance to the next conditional, unless
1055             # we need to go down a level to find it. If we hit an %elsif%, %fi% or %else%,
1056             # stop seeking and resume parsing from that point.
1057             # $debug and print STDERR " [ranging !if block from $i+1 for level $lexeme->[0]: ";
1058 16   33     170 for ($i1=$i+1; ($L->[$i1]->[0] >= $lexeme->[0]) &&
  18   66     277  
      66        
      33        
1059             ($i1<=$end_pos) and
1060             !($L->[$i1]->[0] == $L->[$i]->[0] &&
1061             $L->[$i1]->[1] =~ /^%(elsif\s|fi%|else%)/) &&
1062             $i1<=$#{$L}; $i1++) {}
1063             # $debug and print STDERR "[$i1 computed]";
1064 16 50 33     87 $1 and $1 eq 'fi' and $i1++;
1065 16 50       23 $debug and print STDERR "[if-false offset computed, adjusting i from $i to $i1 ($L->[$i1]->[1])]";
1066 16         35 $i = $i1-1;
1067             }
1068             }
1069 133 50       493 $debug and print STDERR " \n";
1070             }
1071             # $debug and print STDERR " [parse over $start_pos-$end_pos complete]\n";
1072 174         9940 \$out;
1073             }
1074              
1075             =item cond_evaluate CONDITIONAL [ \%ovr ]
1076              
1077             Evaluates the specified conditional left-to-right. At present it does
1078             not handle operators also, just boolean/scalar evaluation.
1079              
1080             =cut
1081              
1082             sub cond_evaluate {
1083 132     132 1 368 my $self = shift;
1084 132         174 my $cond = shift;
1085 132   50     283 my $ovr = shift || [];
1086 132         197 my @cstack = ();
1087 132         142 my ($psc,$subcond,$rcond);
1088 132         175 my $binop_leftover = '';
1089 132         136 my ($x,$y);
1090              
1091             # first recursively evaluate according to parentheses
1092              
1093 132 50       451 $debug and print STDERR " [cond_evaluate(): $cond]";
1094 132 50       250 defined $cond or return undef;
1095              
1096             # have we computed this condition all the way before?
1097             # Generally we can't use this because $ovr may change, but
1098             # if the user wants it, it's fast.
1099 132 100 66     868 $self->{use_full_cond_cache} and $self->{fullcond_cache}{"$ovr\t$cond"} and
1100             return $self->{fullcond_cache}{"$ovr\t$cond"};
1101              
1102             ## BUG: the cond2rpn cache breaks things. It should live for at most one parse() call, not
1103             ## the life of the module.
1104              
1105             # Are we supposed to use the conditional -> RPN conversion cache, and if so,
1106             # have we already parsed this one before?
1107 131 100 66     2844 if ($self->{use_cond2rpn_cache} && $self->{cond2rpn_cache}{$cond}) {
1108 22 50       43 $debug and print STDERR "[cache hit on cond '$cond' \@ $self->{cond2rpn_cache}{$cond}]";
1109              
1110 22         28 @cstack = map { [ $_->[0], $_->[1] ] } @{ $self->{cond2rpn_cache}{$cond} };
  32         148  
  22         63  
1111             # for $x (@{ $self->{cond2rpn_cache}{$cond} }) {
1112             # push @cstack, [ $_->[0], $_->[1] ];
1113             # }
1114              
1115              
1116             # @cstack = @{ $self->{cond2rpn_cache}{$cond} };
1117             } else {
1118 109 50       475 $debug and print STDERR "[cache miss on cond '$cond']";
1119 109         564 while ($cond =~ /(^| |\()\(([^\)]+)\)/) {
1120 3         9 ($psc,$subcond) = ($1,$2);
1121 3         18 $rcond = $self->cond_evaluate($subcond,$ovr);
1122 3 50       8 $debug and print STDERR " [eval $subcond-> $rcond in $cond]";
1123             # $cond =~ s/($&)/$rcond/g;
1124             # fix in 2.005: Shouldn't have permitted active metachars here:
1125 3         66 $cond =~ s/\(\Q$subcond\E\)/$rcond/g;
1126 3 50       11 $debug and print STDERR " [reduced to $cond]";
1127             }
1128 109 50       191 $debug and print STDERR " [simplified cond: $cond]";
1129            
1130             # stdvar, !func, &cgivar, $envvar, 42
1131             # $cond =~ s/(^| )(\w+)\(/$1&$2/g;
1132 109         1220 while ($cond =~ m/(defined |\!| not )?\s*([\$]?([A-Za-z_]\w*|\"[^\"]*\"|\d+|\&\w+\([^)]*\)))
1133             \s*(&&|\|\|| (and|or) | # logical binary ops
1134             \&|\||\^|\<\<|\>\>| # bitwise binary ops
1135             ==|!=|<=>|<=|>=|<|>| (eq|ne|lt|le|gt|ge) | # comparison binary ops
1136              
1137             \=~|\!~| x |\.|\+|\-|\*\*|\*| (mod|div) |\/)?/gmx) { # arithmetic and string ops
1138 190 50       392 $debug and print STDERR " [ conditional ($1,$2,$3,$4,$5,$6,$7,$8)]";
1139            
1140 190         12743 my ($unaryop,$operand,$binaryop) = ($1,$2,$4);
1141             # print STDERR " [unaryop=",($unaryop || 'undef'),", calling ident_eval($operand)]";
1142              
1143 190         232 if (1) {
1144 190 50       903 defined $operand and push @cstack, [ 2, $operand ];
1145             } elsif ($unaryop && $unaryop eq 'defined') {
1146             defined $operand and push @cstack, [ 2, $self->identifier_evaluate($operand,$ovr,undef,undef,undef,1) ];
1147             } else {
1148             defined $operand and push @cstack, [ 2, $self->identifier_evaluate($operand,$ovr) ];
1149             }
1150             # print STDERR "ident_eval($operand): ".$self->identifier_evaluate($operand,$ovr)."\n";
1151 190 100       514 $unaryop and push @cstack, [ 4, $unaryop ];
1152 190 100       558 if ($binop_leftover) {
1153 82         341 push @cstack, [ 5, $binop_leftover ];
1154 82         125 $binop_leftover = '';
1155             }
1156 190 100       393 $binaryop and $binop_leftover=$binaryop;
1157            
1158 190 50       7975 $debug and print STDERR "[unary=$unaryop operand=$operand binaryop=$binaryop lo=$binop_leftover, new cstack={".
1159             $self->dump_stack(\@cstack,1)."} ]";
1160             }
1161            
1162 109 50       234 $binop_leftover and push @cstack, [ 5, $binop_leftover ];
1163            
1164 109 50       301 if ($self->{use_cond2rpn_cache}) {
1165 109         208 $self->{cond2rpn_cache}{$cond} = [ map { [ $_->[0], $_->[1] ] } @cstack ];
  278         1747  
1166             }
1167             }
1168              
1169             # print STDERR "[cache for $cond was: ".$self->dump_stack($self->{cond2rpn_cache}{$cond},1)."]";
1170             # print STDERR "[cstack pre-eval {".$self->dump_stack(\@cstack,1)."} count=$#cstack]";
1171 131         286 for (@cstack) {
1172 310 100       4000 if ($_->[0] == 2) {
1173 216 100       1112 if ($_->[1] eq 'cacheablething') {
1174             # print STDERR "[item = $ovr->{cacheablething}]";
1175             }
1176             # print STDERR "[stack eval ident $_->[1] -> ";
1177 216         662 $_->[1] = $self->identifier_evaluate($_->[1],$ovr,undef,undef,undef,1);
1178             # print STDERR "$_->[1]]";
1179             }
1180             }
1181             # print STDERR "[cstack post-eval {".$self->dump_stack(\@cstack,1)."} count=$#cstack]";
1182             # print STDERR "[cache for $cond now: ".$self->dump_stack($self->{cond2rpn_cache}{$cond},1)."]";
1183              
1184             # now put in the stuff to handle boolean chaining (and/or)
1185 131 100       472 return '' unless @cstack;
1186 130         192 my ($lvalue,$op,$operand,$n,@ostack);
1187 130 50       232 $debug and print STDERR " [pre-loop: cstack contains {".$self->dump_stack(\@cstack,1)."} count=$#cstack]";
1188              
1189 130 50       237 $debug and
1190             print STDERR "[preloop #cstack = $#cstack]";
1191              
1192 130         857 while ($#cstack != 0) {
1193 94 50       1429 $debug and
1194             print STDERR " [cstack contains {".$self->dump_stack(\@cstack,1)."} count=$#cstack]";
1195 94         188 $n = shift @cstack;
1196 94 50       377 if ($n->[0] != 2) {
1197 0         0 print STDERR "Got $lexeme_types{$n->[0]} $n->[1] where identifier expected in '$cond'";
1198 0         0 return undef;
1199             }
1200             # $operand = $n->[1];
1201             # print STDERR "[operand $n->[1] -> ";
1202 94         146 $operand = $n->[1];
1203             # print STDERR "$operand]";
1204 94 50       189 !@cstack and return $operand;
1205              
1206 94         137 $n = shift @cstack;
1207 94 100       333 if ($n->[0] == 4) { # unary op
    50          
1208 7         13 $op = $n->[1];
1209 7         25 unshift @cstack, [ 2, $self->unaryop_evaluate($op,$operand) ];
1210 7         24 next;
1211             } elsif ($n->[0] == 2) { # another identififer
1212 87         108 $lvalue = $operand;
1213 87         460 $operand = $n->[1];
1214             # print STDERR "[new operand $n->[1] -> ";
1215             # $operand = $self->identifier_evaluate($n->[1],$ovr);
1216             # print STDERR "$operand]";
1217              
1218 87         107 $n = shift @cstack;
1219 87 100       207 if ($n->[0] == 5) { # binaryop?
    50          
1220 86         139 $op = $n->[1];
1221 86         267 unshift @cstack, [ 2, $self->binaryop_evaluate($lvalue,$op,$operand) ];
1222 86         258 next;
1223             } elsif ($n->[0] == 4) { # unaryop (to work on operand, ignoring lvalue)
1224 1         2 $op = $n->[1];
1225 1         5 unshift @cstack, [ 2, $self->unaryop_evaluate($op,$operand) ];
1226 1         3 unshift @cstack, [ 2, $lvalue ];
1227 1         3 next;
1228             } else {
1229 0         0 print STDERR "Got $lexeme_types{$n->[0]} $n->[1] where operator expected in '$cond'";
1230 0         0 return '';
1231             }
1232 0         0 next;
1233             } else {
1234 0         0 print STDERR "Got $lexeme_types{$n->[0]} $n->[1] where unaryop or identifier expected in '$cond'";
1235 0         0 return '';
1236             }
1237             }
1238 130         206 $n = $cstack[0];
1239 130 50       289 $debug and
1240             print STDERR "[postloop n={$n->[0],$n->[1]}]";
1241              
1242 130 50       343 if ($self->{use_full_cond_cache}) {
1243 130         624 $self->{fullcond_cache}{"$ovr\t$cond"} = $n->[1];
1244             }
1245 130 100       1890 defined $n->[1] and return $n->[1];
1246 2         8 '';
1247             }
1248              
1249             sub binaryop_evaluate {
1250 86     86 0 105 my $self = shift;
1251 86         214 my ($lvalue,$op,$operand) = @_;
1252              
1253 86 50       190 $debug and
1254             print STDERR "[binaryop_eval($lvalue,$op,$operand)]";
1255 86 50       171 if (!defined $op) {
1256             # print STDERR "[missing operator in binaryop_evaluate]";
1257 0         0 return undef;
1258             }
1259 86 100       146 if (!defined $lvalue) {
1260             # print STDERR "[lvalue undefined in binaryop_evaluate]";
1261 1         4 return undef;
1262             }
1263 85 50       143 if (!defined $operand) {
1264             # print STEDRR "[operand undefined in binaryop_evaluate]";
1265 0         0 return undef;
1266             }
1267             # string comparison ops
1268 85 100 66     1367 if ($op eq 'eq') {
    100 66        
    100 66        
    100 66        
    100 66        
    100 66        
    100 66        
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    50          
1269 18         64 return $lvalue eq $operand;
1270             } elsif ($op eq 'ne') {
1271 1         4 return $lvalue ne $operand;
1272             } elsif ($op eq 'lt') {
1273 2         9 return $lvalue lt $operand;
1274             } elsif ($op eq 'le') {
1275 1         5 return $lvalue le $operand;
1276             } elsif ($op eq 'gt') {
1277 2         11 return $lvalue gt $operand;
1278             } elsif ($op eq 'ge') {
1279 3         12 return $lvalue ge $operand;
1280             } elsif ($op eq '=~' and $self->{enable_pattern_operator}) {
1281 2         41 return $lvalue =~ m/$operand/;
1282             } elsif ($op eq '!~' and $self->{enable_pattern_operator}) {
1283 3         39 return $lvalue !~ m/$operand/;
1284             }
1285             # numeric comparison ops
1286             elsif ($op eq '==') {
1287 5         20 return $lvalue == $operand;
1288             } elsif ($op eq '!=') {
1289 2         9 return $lvalue != $operand;
1290             } elsif ($op eq '<') {
1291 2         9 return $lvalue < $operand;
1292             } elsif ($op eq '<=') {
1293 2         11 return $lvalue <= $operand;
1294             } elsif ($op eq '>') {
1295 1         17 return $lvalue > $operand;
1296             } elsif ($op eq '>=') {
1297 1         5 return $lvalue >= $operand;
1298             } elsif ($op eq '<=>') {
1299 2         12 return $lvalue <=> $operand;
1300             }
1301             # logical ops
1302             elsif ($op eq '&&' or $op eq 'and') {
1303 11   66     58 return ($lvalue && $operand);
1304             } elsif ($op eq '||' or $op eq 'or') {
1305 3   33     53 return ($lvalue || $operand);
1306             }
1307              
1308             # string combination ops
1309             elsif ($op eq '.') {
1310 1         4 return $lvalue . $operand;
1311             } elsif ($op eq 'x') {
1312 1         6 return $lvalue x $operand;
1313             }
1314              
1315             # arithmetic ops
1316             elsif ($op eq '+') {
1317 1         4 return $lvalue + $operand;
1318             } elsif ($op eq '-') {
1319 1         5 return $lvalue - $operand;
1320             } elsif ($op eq '*') {
1321 1         56 return $lvalue * $operand;
1322             } elsif ($op eq '/' and $operand) {
1323 2         13 return $lvalue / $operand;
1324             } elsif ($op eq 'div' and $operand) {
1325 1         6 return int($lvalue/$operand);
1326             } elsif ($op eq 'mod' and $operand) { # % is reserved
1327 1         5 return $lvalue % $operand;
1328             } elsif ($op eq '**') {
1329 2         12 return $lvalue ** $operand;
1330             }
1331             # bitwise ops
1332             elsif ($op eq '^') {
1333 2         10 return 1*$lvalue ^ 1*$operand;
1334             } elsif ($op eq '&') {
1335 2         12 return 1*$lvalue & 1*$operand;
1336             } elsif ($op eq '|') {
1337 1         5 return 1*$lvalue | 1*$operand;
1338             } elsif ($op eq '<<') {
1339 4         19 return 1*$lvalue << 1*$operand;
1340             } elsif ($op eq '>>') {
1341 4         23 return 1*$lvalue >> 1*$operand;
1342             }
1343 0         0 undef;
1344             }
1345              
1346             sub unaryop_evaluate {
1347 8     8 0 13 my $self = shift;
1348 8         13 my ($op,$operand) = @_;
1349              
1350 8 50       20 $debug and
1351             print STDERR " [unary_eval $op, $operand]";
1352 8 50 33     34 if (!$op) {
    100          
    50          
1353 0         0 return (!(!($operand)));
1354             } elsif ($op eq '!') {
1355 6         20 return !$operand;
1356             } elsif ($op eq 'defined' || $op =~ /^defined\s+/) {
1357 2         11 return defined $operand;
1358             }
1359             # fill in other ops here
1360 0         0 undef;
1361             }
1362              
1363             =item identifier_evaluate $identifier \%ovr [ $type, $name ]
1364              
1365             Evaluates the specified identifier and returns its value. Literals,
1366             being of the form \d+, "[...]" and '[...]', are returned as-is (leading
1367             and trailing quotes will be removed from string literals).
1368              
1369             Identifiers of standard (no special type) form are returned as they appear
1370             in \%ovr; if those stored values are listrefs or hashrefs, they will be
1371             returned in formatted form -- listrefs will be returned as a scalar
1372             delimited by the value of $self->{list_delimiter}->{B}, hashes will
1373             be mapped into a scalar using $self->{hash_specifier}->{B} and
1374             $self->{hash_delimiter}->{B}, which three have the form ", ",
1375             "=" and ", " respectively by default.
1376              
1377             Identifiers of the form $name will be checked against the environment
1378             variable of the same name, and if present, that value will be returned,
1379             otherwise undef will be returned.
1380              
1381             Identififers of the form &name will be returned according to those entries
1382             in \%ovr of the form &name -- this is used to provide a separate namespace
1383             for substitutions, e.g. for CGI parameters.
1384              
1385             Identifiers of the form !name will be evaluated according to the return
1386             value(s) from whatever stored procedure(s) have been registered under that
1387             name, if any. See C for details.
1388              
1389             =cut
1390              
1391             sub identifier_evaluate {
1392 254     254 1 318 my $self = shift;
1393 254         367 my $identifier = shift;
1394 254   50     520 my $ovr = shift || {};
1395 254         715 my ($type,$name,$args,$undef_asis) = @_;
1396              
1397             # undef is an OK value, but undef
1398             # is also the correct thing to return in such a case.
1399 254 50 0     3758 $debug and print STDERR " [identifier $identifier(",$type || '',',',$name || '',")]";
      0        
1400 254 50       531 !defined $identifier and return $self->{default_undef_identifier};
1401 254 100       454 !$identifier and return $identifier;
1402 238 100 66     868 unless (defined $type && $name) {
1403 200 100       1057 return $1 if $identifier =~ /^(\d+)$/;
1404 108 100       537 return $1 if $identifier =~ /^\"(.*)\"$/;
1405 56 50       118 return $1 if $identifier =~ /^\'(.*)\'$/;
1406 56 100       391 if ($identifier =~ /^([&\$\"]?)([A-Za-z_]\w*)$/) {
    50          
1407 42         125 ($type,$name) = ($1,$2);
1408             } elsif ($identifier =~ /^&(\w+)\((.*)\)$/) {
1409 14         62 ($type,$name,$args) = ('&',$1,$2);
1410             } else {
1411 0         0 print STDERR "Malformed identifier '$identifier'";
1412 0         0 return undef;
1413             }
1414             }
1415 94 50       198 $debug and print STDERR " [identifier_evaluate: type=$type name=$name]";
1416 94 100       270 if (!$type) {
    50          
    50          
1417 78 100       330 if (!defined $ovr->{$name}) {
    100          
    100          
    50          
    100          
    50          
1418             # print STDERR "!defined $name, undef_asis=$undef_asis";
1419 2 50       12 return ($undef_asis ? undef : $self->{default_undef_identifier} );
1420             } elsif (!ref $ovr->{$name}) {
1421 62         251 return $ovr->{$name};
1422             } elsif (ref $ovr->{$name} eq 'ARRAY') {
1423 4         18 return join($self->{list_delimiter}->{$name} ||
1424             $self->{list_delimiter}->{__default},
1425 4   66     18 @{ $ovr->{$name} });
1426             } elsif (ref $ovr->{$name} eq 'SCALAR') {
1427 0         0 return ${ $ovr->{$name} };
  0         0  
1428             } elsif (ref $ovr->{$name} eq 'HASH') {
1429 12   33     66 return join($self->{hash_delimiter}->{$name} ||
1430             $self->{hash_delimiter}->{__default},
1431 4         11 map { $_.
1432             ($self->{hash_specifier}->{$name} ||
1433             $self->{hash_specifier}->{__default}).
1434             $ovr->{$name}->{$_}
1435 4   33     27 } keys %{$ovr->{$name}}
1436             );
1437             } elsif (ref $ovr->{$name} eq 'CODE') {
1438 6 50       40 !$self->{eval_subroutine_refs} and return $self->{disabled_subref_identifier};
1439 6         34 return $self->evaluate_dynroutine($name,'',$ovr);
1440             }
1441 0         0 return $ovr->{$name};
1442             # } elsif ($type eq '&') {
1443             # return $ovr->{'&'.$name};
1444             } elsif ($type eq "\$") {
1445 0         0 return $ENV{$name};
1446             } elsif ($type eq '&') {
1447 16   100     44 $args ||= '';
1448 16 50       39 $debug and print STDERR " [returning \$self->evaluate_dynroutine($name,$args,$ovr)]";
1449 16 50       52 !$self->{eval_subroutine_refs} and return $self->{disabled_subref_identifier};
1450 16         55 return $self->evaluate_dynroutine($name,$args,$ovr);
1451             }
1452 0         0 return undef;
1453             }
1454              
1455             =item evaluate_dynroutine $name, $args, \%ovr
1456              
1457             Evalutes a routine referenced by a template. The general form gives the
1458             name of the routine in $name (if no such named routine is available,
1459             returns undef), any arguments as a scalar $args, and the key-sub list
1460             in $ovr.
1461              
1462             $args should be given as a scalar -- it will be parsed in
1463             B and the result cached against future use.
1464              
1465             =cut
1466              
1467             sub evaluate_dynroutine {
1468 22     22 1 39 my $self = shift;
1469 22         70 my ($name,$args,$ovr) = @_;
1470 22         27 my @real_args;
1471 22         42 my ($buf,$seg,$sseg) = ('');
1472 22         28 my $use_recursive_parse = 0;
1473 22         27 my %ra;
1474            
1475 22 50 33     118 $name && $ovr or return undef;
1476 22 100       15914 $name =~ /^bt_/ and return $self->evaluate_pragma(@_);
1477 16 50       53 $ovr->{$name} or return undef;
1478 16   100     65 $args ||= '';
1479 16 50       46 $debug && print STDERR " [evaluate_dynroutine: name=$name args=$args ovr=$ovr]";
1480 16 100       647 if ($args) {
1481 7 50       30 if ($self->{dynroutine_arg_cache}{$args}) {
1482 0         0 $args = $self->{dynroutine_arg_cache}{$args};
1483             } else {
1484 7         32 my $targs = $self->parse_dynroutine_args($args);
1485 7         22 $self->{dynroutine_arg_cache}{$args} = $targs;
1486 7         23 $args = $targs;
1487             }
1488             }
1489 16 100       53 if (ref $args eq 'ARRAY') {
1490 7         12 for (0..$#{$args}) {
  7         26  
1491 25 50       158 if ($args->[$_] eq '$_bt_dict') {
    50          
    50          
    50          
1492 0         0 $args->[$_] = $ovr;
1493             } elsif ($args->[$_] =~ /^\\(.*)$/) {
1494             # escaped anything
1495 0         0 $args->[$_] = $1;
1496             } elsif ($args->[$_] =~ /^\$([\$\&]?\w+)$/) {
1497             # scalar
1498 0         0 $args->[$_] = $self->identifier_evaluate($1,$ovr);
1499             } elsif ($args->[$_] =~ /^\$\{([^\}]+)\}$/) {
1500 0         0 $args->[$_] = $self->cond_evaluate($1,$ovr);
1501             }
1502             }
1503 7         14 @real_args = @{ $args };
  7         26  
1504             } else {
1505 9         20 @real_args = ();
1506             }
1507              
1508 16 100 100     105 if (@real_args and !(($#real_args+1) % 2)) {
1509 6 50       18 $debug and print STDERR " [right number of args to recurse, ref=".(ref $ovr->{$name})."]";
1510 6 50 33     35 if (ref $ovr->{$name} eq 'CODE' or
  1   33     1154  
      66        
1511             (ref $ovr->{$name} eq 'ARRAY' and
1512             $#{ $ovr->{$name} } == 2 and
1513             ref $ovr->{$name}->[1] eq 'CODE')) {
1514 6         30 %ra = @real_args;
1515 6 100       20 if ($ra{bt_template}) {
1516 1         5 $use_recursive_parse = 1;
1517             }
1518             # $debug and print STDERR " [use recursive_parse]";
1519             }
1520             }
1521              
1522             # print " [e_d: name=$name, ovr=$ovr ovr->name=$ovr->{$name}]";
1523             # ref $ovr->{$name} eq 'ARRAY' and $debug and print STDERR " [num=".$#{ $ovr->{$name} }."]";
1524 16 100 33     78 if (ref $ovr->{$name} eq 'CODE') {
  2 50       12  
1525 14         23 $buf = &{ $ovr->{$name} }(@real_args);
  14         78  
1526 14 50       108 $debug and print STDERR " [real_args=".join(',',@real_args)." n=$#real_args]";
1527 14 50       1010 !ref $buf and return $buf;
1528 0 0 0     0 if (ref $buf eq 'HASH' and $use_recursive_parse) {
1529 0 0       0 $debug and print STDERR " [would now recurse to parse subref output]";
1530              
1531             }
1532             } elsif (ref $ovr->{$name} eq 'ARRAY' and
1533             $#{ $ovr->{$name} } == 2) {
1534 2 50       16 if (!ref $ovr->{$name}->[0]) {
    50          
1535 0         0 $buf = $ovr->{$name}->[0];
1536 0 0       0 $debug and print STDERR " [started with scalar $buf]";
1537             } elsif (ref $ovr->{$name}->[0] eq 'CODE') {
1538 2         4 $seg = &{ $ovr->{$name}->[0] }(@real_args);
  2         15  
1539 2 50 66     19 if ($use_recursive_parse and ref $seg eq 'HASH') {
1540 0         0 $sseg = $self->parse($ra{bt_template},$seg,$ovr,
1541             { _bt_recurse_count =>
1542             $ovr->{_bt_recurse_count}+1 });
1543 0 0       0 if (ref $sseg eq 'SCALAR') {
    0          
1544 0         0 $buf = $$sseg;
1545             } elsif (!ref $sseg) {
1546 0         0 $buf = $sseg;
1547             }
1548             } else {
1549 2         6 $buf = $seg;
1550             }
1551             }
1552 2 50       14 if (!ref $ovr->{$name}->[1]) {
    50          
1553 0         0 $buf .= $ovr->{$name}->[1];
1554             } elsif (ref $ovr->{$name}->[1] eq 'CODE') {
1555 2         6 while ($seg = &{ $ovr->{$name}->[1] }(@real_args)) {
  7         35  
1556 5 100 66     87 if ($use_recursive_parse and ref $seg eq 'HASH') {
1557 3         30 $sseg = $self->parse($ra{bt_template},$seg,$ovr,
1558             { _bt_recurse_count =>
1559             $ovr->{_bt_recurse_count}+1 });
1560 3 50       25 if (ref $sseg eq 'SCALAR') {
    50          
1561 0         0 $buf .= $$sseg;
1562             } elsif (!ref $sseg) {
1563 3         10 $buf .= $sseg;
1564             }
1565             } else {
1566 2         5 $buf .= $seg;
1567             }
1568             }
1569             }
1570 2 50       27 if (!ref $ovr->{$name}->[2]) {
    50          
1571 0         0 $buf .= $ovr->{$name}->[2];
1572             } elsif (ref $ovr->{$name}->[2] eq 'CODE') {
1573             # $buf .= &{ $ovr->{$name}->[2] }(@real_args);
1574 2         4 $seg = &{ $ovr->{$name}->[2] }(@real_args);
  2         9  
1575 2 50 66     79 if ($use_recursive_parse and ref $seg eq 'HASH') {
1576 0         0 $sseg = $self->parse($ra{bt_template},$seg,$ovr,
1577             { _bt_recurse_count =>
1578             $ovr->{_bt_recurse_count}+1 });
1579 0         0 $buf .= $$sseg;
1580             } else {
1581 2         4 $buf .= $seg;
1582             }
1583             }
1584 2         15 return $buf;
1585             }
1586             }
1587              
1588             =item parse_dynroutine_args $argstr
1589              
1590             Pulls apart the argument string passed to a template-referenced
1591             dynamic routine, and returns a listref for it.
1592              
1593             Format tolerance is only minimally clever. The formats tolerated
1594             are, in any combination:
1595              
1596             word, word,
1597             word => word, word
1598             word => "word \"word\" 'word'"
1599             word => 'word "word"'
1600             word => "word\nword",
1601              
1602             In the first case, each word argument may contain anything but [,=>'"]
1603             (that is, ', ", =, or >; yes, that is not entirely proper).
1604             If you need to use any of those characters, put the arguments in
1605             quotes. Parsing with quotations is more accurate, but depends on
1606             lookbehind assertions and is accordingly slow (the parse
1607             results are cached, so this is mostly an issue in repetitive
1608             executions rather than use of many instances in one template).
1609              
1610             =cut
1611              
1612             sub parse_dynroutine_args {
1613 11     11 1 19 my $self = shift;
1614 11   50     46 my $argstr = shift || return [];
1615 11         25 my @args = ();
1616 11         15 my $x;
1617              
1618 11 100       37 if ($argstr =~ tr/\"\'/\"\'/) {
1619 2         19 while ($argstr =~ m/\s*([^,=>\"\']+?| # word arg (yes, the => in the class is bad
1620             (\"|\')(.*?(?
1621             )\s*(?:,|=>|$)/sgx) { # space, comma, =>
1622 14   66     45 $x = $3 || $1;
1623 14 50 50     43 $x eq "''" or $x eq '""' and $x = '' ;
1624 14         30 $x =~ s/(?
1625 14         77 push @args, $x;
1626             }
1627             } else {
1628 9         105 @args = split(/\s*(?:=>|,)\s*/,$argstr);
1629             }
1630             # warn "parse_args: [new: $argstr -> ".join('|',@args)."]";
1631             # warn "parse_args: vs [old: $argstr -> ".join('|',split(/\s*(?:=>|,)\s*/,$argstr))."]";
1632             # return [ split(/\s*(?:=>|,)\s*/,$argstr) ];
1633 11         52 \@args;
1634             }
1635              
1636             =item evaluate_pragma $name, $args, \%ovr
1637              
1638             =cut
1639              
1640             sub evaluate_pragma {
1641 6     6 1 10 my $self = shift;
1642 6         13 my ($name,$args,$ovr) = @_;
1643 6         8 my @real_args;
1644              
1645 6   50     18 $args ||= '';
1646 6 50 33     38 $name && $ovr or return undef;
1647 6 50       15 $debug && print STDERR " [evaluate_dynroutine: name=$name args=$args ovr=$ovr]";
1648 6 50       25 if ($args) {
1649 6 100       22 if ($self->{dynroutine_arg_cache}{$args}) {
1650 2         8 $args = $self->{dynroutine_arg_cache}{$args};
1651             } else {
1652 4         14 my $targs = $self->parse_dynroutine_args($args);
1653 4         13 $self->{dynroutine_arg_cache}{$args} = $targs;
1654 4         9 $args = $targs;
1655             }
1656             }
1657 6 50       28 if (ref $args eq 'ARRAY') {
1658 6         6 @real_args = @{ $args };
  6         21  
1659             } else {
1660 0         0 @real_args = ();
1661             }
1662 6 100 66     51 unless ($self->{pragma_enable}->{$name} &&
1663             ref $self->{pragma_functions}->{$name} eq 'CODE') {
1664 1 50       4 $debug && print STDERR "pragma $name is disabled or has no function reference (enable=$self->{pragma_enable}->{$name}, ref=$self->{pragma_functions}->{$name}";
1665 1         9 return $self->{disabled_pragma_identifier};
1666             }
1667             # print STDERR "pragma_enable->{$name} is true, calling prama";
1668 5         10 return &{ $self->{pragma_functions}->{$name} }($self,$ovr,@real_args);
  5         23  
1669             }
1670              
1671             =item is_identifier \$candidate
1672              
1673             Takes a reference to a scalar containing a potential identifier.
1674             In a scalar context, returns 1 or 0. In a list context, returns
1675             (type,name) where type is one of the identififer type designators
1676             (&, !, $, etc) and name is the remainder of the identifier.
1677              
1678             =cut
1679              
1680             sub is_identifier {
1681 212     212 1 253 my $self = shift;
1682 212         240 my $nr = shift;
1683              
1684 212 50       404 !defined $nr and return undef;
1685 212 50       408 !ref $nr and $nr = \$nr;
1686              
1687 212 50       435 $debug and print STDERR " [ checking nr=$$nr ]";
1688 212 100 100     3023 if (!$self->{reserved_words}->{$$nr} &&
1689             $$nr =~ /^%?([&\$]?)(\w+)%?$/) {
1690 42 50       84 $debug and print STDERR "[ $$nr is an identifier:($1,$2) ]";
1691 42 50       276 wantarray and return ($1,$2);
1692 0         0 return 1;
1693             # } else {
1694             # $debug and print STDERR " [ not identifier ]";
1695             }
1696 170 50       4918 wantarray and return ();
1697 0         0 return 0;
1698             }
1699              
1700              
1701             =item lex \$src
1702              
1703             Splits the specified source buffer into a series of tokens, returns
1704             a listref to the resulting lexicon. See B for the details.
1705              
1706             =cut
1707              
1708             sub lex {
1709 145     145 1 703 my $self = shift;
1710 145   50     324 my $src = shift || return;
1711 145         176 my ($inlen,$inblock,$pos);
1712 0         0 my ($prior,$opseq,$opcontent);
1713 0         0 my ($itype,$iname);
1714 145         210 my @lexicon = ();
1715 145         181 my $clevel = 0;
1716              
1717 145 50       1043 !ref $src and $src = \$src;
1718              
1719 7     7   96 use re 'taint';
  7         21  
  7         12837  
1720 145 50       611 $self->{compatibility_mode_0x} and
1721             $$src = $self->convert_template_0x_2x($$src);
1722 145 50       340 !$$src and return [];
1723            
1724 145   50     6013 $inlen = length($$src) || 0;
1725 145         194 $pos = 0;
1726 145         9213 LEXEME: while ($pos < $inlen) {
1727 230 50       1130 next LEXEME unless $$src =~ m/([^%]*)(%([^%]*)%)?/mg;
1728 230         340 $pos = pos($$src);
1729 230   100     1533 ($prior,$opseq,$opcontent) = ($1,$2 || '',$3 || '');
      100        
1730 230 100       468 if ($opseq eq '%%') {
1731 2         3 $prior .= '%';
1732 2         3 $opseq = '';
1733             }
1734              
1735 230         651 push @lexicon, [ $clevel, $prior, 0 ];
1736 230 100       971 next LEXEME unless $opseq;
1737             # if ($opseq =~ /^%(if |elsif |fi%)/) {
1738             # $debug and print STDERR " [ found std. conditional $opseq ]";
1739             # push @lexicon, [ ++$clevel, $opseq, 1 ];
1740             # next LEXEME;
1741             # } els
1742             # print STDERR " [opseq=$opseq]";
1743 212 100 66     1093 if (($itype,$iname) = $self->is_identifier(\$opseq)) {
    100 66        
1744 42 50       79 $debug and
1745             print STDERR " [ found identifier $itype,$iname ]";
1746 42         122 push @lexicon, [ $clevel, $opseq, 2, $itype, $iname ];
1747            
1748 42         147 next LEXEME;
1749             } elsif (($opcontent) &&
1750             ($opcontent !~ /^(if\s|elsif\s|fi$|else$)/) &&
1751             ($opcontent =~ tr/^A-Za-z0-9_/^A-Za-z0-9_/)) {
1752 84 50       169 $debug and
1753             print STDERR " [ found non-conditional operation $opcontent ]";
1754 84         244 push @lexicon, [ $clevel, $opseq, 6, $opcontent ];
1755 84         276 next LEXEME;
1756             }
1757 86 100       207 $clevel++ if $opseq =~ /^%if\s/;
1758 86         205 push @lexicon, [ $clevel, $opseq, 1 ];
1759 86 100       1255 $clevel-- if $opseq eq '%fi%';
1760             }
1761 145         372 \@lexicon;
1762             }
1763              
1764             =item load_from_file $filename
1765              
1766             Loads a template from the specified file. If use_file_cache is true,
1767             the file will be stored in the file cache (not necessary if caching
1768             is enabled for lexicons).
1769              
1770             This code is very trusting concerning its filename -- the only check
1771             performed is to strip leading <, >, | and + signs to try to ensure that
1772             the filehandle obtained is read-only. Trailing pipes will be left
1773             alone, so that "/path/to/binary|" may use the output from 'binary'.
1774              
1775             =cut
1776              
1777             sub load_from_file {
1778 48     48 1 59 my $self = shift;
1779 48   50     305 my $fn = shift || return undef;
1780 48         54 my ($b,$buf);
1781              
1782 48 50 33     177 if (!$self->{open_tainted_files} &&
1783             $self->is_tainted($fn)) {
1784 0         0 print STDERR "Text::BasicTemplate: load_from_file: '$fn' is tainted, can't open safely\n";
1785 0         0 return undef;
1786             }
1787 48 100       182 $self->{file_cache}{$fn} and return $self->{file_cache}{$fn};
1788 43         149 $fn =~ s/^[\+<>|]+//;
1789 43         52 $buf = '';
1790 43 50       1730 sysopen(TMPL,$fn,0) || do {
1791 0 0       0 $debug and print STDERR "Text::BasicTemplate::load_from_file($fn): $!";
1792 0         0 return undef;
1793             };
1794 43 50       311 $self->{use_flock} and flock(TMPL,LOCK_SH);
1795 43         382 while (sysread(TMPL,$b,4096)) {
1796 43         316 $buf .= $b;
1797             }
1798 43 50       252 $self->{use_flock} and flock(TMPL,LOCK_UN);
1799 43         421 close(TMPL);
1800 43         80 $buf .= substr($^X,0,0); # deliberately taint the contents
1801 43 50       213 $self->{use_file_cache} and $self->{file_cache}{$fn} = \$buf;
1802 43         155 \$buf;
1803             }
1804              
1805              
1806             ## pragma functions
1807              
1808             sub bt_include {
1809 4     4 1 7 my $self = shift;
1810 4   50     24 my $ovr = shift || {};
1811 4         9 my ($type,$file,$parse) = @_;
1812 4         4 my $buf;
1813              
1814 4 50 33     32 if ($type && !$file) {
1815 0         0 $file = $type;
1816 0         0 $type = 'file';
1817             }
1818 4   33     24 $parse = !($parse and $parse eq 'noparse');
1819            
1820 4 50 33     47 $type && $type =~ /^(file|virtual|semisecure)$/ && $file or
      33        
1821             return '[format: bt_include([ file | virtual | semisecure ], fn, [ noparse])]';
1822 4 50       23 if ($type eq 'semisecure') {
    100          
    50          
1823 7     7   61 no re 'taint';
  7         22  
  7         22455  
1824 0 0       0 if ($file =~ /^(\w[\w\-.]{0,254})$/) {
1825 0         0 $file = $1;
1826             } else {
1827 0         0 return "[bt_include: File '$file' does not match valid pattern in semisecure mode]";
1828             }
1829 0 0 0     0 if ($self->is_tainted($file) &&
1830             !$self->{bt_include_allow_tainted}) {
1831 0         0 return "[bt_include: semisecure filename $file is tainted, can't include]";
1832             }
1833 0 0       0 -e $file or return "[bt_include: semisecure file $file does not exist]";
1834 0 0       0 -f _ or return "[bt_include: semisecure file $file is not a regular file]";
1835 0 0       0 -r _ or return "[bt_include: semisecure file $file not readable]";
1836 0 0       0 $parse and return $self->parse($file,$ovr);
1837 0         0 $buf = $self->load_from_file($file);
1838 0         0 print STDERR "[buf=$buf for file=$file]";
1839 0 0       0 return ((ref $buf eq 'SCALAR') ? $$buf : "[bt_include: load_from_file returned nothing]");
1840             } elsif ($type eq 'virtual') {
1841 2 50 33     19 unless ($self->{include_document_root} || $ENV{DOCUMENT_ROOT}) {
1842 0         0 return '[bt_include: No document root supplied in virtual mode]';
1843             }
1844 2 50 33     8 if ($self->is_tainted($file) &&
1845             !$self->{bt_include_allow_tainted}) {
1846 0         0 return "[bt_include: virtual filename $file is tainted, can't include]";
1847             }
1848 2   33     11 $file = ($self->{include_document_root} || $ENV{DOCUMENT_ROOT}) .
1849             '/' . $file;
1850 2 50       70 -e $file or return "[bt_include: virtual file $file does not exist]";
1851 2 50       5 -f _ or return "[bt_include: virtual file $file is not a regular file]";
1852 2 50       10 -r _ or return "[bt_include: virtual file $file not readable]";
1853 2 50       16 $parse and return $self->parse($file,$ovr);
1854 0         0 $buf = $self->load_from_file($file);
1855 0 0       0 return ((ref $buf eq 'SCALAR') ? $$buf : "[bt_include: load_from_file returned nothing]");
1856             } elsif ($type eq 'file') {
1857 2 50 33     8 if ($self->is_tainted($file) &&
1858             !$self->{bt_include_allow_tainted}) {
1859 0         0 return "[bt_include: filename $file is tainted, can't include]";
1860             }
1861 2 50       80 -e $file or return "[bt_include: file $file does not exist]";
1862 2 50       9 -f _ or return "[bt_include: file $file is not a regular file]";
1863 2 50       12 -r _ or return "[bt_include: file $file not readable]";
1864 2 50       29 $parse and return $self->parse($file,$ovr);
1865 0         0 $buf = $self->load_from_file($file);
1866 0         0 print STDERR "[buf=$buf for file=$file]";
1867 0 0       0 return ((ref $buf eq 'SCALAR') ? $$buf : "[bt_include: load_from_file returned nothing]");
1868             } else {
1869 0         0 return "[bt_include: include type '$type' not known]";
1870             }
1871             }
1872              
1873             =item bt_exec
1874              
1875             =cut
1876              
1877              
1878             sub bt_exec {
1879 1     1 1 3 my $self = shift;
1880 1   50     8 my $ovr = shift || {};
1881 1         3 my ($type,$command,$parse) = @_;
1882 1         2 my $buf;
1883              
1884 1 50 33     50 $type && $type =~ /^(cmd|cgi)$/ && $command or
      33        
1885             return '[format: bt_exec({ cmd | file }, command [, parse ])]';
1886 1   50     4 $parse ||= 0;
1887 1 50       5 if ($type eq 'cmd') {
    0          
1888 1 50       15944 open(IC,$command.'|') ||
1889             return "[bt_exec: Couldn't exec $command: $!]";
1890 1         64 $buf = join(',',);
1891 1         36 close IC;
1892 1 50 33     36 if ($parse && $buf) {
1893 1         31 $buf = $self->parse(\$buf,$ovr);
1894             }
1895 1         44 return $buf;
1896             } elsif ($type eq 'cgi') {
1897 0 0       0 open(IC,$command.'|') ||
1898             return "[bt_exec: Couldn't exec $command: $!]";
1899 0         0 while () {
1900 0         0 chomp;
1901 0 0       0 last if !$_;
1902             }
1903 0         0 $buf = join(',',);
1904 0         0 close IC;
1905 0 0 0     0 if ($parse && $buf) {
1906 0         0 $buf = $self->parse(\$buf,$ovr);
1907             }
1908 0         0 return $buf;
1909             }
1910             }
1911              
1912             =item dump_lexicon \@lexicon [ $start_pos [ $end_pos ] ]
1913              
1914             Returns a dump of the given lexicon. Principally used for debugging the
1915             module, or if you need to optimize templates to save lexical storage.
1916             If $start_pos/$end_pos are given, only that range of the lexical array
1917             is dumped.
1918              
1919             =cut
1920              
1921             sub dump_lexicon {
1922 0     0 1 0 my $self = shift;
1923 0         0 my $L = shift;
1924 0         0 my $l;
1925 0         0 my ($start_pos,$end_pos) = @_;
1926 0         0 my $x;
1927 0         0 my $b = '';
1928              
1929              
1930 0 0       0 ref $L eq 'ARRAY' or return undef;
1931 0   0     0 for (my $i=$start_pos || 0; $i<=($end_pos || $#{$L}); $i++) {
      0        
1932 0         0 $l = $L->[$i];
1933 0         0 $b .= "[ $i: L$l->[0] $lexeme_types{$l->[2]}";
1934 0         0 $x = $l->[1];
1935 0         0 $x =~ s/\n/\\n/g;
1936 0         0 $x =~ s/\t/\\t/g;
1937 0         0 $x =~ s/\r/\\r/g;
1938 0         0 $b .= " '$x'";
1939 0 0       0 defined $l->[3] and $b .= " '$l->[3]'";
1940 0 0       0 defined $l->[4] and $b .= " '$l->[4]'";
1941 0         0 $b .= " ]\n";
1942             }
1943 0         0 $b;
1944             }
1945              
1946             =item dump_stack \@stack
1947              
1948             Dumps the contents of a conditional-eval stack, which consists of a list of listrefs
1949             containing [ type, value ], type being one of the lexeme_types, value being either
1950             the identififer or an operator, depending on the type.
1951              
1952             =cut
1953              
1954             sub dump_stack {
1955 0     0 1 0 my $self = shift;
1956 0         0 my $sr = shift;
1957 0   0     0 my $terse = shift || 0;
1958 0         0 my $S;
1959 0         0 my $b = '';
1960 0         0 my $x = 0;
1961              
1962 0 0       0 ref $sr eq 'ARRAY' or return undef;
1963 0         0 for $S (@{$sr}) {
  0         0  
1964 0 0       0 if ($terse) {
1965 0 0       0 $b .= ',' if $x++;
1966 0         0 $b .= "$S->[1]";
1967             } else {
1968 0         0 $b .= "{ $lexeme_types{$S->[0]}, $S->[1] }";
1969             }
1970             }
1971 0         0 $b;
1972             }
1973              
1974             =item list_lexicon_cache
1975              
1976             Lists the lexicons cached for files/scalars/etc.
1977              
1978             =cut
1979              
1980             sub list_lexicon_cache {
1981 1     1 1 20 my $self = shift;
1982              
1983 1         1 keys %{$self->{lexicon_cache}};
  1         4  
1984             }
1985              
1986             =item list_file_cache
1987              
1988             Lists the files cached in the file cache. Empty unless use_file_cache is
1989             true.
1990              
1991             =cut
1992              
1993             sub list_file_cache {
1994 0     0 1 0 keys %{$_[0]->{file_cache}};
  0         0  
1995             }
1996              
1997             =item list_cond2rpn_cache
1998              
1999             Lists the conditional-to-RPN conversion cache. Empty if B
2000             is false.
2001              
2002             =cut
2003              
2004             sub list_cond2rpn_cache {
2005 0     0 1 0 keys %{$_[0]->{cond2rpn_cache}};
  0         0  
2006             }
2007              
2008             =item list_fullcond_cache
2009              
2010             Lists the contents of the conditional evaluation cache. Empty unless
2011             B is set true.
2012              
2013             =cut
2014              
2015             sub list_fullcond_cache {
2016 0     0 1 0 keys %{$_[0]->{fullcond_cache}};
  0         0  
2017             }
2018              
2019             =item taint_enabled
2020              
2021             Tries to work out if taint checking is enabled, so that the right things
2022             can be enabled/disabled by new().
2023              
2024             =cut
2025              
2026             sub taint_enabled {
2027 7     7 1 16 return not eval { my $x = $^X, kill 0; $x };
  7         84  
  7         35  
2028             }
2029              
2030             =item is_tainted SCALAR
2031              
2032             Returns true if taint checking is enabled and the specified
2033             variable is tainted.
2034              
2035             =cut
2036              
2037             sub is_tainted {
2038 52 50   52 1 139 return undef unless defined $_[1];
2039 52         111 return not eval { my $x = $_[1], kill 0; $x };
  52         167  
  52         244  
2040             }
2041              
2042              
2043             =item debug DEBUGLEVEL
2044              
2045             Activates debugging output.
2046              
2047             =cut
2048              
2049             sub debug {
2050 0     0 1 0 shift;
2051 0         0 $debug = shift;
2052             }
2053              
2054             =item purge_lexicon_cache
2055              
2056             =item purge_cond2rpn_cache
2057              
2058             =item purge_fullcond_cache
2059              
2060             =item purge_file_cache
2061              
2062             Purges the given cache.
2063              
2064             =cut
2065              
2066 2     2 1 7 sub purge_lexicon_cache { $_[0]->{lexicon_cache} = (); }
2067 2     2 1 6 sub purge_cond2rpn_cache { $_[0]->{cond2rpn_cache} = (); }
2068 147     147 1 426 sub purge_fullcond_cache { $_[0]->{fullcond_cache} = (); }
2069 2     2 1 6 sub purge_file_cache { $_[0]->{file_cache} = (); }
2070              
2071              
2072             ## backwards-compatibility functions
2073              
2074              
2075             =item list_cache
2076              
2077             Compatibility function for BasicTemplate 0.x; synonym for B
2078              
2079             =cut
2080              
2081 0     0 1 0 sub list_cache { $_[0]->list_lexicon_cache };
2082              
2083              
2084             =item push, parse_push
2085              
2086             Compatibility functions for BasicTemplate 0.x; synonym for B.
2087              
2088             =cut
2089              
2090 7     7 1 652 sub push { my $self = shift; $self->parse(@_) };
  7         21  
2091 0     0 1 0 sub parse_push { my $self = shift; $self->parse(@_) };
  0         0  
2092              
2093             =item print, parse_print
2094              
2095             Compatibility functions for BasicTempltae 0.x
2096              
2097             =cut
2098              
2099 0     0 1 0 sub print { my $self = shift; print $self->parse(@_); };
  0         0  
2100 0     0 1 0 sub parse_print { my $self = shift; print $self->parse(@_); };
  0         0  
2101              
2102             =item purge_cache
2103              
2104             Compatibility function for BasicTemplate 0.x; purges all
2105             applicable caches.
2106              
2107             =cut
2108              
2109             sub purge_cache {
2110 2     2 1 728 $_[0]->purge_lexicon_cache;
2111 2         10 $_[0]->purge_cond2rpn_cache;
2112 2         11 $_[0]->purge_fullcond_cache;
2113 2         42 $_[0]->purge_file_cache;
2114 2         8 1;
2115             }
2116              
2117             =item uncache FILE
2118              
2119             Compatibility function for BasicTemplate 0.x; purges the
2120             specified file from the file and lexicon caches.
2121              
2122             =cut
2123              
2124             sub uncache {
2125 0     0 1 0 $_[0]->purge_lexicon_cache($_[1]);
2126 0         0 $_[0]->purge_file_cache($_[1]);
2127             }
2128              
2129             =item convert_template_0x_2x $buffer
2130              
2131             Backwards-compatibility function for BasicTemplate 0.x; converts a
2132             template constructed for v0.x to v2.x. Used internally for conversions
2133             on-the-fly in backwards-compatible mode.
2134              
2135             Note that this method will have no effect unless the 0.x template
2136             contains conditionals -- simple %key% substitutions are the same in
2137             both versions.
2138              
2139             =cut
2140              
2141             sub convert_template_0x_2x {
2142 145     145 1 182 my $self = shift;
2143 145   50     368 my $buf = shift || return undef;
2144 145         191 my ($lvalue,$operator,$operand,$aoperand,
2145             $aoperator,$truesub,$atruesub,
2146             $falsesub,$afalsesub);
2147              
2148 145 50       311 ref $buf eq 'SCALAR' and $buf = $$buf;
2149 145 50       266 !$buf and return '';
2150              
2151 7     7   69 use re 'taint';
  7         14  
  7         6034  
2152              
2153             # print STDERR "Pbuf=$buf\n";
2154             # $buf =~ s/([^%])%([^%\w\s?!])/$1%%$2/g;
2155              
2156             #
2157              
2158             # does it have anything that looks 2.0-ish in it?
2159 145 100       929 $buf =~ m/(%if\s+[^%]+%|%&\w+\([^\)]*\)%)/gm and do {
2160             # warn "convert_template_0x_2x(): matched $1, assuming new template";
2161 33         124 return $buf;
2162             };
2163              
2164             # does it use 0.x-style conditionals?
2165 112 100       594 $buf =~ m/%\?|/i) {
2170             # ($itype,$ifn) = (lc $1,$2);
2171             # # more horrible hack -- parses %key% in the filename (-ian)
2172             # while ($itype =~ /%(.*?)%/g) {
2173             # $self->{compat_0x_ovr} and
2174             # defined $self->{compat_0x_ovr}->{$1} and
2175             # $itype =~ s/\Q$1\E/$self->{compat_0x_ovr}->{$1};
2176             # }
2177             # }
2178              
2179             # without the horrible hack:
2180 10         63 $buf =~ s//%&bt_include($1,$2)%/g;
2181              
2182             # print STDERR "3buf=[$buf]\n";
2183              
2184 10         58 while ($buf =~ m/%\?([\w\.\-]+)\s*(==?|!=)\s*([^%]*)%([^%]*)%([^%]*)%/gm) {
2185 8         30 ($lvalue,$operator,$operand,$truesub,$falsesub) =
2186             ($1,$2,$3,$4,$5);
2187 8         14 ($atruesub,$afalsesub) = ($truesub,$falsesub);
2188 8 50       16 if ($operand =~ /^{(\w+)}$/) {
2189 0         0 $aoperand = $1;
2190             } else {
2191 8         16 $aoperand = "\"$operand\"";
2192             }
2193 8 50       15 $aoperator = ($operator eq '!=') ? ' ne ' : ' eq ';
2194             # $operand =~ s/^{(\w+)}$/$1/g;
2195 8         14 $atruesub =~ s/{(\w+)}/%$1%/g;
2196 8         16 $afalsesub =~ s/{(\w+)}/%$1%/g;
2197              
2198             # print STDERR "lvalue=$lvalue operator=$operator operand=$operand truesub=$truesub falsesub=$falsesub\n";
2199            
2200             # print STDERR "$buf =~ s/%\?\s*$lvalue\s*$operator\s*$operand%$truesub%$falsesub%/%if $lvalue$operator$operand%$truesub%else%$falsesub%fi%/xg;\n";
2201            
2202 8         272 $buf =~ s/%\?\s*\Q$lvalue\E\s*\Q$operator\E\s*\Q$operand\E\s*%\Q$truesub%$falsesub%\E/%if $lvalue$aoperator$aoperand%$atruesub%else%$afalsesub%fi%/gm;
2203             }
2204              
2205             # $buf =~ s/([^%]|^)%([,.\'\"<>\[\]{}()@\#\$\^&*])(?!bt_)/$1%%$2/g;
2206             # $buf =~ s/([ =\"]\d+)%([,.\'\"<>\[\]{}()@\#\$\^&*])(?!bt_)/$1%%$2/g;
2207             # print STDERR "backconvert[$buf]";
2208 10         29 $buf;
2209             }
2210              
2211             1;
2212              
2213             __END__