← Index
NYTProf Performance Profile   « line view »
For starman worker -M FindBin --max-requests 50 --workers 2 --user=kohadev-koha --group kohadev-koha --pid /var/run/koha/kohadev/plack.pid --daemonize --access-log /var/log/koha/kohadev/plack.log --error-log /var/log/koha/kohadev/plack-error.log -E deployment --socket /var/run/koha/kohadev/plack.sock /etc/koha/sites/kohadev/plack.psgi
  Run on Fri Jan 8 14:31:06 2016
Reported on Fri Jan 8 14:33:30 2016

Filename/usr/lib/x86_64-linux-gnu/perl5/5.20/Template/Parser.pm
StatementsExecuted 94669 statements in 76.0ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
4011156ms231msTemplate::Parser::::_parseTemplate::Parser::_parse
401148.9ms107msTemplate::Parser::::split_textTemplate::Parser::split_text
9731126.9ms36.1msTemplate::Parser::::tokenise_directiveTemplate::Parser::tokenise_directive
36169119.5ms19.5msTemplate::Parser::::CORE:substTemplate::Parser::CORE:subst (opcode)
11114.9ms15.0msTemplate::Parser::::BEGIN@41Template::Parser::BEGIN@41
40119.89ms348msTemplate::Parser::::parseTemplate::Parser::parse
5379719.54ms9.54msTemplate::Parser::::CORE:matchTemplate::Parser::CORE:match (opcode)
1113.88ms3.99msTemplate::Parser::::BEGIN@40Template::Parser::BEGIN@40
641113.62ms4.13msTemplate::Parser::::locationTemplate::Parser::location
2843112.67ms2.67msTemplate::Parser::::__ANON__[:874]Template::Parser::__ANON__[:874]
3932512.62ms2.62msTemplate::Parser::::CORE:regcompTemplate::Parser::CORE:regcomp (opcode)
411302µs523µsTemplate::Parser::::newTemplate::Parser::new
4121147µs147µsTemplate::Parser::::CORE:qrTemplate::Parser::CORE:qr (opcode)
1311110µs182µsTemplate::Parser::::leave_blockTemplate::Parser::leave_block
41176µs88µsTemplate::Parser::::interpolate_textTemplate::Parser::interpolate_text
41174µs74µsTemplate::Parser::::new_styleTemplate::Parser::new_style
131173µs73µsTemplate::Parser::::block_labelTemplate::Parser::block_label
131150µs50µsTemplate::Parser::::enter_blockTemplate::Parser::enter_block
11130µs153µsTemplate::Parser::::BEGIN@39Template::Parser::BEGIN@39
11119µs32µsTemplate::Parser::::BEGIN@35Template::Parser::BEGIN@35
11119µs66µsTemplate::Parser::::BEGIN@44Template::Parser::BEGIN@44
11114µs28µsTemplate::Parser::::BEGIN@46Template::Parser::BEGIN@46
11112µs21µsTemplate::Parser::::BEGIN@36Template::Parser::BEGIN@36
11112µs68µsTemplate::Parser::::BEGIN@37Template::Parser::BEGIN@37
1119µs26µsTemplate::Parser::::BEGIN@45Template::Parser::BEGIN@45
1110s0sTemplate::Parser::::BEGIN@47Template::Parser::BEGIN@47
0000s0sTemplate::Parser::::_dumpTemplate::Parser::_dump
0000s0sTemplate::Parser::::_parse_errorTemplate::Parser::_parse_error
0000s0sTemplate::Parser::::add_metadataTemplate::Parser::add_metadata
0000s0sTemplate::Parser::::define_blockTemplate::Parser::define_block
0000s0sTemplate::Parser::::in_blockTemplate::Parser::in_block
0000s0sTemplate::Parser::::old_styleTemplate::Parser::old_style
0000s0sTemplate::Parser::::pop_defblockTemplate::Parser::pop_defblock
0000s0sTemplate::Parser::::push_defblockTemplate::Parser::push_defblock
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1#============================================================= -*-Perl-*-
2#
3# Template::Parser
4#
5# DESCRIPTION
6# This module implements a LALR(1) parser and assocated support
7# methods to parse template documents into the appropriate "compiled"
8# format. Much of the parser DFA code (see _parse() method) is based
9# on Francois Desarmenien's Parse::Yapp module. Kudos to him.
10#
11# AUTHOR
12# Andy Wardley <abw@wardley.org>
13#
14# COPYRIGHT
15# Copyright (C) 1996-2007 Andy Wardley. All Rights Reserved.
16#
17# This module is free software; you can redistribute it and/or
18# modify it under the same terms as Perl itself.
19#
20# The following copyright notice appears in the Parse::Yapp
21# documentation.
22#
23# The Parse::Yapp module and its related modules and shell
24# scripts are copyright (c) 1998 Francois Desarmenien,
25# France. All rights reserved.
26#
27# You may use and distribute them under the terms of either
28# the GNU General Public License or the Artistic License, as
29# specified in the Perl README file.
30#
31#============================================================================
32
33package Template::Parser;
34
35244µs
# spent 32µs (19+13) within Template::Parser::BEGIN@35 which was called: # once (19µs+13µs) by Template::Config::load at line 35
use strict;
# spent 32µs making 1 call to Template::Parser::BEGIN@35 # spent 13µs making 1 call to strict::import
36231µs
# spent 21µs (12+9) within Template::Parser::BEGIN@36 which was called: # once (12µs+9µs) by Template::Config::load at line 36
use warnings;
# spent 21µs making 1 call to Template::Parser::BEGIN@36 # spent 9µs making 1 call to warnings::import
372125µs
# spent 68µs (12+57) within Template::Parser::BEGIN@37 which was called: # once (12µs+57µs) by Template::Config::load at line 37
use base 'Template::Base';
# spent 68µs making 1 call to Template::Parser::BEGIN@37 # spent 57µs making 1 call to base::import
38
392277µs
# spent 153µs (30+124) within Template::Parser::BEGIN@39 which was called: # once (30µs+124µs) by Template::Config::load at line 39
use Template::Constants qw( :status :chomp );
# spent 153µs making 1 call to Template::Parser::BEGIN@39 # spent 124µs making 1 call to Exporter::import
4013.99ms
# spent 3.99ms (3.88+107µs) within Template::Parser::BEGIN@40 which was called: # once (3.88ms+107µs) by Template::Config::load at line 40
use Template::Directive;
# spent 3.99ms making 1 call to Template::Parser::BEGIN@40
41115.0ms
# spent 15.0ms (14.9+47µs) within Template::Parser::BEGIN@41 which was called: # once (14.9ms+47µs) by Template::Config::load at line 41
use Template::Grammar;
# spent 15.0ms making 1 call to Template::Parser::BEGIN@41
42
43# parser state constants
442114µs
# spent 66µs (19+47) within Template::Parser::BEGIN@44 which was called: # once (19µs+47µs) by Template::Config::load at line 44
use constant CONTINUE => 0;
# spent 66µs making 1 call to Template::Parser::BEGIN@44 # spent 47µs making 1 call to constant::import
45243µs
# spent 26µs (9+17) within Template::Parser::BEGIN@45 which was called: # once (9µs+17µs) by Template::Config::load at line 45
use constant ACCEPT => 1;
# spent 26µs making 1 call to Template::Parser::BEGIN@45 # spent 17µs making 1 call to constant::import
46243µs
# spent 28µs (14+14) within Template::Parser::BEGIN@46 which was called: # once (14µs+14µs) by Template::Config::load at line 46
use constant ERROR => 2;
# spent 28µs making 1 call to Template::Parser::BEGIN@46 # spent 14µs making 1 call to constant::import
4720s
# spent 0s within Template::Parser::BEGIN@47 which was called: # once (0s+0s) by Template::Config::load at line 47
use constant ABORT => 3;
# spent 0s making 1 call to Template::Parser::BEGIN@47 # spent 0s making 1 call to constant::import
48
49our $VERSION = 2.89;
50our $DEBUG = 0 unless defined $DEBUG;
51our $ERROR = '';
52
53
54#========================================================================
55# -- COMMON TAG STYLES --
56#========================================================================
57
58our $TAG_STYLE = {
59 'default' => [ '\[%', '%\]' ],
60 'template1' => [ '[\[%]%', '%[\]%]' ],
61 'metatext' => [ '%%', '%%' ],
62 'html' => [ '<!--', '-->' ],
63 'mason' => [ '<%', '>' ],
64 'asp' => [ '<%', '%>' ],
65 'php' => [ '<\?', '\?>' ],
66 'star' => [ '\[\*', '\*\]' ],
67};
68$TAG_STYLE->{ template } = $TAG_STYLE->{ tt2 } = $TAG_STYLE->{ default };
69
70
71our $DEFAULT_STYLE = {
72 START_TAG => $TAG_STYLE->{ default }->[0],
73 END_TAG => $TAG_STYLE->{ default }->[1],
74# TAG_STYLE => 'default',
75 ANYCASE => 0,
76 INTERPOLATE => 0,
77 PRE_CHOMP => 0,
78 POST_CHOMP => 0,
79 V1DOLLAR => 0,
80 EVAL_PERL => 0,
81};
82
83our $QUOTED_ESCAPES = {
84 n => "\n",
85 r => "\r",
86 t => "\t",
87};
88
89# note that '-' must come first so Perl doesn't think it denotes a range
9014µsour $CHOMP_FLAGS = qr/[-=~+]/;
# spent 4µs making 1 call to Template::Parser::CORE:qr
91
- -
94#========================================================================
95# ----- PUBLIC METHODS -----
96#========================================================================
97
98#------------------------------------------------------------------------
99# new(\%config)
100#
101# Constructor method.
102#------------------------------------------------------------------------
103
104
# spent 523µs (302+221) within Template::Parser::new which was called 4 times, avg 131µs/call: # 4 times (302µs+221µs) by Template::Config::parser at line 103 of Template/Config.pm, avg 131µs/call
sub new {
1051700ns my $class = shift;
10613µs my $config = $_[0] && ref($_[0]) eq 'HASH' ? shift(@_) : { @_ };
10711µs my ($tagstyle, $debug, $start, $end, $defaults, $grammar, $hash, $key, $udef);
108
109 my $self = bless {
110 START_TAG => undef,
111 END_TAG => undef,
112 TAG_STYLE => 'default',
113 ANYCASE => 0,
114 INTERPOLATE => 0,
115 PRE_CHOMP => 0,
116 POST_CHOMP => 0,
117 V1DOLLAR => 0,
118 EVAL_PERL => 0,
119 FILE_INFO => 1,
120 GRAMMAR => undef,
121 _ERROR => '',
122 IN_BLOCK => [ ],
123 TRACE_VARS => $config->{ TRACE_VARS },
124119µs FACTORY => $config->{ FACTORY } || 'Template::Directive',
125 }, $class;
126
127 # update self with any relevant keys in config
12815µs foreach $key (keys %$self) {
129155µs $self->{ $key } = $config->{ $key } if defined $config->{ $key };
130 }
13112µs $self->{ FILEINFO } = [ ];
132
133 # DEBUG config item can be a bitmask
13411µs if (defined ($debug = $config->{ DEBUG })) {
135 $self->{ DEBUG } = $debug & ( Template::Constants::DEBUG_PARSER
136 | Template::Constants::DEBUG_FLAGS );
137 $self->{ DEBUG_DIRS } = $debug & Template::Constants::DEBUG_DIRS;
138 }
139 # package variable can be set to 1 to support previous behaviour
140 elsif ($DEBUG == 1) {
141 $self->{ DEBUG } = Template::Constants::DEBUG_PARSER;
142 $self->{ DEBUG_DIRS } = 0;
143 }
144 # otherwise let $DEBUG be a bitmask
145 else {
1461900ns $self->{ DEBUG } = $DEBUG & ( Template::Constants::DEBUG_PARSER
147 | Template::Constants::DEBUG_FLAGS );
14812µs $self->{ DEBUG_DIRS } = $DEBUG & Template::Constants::DEBUG_DIRS;
149 }
150
15111µs $grammar = $self->{ GRAMMAR } ||= do {
15211µs require Template::Grammar;
153110µs434µs Template::Grammar->new();
# spent 34µs making 4 calls to Template::Grammar::new, avg 9µs/call
154 };
155
156 # instantiate a FACTORY object
15712µs unless (ref $self->{ FACTORY }) {
1581400ns my $fclass = $self->{ FACTORY };
159 $self->{ FACTORY } = $self->{ FACTORY }->new(
160 NAMESPACE => $config->{ NAMESPACE }
161 )
16219µs4113µs || return $class->error($self->{ FACTORY }->error());
# spent 113µs making 4 calls to Template::Base::new, avg 28µs/call
163 }
164
165 # load grammar rules, states and lex table
16612µs @$self{ qw( LEXTABLE STATES RULES ) }
167 = @$grammar{ qw( LEXTABLE STATES RULES ) };
168
16915µs474µs $self->new_style($config)
# spent 74µs making 4 calls to Template::Parser::new_style, avg 19µs/call
170 || return $class->error($self->error());
171
17214µs return $self;
173}
174
175#-----------------------------------------------------------------------
176# These methods are used to track nested IF and WHILE blocks. Each
177# generated if/while block is given a label indicating the directive
178# type and nesting depth, e.g. FOR0, WHILE1, FOR2, WHILE3, etc. The
179# NEXT and LAST directives use the innermost label, e.g. last WHILE3;
180#-----------------------------------------------------------------------
181
182
# spent 50µs within Template::Parser::enter_block which was called 13 times, avg 4µs/call: # 13 times (50µs+0s) by Template::Grammar::__ANON__[Parser.yp:167] at line 167 of errors/Parser.yp, avg 4µs/call
sub enter_block {
18343µs my ($self, $name) = @_;
18442µs my $blocks = $self->{ IN_BLOCK };
185412µs push(@{ $self->{ IN_BLOCK } }, $name);
186}
187
188
# spent 182µs (110+73) within Template::Parser::leave_block which was called 13 times, avg 14µs/call: # 13 times (110µs+73µs) by Template::Grammar::__ANON__[Parser.yp:168] at line 168 of errors/Parser.yp, avg 14µs/call
sub leave_block {
18942µs my $self = shift;
190410µs1373µs my $label = $self->block_label;
# spent 73µs making 13 calls to Template::Parser::block_label, avg 6µs/call
19144µs pop(@{ $self->{ IN_BLOCK } });
192411µs return $label;
193}
194
195sub in_block {
196 my ($self, $name) = @_;
197 my $blocks = $self->{ IN_BLOCK };
198 return @$blocks && $blocks->[-1] eq $name;
199}
200
201
# spent 73µs within Template::Parser::block_label which was called 13 times, avg 6µs/call: # 13 times (73µs+0s) by Template::Parser::leave_block at line 190, avg 6µs/call
sub block_label {
20242µs my ($self, $prefix, $suffix) = @_;
20343µs my $blocks = $self->{ IN_BLOCK };
20447µs my $name = @$blocks
205 ? $blocks->[-1] . scalar @$blocks
206 : undef;
207422µs return join('', grep { defined $_ } $prefix, $name, $suffix);
208}
209
- -
212#------------------------------------------------------------------------
213# new_style(\%config)
214#
215# Install a new (stacked) parser style. This feature is currently
216# experimental but should mimic the previous behaviour with regard to
217# TAG_STYLE, START_TAG, END_TAG, etc.
218#------------------------------------------------------------------------
219
220
# spent 74µs within Template::Parser::new_style which was called 4 times, avg 19µs/call: # 4 times (74µs+0s) by Template::Parser::new at line 169, avg 19µs/call
sub new_style {
2211400ns my ($self, $config) = @_;
22212µs my $styles = $self->{ STYLE } ||= [ ];
2231300ns my ($tagstyle, $tags, $start, $end, $key);
224
225 # clone new style from previous or default style
22615µs my $style = { %{ $styles->[-1] || $DEFAULT_STYLE } };
227
228 # expand START_TAG and END_TAG from specified TAG_STYLE
2291800ns if ($tagstyle = $config->{ TAG_STYLE }) {
230 return $self->error("Invalid tag style: $tagstyle")
231 unless defined ($tags = $TAG_STYLE->{ $tagstyle });
232 ($start, $end) = @$tags;
233 $config->{ START_TAG } ||= $start;
234 $config->{ END_TAG } ||= $end;
235 }
236
23713µs foreach $key (keys %$DEFAULT_STYLE) {
23882µs $style->{ $key } = $config->{ $key } if defined $config->{ $key };
239 }
24011µs push(@$styles, $style);
24113µs return $style;
242}
243
244
245#------------------------------------------------------------------------
246# old_style()
247#
248# Pop the current parser style and revert to the previous one. See
249# new_style(). ** experimental **
250#------------------------------------------------------------------------
251
252sub old_style {
253 my $self = shift;
254 my $styles = $self->{ STYLE };
255 return $self->error('only 1 parser style remaining')
256 unless (@$styles > 1);
257 pop @$styles;
258 return $styles->[-1];
259}
260
261
262#------------------------------------------------------------------------
263# parse($text, $data)
264#
265# Parses the text string, $text and returns a hash array representing
266# the compiled template block(s) as Perl code, in the format expected
267# by Template::Document.
268#------------------------------------------------------------------------
269
270
# spent 348ms (9.89+338) within Template::Parser::parse which was called 40 times, avg 8.70ms/call: # 40 times (9.89ms+338ms) by Template::Provider::_compile at line 844 of Template/Provider.pm, avg 8.70ms/call
sub parse {
271108µs my ($self, $text, $info) = @_;
272103µs my ($tokens, $block);
273
274 $info->{ DEBUG } = $self->{ DEBUG_DIRS }
2751021µs unless defined $info->{ DEBUG };
276
277# print "info: { ", join(', ', map { "$_ => $info->{ $_ }" } keys %$info), " }\n";
278
279 # store for blocks defined in the template (see define_block())
2801013µs my $defblock = $self->{ DEFBLOCK } = { };
2811015µs my $metadata = $self->{ METADATA } = [ ];
282108µs my $variables = $self->{ VARIABLES } = { };
283107µs $self->{ DEFBLOCKS } = [ ];
284
285109µs $self->{ _ERROR } = '';
286
287 # split file into TEXT/DIRECTIVE chunks
2881030µs40107ms $tokens = $self->split_text($text)
# spent 107ms making 40 calls to Template::Parser::split_text, avg 2.68ms/call
289 || return undef; ## RETURN ##
290
2911013µs push(@{ $self->{ FILEINFO } }, $info);
292
293 # parse chunks
2941031µs40231ms $block = $self->_parse($tokens, $info);
# spent 231ms making 40 calls to Template::Parser::_parse, avg 5.77ms/call
295
296108µs pop(@{ $self->{ FILEINFO } });
297
298103µs return undef unless $block; ## RETURN ##
299
300 $self->debug("compiled main template document block:\n$block")
3011013µs if $self->{ DEBUG } & Template::Constants::DEBUG_PARSER;
302
303 return {
3041082µs BLOCK => $block,
305 DEFBLOCKS => $defblock,
306 VARIABLES => $variables,
307 METADATA => { @$metadata },
308 };
309}
310
- -
313#------------------------------------------------------------------------
314# split_text($text)
315#
316# Split input template text into directives and raw text chunks.
317#------------------------------------------------------------------------
318
319
# spent 107ms (48.9+58.3) within Template::Parser::split_text which was called 40 times, avg 2.68ms/call: # 40 times (48.9ms+58.3ms) by Template::Parser::parse at line 288, avg 2.68ms/call
sub split_text {
320106µs my ($self, $text) = @_;
321103µs my ($pre, $dir, $prelines, $dirlines, $postlines, $chomp, $tags, @tags);
3221015µs my $style = $self->{ STYLE }->[-1];
3231020µs my ($start, $end, $prechomp, $postchomp, $interp ) =
324 @$style{ qw( START_TAG END_TAG PRE_CHOMP POST_CHOMP INTERPOLATE ) };
3251074µs40144µs my $tags_dir = $self->{ANYCASE} ? qr<TAGS>i : qr<TAGS>;
# spent 144µs making 40 calls to Template::Parser::CORE:qr, avg 4µs/call
326
327109µs my @tokens = ();
328103µs my $line = 1;
329
330 return \@tokens ## RETURN ##
33110127µs unless defined $text && length $text;
332
333 # extract all directives from the text
33410300µs80874µs while ($text =~ s/
# spent 702µs making 40 calls to Template::Parser::CORE:subst, avg 18µs/call # spent 172µs making 40 calls to Template::Parser::CORE:regcomp, avg 4µs/call
335 ^(.*?) # $1 - start of line up to directive
336 (?:
337 $start # start of tag
338 (.*?) # $2 - tag contents
339 $end # end of tag
340 )
341 //sx) {
342
343292423µs ($pre, $dir) = ($1, $2);
34429265µs $pre = '' unless defined $pre;
34529223µs $dir = '' unless defined $dir;
346
347292310µs $prelines = ($pre =~ tr/\n//); # newlines in preceeding text
348292104µs $dirlines = ($dir =~ tr/\n//); # newlines in directive tag
34929234µs $postlines = 0; # newlines chomped after tag
350
351292167µs for ($dir) {
352292493µs973333µs if (/^\#/) {
# spent 333µs making 973 calls to Template::Parser::CORE:match, avg 343ns/call
353 # comment out entire directive except for any end chomp flag
354 $dir = ($dir =~ /($CHOMP_FLAGS)$/o) ? $1 : '';
355 }
356 else {
3572921.30ms19462.04ms s/^($CHOMP_FLAGS)?\s*//so;
# spent 1.93ms making 973 calls to Template::Parser::CORE:subst, avg 2µs/call # spent 117µs making 973 calls to Template::Parser::CORE:regcomp, avg 121ns/call
358 # PRE_CHOMP: process whitespace before tag
359292108µs $chomp = $1 ? $1 : $prechomp;
36029289µs $chomp =~ tr/-=~+/1230/;
36129295µs if ($chomp && $pre) {
362 # chomp off whitespace and newline preceding directive
363 if ($chomp == CHOMP_ALL) {
364 $pre =~ s{ (\r?\n|^) [^\S\n]* \z }{}mx;
365 }
366 elsif ($chomp == CHOMP_COLLAPSE) {
367 $pre =~ s{ (\s+) \z }{ }x;
368 }
369 elsif ($chomp == CHOMP_GREEDY) {
370 $pre =~ s{ (\s+) \z }{}x;
371 }
372 }
373 }
374
375 # POST_CHOMP: process whitespace after tag
3762928.15ms19465.58ms s/\s*($CHOMP_FLAGS)?\s*$//so;
# spent 5.43ms making 973 calls to Template::Parser::CORE:subst, avg 6µs/call # spent 154µs making 973 calls to Template::Parser::CORE:regcomp, avg 159ns/call
377292102µs $chomp = $1 ? $1 : $postchomp;
37829277µs $chomp =~ tr/-=~+/1230/;
379292223µs if ($chomp) {
380 if ($chomp == CHOMP_ALL) {
381 $text =~ s{ ^ ([^\S\n]* \n) }{}x
382 && $postlines++;
383 }
384 elsif ($chomp == CHOMP_COLLAPSE) {
385 $text =~ s{ ^ (\s+) }{ }x
386 && ($postlines += $1=~y/\n//);
387 }
388 # any trailing whitespace
389 elsif ($chomp == CHOMP_GREEDY) {
390 $text =~ s{ ^ (\s+) }{}x
391 && ($postlines += $1=~y/\n//);
392 }
393 }
394 }
395
396 # any text preceding the directive can now be added
397292359µs if (length $pre) {
398 push(@tokens, $interp
399 ? [ $pre, $line, 'ITEXT' ]
400 : ('TEXT', $pre) );
401 }
40229257µs $line += $prelines;
403
404 # and now the directive, along with line number information
405292118µs if (length $dir) {
406 # the TAGS directive is a compile-time switch
4072927.26ms19461.09ms if ($dir =~ /^$tags_dir\s+(.*)/) {
# spent 883µs making 973 calls to Template::Parser::CORE:regcomp, avg 907ns/call # spent 210µs making 973 calls to Template::Parser::CORE:match, avg 216ns/call
408 my @tags = split(/\s+/, $1);
409 if (scalar @tags > 1) {
410 ($start, $end) = map { quotemeta($_) } @tags;
411 }
412 elsif ($tags = $TAG_STYLE->{ $tags[0] }) {
413 ($start, $end) = @$tags;
414 }
415 else {
416 warn "invalid TAGS style: $tags[0]\n";
417 }
418 }
419 else {
420 # DIRECTIVE is pushed as:
421 # [ $dirtext, $line_no(s), \@tokens ]
422292634µs97336.1ms push(@tokens,
# spent 36.1ms making 973 calls to Template::Parser::tokenise_directive, avg 37µs/call
423 [ $dir,
424 ($dirlines
425 ? sprintf("%d-%d", $line, $line + $dirlines)
426 : $line),
427 $self->tokenise_directive($dir) ]);
428 }
429 }
430
431 # update line counter to include directive lines and any extra
432 # newline chomped off the start of the following text
4332925.27ms194612.2ms $line += $dirlines + $postlines;
# spent 10.9ms making 973 calls to Template::Parser::CORE:subst, avg 11µs/call # spent 1.30ms making 973 calls to Template::Parser::CORE:regcomp, avg 1µs/call
434 }
435
436 # anything remaining in the string is plain text
4371017µs push(@tokens, $interp
438 ? [ $text, $line, 'ITEXT' ]
439 : ( 'TEXT', $text) )
440 if length $text;
441
4421048µs return \@tokens; ## RETURN ##
443}
444
445
446
447#------------------------------------------------------------------------
448# interpolate_text($text, $line)
449#
450# Examines $text looking for any variable references embedded like
451# $this or like ${ this }.
452#------------------------------------------------------------------------
453
454
# spent 88µs (76+13) within Template::Parser::interpolate_text which was called 4 times, avg 22µs/call: # 4 times (76µs+13µs) by Template::Parser::tokenise_directive at line 587, avg 22µs/call
sub interpolate_text {
4551800ns my ($self, $text, $line) = @_;
4561700ns my @tokens = ();
4571300ns my ($pre, $var, $dir);
458
459
46015µs48µs while ($text =~
# spent 8µs making 4 calls to Template::Parser::CORE:match, avg 2µs/call
461 /
462 ( (?: \\. | [^\$] ){1,3000} ) # escaped or non-'$' character [$1]
463 |
464 ( \$ (?: # embedded variable [$2]
465 (?: \{ ([^\}]*) \} ) # ${ ... } [$3]
466 |
467 ([\w\.]+) # $word [$4]
468 )
469 )
470 /gx) {
471
47212µs ($pre, $var, $dir) = ($1, $3 || $4, $2);
473
474 # preceding text
47512µs if (defined($pre) && length($pre)) {
4761800ns $line += $pre =~ tr/\n//;
47713µs44µs $pre =~ s/\\\$/\$/g;
# spent 4µs making 4 calls to Template::Parser::CORE:subst, avg 900ns/call
47811µs push(@tokens, 'TEXT', $pre);
479 }
480 # $variable reference
48112µs4800ns if ($var) {
# spent 800ns making 4 calls to Template::Parser::CORE:match, avg 200ns/call
482 $line += $dir =~ tr/\n/ /;
483 push(@tokens, [ $dir, $line, $self->tokenise_directive($var) ]);
484 }
485 # other '$' reference - treated as text
486 elsif ($dir) {
487 $line += $dir =~ tr/\n//;
488 push(@tokens, 'TEXT', $dir);
489 }
490 }
491
49214µs return \@tokens;
493}
494
- -
497#------------------------------------------------------------------------
498# tokenise_directive($text)
499#
500# Called by the private _parse() method when it encounters a DIRECTIVE
501# token in the list provided by the split_text() or interpolate_text()
502# methods. The directive text is passed by parameter.
503#
504# The method splits the directive into individual tokens as recognised
505# by the parser grammar (see Template::Grammar for details). It
506# constructs a list of tokens each represented by 2 elements, as per
507# split_text() et al. The first element contains the token type, the
508# second the token itself.
509#
510# The method tokenises the string using a complex (but fast) regex.
511# For a deeper understanding of the regex magic at work here, see
512# Jeffrey Friedl's excellent book "Mastering Regular Expressions",
513# from O'Reilly, ISBN 1-56592-257-3
514#
515# Returns a reference to the list of chunks (each one being 2 elements)
516# identified in the directive text. On error, the internal _ERROR string
517# is set and undef is returned.
518#------------------------------------------------------------------------
519
520
# spent 36.1ms (26.9+9.12) within Template::Parser::tokenise_directive which was called 973 times, avg 37µs/call: # 973 times (26.9ms+9.12ms) by Template::Parser::split_text at line 422, avg 37µs/call
sub tokenise_directive {
521292133µs my ($self, $text, $line) = @_;
52229222µs my ($token, $uctoken, $type, $lookup);
523292105µs my $lextable = $self->{ LEXTABLE };
52429294µs my $style = $self->{ STYLE }->[-1];
525292134µs my ($anycase, $start, $end) = @$style{ qw( ANYCASE START_TAG END_TAG ) };
52629287µs my @tokens = ( );
527
5282921.28ms9773.26ms while ($text =~
# spent 3.26ms making 977 calls to Template::Parser::CORE:match, avg 3µs/call
529 /
530 # strip out any comments
531 (\#[^\n]*)
532 |
533 # a quoted phrase matches in $3
534 (["']) # $2 - opening quote, ' or "
535 ( # $3 - quoted text buffer
536 (?: # repeat group (no backreference)
537 \\\\ # an escaped backslash \\
538 | # ...or...
539 \\\2 # an escaped quote \" or \' (match $1)
540 | # ...or...
541 . # any other character
542 | \n
543 )*? # non-greedy repeat
544 ) # end of $3
545 \2 # match opening quote
546 |
547 # an unquoted number matches in $4
548 (-?\d+(?:\.\d+)?) # numbers
549 |
550 # filename matches in $5
551 ( \/?\w+(?:(?:\/|::?)\w*)+ | \/\w+)
552 |
553 # an identifier matches in $6
554 (\w+) # variable identifier
555 |
556 # an unquoted word or symbol matches in $7
557 ( [(){}\[\]:;,\/\\] # misc parenthesis and symbols
558# | \-> # arrow operator (for future?)
559 | [+\-*] # math operations
560 | \$\{? # dollar with option left brace
561 | => # like '='
562 | [=!<>]?= | [!<>] # eqality tests
563 | &&? | \|\|? # boolean ops
564 | \.\.? # n..n sequence
565 | \S+ # something unquoted
566 ) # end of $7
567 /gmxo) {
568
569 # ignore comments to EOL
570770251µs next if $1;
571
572 # quoted string
573770854µs if (defined ($token = $3)) {
574 # double-quoted string may include $variable references
5752426µs if ($2 eq '"') {
576213µs87µs if ($token =~ /[\$\\]/) {
# spent 7µs making 8 calls to Template::Parser::CORE:match, avg 862ns/call
5771300ns $type = 'QUOTED';
578 # unescape " and \ but leave \$ escaped so that
579 # interpolate_text() doesn't incorrectly treat it
580 # as a variable reference
581# $token =~ s/\\([\\"])/$1/g;
5821800ns for ($token) {
58318µs421µs s/\\([^\$nrt])/$1/g;
# spent 21µs making 4 calls to Template::Parser::CORE:subst, avg 5µs/call
58413µs45µs s/\\([nrt])/$QUOTED_ESCAPES->{ $1 }/ge;
# spent 5µs making 4 calls to Template::Parser::CORE:subst, avg 1µs/call
585 }
586 push(@tokens, ('"') x 2,
587110µs488µs @{ $self->interpolate_text($token) },
# spent 88µs making 4 calls to Template::Parser::interpolate_text, avg 22µs/call
588 ('"') x 2);
58911µs next;
590 }
591 else {
59211µs $type = 'LITERAL';
59317µs414µs $token =~ s['][\\']g;
# spent 14µs making 4 calls to Template::Parser::CORE:subst, avg 4µs/call
59411µs $token = "'$token'";
595 }
596 }
597 else {
598226µs $type = 'LITERAL';
5992224µs $token = "'$token'";
600 }
601 }
602 # number
603 elsif (defined ($token = $4)) {
604 $type = 'NUMBER';
605 }
606 elsif (defined($token = $5)) {
607 $type = 'FILENAME';
608 }
609 elsif (defined($token = $6)) {
610 # Fold potential keywords to UPPER CASE if the ANYCASE option is
611 # set, unless (we've got some preceeding tokens and) the previous
612 # token is a DOT op. This prevents the 'last' in 'data.last'
613 # from being interpreted as the LAST keyword.
61448098µs $uctoken =
615 ($anycase && (! @tokens || $tokens[-2] ne 'DOT'))
616 ? uc $token
617 : $token;
618480423µs if (defined ($type = $lextable->{ $uctoken })) {
619 $token = $uctoken;
620 }
621 else {
62226957µs $type = 'IDENT';
623 }
624 }
625 elsif (defined ($token = $7)) {
626 # reserved words may be in lower case unless case sensitive
62726646µs $uctoken = $anycase ? uc $token : $token;
628266179µs unless (defined ($type = $lextable->{ $uctoken })) {
629 $type = 'UNQUOTED';
630 }
631 }
632
6337697.72ms24405.73ms push(@tokens, $type, $token);
# spent 5.73ms making 2440 calls to Template::Parser::CORE:match, avg 2µs/call
634
635# print(STDERR " +[ $type, $token ]\n")
636# if $DEBUG;
637 }
638
639# print STDERR "tokenise directive() returning:\n [ @tokens ]\n"
640# if $DEBUG;
641
642292641µs return \@tokens; ## RETURN ##
643}
644
645
646#------------------------------------------------------------------------
647# define_block($name, $block)
648#
649# Called by the parser 'defblock' rule when a BLOCK definition is
650# encountered in the template. The name of the block is passed in the
651# first parameter and a reference to the compiled block is passed in
652# the second. This method stores the block in the $self->{ DEFBLOCK }
653# hash which has been initialised by parse() and will later be used
654# by the same method to call the store() method on the calling cache
655# to define the block "externally".
656#------------------------------------------------------------------------
657
658sub define_block {
659 my ($self, $name, $block) = @_;
660 my $defblock = $self->{ DEFBLOCK }
661 || return undef;
662
663 $self->debug("compiled block '$name':\n$block")
664 if $self->{ DEBUG } & Template::Constants::DEBUG_PARSER;
665
666 $defblock->{ $name } = $block;
667
668 return undef;
669}
670
671sub push_defblock {
672 my $self = shift;
673 my $stack = $self->{ DEFBLOCK_STACK } ||= [];
674 push(@$stack, $self->{ DEFBLOCK } );
675 $self->{ DEFBLOCK } = { };
676}
677
678sub pop_defblock {
679 my $self = shift;
680 my $defs = $self->{ DEFBLOCK };
681 my $stack = $self->{ DEFBLOCK_STACK } || return $defs;
682 return $defs unless @$stack;
683 $self->{ DEFBLOCK } = pop @$stack;
684 return $defs;
685}
686
687
688#------------------------------------------------------------------------
689# add_metadata(\@setlist)
690#------------------------------------------------------------------------
691
692sub add_metadata {
693 my ($self, $setlist) = @_;
694 my $metadata = $self->{ METADATA }
695 || return undef;
696
697 push(@$metadata, @$setlist);
698
699 return undef;
700}
701
702
703#------------------------------------------------------------------------
704# location()
705#
706# Return Perl comment indicating current parser file and line
707#------------------------------------------------------------------------
708
709
# spent 4.13ms (3.62+513µs) within Template::Parser::location which was called 641 times, avg 6µs/call: # 641 times (3.62ms+513µs) by Template::Grammar::__ANON__[Parser.yp:79] at line 78 of errors/Parser.yp, avg 6µs/call
sub location {
71019147µs my $self = shift;
71119172µs return "\n" unless $self->{ FILE_INFO };
71219171µs my $line = ${ $self->{ LINE } };
71319172µs my $info = $self->{ FILEINFO }->[-1];
714 my $file = $info->{ path } || $info->{ name }
71519168µs || '(unknown template)';
716191491µs641513µs $line =~ s/\-.*$//; # might be 'n-n'
# spent 513µs making 641 calls to Template::Parser::CORE:subst, avg 800ns/call
71719120µs $line ||= 1;
718191537µs return "#line $line \"$file\"\n";
719}
720
721
722#========================================================================
723# ----- PRIVATE METHODS -----
724#========================================================================
725
726#------------------------------------------------------------------------
727# _parse(\@tokens, \@info)
728#
729# Parses the list of input tokens passed by reference and returns a
730# Template::Directive::Block object which contains the compiled
731# representation of the template.
732#
733# This is the main parser DFA loop. See embedded comments for
734# further details.
735#
736# On error, undef is returned and the internal _ERROR field is set to
737# indicate the error. This can be retrieved by calling the error()
738# method.
739#------------------------------------------------------------------------
740
741
# spent 231ms (156+74.7) within Template::Parser::_parse which was called 40 times, avg 5.77ms/call: # 40 times (156ms+74.7ms) by Template::Parser::parse at line 294, avg 5.77ms/call
sub _parse {
742105µs my ($self, $tokens, $info) = @_;
743103µs my ($token, $value, $text, $line, $inperl);
744 my ($state, $stateno, $status, $action, $lookup, $coderet, @codevars);
745 my ($lhs, $len, $code); # rule contents
7461015µs my $stack = [ [ 0, undef ] ]; # DFA stack
747
748# DEBUG
749# local $" = ', ';
750
751 # retrieve internal rule and state tables
7521014µs my ($states, $rules) = @$self{ qw( STATES RULES ) };
753
754 # If we're tracing variable usage then we need to give the factory a
755 # reference to our $self->{ VARIABLES } for it to fill in. This is a
756 # bit of a hack to back-patch this functionality into TT2.
757 $self->{ FACTORY }->trace_vars($self->{ VARIABLES })
7581011µs if $self->{ TRACE_VARS };
759
760 # call the grammar set_factory method to install emitter factory
7611045µs40109µs $self->{ GRAMMAR }->install_factory($self->{ FACTORY });
# spent 109µs making 40 calls to Template::Grammar::install_factory, avg 3µs/call
762
763103µs $line = $inperl = 0;
7641015µs $self->{ LINE } = \$line;
7651019µs $self->{ FILE } = $info->{ name };
7661011µs $self->{ INPERL } = \$inperl;
767
768104µs $status = CONTINUE;
769105µs my $in_string = 0;
770
771104.07ms while(1) {
772 # get state number and state
7734585997µs $stateno = $stack->[-1]->[0];
7744585974µs $state = $states->[$stateno];
775
776 # see if any lookaheads exist for the current state
77745851.48ms if (exists $state->{'ACTIONS'}) {
778
779 # get next token and expand any directives (i.e. token is an
780 # array ref) onto the front of the token list
7812193786µs while (! defined $token && @$tokens) {
7821648513µs $token = shift(@$tokens);
7831648812µs if (ref $token) {
784292290µs ($text, $line, $token) = @$token;
78529271µs if (ref $token) {
786292104µs if ($info->{ DEBUG } && ! $in_string) {
787 # - - - - - - - - - - - - - - - - - - - - - - - - -
788 # This is gnarly. Look away now if you're easily
789 # frightened. We're pushing parse tokens onto the
790 # pending list to simulate a DEBUG directive like so:
791 # [% DEBUG msg line='20' text='INCLUDE foo' %]
792 # - - - - - - - - - - - - - - - - - - - - - - - - -
793 my $dtext = $text;
794 $dtext =~ s[(['\\])][\\$1]g;
795 unshift(@$tokens,
796 DEBUG => 'DEBUG',
797 IDENT => 'msg',
798 IDENT => 'line',
799 ASSIGN => '=',
800 LITERAL => "'$line'",
801 IDENT => 'text',
802 ASSIGN => '=',
803 LITERAL => "'$dtext'",
804 IDENT => 'file',
805 ASSIGN => '=',
806 LITERAL => "'$info->{ name }'",
807 (';') x 2,
808 @$token,
809 (';') x 2);
810 }
811 else {
812292541µs unshift(@$tokens, @$token, (';') x 2);
813 }
81429254µs $token = undef; # force redo
815 }
816 elsif ($token eq 'ITEXT') {
817 if ($inperl) {
818 # don't perform interpolation in PERL blocks
819 $token = 'TEXT';
820 $value = $text;
821 }
822 else {
823 unshift(@$tokens,
824 @{ $self->interpolate_text($text, $line) });
825 $token = undef; # force redo
826 }
827 }
828 }
829 else {
830 # toggle string flag to indicate if we're crossing
831 # a string boundary
8321356241µs $in_string = ! $in_string if $token eq '"';
8331356281µs $value = shift(@$tokens);
834 }
835 };
836 # clear undefined token to avoid 'undefined variable blah blah'
837 # warnings and let the parser logic pick it up in a minute
8382193219µs $token = '' unless defined $token;
839
840 # get the next state for the current lookahead token
84121931.25ms $action = defined ($lookup = $state->{'ACTIONS'}->{ $token })
842 ? $lookup
843 : defined ($lookup = $state->{'DEFAULT'})
844 ? $lookup
845 : undef;
846 }
847 else {
848 # no lookahead actions
8492392516µs $action = $state->{'DEFAULT'};
850 }
851
852 # ERROR: no ACTION
8534585396µs last unless defined $action;
854
855 # - - - - - - - - - - - - - - - - - - - - - - - - - - - -
856 # shift (+ive ACTION)
857 # - - - - - - - - - - - - - - - - - - - - - - - - - - - -
8584585577µs if ($action > 0) {
8591366819µs push(@$stack, [ $action, $value ]);
8601366269µs $token = $value = undef;
8611366259µs redo;
862 };
863
864 # - - - - - - - - - - - - - - - - - - - - - - - - - - - -
865 # reduce (-ive ACTION)
866 # - - - - - - - - - - - - - - - - - - - - - - - - - - - -
86732193.08ms ($lhs, $len, $code) = @{ $rules->[ -$action ] };
868
869 # no action imples ACCEPTance
8703219263µs $action
871 or $status = ACCEPT;
872
873 # use dummy sub if code ref doesn't exist
8748871.76ms
# spent 2.67ms within Template::Parser::__ANON__[/usr/lib/x86_64-linux-gnu/perl5/5.20/Template/Parser.pm:874] which was called 2843 times, avg 938ns/call: # 2843 times (2.67ms+0s) by Template::Parser::_parse at line 882, avg 938ns/call
$code = sub { $_[1] }
87532191.50ms unless $code;
876
877 @codevars = $len
87832195.43ms ? map { $_->[1] } @$stack[ -$len .. -1 ]
879 : ();
880
88132191.12ms eval {
88232194.11ms1049174.6ms $coderet = &$code( $self, @codevars );
# spent 33.7ms making 976 calls to Template::Grammar::__ANON__[Parser.yp:76], avg 35µs/call # spent 16.8ms making 641 calls to Template::Grammar::__ANON__[Parser.yp:79], avg 26µs/call # spent 4.45ms making 597 calls to Template::Grammar::__ANON__[Parser.yp:305], avg 7µs/call # spent 2.85ms making 372 calls to Template::Grammar::__ANON__[Parser.yp:67], avg 8µs/call # spent 2.67ms making 2843 calls to Template::Parser::__ANON__[Template/Parser.pm:874], avg 938ns/call # spent 2.55ms making 239 calls to Template::Grammar::__ANON__[Parser.yp:141], avg 11µs/call # spent 1.95ms making 1245 calls to Template::Grammar::__ANON__[Parser.yp:72], avg 2µs/call # spent 1.58ms making 295 calls to Template::Grammar::__ANON__[Parser.yp:90], avg 5µs/call # spent 1.20ms making 797 calls to Template::Grammar::__ANON__[Parser.yp:345], avg 2µs/call # spent 861µs making 764 calls to Template::Grammar::__ANON__[Parser.yp:341], avg 1µs/call # spent 726µs making 40 calls to Template::Grammar::__ANON__[Parser.yp:64], avg 18µs/call # spent 591µs making 13 calls to Template::Grammar::__ANON__[Parser.yp:168], avg 45µs/call # spent 583µs making 372 calls to Template::Grammar::__ANON__[Parser.yp:73], avg 2µs/call # spent 556µs making 33 calls to Template::Grammar::__ANON__[Parser.yp:203], avg 17µs/call # spent 507µs making 36 calls to Template::Grammar::__ANON__[Parser.yp:118], avg 14µs/call # spent 379µs making 227 calls to Template::Grammar::__ANON__[Parser.yp:364], avg 2µs/call # spent 338µs making 195 calls to Template::Grammar::__ANON__[Parser.yp:334], avg 2µs/call # spent 285µs making 33 calls to Template::Grammar::__ANON__[Parser.yp:342], avg 9µs/call # spent 251µs making 183 calls to Template::Grammar::__ANON__[Parser.yp:152], avg 1µs/call # spent 167µs making 127 calls to Template::Grammar::__ANON__[Parser.yp:387], avg 1µs/call # spent 128µs making 5 calls to Template::Grammar::__ANON__[Parser.yp:115], avg 26µs/call # spent 128µs making 69 calls to Template::Grammar::__ANON__[Parser.yp:407], avg 2µs/call # spent 126µs making 8 calls to Template::Grammar::__ANON__[Parser.yp:227], avg 16µs/call # spent 125µs making 81 calls to Template::Grammar::__ANON__[Parser.yp:412], avg 2µs/call # spent 120µs making 4 calls to Template::Grammar::__ANON__[Parser.yp:187], avg 30µs/call # spent 108µs making 49 calls to Template::Grammar::__ANON__[Parser.yp:416], avg 2µs/call # spent 101µs making 13 calls to Template::Grammar::__ANON__[Parser.yp:167], avg 8µs/call # spent 98µs making 60 calls to Template::Grammar::__ANON__[Parser.yp:151], avg 2µs/call # spent 85µs making 49 calls to Template::Grammar::__ANON__[Parser.yp:382], avg 2µs/call # spent 78µs making 4 calls to Template::Grammar::__ANON__[Parser.yp:440], avg 20µs/call # spent 69µs making 4 calls to Template::Grammar::__ANON__[Parser.yp:229], avg 17µs/call # spent 63µs making 4 calls to Template::Grammar::__ANON__[Parser.yp:145], avg 16µs/call # spent 58µs making 4 calls to Template::Grammar::__ANON__[Parser.yp:144], avg 14µs/call # spent 51µs making 22 calls to Template::Grammar::__ANON__[Parser.yp:360], avg 2µs/call # spent 37µs making 4 calls to Template::Grammar::__ANON__[Parser.yp:307], avg 9µs/call # spent 33µs making 4 calls to Template::Grammar::__ANON__[Parser.yp:109], avg 8µs/call # spent 28µs making 13 calls to Template::Grammar::__ANON__[Parser.yp:176], avg 2µs/call # spent 25µs making 6 calls to Template::Grammar::__ANON__[Parser.yp:357], avg 4µs/call # spent 21µs making 12 calls to Template::Grammar::__ANON__[Parser.yp:408], avg 2µs/call # spent 17µs making 11 calls to Template::Grammar::__ANON__[Parser.yp:359], avg 2µs/call # spent 14µs making 4 calls to Template::Grammar::__ANON__[Parser.yp:198], avg 4µs/call # spent 14µs making 5 calls to Template::Grammar::__ANON__[Parser.yp:374], avg 3µs/call # spent 12µs making 12 calls to Template::Grammar::__ANON__[Parser.yp:386], avg 1µs/call # spent 12µs making 4 calls to Template::Grammar::__ANON__[Parser.yp:435], avg 3µs/call # spent 11µs making 4 calls to Template::Grammar::__ANON__[Parser.yp:200], avg 3µs/call # spent 9µs making 4 calls to Template::Grammar::__ANON__[Parser.yp:420], avg 2µs/call # spent 6µs making 4 calls to Template::Grammar::__ANON__[Parser.yp:436], avg 2µs/call
883 };
8843219296µs if ($@) {
885 my $err = $@;
886 chomp $err;
887 return $self->_parse_error($err);
888 }
889
890 # reduce stack by $len
89132191.58ms splice(@$stack, -$len, $len);
892
893 # ACCEPT
8943219429µs return $coderet ## RETURN ##
895 if $status == ACCEPT;
896
897 # ABORT
898 return undef ## RETURN ##
8993209228µs if $status == ABORT;
900
901 # ERROR
902 last
9033209417µs if $status == ERROR;
904 }
905 continue {
906 push(@$stack, [ $states->[ $stack->[-1][0] ]->{'GOTOS'}->{ $lhs },
907 $coderet ]),
908 }
909
910 # ERROR ## RETURN ##
911 return $self->_parse_error('unexpected end of input')
912 unless defined $value;
913
914 # munge text of last directive to make it readable
915# $text =~ s/\n/\\n/g;
916
917 return $self->_parse_error("unexpected end of directive", $text)
918 if $value eq ';'; # end of directive SEPARATOR
919
920 return $self->_parse_error("unexpected token ($value)", $text);
921}
922
- -
925#------------------------------------------------------------------------
926# _parse_error($msg, $dirtext)
927#
928# Method used to handle errors encountered during the parse process
929# in the _parse() method.
930#------------------------------------------------------------------------
931
932sub _parse_error {
933 my ($self, $msg, $text) = @_;
934 my $line = $self->{ LINE };
935 $line = ref($line) ? $$line : $line;
936 $line = 'unknown' unless $line;
937
938 $msg .= "\n [% $text %]"
939 if defined $text;
940
941 return $self->error("line $line: $msg");
942}
943
944
945#------------------------------------------------------------------------
946# _dump()
947#
948# Debug method returns a string representing the internal state of the
949# object.
950#------------------------------------------------------------------------
951
952sub _dump {
953 my $self = shift;
954 my $output = "[Template::Parser] {\n";
955 my $format = " %-16s => %s\n";
956 my $key;
957
958 foreach $key (qw( START_TAG END_TAG TAG_STYLE ANYCASE INTERPOLATE
959 PRE_CHOMP POST_CHOMP V1DOLLAR )) {
960 my $val = $self->{ $key };
961 $val = '<undef>' unless defined $val;
962 $output .= sprintf($format, $key, $val);
963 }
964
965 $output .= '}';
966 return $output;
967}
968
969
9701;
971
972__END__
 
# spent 9.54ms within Template::Parser::CORE:match which was called 5379 times, avg 2µs/call: # 2440 times (5.73ms+0s) by Template::Parser::tokenise_directive at line 633, avg 2µs/call # 977 times (3.26ms+0s) by Template::Parser::tokenise_directive at line 528, avg 3µs/call # 973 times (333µs+0s) by Template::Parser::split_text at line 352, avg 343ns/call # 973 times (210µs+0s) by Template::Parser::split_text at line 407, avg 216ns/call # 8 times (7µs+0s) by Template::Parser::tokenise_directive at line 576, avg 862ns/call # 4 times (8µs+0s) by Template::Parser::interpolate_text at line 460, avg 2µs/call # 4 times (800ns+0s) by Template::Parser::interpolate_text at line 481, avg 200ns/call
sub Template::Parser::CORE:match; # opcode
# spent 147µs within Template::Parser::CORE:qr which was called 41 times, avg 4µs/call: # 40 times (144µs+0s) by Template::Parser::split_text at line 325, avg 4µs/call # once (4µs+0s) by Template::Config::load at line 90
sub Template::Parser::CORE:qr; # opcode
# spent 2.62ms within Template::Parser::CORE:regcomp which was called 3932 times, avg 667ns/call: # 973 times (1.30ms+0s) by Template::Parser::split_text at line 433, avg 1µs/call # 973 times (883µs+0s) by Template::Parser::split_text at line 407, avg 907ns/call # 973 times (154µs+0s) by Template::Parser::split_text at line 376, avg 159ns/call # 973 times (117µs+0s) by Template::Parser::split_text at line 357, avg 121ns/call # 40 times (172µs+0s) by Template::Parser::split_text at line 334, avg 4µs/call
sub Template::Parser::CORE:regcomp; # opcode
# spent 19.5ms within Template::Parser::CORE:subst which was called 3616 times, avg 5µs/call: # 973 times (10.9ms+0s) by Template::Parser::split_text at line 433, avg 11µs/call # 973 times (5.43ms+0s) by Template::Parser::split_text at line 376, avg 6µs/call # 973 times (1.93ms+0s) by Template::Parser::split_text at line 357, avg 2µs/call # 641 times (513µs+0s) by Template::Parser::location at line 716, avg 800ns/call # 40 times (702µs+0s) by Template::Parser::split_text at line 334, avg 18µs/call # 4 times (21µs+0s) by Template::Parser::tokenise_directive at line 583, avg 5µs/call # 4 times (14µs+0s) by Template::Parser::tokenise_directive at line 593, avg 4µs/call # 4 times (5µs+0s) by Template::Parser::tokenise_directive at line 584, avg 1µs/call # 4 times (4µs+0s) by Template::Parser::interpolate_text at line 477, avg 900ns/call
sub Template::Parser::CORE:subst; # opcode