← Index
NYTProf Performance Profile   « line view »
For rbm/rbm
  Run on Wed Feb 12 20:36:06 2020
Reported on Wed Feb 12 21:42:27 2020

Filename/usr/lib/x86_64-linux-gnu/perl5/5.28/Template/Parser.pm
StatementsExecuted 229996342 statements in 218s
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
37640011120s171sTemplate::Parser::::_parseTemplate::Parser::_parse
3764001128.5s57.4sTemplate::Parser::::split_textTemplate::Parser::split_text
3753871123.0s49.2sTemplate::Parser::::newTemplate::Parser::new
3147131116.1s21.3sTemplate::Parser::::tokenise_directiveTemplate::Parser::tokenise_directive
3764001110.7s239sTemplate::Parser::::parseTemplate::Parser::parse
3753871110.3s17.5sTemplate::Parser::::new_styleTemplate::Parser::new_style
18460641116.08s6.08sTemplate::Parser::::CORE:substTemplate::Parser::CORE:subst (opcode)
375387115.41s7.19sTemplate::Parser::::text_splitterTemplate::Parser::text_splitter
2643427715.23s5.23sTemplate::Parser::::CORE:matchTemplate::Parser::CORE:match (opcode)
313428112.84s3.20sTemplate::Parser::::locationTemplate::Parser::location
2010639612.33s2.33sTemplate::Parser::::CORE:regcompTemplate::Parser::CORE:regcomp (opcode)
2490942111.83s1.83sTemplate::Parser::::__ANON__[:955]Template::Parser::__ANON__[:955]
751789411.22s1.22sTemplate::Parser::::CORE:qrTemplate::Parser::CORE:qr (opcode)
19911178.9ms86.4msTemplate::Parser::::interpolate_textTemplate::Parser::interpolate_text
59681170.5ms121msTemplate::Parser::::leave_blockTemplate::Parser::leave_block
59681150.2ms50.2msTemplate::Parser::::block_labelTemplate::Parser::block_label
59681132.0ms32.0msTemplate::Parser::::enter_blockTemplate::Parser::enter_block
11114.6ms14.7msTemplate::Parser::::BEGIN@41Template::Parser::BEGIN@41
3982115.01ms5.01msTemplate::Parser::::CORE:substcontTemplate::Parser::CORE:substcont (opcode)
1113.70ms3.94msTemplate::Parser::::BEGIN@40Template::Parser::BEGIN@40
11115µs20µsTemplate::Parser::::BEGIN@35Template::Parser::BEGIN@35
11112µs83µsTemplate::Parser::::BEGIN@44Template::Parser::BEGIN@44
1119µs102µsTemplate::Parser::::BEGIN@37Template::Parser::BEGIN@37
1118µs246µsTemplate::Parser::::BEGIN@39Template::Parser::BEGIN@39
1117µs31µsTemplate::Parser::::BEGIN@45Template::Parser::BEGIN@45
1116µs32µsTemplate::Parser::::BEGIN@36Template::Parser::BEGIN@36
1115µs27µsTemplate::Parser::::BEGIN@46Template::Parser::BEGIN@46
1115µs26µsTemplate::Parser::::BEGIN@47Template::Parser::BEGIN@47
2214µs4µsTemplate::Parser::::__ANON__Template::Parser::__ANON__ (xsub)
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 associated 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
35224µs224µs
# spent 20µs (15+4) within Template::Parser::BEGIN@35 which was called: # once (15µs+4µs) by Template::Config::load at line 35
use strict;
# spent 20µs making 1 call to Template::Parser::BEGIN@35 # spent 4µs making 1 call to strict::import
36223µs258µs
# spent 32µs (6+26) within Template::Parser::BEGIN@36 which was called: # once (6µs+26µs) by Template::Config::load at line 36
use warnings;
# spent 32µs making 1 call to Template::Parser::BEGIN@36 # spent 26µs making 1 call to warnings::import
37230µs2196µs
# spent 102µs (9+94) within Template::Parser::BEGIN@37 which was called: # once (9µs+94µs) by Template::Config::load at line 37
use base 'Template::Base';
# spent 102µs making 1 call to Template::Parser::BEGIN@37 # spent 94µs making 1 call to base::import
38
39230µs2484µs
# spent 246µs (8+238) within Template::Parser::BEGIN@39 which was called: # once (8µs+238µs) by Template::Config::load at line 39
use Template::Constants qw( :status :chomp );
# spent 246µs making 1 call to Template::Parser::BEGIN@39 # spent 238µs making 1 call to Exporter::import
402179µs23.95ms
# spent 3.94ms (3.70+246µs) within Template::Parser::BEGIN@40 which was called: # once (3.70ms+246µs) by Template::Config::load at line 40
use Template::Directive;
# spent 3.94ms making 1 call to Template::Parser::BEGIN@40 # spent 2µs making 1 call to Template::Parser::__ANON__
412258µs214.7ms
# spent 14.7ms (14.6+58µs) within Template::Parser::BEGIN@41 which was called: # once (14.6ms+58µs) by Template::Config::load at line 41
use Template::Grammar;
# spent 14.7ms making 1 call to Template::Parser::BEGIN@41 # spent 3µs making 1 call to Template::Parser::__ANON__
42
43# parser state constants
44230µs2153µs
# spent 83µs (12+71) within Template::Parser::BEGIN@44 which was called: # once (12µs+71µs) by Template::Config::load at line 44
use constant CONTINUE => 0;
# spent 83µs making 1 call to Template::Parser::BEGIN@44 # spent 71µs making 1 call to constant::import
45223µs255µs
# spent 31µs (7+24) within Template::Parser::BEGIN@45 which was called: # once (7µs+24µs) by Template::Config::load at line 45
use constant ACCEPT => 1;
# spent 31µs making 1 call to Template::Parser::BEGIN@45 # spent 24µs making 1 call to constant::import
46221µs249µs
# spent 27µs (5+22) within Template::Parser::BEGIN@46 which was called: # once (5µs+22µs) by Template::Config::load at line 46
use constant ERROR => 2;
# spent 27µs making 1 call to Template::Parser::BEGIN@46 # spent 22µs making 1 call to constant::import
4723.52ms248µs
# spent 26µs (5+21) within Template::Parser::BEGIN@47 which was called: # once (5µs+21µs) by Template::Config::load at line 47
use constant ABORT => 3;
# spent 26µs making 1 call to Template::Parser::BEGIN@47 # spent 21µs making 1 call to constant::import
48
491400nsour $VERSION = 2.89;
501400nsour $DEBUG = 0 unless defined $DEBUG;
511400nsour $ERROR = '';
52
53# The ANYCASE option can cause conflicts when reserved words are used as
54# variable names, hash keys, template names, plugin names, etc. The
55#
56# $ANYCASE_BEFORE regex identifies where such a word precedes an assignment,
57# either as a variable (C<wrapper = 'html'>) or hash key (C<{ wrapper => 'html' }).
58# In that case it is treated as a simple words rather than being the lower case
59# equivalent of the upper case keyword (e.g. WRAPPER).
60#
61# $ANYCASE_AFTER is used to identify when such a word follows a symbols that
62# suggests it can't be a keyword, e.g. after BLOCK INCLUDE WRAPPER, USE, etc.
63111µs12µsour $ANYCASE_BEFORE = qr/\G((?=\s*[=\.]))/;
# spent 2µs making 1 call to Template::Parser::CORE:qr
64our $ANYCASE_AFTER = {
65122µs map { $_ => 1 }
66 qw(
67 GET SET CALL DEFAULT INSERT INCLUDE PROCESS WRAPPER BLOCK USE
68 PLUGIN FILTER MACRO IN TO STEP AND OR NOT DIV MOD DOT
69 IF UNLESS ELSIF FOR WHILE SWITCH CASE META THROW CATCH VIEW
70 CMPOP BINOP COMMA
71 ),
72 '(', '[', '{'
73 # not sure about ASSIGN as it breaks C<header_html = include header>
74};
75
76
77#========================================================================
78# -- COMMON TAG STYLES --
79#========================================================================
80
8118µsour $TAG_STYLE = {
82 'outline' => [ '\[%', '%\]', '%%' ], # NEW! Outline tag
83 'default' => [ '\[%', '%\]' ],
84 'template1' => [ '[\[%]%', '%[\]%]' ],
85 'metatext' => [ '%%', '%%' ],
86 'html' => [ '<!--', '-->' ],
87 'mason' => [ '<%', '>' ],
88 'asp' => [ '<%', '%>' ],
89 'php' => [ '<\?', '\?>' ],
90 'star' => [ '\[\*', '\*\]' ],
91};
9211µs$TAG_STYLE->{ template } = $TAG_STYLE->{ tt2 } = $TAG_STYLE->{ default };
93
94
95our $DEFAULT_STYLE = {
96 START_TAG => $TAG_STYLE->{ default }->[0],
97 END_TAG => $TAG_STYLE->{ default }->[1],
9817µs OUTLINE_TAG => $TAG_STYLE->{ default }->[2],
99# TAG_STYLE => 'default',
100 ANYCASE => 0,
101 INTERPOLATE => 0,
102 PRE_CHOMP => 0,
103 POST_CHOMP => 0,
104 V1DOLLAR => 0,
105 EVAL_PERL => 0,
106};
107
10812µsour $QUOTED_ESCAPES = {
109 n => "\n",
110 r => "\r",
111 t => "\t",
112};
113
114# note that '-' must come first so Perl doesn't think it denotes a range
11513µs1600nsour $CHOMP_FLAGS = qr/[-=~+]/;
# spent 600ns making 1 call to Template::Parser::CORE:qr
116
- -
119#========================================================================
120# ----- PUBLIC METHODS -----
121#========================================================================
122
123#------------------------------------------------------------------------
124# new(\%config)
125#
126# Constructor method.
127#------------------------------------------------------------------------
128
129
# spent 49.2s (23.0+26.2) within Template::Parser::new which was called 375387 times, avg 131µs/call: # 375387 times (23.0s+26.2s) by Template::Config::parser at line 103 of Template/Config.pm, avg 131µs/call
sub new {
130375387155ms my $class = shift;
131375387706ms my $config = $_[0] && ref($_[0]) eq 'HASH' ? shift(@_) : { @_ };
132375387168ms my ($tagstyle, $debug, $start, $end, $defaults, $grammar, $hash, $key, $udef);
133
134 my $self = bless {
135 START_TAG => undef,
136 END_TAG => undef,
137 OUTLINE_TAG => undef,
138 TAG_STYLE => 'default',
139 ANYCASE => 0,
140 INTERPOLATE => 0,
141 PRE_CHOMP => 0,
142 POST_CHOMP => 0,
143 V1DOLLAR => 0,
144 EVAL_PERL => 0,
145 FILE_INFO => 1,
146 GRAMMAR => undef,
147 _ERROR => '',
148 IN_BLOCK => [ ],
149 TRACE_VARS => $config->{ TRACE_VARS },
1503753875.56s FACTORY => $config->{ FACTORY } || 'Template::Directive',
151 }, $class;
152
153 # update self with any relevant keys in config
1543753871.40s foreach $key (keys %$self) {
15560061921.73s $self->{ $key } = $config->{ $key } if defined $config->{ $key };
156 }
157375387510ms $self->{ FILEINFO } = [ ];
158
159 # DEBUG config item can be a bitmask
160375387805ms if (defined ($debug = $config->{ DEBUG })) {
161 $self->{ DEBUG } = $debug & ( Template::Constants::DEBUG_PARSER
162 | Template::Constants::DEBUG_FLAGS );
163 $self->{ DEBUG_DIRS } = $debug & Template::Constants::DEBUG_DIRS;
164 }
165 # package variable can be set to 1 to support previous behaviour
166 elsif ($DEBUG == 1) {
167 $self->{ DEBUG } = Template::Constants::DEBUG_PARSER;
168 $self->{ DEBUG_DIRS } = 0;
169 }
170 # otherwise let $DEBUG be a bitmask
171 else {
172375387341ms $self->{ DEBUG } = $DEBUG & ( Template::Constants::DEBUG_PARSER
173 | Template::Constants::DEBUG_FLAGS );
174375387285ms $self->{ DEBUG_DIRS } = $DEBUG & Template::Constants::DEBUG_DIRS;
175 }
176
177375387427ms $grammar = $self->{ GRAMMAR } ||= do {
178375387229ms require Template::Grammar;
1793753871.34s3753871.92s Template::Grammar->new();
# spent 1.92s making 375387 calls to Template::Grammar::new, avg 5µs/call
180 };
181
182 # instantiate a FACTORY object
183375387553ms unless (ref $self->{ FACTORY }) {
184375387272ms my $fclass = $self->{ FACTORY };
185 $self->{ FACTORY } = $self->{ FACTORY }->new(
186 NAMESPACE => $config->{ NAMESPACE }
187 )
1883753871.66s3753876.75s || return $class->error($self->{ FACTORY }->error());
# spent 6.75s making 375387 calls to Template::Base::new, avg 18µs/call
189 }
190
191 # load grammar rules, states and lex table
192 @$self{ qw( LEXTABLE STATES RULES ) }
1933753871.39s = @$grammar{ qw( LEXTABLE STATES RULES ) };
194
1953753871.25s37538717.5s $self->new_style($config)
# spent 17.5s making 375387 calls to Template::Parser::new_style, avg 47µs/call
196 || return $class->error($self->error());
197
1983753871.93s return $self;
199}
200
201#-----------------------------------------------------------------------
202# These methods are used to track nested IF and WHILE blocks. Each
203# generated if/while block is given a label indicating the directive
204# type and nesting depth, e.g. FOR0, WHILE1, FOR2, WHILE3, etc. The
205# NEXT and LAST directives use the innermost label, e.g. last WHILE3;
206#-----------------------------------------------------------------------
207
208
# spent 32.0ms within Template::Parser::enter_block which was called 5968 times, avg 5µs/call: # 5968 times (32.0ms+0s) by Template::Grammar::__ANON__[Parser.yp:167] at line 167 of /root/tor-browser-build/Parser.yp, avg 5µs/call
sub enter_block {
20959683.94ms my ($self, $name) = @_;
21059686.57ms my $blocks = $self->{ IN_BLOCK };
211596843.7ms push(@{ $self->{ IN_BLOCK } }, $name);
212}
213
214
# spent 121ms (70.5+50.2) within Template::Parser::leave_block which was called 5968 times, avg 20µs/call: # 5968 times (70.5ms+50.2ms) by Template::Grammar::__ANON__[Parser.yp:168] at line 168 of /root/tor-browser-build/Parser.yp, avg 20µs/call
sub leave_block {
21559683.33ms my $self = shift;
216596823.9ms596850.2ms my $label = $self->block_label;
# spent 50.2ms making 5968 calls to Template::Parser::block_label, avg 8µs/call
21759688.52ms pop(@{ $self->{ IN_BLOCK } });
218596835.1ms return $label;
219}
220
221sub in_block {
222 my ($self, $name) = @_;
223 my $blocks = $self->{ IN_BLOCK };
224 return @$blocks && $blocks->[-1] eq $name;
225}
226
227
# spent 50.2ms within Template::Parser::block_label which was called 5968 times, avg 8µs/call: # 5968 times (50.2ms+0s) by Template::Parser::leave_block at line 216, avg 8µs/call
sub block_label {
22859685.99ms my ($self, $prefix, $suffix) = @_;
22959687.18ms my $blocks = $self->{ IN_BLOCK };
230596814.0ms my $name = @$blocks
231 ? $blocks->[-1] . scalar @$blocks
232 : undef;
233596845.5ms return join('', grep { defined $_ } $prefix, $name, $suffix);
234}
235
- -
238#------------------------------------------------------------------------
239# new_style(\%config)
240#
241# Install a new (stacked) parser style. This feature is currently
242# experimental but should mimic the previous behaviour with regard to
243# TAG_STYLE, START_TAG, END_TAG, etc.
244#------------------------------------------------------------------------
245
246
# spent 17.5s (10.3+7.19) within Template::Parser::new_style which was called 375387 times, avg 47µs/call: # 375387 times (10.3s+7.19s) by Template::Parser::new at line 195, avg 47µs/call
sub new_style {
247375387246ms my ($self, $config) = @_;
248375387661ms my $styles = $self->{ STYLE } ||= [ ];
249375387171ms my ($tagstyle, $tags, $start, $end, $out, $key);
250
251 # clone new style from previous or default style
2523753872.47s my $style = { %{ $styles->[-1] || $DEFAULT_STYLE } };
253
254 # expand START_TAG and END_TAG from specified TAG_STYLE
255375387351ms if ($tagstyle = $config->{ TAG_STYLE }) {
256 return $self->error("Invalid tag style: $tagstyle")
257 unless defined ($tags = $TAG_STYLE->{ $tagstyle });
258 ($start, $end, $out) = @$tags;
259 $config->{ START_TAG } ||= $start;
260 $config->{ END_TAG } ||= $end;
261 $config->{ OUTLINE_TAG } ||= $out;
262 }
263
264375387832ms foreach $key (keys %$DEFAULT_STYLE) {
26533784831.08s $style->{ $key } = $config->{ $key } if defined $config->{ $key };
266 }
267
268375387305ms $start = $style->{ START_TAG };
269375387317ms $end = $style->{ END_TAG };
270375387227ms $out = $style->{ OUTLINE_TAG };
2713753871.26s3753877.19s $style->{ TEXT_SPLIT } = $self->text_splitter($start, $end, $out);
# spent 7.19s making 375387 calls to Template::Parser::text_splitter, avg 19µs/call
272
273375387166ms push(@$styles, $style);
2743753872.12s return $style;
275}
276
277
# spent 7.19s (5.41+1.78) within Template::Parser::text_splitter which was called 375387 times, avg 19µs/call: # 375387 times (5.41s+1.78s) by Template::Parser::new_style at line 271, avg 19µs/call
sub text_splitter {
278375387365ms my ($self, $start, $end, $out) = @_;
279
280375387262ms if (defined $out) {
281 return qr/
282 \A(.*?) # $1 - start of line up to directive
283 (?:
284 (?:
285 ^$out # outline tag at start of line
286 (.*?) # $2 - content of that line
287 (?:\n|$) # end of that line or file
288 )
289 |
290 (?:
291 $start # start of tag
292 (.*?) # $3 - tag contents
293 $end # end of tag
294 )
295 )
296 /msx;
297 }
298 else {
2993753877.85s7507741.78s return qr/
# spent 996ms making 375387 calls to Template::Parser::CORE:regcomp, avg 3µs/call # spent 788ms making 375387 calls to Template::Parser::CORE:qr, avg 2µs/call
300 ^(.*?) # $1 - start of line up to directive
301 (?:
302 $start # start of tag
303 (.*?) # $2 - tag contents
304 $end # end of tag
305 )
306 /sx;
307 }
308}
309
310#------------------------------------------------------------------------
311# old_style()
312#
313# Pop the current parser style and revert to the previous one. See
314# new_style(). ** experimental **
315#------------------------------------------------------------------------
316
317sub old_style {
318 my $self = shift;
319 my $styles = $self->{ STYLE };
320 return $self->error('only 1 parser style remaining')
321 unless (@$styles > 1);
322 pop @$styles;
323 return $styles->[-1];
324}
325
326
327#------------------------------------------------------------------------
328# parse($text, $data)
329#
330# Parses the text string, $text and returns a hash array representing
331# the compiled template block(s) as Perl code, in the format expected
332# by Template::Document.
333#------------------------------------------------------------------------
334
335
# spent 239s (10.7+228) within Template::Parser::parse which was called 376400 times, avg 634µs/call: # 376400 times (10.7s+228s) by Template::Provider::_compile at line 844 of Template/Provider.pm, avg 634µs/call
sub parse {
336376400321ms my ($self, $text, $info) = @_;
337376400134ms my ($tokens, $block);
338
339 $info->{ DEBUG } = $self->{ DEBUG_DIRS }
340376400629ms unless defined $info->{ DEBUG };
341
342# print "info: { ", join(', ', map { "$_ => $info->{ $_ }" } keys %$info), " }\n";
343
344 # store for blocks defined in the template (see define_block())
345376400456ms my $defblock = $self->{ DEFBLOCK } = { };
346376400416ms my $metadata = $self->{ METADATA } = [ ];
347376400432ms my $variables = $self->{ VARIABLES } = { };
348376400327ms $self->{ DEFBLOCKS } = [ ];
349
350376400340ms $self->{ _ERROR } = '';
351
352 # split file into TEXT/DIRECTIVE chunks
353376400980ms37640057.4s $tokens = $self->split_text($text)
# spent 57.4s making 376400 calls to Template::Parser::split_text, avg 153µs/call
354 || return undef; ## RETURN ##
355
356376400487ms push(@{ $self->{ FILEINFO } }, $info);
357
358 # parse chunks
3593764001.21s376400171s $block = $self->_parse($tokens, $info);
# spent 171s making 376400 calls to Template::Parser::_parse, avg 453µs/call
360
361376400300ms pop(@{ $self->{ FILEINFO } });
362
363376400149ms return undef unless $block; ## RETURN ##
364
365 $self->debug("compiled main template document block:\n$block")
366376400377ms if $self->{ DEBUG } & Template::Constants::DEBUG_PARSER;
367
368 return {
3693764002.95s BLOCK => $block,
370 DEFBLOCKS => $defblock,
371 VARIABLES => $variables,
372 METADATA => { @$metadata },
373 };
374}
375
- -
378#------------------------------------------------------------------------
379# split_text($text)
380#
381# Split input template text into directives and raw text chunks.
382#------------------------------------------------------------------------
383
384
# spent 57.4s (28.5+28.9) within Template::Parser::split_text which was called 376400 times, avg 153µs/call: # 376400 times (28.5s+28.9s) by Template::Parser::parse at line 353, avg 153µs/call
sub split_text {
385376400245ms my ($self, $text) = @_;
386376400198ms my ($pre, $dir, $prelines, $dirlines, $postlines, $chomp, $tags, @tags);
387376400412ms my $style = $self->{ STYLE }->[-1];
388 my ($start, $end, $out, $prechomp, $postchomp, $interp ) =
3893764001.11s @$style{ qw( START_TAG END_TAG OUTLINE_TAG PRE_CHOMP POST_CHOMP INTERPOLATE ) };
3903764002.38s376400434ms my $tags_dir = $self->{ANYCASE} ? qr<TAGS>i : qr<TAGS>;
# spent 434ms making 376400 calls to Template::Parser::CORE:qr, avg 1µs/call
391376400281ms my $split = $style->{ TEXT_SPLIT };
392376400303ms my $has_out = defined $out;
393
394376400265ms my @tokens = ();
395376400192ms my $line = 1;
396
397 return \@tokens ## RETURN ##
398376400315ms unless defined $text && length $text;
399
400 # extract all directives from the text
4013764005.54s7528001.92s while ($text =~ s/$split//) {
# spent 1.30s making 376400 calls to Template::Parser::CORE:subst, avg 3µs/call # spent 619ms making 376400 calls to Template::Parser::CORE:regcomp, avg 2µs/call
402314713436ms $pre = $1;
403314713521ms $dir = defined($2) ? $2 : $3;
404314713123ms $pre = '' unless defined $pre;
405314713118ms $dir = '' unless defined $dir;
406
407314713272ms $prelines = ($pre =~ tr/\n//); # newlines in preceding text
408314713128ms $dirlines = ($dir =~ tr/\n//); # newlines in directive tag
40931471397.7ms $postlines = 0; # newlines chomped after tag
410
411314713284ms for ($dir) {
4123147131.61s314713175ms if (/^\#/) {
# spent 175ms making 314713 calls to Template::Parser::CORE:match, avg 557ns/call
413 # comment out entire directive except for any end chomp flag
414 $dir = ($dir =~ /($CHOMP_FLAGS)$/o) ? $1 : '';
415 }
416 else {
417
4183147133.52s629426718ms if(s/^($CHOMP_FLAGS)?(\s*)//so && $2) {
# spent 651ms making 314713 calls to Template::Parser::CORE:subst, avg 2µs/call # spent 67.2ms making 314713 calls to Template::Parser::CORE:regcomp, avg 214ns/call
419314713205ms my $chomped = $2;
420314713180ms my $linecount = ($chomped =~ tr/\n//); # newlines in chomped whitespace
421314713105ms $linecount ||= 0;
42231471356.2ms $prelines += $linecount;
423314713120ms $dirlines -= $linecount;
424 }
425 # PRE_CHOMP: process whitespace before tag
426314713173ms $chomp = $1 ? $1 : $prechomp;
427314713149ms $chomp =~ tr/-=~+/1230/;
428314713107ms if ($chomp && $pre) {
429 # chomp off whitespace and newline preceding directive
43019911.11ms if ($chomp == CHOMP_ALL) {
431199127.6ms19916.47ms $pre =~ s{ (\r?\n|^) [^\S\n]* \z }{}mx;
# spent 6.47ms making 1991 calls to Template::Parser::CORE:subst, avg 3µs/call
432 }
433 elsif ($chomp == CHOMP_COLLAPSE) {
434 $pre =~ s{ (\s+) \z }{ }x;
435 }
436 elsif ($chomp == CHOMP_GREEDY) {
437 $pre =~ s{ (\s+) \z }{}x;
438 }
439 }
440 }
441
442 # POST_CHOMP: process whitespace after tag
4433147135.32s6294263.05s s/\s*($CHOMP_FLAGS)?\s*$//so;
# spent 3.01s making 314713 calls to Template::Parser::CORE:subst, avg 10µs/call # spent 36.7ms making 314713 calls to Template::Parser::CORE:regcomp, avg 117ns/call
444314713205ms $chomp = $1 ? $1 : $postchomp;
445314713122ms $chomp =~ tr/-=~+/1230/;
446314713215ms if ($chomp) {
4474716532.1ms if ($chomp == CHOMP_ALL) {
44847165364ms47165122ms $text =~ s{ ^ ([^\S\n]* \n) }{}x
# spent 122ms making 47165 calls to Template::Parser::CORE:subst, avg 3µs/call
449 && $postlines++;
450 }
451 elsif ($chomp == CHOMP_COLLAPSE) {
452 $text =~ s{ ^ (\s+) }{ }x
453 && ($postlines += $1=~y/\n//);
454 }
455 # any trailing whitespace
456 elsif ($chomp == CHOMP_GREEDY) {
457 $text =~ s{ ^ (\s+) }{}x
458 && ($postlines += $1=~y/\n//);
459 }
460 }
461 }
462
463 # any text preceding the directive can now be added
464314713392ms if (length $pre) {
465 push(@tokens, $interp
466 ? [ $pre, $line, 'ITEXT' ]
467 : ('TEXT', $pre) );
468 }
469314713112ms $line += $prelines;
470
471 # and now the directive, along with line number information
472314713138ms if (length $dir) {
473 # the TAGS directive is a compile-time switch
4743147132.72s629426472ms if ($dir =~ /^$tags_dir\s+(.*)/) {
# spent 360ms making 314713 calls to Template::Parser::CORE:regcomp, avg 1µs/call # spent 112ms making 314713 calls to Template::Parser::CORE:match, avg 357ns/call
475 my @tags = split(/\s+/, $1);
476 if (scalar @tags > 1) {
477 ($start, $end, $out) = map { quotemeta($_) } @tags;
478 $split = $self->text_splitter($start, $end, $out);
479 }
480 elsif ($tags = $TAG_STYLE->{ $tags[0] }) {
481 ($start, $end, $out) = @$tags;
482 $split = $self->text_splitter($start, $end, $out);
483 }
484 else {
485 warn "invalid TAGS style: $tags[0]\n";
486 }
487 }
488 else {
489 # DIRECTIVE is pushed as:
490 # [ $dirtext, $line_no(s), \@tokens ]
4913147131.16s31471321.3s push(@tokens,
# spent 21.3s making 314713 calls to Template::Parser::tokenise_directive, avg 68µs/call
492 [ $dir,
493 ($dirlines
494 ? sprintf("%d-%d", $line, $line + $dirlines)
495 : $line),
496 $self->tokenise_directive($dir) ]);
497 }
498 }
499
500 # update line counter to include directive lines and any extra
501 # newline chomped off the start of the following text
5023147133.23s629426777ms $line += $dirlines + $postlines;
# spent 530ms making 314713 calls to Template::Parser::CORE:subst, avg 2µs/call # spent 248ms making 314713 calls to Template::Parser::CORE:regcomp, avg 787ns/call
503 }
504
505 # anything remaining in the string is plain text
506376400389ms push(@tokens, $interp
507 ? [ $text, $line, 'ITEXT' ]
508 : ( 'TEXT', $text) )
509 if length $text;
510
5113764002.69s return \@tokens; ## RETURN ##
512}
513
- -
516#------------------------------------------------------------------------
517# interpolate_text($text, $line)
518#
519# Examines $text looking for any variable references embedded like
520# $this or like ${ this }.
521#------------------------------------------------------------------------
522
523
# spent 86.4ms (78.9+7.44) within Template::Parser::interpolate_text which was called 1991 times, avg 43µs/call: # 1991 times (78.9ms+7.44ms) by Template::Parser::tokenise_directive at line 656, avg 43µs/call
sub interpolate_text {
52419912.18ms my ($self, $text, $line) = @_;
52519913.16ms my @tokens = ();
5261991674µs my ($pre, $var, $dir);
527
528
529199121.4ms19916.75ms while ($text =~
# spent 6.75ms making 1991 calls to Template::Parser::CORE:match, avg 3µs/call
530 /
531 ( (?: \\. | [^\$] ){1,3000} ) # escaped or non-'$' character [$1]
532 |
533 ( \$ (?: # embedded variable [$2]
534 (?: \{ ([^\}]*) \} ) # ${ ... } [$3]
535 |
536 ([\w\.]+) # $word [$4]
537 )
538 )
539 /gx) {
540
54119914.32ms ($pre, $var, $dir) = ($1, $3 || $4, $2);
542
543 # preceding text
54419912.28ms if (defined($pre) && length($pre)) {
54519912.01ms $line += $pre =~ tr/\n//;
546199119.5ms1991355µs $pre =~ s/\\\$/\$/g;
# spent 355µs making 1991 calls to Template::Parser::CORE:subst, avg 178ns/call
54719912.72ms push(@tokens, 'TEXT', $pre);
548 }
549 # $variable reference
550199121.3ms1991330µs if ($var) {
# spent 330µs making 1991 calls to Template::Parser::CORE:match, avg 166ns/call
551 $line += $dir =~ tr/\n/ /;
552 push(@tokens, [ $dir, $line, $self->tokenise_directive($var) ]);
553 }
554 # other '$' reference - treated as text
555 elsif ($dir) {
556 $line += $dir =~ tr/\n//;
557 push(@tokens, 'TEXT', $dir);
558 }
559 }
560
561199116.5ms return \@tokens;
562}
563
- -
566#------------------------------------------------------------------------
567# tokenise_directive($text)
568#
569# Called by the private _parse() method when it encounters a DIRECTIVE
570# token in the list provided by the split_text() or interpolate_text()
571# methods. The directive text is passed by parameter.
572#
573# The method splits the directive into individual tokens as recognised
574# by the parser grammar (see Template::Grammar for details). It
575# constructs a list of tokens each represented by 2 elements, as per
576# split_text() et al. The first element contains the token type, the
577# second the token itself.
578#
579# The method tokenises the string using a complex (but fast) regex.
580# For a deeper understanding of the regex magic at work here, see
581# Jeffrey Friedl's excellent book "Mastering Regular Expressions",
582# from O'Reilly, ISBN 1-56592-257-3
583#
584# Returns a reference to the list of chunks (each one being 2 elements)
585# identified in the directive text. On error, the internal _ERROR string
586# is set and undef is returned.
587#------------------------------------------------------------------------
588
589
# spent 21.3s (16.1+5.12) within Template::Parser::tokenise_directive which was called 314713 times, avg 68µs/call: # 314713 times (16.1s+5.12s) by Template::Parser::split_text at line 491, avg 68µs/call
sub tokenise_directive {
590314713182ms my ($self, $text, $line) = @_;
591314713101ms my ($token, $uctoken, $type, $lookup);
592314713247ms my $lextable = $self->{ LEXTABLE };
593314713211ms my $style = $self->{ STYLE }->[-1];
594314713412ms my ($anycase, $start, $end) = @$style{ qw( ANYCASE START_TAG END_TAG ) };
595314713156ms my @tokens = ( );
596
5973147133.03s3167041.70s while ($text =~
# spent 1.70s making 316704 calls to Template::Parser::CORE:match, avg 5µs/call
598 /
599 # strip out any comments
600 (\#[^\n]*)
601 |
602 # a quoted phrase matches in $3
603 (["']) # $2 - opening quote, ' or "
604 ( # $3 - quoted text buffer
605 (?: # repeat group (no backreference)
606 \\\\ # an escaped backslash \\
607 | # ...or...
608 \\\2 # an escaped quote \" or \' (match $1)
609 | # ...or...
610 . # any other character
611 | \n
612 )*? # non-greedy repeat
613 ) # end of $3
614 \2 # match opening quote
615 |
616 # an unquoted number matches in $4
617 (-?\d+(?:\.\d+)?) # numbers
618 |
619 # filename matches in $5
620 ( \/?\w+(?:(?:\/|::?)\w*)+ | \/\w+)
621 |
622 # an identifier matches in $6
623 (\w+) # variable identifier
624 |
625 # an unquoted word or symbol matches in $7
626 ( [(){}\[\]:;,\/\\] # misc parenthesis and symbols
627# | \-> # arrow operator (for future?)
628 | [+\-*] # math operations
629 | \$\{? # dollar with option left brace
630 | => # like '='
631 | [=!<>]?= | [!<>] # eqality tests
632 | &&? | \|\|? # boolean ops
633 | \.\.? # n..n sequence
634 | \S+ # something unquoted
635 ) # end of $7
636 /gmxo) {
637
638 # ignore comments to EOL
6391536347345ms next if $1;
640
641 # quoted string
64215363472.32s if (defined ($token = $3)) {
643 # double-quoted string may include $variable references
644243677175ms if ($2 eq '"') {
645158959736ms158959106ms if ($token =~ /[\$\\]/) {
# spent 106ms making 158959 calls to Template::Parser::CORE:match, avg 664ns/call
64619911.37ms $type = 'QUOTED';
647 # unescape " and \ but leave \$ escaped so that
648 # interpolate_text() doesn't incorrectly treat it
649 # as a variable reference
650# $token =~ s/\\([\\"])/$1/g;
65119912.66ms for ($token) {
652199110.2ms19914.44ms s/\\([^\$nrt])/$1/g;
# spent 4.44ms making 1991 calls to Template::Parser::CORE:subst, avg 2µs/call
653199153.1ms59739.94ms s/\\([nrt])/$QUOTED_ESCAPES->{ $1 }/ge;
# spent 5.01ms making 3982 calls to Template::Parser::CORE:substcont, avg 1µs/call # spent 4.93ms making 1991 calls to Template::Parser::CORE:subst, avg 2µs/call
654 }
655 push(@tokens, ('"') x 2,
656199114.2ms199186.4ms @{ $self->interpolate_text($token) },
# spent 86.4ms making 1991 calls to Template::Parser::interpolate_text, avg 43µs/call
657 ('"') x 2);
65819911.71ms next;
659 }
660 else {
66115696874.4ms $type = 'LITERAL';
662156968666ms15696880.9ms $token =~ s['][\\']g;
# spent 80.9ms making 156968 calls to Template::Parser::CORE:subst, avg 515ns/call
66315696889.1ms $token = "'$token'";
664 }
665 }
666 else {
6678471819.9ms $type = 'LITERAL';
6688471837.2ms $token = "'$token'";
669 }
670 }
671 # number
672 elsif (defined ($token = $4)) {
673 $type = 'NUMBER';
674 }
675 elsif (defined($token = $5)) {
676 $type = 'FILENAME';
677 }
678 elsif (defined($token = $6)) {
679 # Fold potential keywords to UPPER CASE if the ANYCASE option is
680 # set, unless (we've got some preceding tokens and) the previous
681 # token is a DOT op. This prevents the 'last' in 'data.last'
682 # from being interpreted as the LAST keyword.
683571294229ms if ($anycase) {
684 # if the token follows a dot or precedes an assignment then
685 # it's not for folding, e.g. the 'wrapper' in this:
686 # [% page = { wrapper='html' }; page.wrapper %]
687 if ((@tokens && $ANYCASE_AFTER->{ $tokens[-2] })
688 || ($text =~ /$ANYCASE_BEFORE/gc)) {
689 # keep the token unmodified
690 $uctoken = $token;
691 }
692 else {
693 $uctoken = uc $token;
694 }
695 }
696 else {
697571294160ms $uctoken = $token;
698 }
699571294616ms if (defined ($type = $lextable->{ $uctoken })) {
700 $token = $uctoken;
701 }
702 else {
703431260163ms $type = 'IDENT';
704 }
705 }
706 elsif (defined ($token = $7)) {
707 # reserved words may be in lower case unless case sensitive
708707297145ms $uctoken = $anycase ? uc $token : $token;
709707297473ms unless (defined ($type = $lextable->{ $uctoken })) {
710 $type = 'UNQUOTED';
711 }
712 }
713
71415343569.64s15343563.13s push(@tokens, $type, $token);
# spent 3.13s making 1534356 calls to Template::Parser::CORE:match, avg 2µs/call
715
716# print(STDERR " +[ $type, $token ]\n")
717# if $DEBUG;
718 }
719
720# print STDERR "tokenise directive() returning:\n [ @tokens ]\n"
721# if $DEBUG;
722
7233147131.88s return \@tokens; ## RETURN ##
724}
725
726
727#------------------------------------------------------------------------
728# define_block($name, $block)
729#
730# Called by the parser 'defblock' rule when a BLOCK definition is
731# encountered in the template. The name of the block is passed in the
732# first parameter and a reference to the compiled block is passed in
733# the second. This method stores the block in the $self->{ DEFBLOCK }
734# hash which has been initialised by parse() and will later be used
735# by the same method to call the store() method on the calling cache
736# to define the block "externally".
737#------------------------------------------------------------------------
738
739sub define_block {
740 my ($self, $name, $block) = @_;
741 my $defblock = $self->{ DEFBLOCK }
742 || return undef;
743
744 $self->debug("compiled block '$name':\n$block")
745 if $self->{ DEBUG } & Template::Constants::DEBUG_PARSER;
746
747 $defblock->{ $name } = $block;
748
749 return undef;
750}
751
752sub push_defblock {
753 my $self = shift;
754 my $stack = $self->{ DEFBLOCK_STACK } ||= [];
755 push(@$stack, $self->{ DEFBLOCK } );
756 $self->{ DEFBLOCK } = { };
757}
758
759sub pop_defblock {
760 my $self = shift;
761 my $defs = $self->{ DEFBLOCK };
762 my $stack = $self->{ DEFBLOCK_STACK } || return $defs;
763 return $defs unless @$stack;
764 $self->{ DEFBLOCK } = pop @$stack;
765 return $defs;
766}
767
768
769#------------------------------------------------------------------------
770# add_metadata(\@setlist)
771#------------------------------------------------------------------------
772
773sub add_metadata {
774 my ($self, $setlist) = @_;
775 my $metadata = $self->{ METADATA }
776 || return undef;
777
778 push(@$metadata, @$setlist);
779
780 return undef;
781}
782
783
784#------------------------------------------------------------------------
785# location()
786#
787# Return Perl comment indicating current parser file and line
788#------------------------------------------------------------------------
789
790
# spent 3.20s (2.84+362ms) within Template::Parser::location which was called 313428 times, avg 10µs/call: # 313428 times (2.84s+362ms) by Template::Grammar::__ANON__[Parser.yp:79] at line 78 of /root/tor-browser-build/Parser.yp, avg 10µs/call
sub location {
791313428122ms my $self = shift;
792313428160ms return "\n" unless $self->{ FILE_INFO };
793313428218ms my $line = ${ $self->{ LINE } };
794313428242ms my $info = $self->{ FILEINFO }->[-1];
795 my $file = $info->{ path } || $info->{ name }
796313428275ms || '(unknown template)';
7973134281.41s313428362ms $line =~ s/\-.*$//; # might be 'n-n'
# spent 362ms making 313428 calls to Template::Parser::CORE:subst, avg 1µs/call
798313428115ms $line ||= 1;
7993134281.43s return "#line $line \"$file\"\n";
800}
801
802
803#========================================================================
804# ----- PRIVATE METHODS -----
805#========================================================================
806
807#------------------------------------------------------------------------
808# _parse(\@tokens, \@info)
809#
810# Parses the list of input tokens passed by reference and returns a
811# Template::Directive::Block object which contains the compiled
812# representation of the template.
813#
814# This is the main parser DFA loop. See embedded comments for
815# further details.
816#
817# On error, undef is returned and the internal _ERROR field is set to
818# indicate the error. This can be retrieved by calling the error()
819# method.
820#------------------------------------------------------------------------
821
822
# spent 171s (120+51.0) within Template::Parser::_parse which was called 376400 times, avg 453µs/call: # 376400 times (120s+51.0s) by Template::Parser::parse at line 359, avg 453µs/call
sub _parse {
823376400209ms my ($self, $tokens, $info) = @_;
824376400208ms my ($token, $value, $text, $line, $inperl);
825 my ($state, $stateno, $status, $action, $lookup, $coderet, @codevars);
826 my ($lhs, $len, $code); # rule contents
827376400556ms my $stack = [ [ 0, undef ] ]; # DFA stack
828
829# DEBUG
830# local $" = ', ';
831
832 # retrieve internal rule and state tables
833376400381ms my ($states, $rules) = @$self{ qw( STATES RULES ) };
834
835 # If we're tracing variable usage then we need to give the factory a
836 # reference to our $self->{ VARIABLES } for it to fill in. This is a
837 # bit of a hack to back-patch this functionality into TT2.
838 $self->{ FACTORY }->trace_vars($self->{ VARIABLES })
839376400373ms if $self->{ TRACE_VARS };
840
841 # call the grammar set_factory method to install emitter factory
8423764001.39s376400747ms $self->{ GRAMMAR }->install_factory($self->{ FACTORY });
# spent 747ms making 376400 calls to Template::Grammar::install_factory, avg 2µs/call
843
844376400179ms $line = $inperl = 0;
845376400425ms $self->{ LINE } = \$line;
846376400581ms $self->{ FILE } = $info->{ name };
847376400430ms $self->{ INPERL } = \$inperl;
848
849376400190ms $status = CONTINUE;
850376400179ms my $in_string = 0;
851
8523764009.36s while(1) {
853 # get state number and state
85499286552.17s $stateno = $stack->[-1]->[0];
85599286552.96s $state = $states->[$stateno];
856
857 # see if any lookaheads exist for the current state
85899286555.39s if (exists $state->{'ACTIONS'}) {
859
860 # get next token and expand any directives (i.e. token is an
861 # array ref) onto the front of the token list
86246162361.81s while (! defined $token && @$tokens) {
86326653971.03s $token = shift(@$tokens);
86426653971.71s if (ref $token) {
865314713338ms ($text, $line, $token) = @$token;
866314713135ms if (ref $token) {
867314713247ms if ($info->{ DEBUG } && ! $in_string) {
868 # - - - - - - - - - - - - - - - - - - - - - - - - -
869 # This is gnarly. Look away now if you're easily
870 # frightened. We're pushing parse tokens onto the
871 # pending list to simulate a DEBUG directive like so:
872 # [% DEBUG msg line='20' text='INCLUDE foo' %]
873 # - - - - - - - - - - - - - - - - - - - - - - - - -
874 my $dtext = $text;
875 $dtext =~ s[(['\\])][\\$1]g;
876 unshift(@$tokens,
877 DEBUG => 'DEBUG',
878 IDENT => 'msg',
879 IDENT => 'line',
880 ASSIGN => '=',
881 LITERAL => "'$line'",
882 IDENT => 'text',
883 ASSIGN => '=',
884 LITERAL => "'$dtext'",
885 IDENT => 'file',
886 ASSIGN => '=',
887 LITERAL => "'$info->{ name }'",
888 (';') x 2,
889 @$token,
890 (';') x 2);
891 }
892 else {
8933147131.22s unshift(@$tokens, @$token, (';') x 2);
894 }
89531471374.1ms $token = undef; # force redo
896 }
897 elsif ($token eq 'ITEXT') {
898 if ($inperl) {
899 # don't perform interpolation in PERL blocks
900 $token = 'TEXT';
901 $value = $text;
902 }
903 else {
904 unshift(@$tokens,
905 @{ $self->interpolate_text($text, $line) });
906 $token = undef; # force redo
907 }
908 }
909 }
910 else {
911 # toggle string flag to indicate if we're crossing
912 # a string boundary
9132350684558ms $in_string = ! $in_string if $token eq '"';
9142350684687ms $value = shift(@$tokens);
915 }
916 };
917 # clear undefined token to avoid 'undefined variable blah blah'
918 # warnings and let the parser logic pick it up in a minute
9194616236740ms $token = '' unless defined $token;
920
921 # get the next state for the current lookahead token
922 $action = defined ($lookup = $state->{'ACTIONS'}->{ $token })
923 ? $lookup
92446162363.99s : defined ($lookup = $state->{'DEFAULT'})
925 ? $lookup
926 : undef;
927 }
928 else {
929 # no lookahead actions
93053124191.39s $action = $state->{'DEFAULT'};
931 }
932
933 # ERROR: no ACTION
93499286551.09s last unless defined $action;
935
936 # - - - - - - - - - - - - - - - - - - - - - - - - - - - -
937 # shift (+ive ACTION)
938 # - - - - - - - - - - - - - - - - - - - - - - - - - - - -
93999286551.57s if ($action > 0) {
94027270841.58s push(@$stack, [ $action, $value ]);
9412727084596ms $token = $value = undef;
9422727084583ms redo;
943 };
944
945 # - - - - - - - - - - - - - - - - - - - - - - - - - - - -
946 # reduce (-ive ACTION)
947 # - - - - - - - - - - - - - - - - - - - - - - - - - - - -
94872015718.02s ($lhs, $len, $code) = @{ $rules->[ -$action ] };
949
950 # no action imples ACCEPTance
9517201571834ms $action
952 or $status = ACCEPT;
953
954 # use dummy sub if code ref doesn't exist
955249094215.9s
# spent 1.83s within Template::Parser::__ANON__[/usr/lib/x86_64-linux-gnu/perl5/5.28/Template/Parser.pm:955] which was called 2490942 times, avg 734ns/call: # 2490942 times (1.83s+0s) by Template::Parser::_parse at line 963, avg 734ns/call
$code = sub { $_[1] }
95672015713.95s unless $code;
957
958 @codevars = $len
95972015719.32s ? map { $_->[1] } @$stack[ -$len .. -1 ]
960 : ();
961
96272015711.96s eval {
963720157111.4s720157150.2s $coderet = &$code( $self, @codevars );
# spent 15.4s making 495642 calls to Template::Grammar::__ANON__[Parser.yp:76], avg 31µs/call # spent 7.08s making 376400 calls to Template::Grammar::__ANON__[Parser.yp:64], avg 19µs/call # spent 5.53s making 321403 calls to Template::Grammar::__ANON__[Parser.yp:79], avg 17µs/call # spent 4.75s making 431466 calls to Template::Grammar::__ANON__[Parser.yp:67], avg 11µs/call # spent 4.59s making 372329 calls to Template::Grammar::__ANON__[Parser.yp:305], avg 12µs/call # spent 2.66s making 250383 calls to Template::Grammar::__ANON__[Parser.yp:90], avg 11µs/call # spent 2.37s making 242791 calls to Template::Grammar::__ANON__[Parser.yp:342], avg 10µs/call # spent 1.83s making 2490942 calls to Template::Parser::__ANON__[Template/Parser.pm:955], avg 734ns/call # spent 1.11s making 431466 calls to Template::Grammar::__ANON__[Parser.yp:73], avg 3µs/call # spent 923ms making 385579 calls to Template::Grammar::__ANON__[Parser.yp:72], avg 2µs/call # spent 739ms making 424294 calls to Template::Grammar::__ANON__[Parser.yp:345], avg 2µs/call # spent 588ms making 37103 calls to Template::Grammar::__ANON__[Parser.yp:141], avg 16µs/call # spent 506ms making 285731 calls to Template::Grammar::__ANON__[Parser.yp:382], avg 2µs/call # spent 423ms making 159453 calls to Template::Grammar::__ANON__[Parser.yp:341], avg 3µs/call # spent 357ms making 5968 calls to Template::Grammar::__ANON__[Parser.yp:168], avg 60µs/call # spent 307ms making 249772 calls to Template::Grammar::__ANON__[Parser.yp:387], avg 1µs/call # spent 130ms making 4031 calls to Template::Grammar::__ANON__[Parser.yp:115], avg 32µs/call # spent 123ms making 3982 calls to Template::Grammar::__ANON__[Parser.yp:95], avg 31µs/call # spent 89.7ms making 5968 calls to Template::Grammar::__ANON__[Parser.yp:167], avg 15µs/call # spent 70.2ms making 6966 calls to Template::Grammar::__ANON__[Parser.yp:113], avg 10µs/call # spent 67.4ms making 21902 calls to Template::Grammar::__ANON__[Parser.yp:334], avg 3µs/call # spent 57.0ms making 22050 calls to Template::Grammar::__ANON__[Parser.yp:331], avg 3µs/call # spent 53.4ms making 28096 calls to Template::Grammar::__ANON__[Parser.yp:152], avg 2µs/call # spent 49.3ms making 1991 calls to Template::Grammar::__ANON__[Parser.yp:440], avg 25µs/call # spent 46.9ms making 42940 calls to Template::Grammar::__ANON__[Parser.yp:386], avg 1µs/call # spent 44.0ms making 22921 calls to Template::Grammar::__ANON__[Parser.yp:358], avg 2µs/call # spent 43.9ms making 1013 calls to Template::Grammar::__ANON__[Parser.yp:118], avg 43µs/call # spent 42.1ms making 3982 calls to Template::Grammar::__ANON__[Parser.yp:114], avg 11µs/call # spent 36.4ms making 18052 calls to Template::Grammar::__ANON__[Parser.yp:302], avg 2µs/call # spent 29.2ms making 1991 calls to Template::Grammar::__ANON__[Parser.yp:307], avg 15µs/call # spent 24.9ms making 9007 calls to Template::Grammar::__ANON__[Parser.yp:151], avg 3µs/call # spent 17.9ms making 6015 calls to Template::Grammar::__ANON__[Parser.yp:361], avg 3µs/call # spent 15.8ms making 5988 calls to Template::Grammar::__ANON__[Parser.yp:325], avg 3µs/call # spent 15.2ms making 8013 calls to Template::Grammar::__ANON__[Parser.yp:374], avg 2µs/call # spent 14.1ms making 2984 calls to Template::Grammar::__ANON__[Parser.yp:175], avg 5µs/call # spent 11.5ms making 2984 calls to Template::Grammar::__ANON__[Parser.yp:176], avg 4µs/call # spent 8.12ms making 2988 calls to Template::Grammar::__ANON__[Parser.yp:150], avg 3µs/call # spent 7.43ms making 1990 calls to Template::Grammar::__ANON__[Parser.yp:360], avg 4µs/call # spent 6.88ms making 1991 calls to Template::Grammar::__ANON__[Parser.yp:435], avg 3µs/call # spent 5.54ms making 2016 calls to Template::Grammar::__ANON__[Parser.yp:359], avg 3µs/call # spent 4.79ms making 1991 calls to Template::Grammar::__ANON__[Parser.yp:299], avg 2µs/call # spent 4.44ms making 1990 calls to Template::Grammar::__ANON__[Parser.yp:322], avg 2µs/call # spent 3.56ms making 1991 calls to Template::Grammar::__ANON__[Parser.yp:301], avg 2µs/call # spent 3.50ms making 1991 calls to Template::Grammar::__ANON__[Parser.yp:436], avg 2µs/call # spent 3.42ms making 1013 calls to Template::Grammar::__ANON__[Parser.yp:412], avg 3µs/call # spent 3.08ms making 1013 calls to Template::Grammar::__ANON__[Parser.yp:407], avg 3µs/call # spent 2.94ms making 998 calls to Template::Grammar::__ANON__[Parser.yp:416], avg 3µs/call # spent 3µs making 1 call to Template::Grammar::__ANON__[Parser.yp:362]
964 };
9657201571731ms if ($@) {
966 my $err = $@;
967 chomp $err;
968 return $self->_parse_error($err);
969 }
970
971 # reduce stack by $len
97272015713.51s splice(@$stack, -$len, $len);
973
974 # ACCEPT
97572015713.64s return $coderet ## RETURN ##
976 if $status == ACCEPT;
977
978 # ABORT
979 return undef ## RETURN ##
98068251711.01s if $status == ABORT;
981
982 # ERROR
983 last
98468251711.07s if $status == ERROR;
985 }
986 continue {
987 push(@$stack, [ $states->[ $stack->[-1][0] ]->{'GOTOS'}->{ $lhs },
988 $coderet ]),
989 }
990
991 # ERROR ## RETURN ##
992 return $self->_parse_error('unexpected end of input')
993 unless defined $value;
994
995 # munge text of last directive to make it readable
996# $text =~ s/\n/\\n/g;
997
998 return $self->_parse_error("unexpected end of directive", $text)
999 if $value eq ';'; # end of directive SEPARATOR
1000
1001 return $self->_parse_error("unexpected token ($value)", $text);
1002}
1003
- -
1006#------------------------------------------------------------------------
1007# _parse_error($msg, $dirtext)
1008#
1009# Method used to handle errors encountered during the parse process
1010# in the _parse() method.
1011#------------------------------------------------------------------------
1012
1013sub _parse_error {
1014 my ($self, $msg, $text) = @_;
1015 my $line = $self->{ LINE };
1016 $line = ref($line) ? $$line : $line;
1017 $line = 'unknown' unless $line;
1018
1019 $msg .= "\n [% $text %]"
1020 if defined $text;
1021
1022 return $self->error("line $line: $msg");
1023}
1024
1025
1026#------------------------------------------------------------------------
1027# _dump()
1028#
1029# Debug method returns a string representing the internal state of the
1030# object.
1031#------------------------------------------------------------------------
1032
1033sub _dump {
1034 my $self = shift;
1035 my $output = "[Template::Parser] {\n";
1036 my $format = " %-16s => %s\n";
1037 my $key;
1038
1039 foreach $key (qw( START_TAG END_TAG TAG_STYLE ANYCASE INTERPOLATE
1040 PRE_CHOMP POST_CHOMP V1DOLLAR )) {
1041 my $val = $self->{ $key };
1042 $val = '<undef>' unless defined $val;
1043 $output .= sprintf($format, $key, $val);
1044 }
1045
1046 $output .= '}';
1047 return $output;
1048}
1049
1050
1051118µs1;
1052
1053__END__
 
# spent 5.23s within Template::Parser::CORE:match which was called 2643427 times, avg 2µs/call: # 1534356 times (3.13s+0s) by Template::Parser::tokenise_directive at line 714, avg 2µs/call # 316704 times (1.70s+0s) by Template::Parser::tokenise_directive at line 597, avg 5µs/call # 314713 times (175ms+0s) by Template::Parser::split_text at line 412, avg 557ns/call # 314713 times (112ms+0s) by Template::Parser::split_text at line 474, avg 357ns/call # 158959 times (106ms+0s) by Template::Parser::tokenise_directive at line 645, avg 664ns/call # 1991 times (6.75ms+0s) by Template::Parser::interpolate_text at line 529, avg 3µs/call # 1991 times (330µs+0s) by Template::Parser::interpolate_text at line 550, avg 166ns/call
sub Template::Parser::CORE:match; # opcode
# spent 1.22s within Template::Parser::CORE:qr which was called 751789 times, avg 2µs/call: # 376400 times (434ms+0s) by Template::Parser::split_text at line 390, avg 1µs/call # 375387 times (788ms+0s) by Template::Parser::text_splitter at line 299, avg 2µs/call # once (2µs+0s) by Template::Config::load at line 63 # once (600ns+0s) by Template::Config::load at line 115
sub Template::Parser::CORE:qr; # opcode
# spent 2.33s within Template::Parser::CORE:regcomp which was called 2010639 times, avg 1µs/call: # 376400 times (619ms+0s) by Template::Parser::split_text at line 401, avg 2µs/call # 375387 times (996ms+0s) by Template::Parser::text_splitter at line 299, avg 3µs/call # 314713 times (360ms+0s) by Template::Parser::split_text at line 474, avg 1µs/call # 314713 times (248ms+0s) by Template::Parser::split_text at line 502, avg 787ns/call # 314713 times (67.2ms+0s) by Template::Parser::split_text at line 418, avg 214ns/call # 314713 times (36.7ms+0s) by Template::Parser::split_text at line 443, avg 117ns/call
sub Template::Parser::CORE:regcomp; # opcode
# spent 6.08s within Template::Parser::CORE:subst which was called 1846064 times, avg 3µs/call: # 376400 times (1.30s+0s) by Template::Parser::split_text at line 401, avg 3µs/call # 314713 times (3.01s+0s) by Template::Parser::split_text at line 443, avg 10µs/call # 314713 times (651ms+0s) by Template::Parser::split_text at line 418, avg 2µs/call # 314713 times (530ms+0s) by Template::Parser::split_text at line 502, avg 2µs/call # 313428 times (362ms+0s) by Template::Parser::location at line 797, avg 1µs/call # 156968 times (80.9ms+0s) by Template::Parser::tokenise_directive at line 662, avg 515ns/call # 47165 times (122ms+0s) by Template::Parser::split_text at line 448, avg 3µs/call # 1991 times (6.47ms+0s) by Template::Parser::split_text at line 431, avg 3µs/call # 1991 times (4.93ms+0s) by Template::Parser::tokenise_directive at line 653, avg 2µs/call # 1991 times (4.44ms+0s) by Template::Parser::tokenise_directive at line 652, avg 2µs/call # 1991 times (355µs+0s) by Template::Parser::interpolate_text at line 546, avg 178ns/call
sub Template::Parser::CORE:subst; # opcode
# spent 5.01ms within Template::Parser::CORE:substcont which was called 3982 times, avg 1µs/call: # 3982 times (5.01ms+0s) by Template::Parser::tokenise_directive at line 653, avg 1µs/call
sub Template::Parser::CORE:substcont; # opcode
# spent 4µs within Template::Parser::__ANON__ which was called 2 times, avg 2µs/call: # once (3µs+0s) by Template::Parser::BEGIN@41 at line 41 # once (2µs+0s) by Template::Parser::BEGIN@40 at line 40
sub Template::Parser::__ANON__; # xsub