← Index
NYTProf Performance Profile   « line view »
For rbm/rbm
  Run on Wed Feb 12 03:38:15 2020
Reported on Wed Feb 12 04:56:37 2020

Filename/usr/lib/x86_64-linux-gnu/perl5/5.28/Template/Parser.pm
StatementsExecuted 231636656 statements in 224s
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
38417411122s174sTemplate::Parser::::_parseTemplate::Parser::_parse
3841741128.3s58.0sTemplate::Parser::::split_textTemplate::Parser::split_text
3831611125.4s53.1sTemplate::Parser::::newTemplate::Parser::new
3147131116.6s21.9sTemplate::Parser::::tokenise_directiveTemplate::Parser::tokenise_directive
3831611111.2s18.7sTemplate::Parser::::new_styleTemplate::Parser::new_style
3841741111.1s244sTemplate::Parser::::parseTemplate::Parser::parse
18538381116.02s6.02sTemplate::Parser::::CORE:substTemplate::Parser::CORE:subst (opcode)
383161115.63s7.45sTemplate::Parser::::text_splitterTemplate::Parser::text_splitter
2643427715.39s5.39sTemplate::Parser::::CORE:matchTemplate::Parser::CORE:match (opcode)
313428112.91s3.24sTemplate::Parser::::locationTemplate::Parser::location
2026187612.48s2.48sTemplate::Parser::::CORE:regcompTemplate::Parser::CORE:regcomp (opcode)
2498716111.81s1.81sTemplate::Parser::::__ANON__[:955]Template::Parser::__ANON__[:955]
767337411.32s1.32sTemplate::Parser::::CORE:qrTemplate::Parser::CORE:qr (opcode)
59681185.0ms135msTemplate::Parser::::leave_blockTemplate::Parser::leave_block
59681149.9ms49.9msTemplate::Parser::::block_labelTemplate::Parser::block_label
19911148.4ms56.3msTemplate::Parser::::interpolate_textTemplate::Parser::interpolate_text
59681139.0ms39.0msTemplate::Parser::::enter_blockTemplate::Parser::enter_block
11114.0ms14.1msTemplate::Parser::::BEGIN@41Template::Parser::BEGIN@41
3982115.03ms5.03msTemplate::Parser::::CORE:substcontTemplate::Parser::CORE:substcont (opcode)
1114.36ms4.61msTemplate::Parser::::BEGIN@40Template::Parser::BEGIN@40
11116µs20µsTemplate::Parser::::BEGIN@35Template::Parser::BEGIN@35
11110µs100µsTemplate::Parser::::BEGIN@44Template::Parser::BEGIN@44
1119µs88µsTemplate::Parser::::BEGIN@37Template::Parser::BEGIN@37
1118µs245µsTemplate::Parser::::BEGIN@39Template::Parser::BEGIN@39
1118µs31µsTemplate::Parser::::BEGIN@36Template::Parser::BEGIN@36
1116µs29µsTemplate::Parser::::BEGIN@45Template::Parser::BEGIN@45
1116µs28µsTemplate::Parser::::BEGIN@46Template::Parser::BEGIN@46
1115µs25µsTemplate::Parser::::BEGIN@47Template::Parser::BEGIN@47
2213µs3µ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
35231µs225µs
# spent 20µs (16+5) within Template::Parser::BEGIN@35 which was called: # once (16µs+5µ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
36224µs255µs
# spent 31µs (8+24) within Template::Parser::BEGIN@36 which was called: # once (8µs+24µs) by Template::Config::load at line 36
use warnings;
# spent 31µs making 1 call to Template::Parser::BEGIN@36 # spent 24µs making 1 call to warnings::import
37232µs2166µs
# spent 88µs (9+79) within Template::Parser::BEGIN@37 which was called: # once (9µs+79µs) by Template::Config::load at line 37
use base 'Template::Base';
# spent 88µs making 1 call to Template::Parser::BEGIN@37 # spent 79µs making 1 call to base::import
38
39231µs2482µs
# spent 245µs (8+237) within Template::Parser::BEGIN@39 which was called: # once (8µs+237µs) by Template::Config::load at line 39
use Template::Constants qw( :status :chomp );
# spent 245µs making 1 call to Template::Parser::BEGIN@39 # spent 237µs making 1 call to Exporter::import
402844µs24.62ms
# spent 4.61ms (4.36+251µs) within Template::Parser::BEGIN@40 which was called: # once (4.36ms+251µs) by Template::Config::load at line 40
use Template::Directive;
# spent 4.61ms making 1 call to Template::Parser::BEGIN@40 # spent 1µs making 1 call to Template::Parser::__ANON__
412706µs214.1ms
# spent 14.1ms (14.0+49µs) within Template::Parser::BEGIN@41 which was called: # once (14.0ms+49µs) by Template::Config::load at line 41
use Template::Grammar;
# spent 14.1ms making 1 call to Template::Parser::BEGIN@41 # spent 2µs making 1 call to Template::Parser::__ANON__
42
43# parser state constants
44231µs2191µs
# spent 100µs (10+90) within Template::Parser::BEGIN@44 which was called: # once (10µs+90µs) by Template::Config::load at line 44
use constant CONTINUE => 0;
# spent 100µs making 1 call to Template::Parser::BEGIN@44 # spent 90µs making 1 call to constant::import
45223µs252µs
# spent 29µs (6+23) within Template::Parser::BEGIN@45 which was called: # once (6µs+23µs) by Template::Config::load at line 45
use constant ACCEPT => 1;
# spent 29µs making 1 call to Template::Parser::BEGIN@45 # spent 23µs making 1 call to constant::import
46221µs250µs
# spent 28µs (6+22) within Template::Parser::BEGIN@46 which was called: # once (6µs+22µs) by Template::Config::load at line 46
use constant ERROR => 2;
# spent 28µs making 1 call to Template::Parser::BEGIN@46 # spent 22µs making 1 call to constant::import
4723.62ms245µs
# spent 25µs (5+20) within Template::Parser::BEGIN@47 which was called: # once (5µs+20µs) by Template::Config::load at line 47
use constant ABORT => 3;
# spent 25µs making 1 call to Template::Parser::BEGIN@47 # spent 20µs making 1 call to constant::import
48
491600nsour $VERSION = 2.89;
501500nsour $DEBUG = 0 unless defined $DEBUG;
511300nsour $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.
63112µs12µsour $ANYCASE_BEFORE = qr/\G((?=\s*[=\.]))/;
# spent 2µs making 1 call to Template::Parser::CORE:qr
64our $ANYCASE_AFTER = {
65121µ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],
9814µ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
10814µ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µs1700nsour $CHOMP_FLAGS = qr/[-=~+]/;
# spent 700ns 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 53.1s (25.4+27.7) within Template::Parser::new which was called 383161 times, avg 139µs/call: # 383161 times (25.4s+27.7s) by Template::Config::parser at line 103 of Template/Config.pm, avg 139µs/call
sub new {
130383161217ms my $class = shift;
131383161746ms my $config = $_[0] && ref($_[0]) eq 'HASH' ? shift(@_) : { @_ };
132383161158ms 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 },
1503831616.13s FACTORY => $config->{ FACTORY } || 'Template::Directive',
151 }, $class;
152
153 # update self with any relevant keys in config
1543831611.45s foreach $key (keys %$self) {
15561305761.87s $self->{ $key } = $config->{ $key } if defined $config->{ $key };
156 }
157383161577ms $self->{ FILEINFO } = [ ];
158
159 # DEBUG config item can be a bitmask
160383161881ms 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 {
172383161346ms $self->{ DEBUG } = $DEBUG & ( Template::Constants::DEBUG_PARSER
173 | Template::Constants::DEBUG_FLAGS );
174383161274ms $self->{ DEBUG_DIRS } = $DEBUG & Template::Constants::DEBUG_DIRS;
175 }
176
177383161521ms $grammar = $self->{ GRAMMAR } ||= do {
178383161285ms require Template::Grammar;
1793831611.55s3831611.97s Template::Grammar->new();
# spent 1.97s making 383161 calls to Template::Grammar::new, avg 5µs/call
180 };
181
182 # instantiate a FACTORY object
183383161651ms unless (ref $self->{ FACTORY }) {
184383161346ms my $fclass = $self->{ FACTORY };
185 $self->{ FACTORY } = $self->{ FACTORY }->new(
186 NAMESPACE => $config->{ NAMESPACE }
187 )
1883831611.99s3831617.07s || return $class->error($self->{ FACTORY }->error());
# spent 7.07s making 383161 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 ) }
1933831611.63s = @$grammar{ qw( LEXTABLE STATES RULES ) };
194
1953831611.37s38316118.7s $self->new_style($config)
# spent 18.7s making 383161 calls to Template::Parser::new_style, avg 49µs/call
196 || return $class->error($self->error());
197
1983831611.75s 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 39.0ms within Template::Parser::enter_block which was called 5968 times, avg 7µs/call: # 5968 times (39.0ms+0s) by Template::Grammar::__ANON__[Parser.yp:167] at line 167 of /root/tor-browser-build/Parser.yp, avg 7µs/call
sub enter_block {
20959684.59ms my ($self, $name) = @_;
210596811.5ms my $blocks = $self->{ IN_BLOCK };
211596849.6ms push(@{ $self->{ IN_BLOCK } }, $name);
212}
213
214
# spent 135ms (85.0+49.9) within Template::Parser::leave_block which was called 5968 times, avg 23µs/call: # 5968 times (85.0ms+49.9ms) by Template::Grammar::__ANON__[Parser.yp:168] at line 168 of /root/tor-browser-build/Parser.yp, avg 23µs/call
sub leave_block {
21559683.77ms my $self = shift;
216596821.9ms596849.9ms my $label = $self->block_label;
# spent 49.9ms making 5968 calls to Template::Parser::block_label, avg 8µs/call
21759688.09ms pop(@{ $self->{ IN_BLOCK } });
218596831.8ms 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 49.9ms within Template::Parser::block_label which was called 5968 times, avg 8µs/call: # 5968 times (49.9ms+0s) by Template::Parser::leave_block at line 216, avg 8µs/call
sub block_label {
22859684.55ms my ($self, $prefix, $suffix) = @_;
22959687.22ms my $blocks = $self->{ IN_BLOCK };
230596814.3ms my $name = @$blocks
231 ? $blocks->[-1] . scalar @$blocks
232 : undef;
233596862.3ms 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 18.7s (11.2+7.45) within Template::Parser::new_style which was called 383161 times, avg 49µs/call: # 383161 times (11.2s+7.45s) by Template::Parser::new at line 195, avg 49µs/call
sub new_style {
247383161248ms my ($self, $config) = @_;
248383161770ms my $styles = $self->{ STYLE } ||= [ ];
249383161172ms my ($tagstyle, $tags, $start, $end, $out, $key);
250
251 # clone new style from previous or default style
2523831612.73s my $style = { %{ $styles->[-1] || $DEFAULT_STYLE } };
253
254 # expand START_TAG and END_TAG from specified TAG_STYLE
255383161364ms 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
2643831611.02s foreach $key (keys %$DEFAULT_STYLE) {
26534484491.14s $style->{ $key } = $config->{ $key } if defined $config->{ $key };
266 }
267
268383161298ms $start = $style->{ START_TAG };
269383161288ms $end = $style->{ END_TAG };
270383161287ms $out = $style->{ OUTLINE_TAG };
2713831611.52s3831617.45s $style->{ TEXT_SPLIT } = $self->text_splitter($start, $end, $out);
# spent 7.45s making 383161 calls to Template::Parser::text_splitter, avg 19µs/call
272
273383161273ms push(@$styles, $style);
2743831612.06s return $style;
275}
276
277
# spent 7.45s (5.63+1.82) within Template::Parser::text_splitter which was called 383161 times, avg 19µs/call: # 383161 times (5.63s+1.82s) by Template::Parser::new_style at line 271, avg 19µs/call
sub text_splitter {
278383161382ms my ($self, $start, $end, $out) = @_;
279
280383161264ms 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 {
2993831618.00s7663221.82s return qr/
# spent 1.05s making 383161 calls to Template::Parser::CORE:regcomp, avg 3µs/call # spent 769ms making 383161 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 244s (11.1+232) within Template::Parser::parse which was called 384174 times, avg 634µs/call: # 384174 times (11.1s+232s) by Template::Provider::_compile at line 844 of Template/Provider.pm, avg 634µs/call
sub parse {
336384174364ms my ($self, $text, $info) = @_;
337384174109ms my ($tokens, $block);
338
339 $info->{ DEBUG } = $self->{ DEBUG_DIRS }
340384174675ms 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())
345384174679ms my $defblock = $self->{ DEFBLOCK } = { };
346384174557ms my $metadata = $self->{ METADATA } = [ ];
347384174527ms my $variables = $self->{ VARIABLES } = { };
348384174321ms $self->{ DEFBLOCKS } = [ ];
349
350384174271ms $self->{ _ERROR } = '';
351
352 # split file into TEXT/DIRECTIVE chunks
353384174961ms38417458.0s $tokens = $self->split_text($text)
# spent 58.0s making 384174 calls to Template::Parser::split_text, avg 151µs/call
354 || return undef; ## RETURN ##
355
356384174422ms push(@{ $self->{ FILEINFO } }, $info);
357
358 # parse chunks
3593841741.10s384174174s $block = $self->_parse($tokens, $info);
# spent 174s making 384174 calls to Template::Parser::_parse, avg 454µs/call
360
361384174339ms pop(@{ $self->{ FILEINFO } });
362
363384174159ms return undef unless $block; ## RETURN ##
364
365 $self->debug("compiled main template document block:\n$block")
366384174342ms if $self->{ DEBUG } & Template::Constants::DEBUG_PARSER;
367
368 return {
3693841743.12s 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 58.0s (28.3+29.7) within Template::Parser::split_text which was called 384174 times, avg 151µs/call: # 384174 times (28.3s+29.7s) by Template::Parser::parse at line 353, avg 151µs/call
sub split_text {
385384174383ms my ($self, $text) = @_;
386384174206ms my ($pre, $dir, $prelines, $dirlines, $postlines, $chomp, $tags, @tags);
387384174515ms my $style = $self->{ STYLE }->[-1];
388 my ($start, $end, $out, $prechomp, $postchomp, $interp ) =
389384174897ms @$style{ qw( START_TAG END_TAG OUTLINE_TAG PRE_CHOMP POST_CHOMP INTERPOLATE ) };
3903841742.17s384174549ms my $tags_dir = $self->{ANYCASE} ? qr<TAGS>i : qr<TAGS>;
# spent 549ms making 384174 calls to Template::Parser::CORE:qr, avg 1µs/call
391384174267ms my $split = $style->{ TEXT_SPLIT };
392384174328ms my $has_out = defined $out;
393
394384174261ms my @tokens = ();
395384174167ms my $line = 1;
396
397 return \@tokens ## RETURN ##
398384174334ms unless defined $text && length $text;
399
400 # extract all directives from the text
4013841745.58s7683481.93s while ($text =~ s/$split//) {
# spent 1.27s making 384174 calls to Template::Parser::CORE:subst, avg 3µs/call # spent 666ms making 384174 calls to Template::Parser::CORE:regcomp, avg 2µs/call
402314713386ms $pre = $1;
403314713406ms $dir = defined($2) ? $2 : $3;
404314713109ms $pre = '' unless defined $pre;
405314713119ms $dir = '' unless defined $dir;
406
407314713269ms $prelines = ($pre =~ tr/\n//); # newlines in preceding text
408314713110ms $dirlines = ($dir =~ tr/\n//); # newlines in directive tag
409314713105ms $postlines = 0; # newlines chomped after tag
410
411314713298ms for ($dir) {
4123147131.56s314713175ms 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.45s629426751ms if(s/^($CHOMP_FLAGS)?(\s*)//so && $2) {
# spent 664ms making 314713 calls to Template::Parser::CORE:subst, avg 2µs/call # spent 87.1ms making 314713 calls to Template::Parser::CORE:regcomp, avg 277ns/call
419314713173ms my $chomped = $2;
420314713152ms my $linecount = ($chomped =~ tr/\n//); # newlines in chomped whitespace
421314713135ms $linecount ||= 0;
422314713100ms $prelines += $linecount;
423314713120ms $dirlines -= $linecount;
424 }
425 # PRE_CHOMP: process whitespace before tag
426314713158ms $chomp = $1 ? $1 : $prechomp;
427314713125ms $chomp =~ tr/-=~+/1230/;
428314713118ms if ($chomp && $pre) {
429 # chomp off whitespace and newline preceding directive
4301991943µs if ($chomp == CHOMP_ALL) {
431199111.1ms19916.35ms $pre =~ s{ (\r?\n|^) [^\S\n]* \z }{}mx;
# spent 6.35ms 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.43s6294263.02s s/\s*($CHOMP_FLAGS)?\s*$//so;
# spent 2.97s making 314713 calls to Template::Parser::CORE:subst, avg 9µs/call # spent 42.0ms making 314713 calls to Template::Parser::CORE:regcomp, avg 133ns/call
444314713185ms $chomp = $1 ? $1 : $postchomp;
445314713121ms $chomp =~ tr/-=~+/1230/;
446314713172ms if ($chomp) {
4474716541.3ms if ($chomp == CHOMP_ALL) {
44847165294ms47165124ms $text =~ s{ ^ ([^\S\n]* \n) }{}x
# spent 124ms 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
464314713383ms if (length $pre) {
465 push(@tokens, $interp
466 ? [ $pre, $line, 'ITEXT' ]
467 : ('TEXT', $pre) );
468 }
46931471369.5ms $line += $prelines;
470
471 # and now the directive, along with line number information
472314713165ms if (length $dir) {
473 # the TAGS directive is a compile-time switch
4743147132.73s629426449ms if ($dir =~ /^$tags_dir\s+(.*)/) {
# spent 355ms making 314713 calls to Template::Parser::CORE:regcomp, avg 1µs/call # spent 94.1ms making 314713 calls to Template::Parser::CORE:match, avg 299ns/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.36s31471321.9s push(@tokens,
# spent 21.9s making 314713 calls to Template::Parser::tokenise_directive, avg 70µ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.30s629426809ms $line += $dirlines + $postlines;
# spent 536ms making 314713 calls to Template::Parser::CORE:subst, avg 2µs/call # spent 273ms making 314713 calls to Template::Parser::CORE:regcomp, avg 868ns/call
503 }
504
505 # anything remaining in the string is plain text
506384174507ms push(@tokens, $interp
507 ? [ $text, $line, 'ITEXT' ]
508 : ( 'TEXT', $text) )
509 if length $text;
510
5113841742.44s 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 56.3ms (48.4+7.91) within Template::Parser::interpolate_text which was called 1991 times, avg 28µs/call: # 1991 times (48.4ms+7.91ms) by Template::Parser::tokenise_directive at line 656, avg 28µs/call
sub interpolate_text {
52419912.01ms my ($self, $text, $line) = @_;
52519912.56ms my @tokens = ();
5261991774µs my ($pre, $var, $dir);
527
528
529199120.7ms19917.05ms while ($text =~
# spent 7.05ms making 1991 calls to Template::Parser::CORE:match, avg 4µ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.82ms ($pre, $var, $dir) = ($1, $3 || $4, $2);
542
543 # preceding text
54419912.42ms if (defined($pre) && length($pre)) {
54519911.69ms $line += $pre =~ tr/\n//;
54619914.98ms1991554µs $pre =~ s/\\\$/\$/g;
# spent 554µs making 1991 calls to Template::Parser::CORE:subst, avg 278ns/call
54719912.46ms push(@tokens, 'TEXT', $pre);
548 }
549 # $variable reference
55019916.48ms1991310µs if ($var) {
# spent 310µs making 1991 calls to Template::Parser::CORE:match, avg 156ns/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
561199123.9ms 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.9s (16.6+5.29) within Template::Parser::tokenise_directive which was called 314713 times, avg 70µs/call: # 314713 times (16.6s+5.29s) by Template::Parser::split_text at line 491, avg 70µs/call
sub tokenise_directive {
590314713192ms my ($self, $text, $line) = @_;
59131471389.7ms my ($token, $uctoken, $type, $lookup);
592314713224ms my $lextable = $self->{ LEXTABLE };
593314713234ms my $style = $self->{ STYLE }->[-1];
594314713354ms my ($anycase, $start, $end) = @$style{ qw( ANYCASE START_TAG END_TAG ) };
595314713181ms my @tokens = ( );
596
5973147133.14s3167041.77s while ($text =~
# spent 1.77s making 316704 calls to Template::Parser::CORE:match, avg 6µ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
6391536347366ms next if $1;
640
641 # quoted string
64215363472.24s if (defined ($token = $3)) {
643 # double-quoted string may include $variable references
644243677173ms if ($2 eq '"') {
645158959741ms158959109ms if ($token =~ /[\$\\]/) {
# spent 109ms making 158959 calls to Template::Parser::CORE:match, avg 687ns/call
64619911.03ms $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.41ms for ($token) {
652199113.7ms19914.44ms s/\\([^\$nrt])/$1/g;
# spent 4.44ms making 1991 calls to Template::Parser::CORE:subst, avg 2µs/call
653199138.0ms597310.3ms s/\\([nrt])/$QUOTED_ESCAPES->{ $1 }/ge;
# spent 5.25ms making 1991 calls to Template::Parser::CORE:subst, avg 3µs/call # spent 5.03ms making 3982 calls to Template::Parser::CORE:substcont, avg 1µs/call
654 }
655 push(@tokens, ('"') x 2,
656199114.1ms199156.3ms @{ $self->interpolate_text($token) },
# spent 56.3ms making 1991 calls to Template::Parser::interpolate_text, avg 28µs/call
657 ('"') x 2);
65819911.68ms next;
659 }
660 else {
66115696861.4ms $type = 'LITERAL';
662156968608ms156968101ms $token =~ s['][\\']g;
# spent 101ms making 156968 calls to Template::Parser::CORE:subst, avg 644ns/call
66315696890.3ms $token = "'$token'";
664 }
665 }
666 else {
6678471818.8ms $type = 'LITERAL';
6688471827.5ms $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.
683571294246ms 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 {
697571294148ms $uctoken = $token;
698 }
699571294573ms if (defined ($type = $lextable->{ $uctoken })) {
700 $token = $uctoken;
701 }
702 else {
703431260147ms $type = 'IDENT';
704 }
705 }
706 elsif (defined ($token = $7)) {
707 # reserved words may be in lower case unless case sensitive
708707297138ms $uctoken = $anycase ? uc $token : $token;
709707297475ms unless (defined ($type = $lextable->{ $uctoken })) {
710 $type = 'UNQUOTED';
711 }
712 }
713
714153435610.4s15343563.24s push(@tokens, $type, $token);
# spent 3.24s 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.79s 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.24s (2.91+334ms) within Template::Parser::location which was called 313428 times, avg 10µs/call: # 313428 times (2.91s+334ms) by Template::Grammar::__ANON__[Parser.yp:79] at line 78 of /root/tor-browser-build/Parser.yp, avg 10µs/call
sub location {
791313428129ms my $self = shift;
792313428158ms return "\n" unless $self->{ FILE_INFO };
793313428224ms my $line = ${ $self->{ LINE } };
794313428173ms my $info = $self->{ FILEINFO }->[-1];
795 my $file = $info->{ path } || $info->{ name }
796313428223ms || '(unknown template)';
7973134281.57s313428334ms $line =~ s/\-.*$//; # might be 'n-n'
# spent 334ms making 313428 calls to Template::Parser::CORE:subst, avg 1µs/call
79831342888.2ms $line ||= 1;
7993134281.59s 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 174s (122+52.7) within Template::Parser::_parse which was called 384174 times, avg 454µs/call: # 384174 times (122s+52.7s) by Template::Parser::parse at line 359, avg 454µs/call
sub _parse {
823384174190ms my ($self, $tokens, $info) = @_;
824384174164ms my ($token, $value, $text, $line, $inperl);
825 my ($state, $stateno, $status, $action, $lookup, $coderet, @codevars);
826 my ($lhs, $len, $code); # rule contents
827384174571ms my $stack = [ [ 0, undef ] ]; # DFA stack
828
829# DEBUG
830# local $" = ', ';
831
832 # retrieve internal rule and state tables
833384174572ms 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 })
839384174346ms if $self->{ TRACE_VARS };
840
841 # call the grammar set_factory method to install emitter factory
8423841741.60s384174747ms $self->{ GRAMMAR }->install_factory($self->{ FACTORY });
# spent 747ms making 384174 calls to Template::Grammar::install_factory, avg 2µs/call
843
844384174197ms $line = $inperl = 0;
845384174661ms $self->{ LINE } = \$line;
846384174598ms $self->{ FILE } = $info->{ name };
847384174457ms $self->{ INPERL } = \$inperl;
848
849384174180ms $status = CONTINUE;
850384174213ms my $in_string = 0;
851
8523841749.33s while(1) {
853 # get state number and state
85499830732.18s $stateno = $stack->[-1]->[0];
85599830732.82s $state = $states->[$stateno];
856
857 # see if any lookaheads exist for the current state
85899830735.07s 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
86246395581.96s while (! defined $token && @$tokens) {
86326731711.05s $token = shift(@$tokens);
86426731711.77s if (ref $token) {
865314713382ms ($text, $line, $token) = @$token;
866314713127ms if (ref $token) {
867314713272ms 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.20s unshift(@$tokens, @$token, (';') x 2);
894 }
89531471390.9ms $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
9132358458559ms $in_string = ! $in_string if $token eq '"';
9142358458659ms $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
9194639558784ms $token = '' unless defined $token;
920
921 # get the next state for the current lookahead token
922 $action = defined ($lookup = $state->{'ACTIONS'}->{ $token })
923 ? $lookup
92446395583.82s : defined ($lookup = $state->{'DEFAULT'})
925 ? $lookup
926 : undef;
927 }
928 else {
929 # no lookahead actions
93053435151.39s $action = $state->{'DEFAULT'};
931 }
932
933 # ERROR: no ACTION
93499830731.27s last unless defined $action;
935
936 # - - - - - - - - - - - - - - - - - - - - - - - - - - - -
937 # shift (+ive ACTION)
938 # - - - - - - - - - - - - - - - - - - - - - - - - - - - -
93999830731.66s if ($action > 0) {
94027426321.57s push(@$stack, [ $action, $value ]);
9412742632553ms $token = $value = undef;
9422742632490ms redo;
943 };
944
945 # - - - - - - - - - - - - - - - - - - - - - - - - - - - -
946 # reduce (-ive ACTION)
947 # - - - - - - - - - - - - - - - - - - - - - - - - - - - -
94872404418.15s ($lhs, $len, $code) = @{ $rules->[ -$action ] };
949
950 # no action imples ACCEPTance
9517240441841ms $action
952 or $status = ACCEPT;
953
954 # use dummy sub if code ref doesn't exist
955249871616.5s
# spent 1.81s within Template::Parser::__ANON__[/usr/lib/x86_64-linux-gnu/perl5/5.28/Template/Parser.pm:955] which was called 2498716 times, avg 725ns/call: # 2498716 times (1.81s+0s) by Template::Parser::_parse at line 963, avg 725ns/call
$code = sub { $_[1] }
95672404413.88s unless $code;
957
958 @codevars = $len
95972404419.51s ? map { $_->[1] } @$stack[ -$len .. -1 ]
960 : ();
961
96272404412.04s eval {
963724044111.4s724044151.9s $coderet = &$code( $self, @codevars );
# spent 16.7s making 503416 calls to Template::Grammar::__ANON__[Parser.yp:76], avg 33µs/call # spent 7.12s making 384174 calls to Template::Grammar::__ANON__[Parser.yp:64], avg 19µs/call # spent 5.69s making 321403 calls to Template::Grammar::__ANON__[Parser.yp:79], avg 18µs/call # spent 4.95s making 439240 calls to Template::Grammar::__ANON__[Parser.yp:67], avg 11µs/call # spent 4.50s making 372329 calls to Template::Grammar::__ANON__[Parser.yp:305], avg 12µs/call # spent 2.62s making 250383 calls to Template::Grammar::__ANON__[Parser.yp:90], avg 10µs/call # spent 2.45s making 242791 calls to Template::Grammar::__ANON__[Parser.yp:342], avg 10µs/call # spent 1.81s making 2498716 calls to Template::Parser::__ANON__[Template/Parser.pm:955], avg 725ns/call # spent 1.23s making 439240 calls to Template::Grammar::__ANON__[Parser.yp:73], avg 3µs/call # spent 966ms making 385579 calls to Template::Grammar::__ANON__[Parser.yp:72], avg 3µs/call # spent 676ms making 37103 calls to Template::Grammar::__ANON__[Parser.yp:141], avg 18µs/call # spent 657ms making 424294 calls to Template::Grammar::__ANON__[Parser.yp:345], avg 2µs/call # spent 514ms making 285731 calls to Template::Grammar::__ANON__[Parser.yp:382], avg 2µs/call # spent 350ms making 5968 calls to Template::Grammar::__ANON__[Parser.yp:168], avg 59µs/call # spent 314ms making 159453 calls to Template::Grammar::__ANON__[Parser.yp:341], avg 2µs/call # spent 314ms making 249772 calls to Template::Grammar::__ANON__[Parser.yp:387], avg 1µs/call # spent 120ms making 3982 calls to Template::Grammar::__ANON__[Parser.yp:95], avg 30µs/call # spent 101ms making 5968 calls to Template::Grammar::__ANON__[Parser.yp:167], avg 17µs/call # spent 96.6ms making 4031 calls to Template::Grammar::__ANON__[Parser.yp:115], avg 24µs/call # spent 80.8ms making 6966 calls to Template::Grammar::__ANON__[Parser.yp:113], avg 12µs/call # spent 58.5ms making 21902 calls to Template::Grammar::__ANON__[Parser.yp:334], avg 3µs/call # spent 54.3ms making 42940 calls to Template::Grammar::__ANON__[Parser.yp:386], avg 1µs/call # spent 49.0ms making 1991 calls to Template::Grammar::__ANON__[Parser.yp:440], avg 25µs/call # spent 48.8ms making 22050 calls to Template::Grammar::__ANON__[Parser.yp:331], avg 2µs/call # spent 47.7ms making 28096 calls to Template::Grammar::__ANON__[Parser.yp:152], avg 2µs/call # spent 47.6ms making 22921 calls to Template::Grammar::__ANON__[Parser.yp:358], avg 2µs/call # spent 46.5ms making 1013 calls to Template::Grammar::__ANON__[Parser.yp:118], avg 46µs/call # spent 39.6ms making 18052 calls to Template::Grammar::__ANON__[Parser.yp:302], avg 2µs/call # spent 35.3ms making 3982 calls to Template::Grammar::__ANON__[Parser.yp:114], avg 9µs/call # spent 30.6ms making 1991 calls to Template::Grammar::__ANON__[Parser.yp:307], avg 15µs/call # spent 21.6ms making 9007 calls to Template::Grammar::__ANON__[Parser.yp:151], avg 2µs/call # spent 18.6ms making 5988 calls to Template::Grammar::__ANON__[Parser.yp:325], avg 3µs/call # spent 16.7ms making 6015 calls to Template::Grammar::__ANON__[Parser.yp:361], avg 3µs/call # spent 13.7ms making 8013 calls to Template::Grammar::__ANON__[Parser.yp:374], avg 2µs/call # spent 11.1ms making 2984 calls to Template::Grammar::__ANON__[Parser.yp:176], avg 4µs/call # spent 10.8ms making 2984 calls to Template::Grammar::__ANON__[Parser.yp:175], avg 4µs/call # spent 8.16ms making 2988 calls to Template::Grammar::__ANON__[Parser.yp:150], avg 3µs/call # spent 7.46ms making 1991 calls to Template::Grammar::__ANON__[Parser.yp:435], avg 4µs/call # spent 6.38ms making 2016 calls to Template::Grammar::__ANON__[Parser.yp:359], avg 3µs/call # spent 5.36ms making 1990 calls to Template::Grammar::__ANON__[Parser.yp:360], avg 3µs/call # spent 4.99ms making 1991 calls to Template::Grammar::__ANON__[Parser.yp:299], avg 3µs/call # spent 4.55ms making 1991 calls to Template::Grammar::__ANON__[Parser.yp:301], avg 2µs/call # spent 4.12ms making 1991 calls to Template::Grammar::__ANON__[Parser.yp:436], avg 2µs/call # spent 3.90ms making 1990 calls to Template::Grammar::__ANON__[Parser.yp:322], avg 2µs/call # spent 3.49ms making 1013 calls to Template::Grammar::__ANON__[Parser.yp:407], avg 3µs/call # spent 3.19ms making 998 calls to Template::Grammar::__ANON__[Parser.yp:416], avg 3µs/call # spent 2.62ms making 1013 calls to Template::Grammar::__ANON__[Parser.yp:412], avg 3µs/call # spent 3µs making 1 call to Template::Grammar::__ANON__[Parser.yp:362]
964 };
9657240441756ms if ($@) {
966 my $err = $@;
967 chomp $err;
968 return $self->_parse_error($err);
969 }
970
971 # reduce stack by $len
97272404413.82s splice(@$stack, -$len, $len);
973
974 # ACCEPT
97572404413.99s return $coderet ## RETURN ##
976 if $status == ACCEPT;
977
978 # ABORT
979 return undef ## RETURN ##
9806856267996ms if $status == ABORT;
981
982 # ERROR
983 last
98468562671.09s 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.39s within Template::Parser::CORE:match which was called 2643427 times, avg 2µs/call: # 1534356 times (3.24s+0s) by Template::Parser::tokenise_directive at line 714, avg 2µs/call # 316704 times (1.77s+0s) by Template::Parser::tokenise_directive at line 597, avg 6µs/call # 314713 times (175ms+0s) by Template::Parser::split_text at line 412, avg 557ns/call # 314713 times (94.1ms+0s) by Template::Parser::split_text at line 474, avg 299ns/call # 158959 times (109ms+0s) by Template::Parser::tokenise_directive at line 645, avg 687ns/call # 1991 times (7.05ms+0s) by Template::Parser::interpolate_text at line 529, avg 4µs/call # 1991 times (310µs+0s) by Template::Parser::interpolate_text at line 550, avg 156ns/call
sub Template::Parser::CORE:match; # opcode
# spent 1.32s within Template::Parser::CORE:qr which was called 767337 times, avg 2µs/call: # 384174 times (549ms+0s) by Template::Parser::split_text at line 390, avg 1µs/call # 383161 times (769ms+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 (700ns+0s) by Template::Config::load at line 115
sub Template::Parser::CORE:qr; # opcode
# spent 2.48s within Template::Parser::CORE:regcomp which was called 2026187 times, avg 1µs/call: # 384174 times (666ms+0s) by Template::Parser::split_text at line 401, avg 2µs/call # 383161 times (1.05s+0s) by Template::Parser::text_splitter at line 299, avg 3µs/call # 314713 times (355ms+0s) by Template::Parser::split_text at line 474, avg 1µs/call # 314713 times (273ms+0s) by Template::Parser::split_text at line 502, avg 868ns/call # 314713 times (87.1ms+0s) by Template::Parser::split_text at line 418, avg 277ns/call # 314713 times (42.0ms+0s) by Template::Parser::split_text at line 443, avg 133ns/call
sub Template::Parser::CORE:regcomp; # opcode
# spent 6.02s within Template::Parser::CORE:subst which was called 1853838 times, avg 3µs/call: # 384174 times (1.27s+0s) by Template::Parser::split_text at line 401, avg 3µs/call # 314713 times (2.97s+0s) by Template::Parser::split_text at line 443, avg 9µs/call # 314713 times (664ms+0s) by Template::Parser::split_text at line 418, avg 2µs/call # 314713 times (536ms+0s) by Template::Parser::split_text at line 502, avg 2µs/call # 313428 times (334ms+0s) by Template::Parser::location at line 797, avg 1µs/call # 156968 times (101ms+0s) by Template::Parser::tokenise_directive at line 662, avg 644ns/call # 47165 times (124ms+0s) by Template::Parser::split_text at line 448, avg 3µs/call # 1991 times (6.35ms+0s) by Template::Parser::split_text at line 431, avg 3µs/call # 1991 times (5.25ms+0s) by Template::Parser::tokenise_directive at line 653, avg 3µs/call # 1991 times (4.44ms+0s) by Template::Parser::tokenise_directive at line 652, avg 2µs/call # 1991 times (554µs+0s) by Template::Parser::interpolate_text at line 546, avg 278ns/call
sub Template::Parser::CORE:subst; # opcode
# spent 5.03ms within Template::Parser::CORE:substcont which was called 3982 times, avg 1µs/call: # 3982 times (5.03ms+0s) by Template::Parser::tokenise_directive at line 653, avg 1µs/call
sub Template::Parser::CORE:substcont; # opcode
# spent 3µs within Template::Parser::__ANON__ which was called 2 times, avg 2µs/call: # once (2µs+0s) by Template::Parser::BEGIN@41 at line 41 # once (1µs+0s) by Template::Parser::BEGIN@40 at line 40
sub Template::Parser::__ANON__; # xsub