| Filename | /usr/lib/x86_64-linux-gnu/perl5/5.20/Template/Document.pm |
| Statements | Executed 266 statements in 6.63ms |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 40 | 1 | 1 | 23.9ms | 24.8ms | Template::Document::new |
| 40 | 1 | 1 | 931µs | 931µs | Template::Document::CORE:match (opcode) |
| 40 | 1 | 1 | 761µs | 479ms | Template::Document::process (recurses: max depth 2, inclusive time 148ms) |
| 4 | 1 | 1 | 34µs | 63µs | Template::Document::AUTOLOAD |
| 4 | 1 | 1 | 29µs | 29µs | Template::Document::CORE:subst (opcode) |
| 1 | 1 | 1 | 14µs | 22µs | Template::Document::BEGIN@24 |
| 1 | 1 | 1 | 10µs | 10µs | Template::Document::BEGIN@34 |
| 4 | 1 | 1 | 9µs | 9µs | Template::Document::blocks |
| 1 | 1 | 1 | 8µs | 41µs | Template::Document::BEGIN@26 |
| 1 | 1 | 1 | 7µs | 12µs | Template::Document::BEGIN@25 |
| 1 | 1 | 1 | 7µs | 18µs | Template::Document::BEGIN@27 |
| 0 | 0 | 0 | 0s | 0s | Template::Document::_dump |
| 0 | 0 | 0 | 0s | 0s | Template::Document::as_perl |
| 0 | 0 | 0 | 0s | 0s | Template::Document::block |
| 0 | 0 | 0 | 0s | 0s | Template::Document::catch_warnings |
| 0 | 0 | 0 | 0s | 0s | Template::Document::variables |
| 0 | 0 | 0 | 0s | 0s | Template::Document::write_perl_file |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | ##============================================================= -*-Perl-*- | ||||
| 2 | # | ||||
| 3 | # Template::Document | ||||
| 4 | # | ||||
| 5 | # DESCRIPTION | ||||
| 6 | # Module defining a class of objects which encapsulate compiled | ||||
| 7 | # templates, storing additional block definitions and metadata | ||||
| 8 | # as well as the compiled Perl sub-routine representing the main | ||||
| 9 | # template content. | ||||
| 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 | #============================================================================ | ||||
| 21 | |||||
| 22 | package Template::Document; | ||||
| 23 | |||||
| 24 | 2 | 29µs | # spent 22µs (14+8) within Template::Document::BEGIN@24 which was called:
# once (14µs+8µs) by Template::Provider::BEGIN@46 at line 24 # spent 22µs making 1 call to Template::Document::BEGIN@24
# spent 8µs making 1 call to strict::import | ||
| 25 | 2 | 16µs | # spent 12µs (7+4) within Template::Document::BEGIN@25 which was called:
# once (7µs+4µs) by Template::Provider::BEGIN@46 at line 25 # spent 12µs making 1 call to Template::Document::BEGIN@25
# spent 4µs making 1 call to warnings::import | ||
| 26 | 2 | 74µs | # spent 41µs (8+33) within Template::Document::BEGIN@26 which was called:
# once (8µs+33µs) by Template::Provider::BEGIN@46 at line 26 # spent 41µs making 1 call to Template::Document::BEGIN@26
# spent 33µs making 1 call to base::import | ||
| 27 | 2 | 28µs | # spent 18µs (7+10) within Template::Document::BEGIN@27 which was called:
# once (7µs+10µs) by Template::Provider::BEGIN@46 at line 27 # spent 18µs making 1 call to Template::Document::BEGIN@27
# spent 10µs making 1 call to Exporter::import | ||
| 28 | |||||
| 29 | our $VERSION = 2.79; | ||||
| 30 | our $DEBUG = 0 unless defined $DEBUG; | ||||
| 31 | our $ERROR = ''; | ||||
| 32 | our ($COMPERR, $AUTOLOAD, $UNICODE); | ||||
| 33 | |||||
| 34 | # spent 10µs within Template::Document::BEGIN@34 which was called:
# once (10µs+0s) by Template::Provider::BEGIN@46 at line 47 | ||||
| 35 | # UNICODE is supported in versions of Perl from 5.008 onwards | ||||
| 36 | if ($UNICODE = $] > 5.007 ? 1 : 0) { | ||||
| 37 | if ($] > 5.008) { | ||||
| 38 | # utf8::is_utf8() available from Perl 5.8.1 onwards | ||||
| 39 | *is_utf8 = \&utf8::is_utf8; | ||||
| 40 | } | ||||
| 41 | elsif ($] == 5.008) { | ||||
| 42 | # use Encode::is_utf8() for Perl 5.8.0 | ||||
| 43 | require Encode; | ||||
| 44 | *is_utf8 = \&Encode::is_utf8; | ||||
| 45 | } | ||||
| 46 | } | ||||
| 47 | 1 | 10µs | } # spent 10µs making 1 call to Template::Document::BEGIN@34 | ||
| 48 | |||||
| 49 | |||||
| 50 | #======================================================================== | ||||
| 51 | # ----- PUBLIC METHODS ----- | ||||
| 52 | #======================================================================== | ||||
| 53 | |||||
| 54 | #------------------------------------------------------------------------ | ||||
| 55 | # new(\%document) | ||||
| 56 | # | ||||
| 57 | # Creates a new self-contained Template::Document object which | ||||
| 58 | # encapsulates a compiled Perl sub-routine, $block, any additional | ||||
| 59 | # BLOCKs defined within the document ($defblocks, also Perl sub-routines) | ||||
| 60 | # and additional $metadata about the document. | ||||
| 61 | #------------------------------------------------------------------------ | ||||
| 62 | |||||
| 63 | # spent 24.8ms (23.9+931µs) within Template::Document::new which was called 40 times, avg 621µs/call:
# 40 times (23.9ms+931µs) by Template::Provider::_compile at line 894 of Template/Provider.pm, avg 621µs/call | ||||
| 64 | 10 | 5µs | my ($class, $doc) = @_; | ||
| 65 | 10 | 17µs | my ($block, $defblocks, $variables, $metadata) = @$doc{ qw( BLOCK DEFBLOCKS VARIABLES METADATA ) }; | ||
| 66 | 10 | 2µs | $defblocks ||= { }; | ||
| 67 | 10 | 2µs | $metadata ||= { }; | ||
| 68 | |||||
| 69 | # evaluate Perl code in $block to create sub-routine reference if necessary | ||||
| 70 | 10 | 5µs | unless (ref $block) { | ||
| 71 | 10 | 58µs | local $SIG{__WARN__} = \&catch_warnings; | ||
| 72 | 10 | 6µs | $COMPERR = ''; | ||
| 73 | |||||
| 74 | # DON'T LOOK NOW! - blindly untainting can make you go blind! | ||||
| 75 | 10 | 292µs | 40 | 931µs | $block =~ /(.*)/s; # spent 931µs making 40 calls to Template::Document::CORE:match, avg 23µs/call |
| 76 | 10 | 53µs | $block = $1; | ||
| 77 | |||||
| 78 | 10 | 5.85ms | $block = eval $block; # spent 4µs executing statements in string eval
# spent 3µs executing statements in string eval
# spent 0s executing statements in 3 string evals (merged)
# spent 0s executing statements in 4 string evals (merged)
# spent 0s executing statements in 4 string evals (merged)
# spent 0s executing statements in 4 string evals (merged)
# spent 0s executing statements in 4 string evals (merged) # includes 35µs spent executing 4 calls to 1 sub defined therein. # spent 0s executing statements in 4 string evals (merged) # includes 39µs spent executing 4 calls to 1 sub defined therein. # spent 0s executing statements in 4 string evals (merged) # spent 0s executing statements in 3 string evals (merged) # spent 0s executing statements in 4 string evals (merged) # spent 0s executing statements in 4 string evals (merged) | ||
| 79 | 10 | 26µs | return $class->error($@) | ||
| 80 | unless defined $block; | ||||
| 81 | } | ||||
| 82 | |||||
| 83 | # same for any additional BLOCK definitions | ||||
| 84 | @$defblocks{ keys %$defblocks } = | ||||
| 85 | # MORE BLIND UNTAINTING - turn away if you're squeamish | ||||
| 86 | map { | ||||
| 87 | 10 | 20µs | ref($_) | ||
| 88 | ? $_ | ||||
| 89 | : ( /(.*)/s && eval($1) or return $class->error($@) ) | ||||
| 90 | } values %$defblocks; | ||||
| 91 | |||||
| 92 | 10 | 119µs | bless { | ||
| 93 | %$metadata, | ||||
| 94 | _BLOCK => $block, | ||||
| 95 | _DEFBLOCKS => $defblocks, | ||||
| 96 | _VARIABLES => $variables, | ||||
| 97 | _HOT => 0, | ||||
| 98 | }, $class; | ||||
| 99 | } | ||||
| 100 | |||||
| 101 | |||||
| 102 | #------------------------------------------------------------------------ | ||||
| 103 | # block() | ||||
| 104 | # | ||||
| 105 | # Returns a reference to the internal sub-routine reference, _BLOCK, | ||||
| 106 | # that constitutes the main document template. | ||||
| 107 | #------------------------------------------------------------------------ | ||||
| 108 | |||||
| 109 | sub block { | ||||
| 110 | return $_[0]->{ _BLOCK }; | ||||
| 111 | } | ||||
| 112 | |||||
| 113 | |||||
| 114 | #------------------------------------------------------------------------ | ||||
| 115 | # blocks() | ||||
| 116 | # | ||||
| 117 | # Returns a reference to a hash array containing any BLOCK definitions | ||||
| 118 | # from the template. The hash keys are the BLOCK nameand the values | ||||
| 119 | # are references to Template::Document objects. Returns 0 (# an empty hash) | ||||
| 120 | # if no blocks are defined. | ||||
| 121 | #------------------------------------------------------------------------ | ||||
| 122 | |||||
| 123 | # spent 9µs within Template::Document::blocks which was called 4 times, avg 2µs/call:
# 4 times (9µs+0s) by Template::Context::process at line 339 of Template/Context.pm, avg 2µs/call | ||||
| 124 | 1 | 3µs | return $_[0]->{ _DEFBLOCKS }; | ||
| 125 | } | ||||
| 126 | |||||
| 127 | |||||
| 128 | #----------------------------------------------------------------------- | ||||
| 129 | # variables() | ||||
| 130 | # | ||||
| 131 | # Returns a reference to a hash of variables used in the template. | ||||
| 132 | # This requires the TRACE_VARS option to be enabled. | ||||
| 133 | #----------------------------------------------------------------------- | ||||
| 134 | |||||
| 135 | sub variables { | ||||
| 136 | return $_[0]->{ _VARIABLES }; | ||||
| 137 | } | ||||
| 138 | |||||
| 139 | #------------------------------------------------------------------------ | ||||
| 140 | # process($context) | ||||
| 141 | # | ||||
| 142 | # Process the document in a particular context. Checks for recursion, | ||||
| 143 | # registers the document with the context via visit(), processes itself, | ||||
| 144 | # and then unwinds with a large gin and tonic. | ||||
| 145 | #------------------------------------------------------------------------ | ||||
| 146 | |||||
| 147 | # spent 479ms (761µs+479) within Template::Document::process which was called 40 times, avg 12.0ms/call:
# 40 times (761µs+479ms) by Template::Context::process at line 347 of Template/Context.pm, avg 12.0ms/call | ||||
| 148 | 10 | 6µs | my ($self, $context) = @_; | ||
| 149 | 10 | 6µs | my $defblocks = $self->{ _DEFBLOCKS }; | ||
| 150 | 10 | 2µs | my $output; | ||
| 151 | |||||
| 152 | |||||
| 153 | # check we're not already visiting this template | ||||
| 154 | return $context->throw(Template::Constants::ERROR_FILE, | ||||
| 155 | "recursion into '$self->{ name }'") | ||||
| 156 | 10 | 4µs | if $self->{ _HOT } && ! $context->{ RECURSION }; ## RETURN ## | ||
| 157 | |||||
| 158 | 10 | 30µs | 40 | 128µs | $context->visit($self, $defblocks); # spent 128µs making 40 calls to Template::Context::visit, avg 3µs/call |
| 159 | |||||
| 160 | 10 | 14µs | $self->{ _HOT } = 1; | ||
| 161 | 10 | 5µs | eval { | ||
| 162 | 10 | 4µs | my $block = $self->{ _BLOCK }; | ||
| 163 | 10 | 19µs | 40 | 626ms | $output = &$block($context); # spent 385ms making 3 calls to Template::Document::__ANON__[koha-tmpl/intranet-tmpl/prog/en/modules/errors/404.tt:45], avg 128ms/call
# spent 94.1ms making 1 call to Template::Document::__ANON__[koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt:203]
# spent 87.9ms making 4 calls to Template::Document::__ANON__[koha-tmpl/intranet-tmpl/prog/en/includes/doc-head-close.inc:99], avg 22.0ms/call
# spent 24.5ms making 3 calls to Template::Document::__ANON__[koha-tmpl/intranet-tmpl/prog/en/includes/cat-search.inc:41], avg 8.17ms/call
# spent 19.6ms making 4 calls to Template::Document::__ANON__[koha-tmpl/intranet-tmpl/prog/en/includes/doc-head-open.inc:36], avg 4.90ms/call
# spent 6.53ms making 1 call to Template::Document::__ANON__[koha-tmpl/intranet-tmpl/prog/en/includes/home-search.inc:48]
# spent 5.10ms making 4 calls to Template::Document::__ANON__[koha-tmpl/intranet-tmpl/prog/en/includes/intranetstylesheet.inc:28], avg 1.27ms/call
# spent 2.90ms making 4 calls to Template::Document::__ANON__[koha-tmpl/intranet-tmpl/prog/en/includes/header.inc:120], avg 725µs/call
# spent 510µs making 4 calls to Template::Document::__ANON__[koha-tmpl/intranet-tmpl/prog/en/includes/patron-search-box.inc:62], avg 128µs/call
# spent 119µs making 4 calls to Template::Document::__ANON__[koha-tmpl/intranet-tmpl/prog/en/includes/intranet-bottom.inc:94], avg 30µs/call
# spent 47µs making 4 calls to Template::Document::__ANON__[(eval 1134)[Template/Document.pm:78]:16], avg 12µs/call
# spent 42µs making 4 calls to Template::Document::__ANON__[(eval 1133)[Template/Document.pm:78]:16], avg 10µs/call |
| 164 | }; | ||||
| 165 | 10 | 15µs | $self->{ _HOT } = 0; | ||
| 166 | |||||
| 167 | 10 | 24µs | 40 | 92µs | $context->leave(); # spent 92µs making 40 calls to Template::Context::leave, avg 2µs/call |
| 168 | |||||
| 169 | 10 | 2µs | die $context->catch($@) | ||
| 170 | if $@; | ||||
| 171 | |||||
| 172 | 10 | 28µs | return $output; | ||
| 173 | } | ||||
| 174 | |||||
| 175 | |||||
| 176 | #------------------------------------------------------------------------ | ||||
| 177 | # AUTOLOAD | ||||
| 178 | # | ||||
| 179 | # Provides pseudo-methods for read-only access to various internal | ||||
| 180 | # members. | ||||
| 181 | #------------------------------------------------------------------------ | ||||
| 182 | |||||
| 183 | # spent 63µs (34+29) within Template::Document::AUTOLOAD which was called 4 times, avg 16µs/call:
# 4 times (34µs+29µs) by Template::Stash::XS::get at line 2 of koha-tmpl/intranet-tmpl/prog/en/includes/doc-head-open.inc, avg 16µs/call | ||||
| 184 | 1 | 500ns | my $self = shift; | ||
| 185 | 1 | 500ns | my $method = $AUTOLOAD; | ||
| 186 | |||||
| 187 | 1 | 12µs | 4 | 29µs | $method =~ s/.*:://; # spent 29µs making 4 calls to Template::Document::CORE:subst, avg 7µs/call |
| 188 | 1 | 500ns | return if $method eq 'DESTROY'; | ||
| 189 | # my ($pkg, $file, $line) = caller(); | ||||
| 190 | # print STDERR "called $self->AUTOLOAD($method) from $file line $line\n"; | ||||
| 191 | 1 | 3µs | return $self->{ $method }; | ||
| 192 | } | ||||
| 193 | |||||
| 194 | |||||
| 195 | #======================================================================== | ||||
| 196 | # ----- PRIVATE METHODS ----- | ||||
| 197 | #======================================================================== | ||||
| 198 | |||||
| 199 | |||||
| 200 | #------------------------------------------------------------------------ | ||||
| 201 | # _dump() | ||||
| 202 | # | ||||
| 203 | # Debug method which returns a string representing the internal state | ||||
| 204 | # of the object. | ||||
| 205 | #------------------------------------------------------------------------ | ||||
| 206 | |||||
| 207 | sub _dump { | ||||
| 208 | my $self = shift; | ||||
| 209 | my $dblks; | ||||
| 210 | my $output = "$self : $self->{ name }\n"; | ||||
| 211 | |||||
| 212 | $output .= "BLOCK: $self->{ _BLOCK }\nDEFBLOCKS:\n"; | ||||
| 213 | |||||
| 214 | if ($dblks = $self->{ _DEFBLOCKS }) { | ||||
| 215 | foreach my $b (keys %$dblks) { | ||||
| 216 | $output .= " $b: $dblks->{ $b }\n"; | ||||
| 217 | } | ||||
| 218 | } | ||||
| 219 | |||||
| 220 | return $output; | ||||
| 221 | } | ||||
| 222 | |||||
| 223 | |||||
| 224 | #======================================================================== | ||||
| 225 | # ----- CLASS METHODS ----- | ||||
| 226 | #======================================================================== | ||||
| 227 | |||||
| 228 | #------------------------------------------------------------------------ | ||||
| 229 | # as_perl($content) | ||||
| 230 | # | ||||
| 231 | # This method expects a reference to a hash passed as the first argument | ||||
| 232 | # containing 3 items: | ||||
| 233 | # METADATA # a hash of template metadata | ||||
| 234 | # BLOCK # string containing Perl sub definition for main block | ||||
| 235 | # DEFBLOCKS # hash containing further subs for addional BLOCK defs | ||||
| 236 | # It returns a string containing Perl code which, when evaluated and | ||||
| 237 | # executed, will instantiate a new Template::Document object with the | ||||
| 238 | # above data. On error, it returns undef with an appropriate error | ||||
| 239 | # message set in $ERROR. | ||||
| 240 | #------------------------------------------------------------------------ | ||||
| 241 | |||||
| 242 | sub as_perl { | ||||
| 243 | my ($class, $content) = @_; | ||||
| 244 | my ($block, $defblocks, $metadata) = @$content{ qw( BLOCK DEFBLOCKS METADATA ) }; | ||||
| 245 | |||||
| 246 | $block =~ s/\n(?!#line)/\n /g; | ||||
| 247 | $block =~ s/\s+$//; | ||||
| 248 | |||||
| 249 | $defblocks = join('', map { | ||||
| 250 | my $code = $defblocks->{ $_ }; | ||||
| 251 | $code =~ s/\n(?!#line)/\n /g; | ||||
| 252 | $code =~ s/\s*$//; | ||||
| 253 | " '$_' => $code,\n"; | ||||
| 254 | } keys %$defblocks); | ||||
| 255 | $defblocks =~ s/\s+$//; | ||||
| 256 | |||||
| 257 | $metadata = join('', map { | ||||
| 258 | my $x = $metadata->{ $_ }; | ||||
| 259 | $x =~ s/(['\\])/\\$1/g; | ||||
| 260 | " '$_' => '$x',\n"; | ||||
| 261 | } keys %$metadata); | ||||
| 262 | $metadata =~ s/\s+$//; | ||||
| 263 | |||||
| 264 | return <<EOF | ||||
| 265 | #------------------------------------------------------------------------ | ||||
| 266 | # Compiled template generated by the Template Toolkit version $Template::VERSION | ||||
| 267 | #------------------------------------------------------------------------ | ||||
| 268 | |||||
| 269 | $class->new({ | ||||
| 270 | METADATA => { | ||||
| 271 | $metadata | ||||
| 272 | }, | ||||
| 273 | BLOCK => $block, | ||||
| 274 | DEFBLOCKS => { | ||||
| 275 | $defblocks | ||||
| 276 | }, | ||||
| 277 | }); | ||||
| 278 | EOF | ||||
| 279 | } | ||||
| 280 | |||||
| 281 | |||||
| 282 | #------------------------------------------------------------------------ | ||||
| 283 | # write_perl_file($filename, \%content) | ||||
| 284 | # | ||||
| 285 | # This method calls as_perl() to generate the Perl code to represent a | ||||
| 286 | # compiled template with the content passed as the second argument. | ||||
| 287 | # It then writes this to the file denoted by the first argument. | ||||
| 288 | # | ||||
| 289 | # Returns 1 on success. On error, sets the $ERROR package variable | ||||
| 290 | # to contain an error message and returns undef. | ||||
| 291 | #------------------------------------------------------------------------ | ||||
| 292 | |||||
| 293 | sub write_perl_file { | ||||
| 294 | my ($class, $file, $content) = @_; | ||||
| 295 | my ($fh, $tmpfile); | ||||
| 296 | |||||
| 297 | return $class->error("invalid filename: $file") | ||||
| 298 | unless $file =~ /^(.+)$/s; | ||||
| 299 | |||||
| 300 | eval { | ||||
| 301 | require File::Temp; | ||||
| 302 | require File::Basename; | ||||
| 303 | ($fh, $tmpfile) = File::Temp::tempfile( | ||||
| 304 | DIR => File::Basename::dirname($file) | ||||
| 305 | ); | ||||
| 306 | my $perlcode = $class->as_perl($content) || die $!; | ||||
| 307 | |||||
| 308 | if ($UNICODE && is_utf8($perlcode)) { | ||||
| 309 | $perlcode = "use utf8;\n\n$perlcode"; | ||||
| 310 | binmode $fh, ":utf8"; | ||||
| 311 | } | ||||
| 312 | print $fh $perlcode; | ||||
| 313 | close($fh); | ||||
| 314 | }; | ||||
| 315 | return $class->error($@) if $@; | ||||
| 316 | return rename($tmpfile, $file) | ||||
| 317 | || $class->error($!); | ||||
| 318 | } | ||||
| 319 | |||||
| 320 | |||||
| 321 | #------------------------------------------------------------------------ | ||||
| 322 | # catch_warnings($msg) | ||||
| 323 | # | ||||
| 324 | # Installed as | ||||
| 325 | #------------------------------------------------------------------------ | ||||
| 326 | |||||
| 327 | sub catch_warnings { | ||||
| 328 | $COMPERR .= join('', @_); | ||||
| 329 | } | ||||
| 330 | |||||
| 331 | |||||
| 332 | 1; | ||||
| 333 | |||||
| 334 | __END__ | ||||
# spent 931µs within Template::Document::CORE:match which was called 40 times, avg 23µs/call:
# 40 times (931µs+0s) by Template::Document::new at line 75, avg 23µs/call | |||||
# spent 29µs within Template::Document::CORE:subst which was called 4 times, avg 7µs/call:
# 4 times (29µs+0s) by Template::Document::AUTOLOAD at line 187, avg 7µs/call |