← Index
NYTProf Performance Profile   « line view »
For ./view
  Run on Fri Jul 31 19:05:14 2015
Reported on Fri Jul 31 19:08:11 2015

Filename/var/www/foswiki11/lib/Foswiki/Macros/INCLUDE.pm
StatementsExecuted 832 statements in 6.29ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
63112.94ms3.06msFoswiki::::_fixupIncludedTopicFoswiki::_fixupIncludedTopic
7111.22ms9.30sFoswiki::::INCLUDEFoswiki::INCLUDE (recurses: max depth 2, inclusive time 8.98s)
611699µs17.4sFoswiki::::__ANON__[:331]Foswiki::__ANON__[:331]
411113µs113µsFoswiki::::_fixIncludeLinkFoswiki::_fixIncludeLink
611112µs3.81msFoswiki::::__ANON__[:348]Foswiki::__ANON__[:348]
11126µs80µsFoswiki::::_includeWarningFoswiki::_includeWarning
11116µs30µsFoswiki::::BEGIN@4.56Foswiki::BEGIN@4.56
11110µs16µsFoswiki::::BEGIN@5.57Foswiki::BEGIN@5.57
0000s0sFoswiki::::applyPatternToIncludedTextFoswiki::applyPatternToIncludedText
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1# See bottom of file for license and copyright information
2package Foswiki;
3
4229µs243µs
# spent 30µs (16+14) within Foswiki::BEGIN@4.56 which was called: # once (16µs+14µs) by Foswiki::_expandMacroOnTopicRendering at line 4
use strict;
# spent 30µs making 1 call to Foswiki::BEGIN@4.56 # spent 14µs making 1 call to strict::import
521.40ms222µs
# spent 16µs (10+6) within Foswiki::BEGIN@5.57 which was called: # once (10µs+6µs) by Foswiki::_expandMacroOnTopicRendering at line 5
use warnings;
# spent 16µs making 1 call to Foswiki::BEGIN@5.57 # spent 6µs making 1 call to warnings::import
6
7# applyPatternToIncludedText( $text, $pattern ) -> $text
8# Apply a pattern on included text to extract a subset
9# Package-private; used by IncludeHandlers.
10sub applyPatternToIncludedText {
11 my ( $text, $pattern ) = @_;
12
13 $pattern = Foswiki::Sandbox::untaint( $pattern, \&validatePattern );
14
15 my $ok = 0;
16 eval {
17
18 # The eval acts as a try block in case there is anything evil in
19 # the pattern.
20
21 # The () ensures that $1 is defined if $pattern matches
22 # but does not capture anything
23 if ( $text =~ m/$pattern()/is ) {
24 $text = $1;
25 }
26 else {
27
28 # The pattern did not match, so return nothing
29 $text = '';
30 }
31 $ok = 1;
32 };
33 $text = '' unless $ok;
34
35 return $text;
36}
37
38# Replace web references in a topic. Called from forEachLine, applying to
39# each non-verbatim and non-literal line.
40
# spent 3.06ms (2.94+113µs) within Foswiki::_fixupIncludedTopic which was called 63 times, avg 49µs/call: # 63 times (2.94ms+113µs) by Foswiki::Render::forEachLine at line 1880 of /var/www/foswiki11/lib/Foswiki/Render.pm, avg 49µs/call
sub _fixupIncludedTopic {
416347µs my ( $text, $options ) = @_;
42
436332µs my $fromWeb = $options->{web};
44
456331µs unless ( $options->{in_noautolink} ) {
46
47 # 'TopicName' to 'Web.TopicName'
48582.62ms $text =~
49s#(?:^|(?<=[\s(]))($Foswiki::regex{wikiWordRegex})(?=\s|\)|$)#$fromWeb.$1#go;
50 }
51
52 # Handle explicit [[]] everywhere
53 # '[[TopicName][...]]' to '[[Web.TopicName][...]]'
546356µs $text =~ s/\[\[([^]]+)\](?:\[([^]]+)\])?\]/
5548µs4113µs _fixIncludeLink( $fromWeb, $1, $2 )/geo;
# spent 113µs making 4 calls to Foswiki::_fixIncludeLink, avg 28µs/call
56
5763228µs return $text;
58}
59
60# Add a web reference to a [[...][...]] link in an included topic
61
# spent 113µs within Foswiki::_fixIncludeLink which was called 4 times, avg 28µs/call: # 4 times (113µs+0s) by Foswiki::_fixupIncludedTopic at line 55, avg 28µs/call
sub _fixIncludeLink {
6248µs my ( $web, $link, $label ) = @_;
63
64 # Detect absolute and relative URLs and web-qualified wikinames
654113µs if ( $link =~
66m#^($Foswiki::regex{webNameRegex}\.|$Foswiki::regex{defaultWebNameRegex}\.|$Foswiki::regex{linkProtocolPattern}:|/)#o
67 )
68 {
69 if ($label) {
70 return "[[$link][$label]]";
71 }
72 else {
73 return "[[$link]]";
74 }
75 }
76 elsif ( !$label ) {
77
78 # Must be wikiword or spaced-out wikiword (or illegal link :-/)
79 $label = $link;
80 }
81
82 # If link is only an anchor, leave it as is (Foswikitask:Item771)
831300ns return "[[$link][$label]]" if $link =~ /^#/;
8413µs return "[[$web.$link][$label]]";
85}
86
87# generate an include warning
88# SMELL: varying number of parameters idiotic to handle for customized $warn
89
# spent 80µs (26+54) within Foswiki::_includeWarning which was called: # once (26µs+54µs) by Foswiki::INCLUDE at line 182
sub _includeWarning {
901800ns my $this = shift;
9111µs my $warn = shift;
921700ns my $message = shift;
93
9413µs154µs if ( $warn eq 'on' ) {
# spent 54µs making 1 call to Foswiki::isTrue
95 return $this->inlineAlert( 'alerts', $message, @_ );
96 }
97 elsif ( isTrue($warn) ) {
98
99 # different inlineAlerts need different argument counts
10011µs my $argument = '';
10111µs if ( $message eq 'topic_not_found' ) {
10212µs my ( $web, $topic ) = @_;
10312µs $argument = "$web.$topic";
104 }
105 else {
106 $argument = shift;
107 }
10812µs $warn =~ s/\$topic/$argument/go if $argument;
10916µs return $warn;
110 } # else fail silently
111 return '';
112}
113
114# Processes a specific instance %<nop>INCLUDE{...}% syntax.
115# Returns the text to be inserted in place of the INCLUDE command.
116# $includingTopicObject should be for the immediate parent topic in the
117# include hierarchy. Works for both URLs and absolute server paths.
118
# spent 9.30s (1.22ms+9.30) within Foswiki::INCLUDE which was called 7 times, avg 1.33s/call: # 7 times (1.22ms+9.30s) by Foswiki::_expandMacroOnTopicRendering at line 3160 of /var/www/foswiki11/lib/Foswiki.pm, avg 1.33s/call
sub INCLUDE {
11976µs my ( $this, $params, $includingTopicObject ) = @_;
120
121 # remember args for the key before mangling the params
122720µs7120µs my $args = $params->stringify();
# spent 120µs making 7 calls to Foswiki::Attrs::stringify, avg 17µs/call
123
124 # Remove params, so they don't get expanded in the included page
12572µs my %control;
12677µs for my $p (qw(_DEFAULT pattern rev section raw warn)) {
1274299µs42111µs $control{$p} = $params->remove($p);
# spent 111µs making 42 calls to Foswiki::Attrs::remove, avg 3µs/call
128 }
129
130713µs5214µs $control{warn} ||= $this->{prefs}->getPreference('INCLUDEWARNING');
# spent 214µs making 5 calls to Foswiki::Prefs::getPreference, avg 43µs/call
131
132 # make sure we have something to include. If we don't do this, then
133 # normalizeWebTopicName will default to WebHome. TWikibug:Item2209.
13473µs unless ( $control{_DEFAULT} ) {
135 return $this->_includeWarning( $control{warn}, 'bad_include_path', '' );
136 }
137
138 # Filter out '..' from path to prevent includes of '../../file'
139713µs if ( $Foswiki::cfg{DenyDotDotInclude} && $control{_DEFAULT} =~ /\.\./ ) {
140 return $this->_includeWarning( $control{warn}, 'bad_include_path',
141 $control{_DEFAULT} );
142 }
143
144 # no sense in considering an empty string as an unfindable section
14573µs delete $control{section}
146 if ( defined( $control{section} ) && $control{section} eq '' );
14774µs $control{raw} ||= '';
148716µs716µs $control{inWeb} = $includingTopicObject->web;
# spent 16µs making 7 calls to Foswiki::Meta::web, avg 2µs/call
149714µs714µs $control{inTopic} = $includingTopicObject->topic;
# spent 14µs making 7 calls to Foswiki::Meta::topic, avg 2µs/call
150
151 # Protocol links e.g. http:, https:, doc:
15276µs if ( $control{_DEFAULT} =~ /^([a-z]+):/ ) {
153 my $handler = $1;
154 eval 'use Foswiki::IncludeHandlers::' . $handler . ' ()';
155 if ($@) {
156 return $this->_includeWarning( $control{warn}, 'bad_include_path',
157 $control{_DEFAULT} );
158 }
159 else {
160 $handler = 'Foswiki::IncludeHandlers::' . $handler;
161 return $handler->INCLUDE( $this, \%control, $params );
162 }
163 }
164
165 # No protocol handler; must be a topic reference
166
16772µs my $text = '';
16871µs my $includedWeb;
16976µs my $includedTopic = $control{_DEFAULT};
17074µs $includedTopic =~ s/\.txt$//; # strip optional (undocumented) .txt
171
172732µs14146µs ( $includedWeb, $includedTopic ) =
# spent 132µs making 7 calls to Foswiki::normalizeWebTopicName, avg 19µs/call # spent 14µs making 7 calls to Foswiki::Meta::web, avg 2µs/call
173 $this->normalizeWebTopicName( $includingTopicObject->web,
174 $includedTopic );
175
176721µs757µs if ( !Foswiki::isValidTopicName( $includedTopic, 1 ) ) {
# spent 57µs making 7 calls to Foswiki::isValidTopicName, avg 8µs/call
177 return $this->_includeWarning( $control{warn}, 'bad_include_path',
178 $control{_DEFAULT} );
179 }
180
181 # See Codev.FailedIncludeWarning for the history.
182741µs8560µs unless ( $this->{store}->topicExists( $includedWeb, $includedTopic ) ) {
# spent 480µs making 7 calls to Foswiki::Store::VC::Store::topicExists, avg 69µs/call # spent 80µs making 1 call to Foswiki::_includeWarning
183 return _includeWarning( $this, $control{warn}, 'topic_not_found',
184 $includedWeb, $includedTopic );
185 }
186
187 # prevent recursive includes. Note that the inclusion of a topic into
188 # itself is not blocked; however subsequent attempts to include the
189 # topic will fail. There is a hard block of 99 on any recursive include.
190627µs1226µs my $key = $includingTopicObject->web . '.' . $includingTopicObject->topic;
# spent 15µs making 6 calls to Foswiki::Meta::web, avg 3µs/call # spent 11µs making 6 calls to Foswiki::Meta::topic, avg 2µs/call
191614µs my $count = grep( $key, keys %{ $this->{_INCLUDES} } );
19263µs $key .= $args;
19366µs if ( $this->{_INCLUDES}->{$key} || $count > 99 ) {
194 return _includeWarning( $this, $control{warn}, 'already_included',
195 "$includedWeb.$includedTopic", '' );
196 }
197
198 # Push the topic context to the included topic, so we can create
199 # local (SESSION) macro definitions without polluting the including
200 # topic namespace.
201619µs62.80ms $this->{prefs}->pushTopicContext( $this->{webName}, $this->{topicName} );
# spent 2.80ms making 6 calls to Foswiki::Prefs::pushTopicContext, avg 467µs/call
202
203611µs $this->{_INCLUDES}->{$key} = 1;
204
205624µs6588ms my $includedTopicObject =
# spent 588ms making 6 calls to Foswiki::Meta::load, avg 98.1ms/call
206 Foswiki::Meta->load( $this, $includedWeb, $includedTopic, $control{rev} );
207629µs6306ms unless ( $includedTopicObject->haveAccess('VIEW') ) {
# spent 306ms making 6 calls to Foswiki::Meta::haveAccess, avg 51.0ms/call
208 if ( isTrue( $control{warn} ) ) {
209 return $this->inlineAlert( 'alerts', 'access_denied',
210 "[[$includedWeb.$includedTopic]]" );
211 } # else fail silently
212 return '';
213 }
214639µs639µs my $memWeb = $this->{prefs}->getPreference('INCLUDINGWEB');
# spent 39µs making 6 calls to Foswiki::Prefs::getPreference, avg 6µs/call
215619µs617µs my $memTopic = $this->{prefs}->getPreference('INCLUDINGTOPIC');
# spent 17µs making 6 calls to Foswiki::Prefs::getPreference, avg 3µs/call
216
21765µs my $verbatim = {};
21864µs my $dirtyAreas = {};
219
# spent 17.4s (699µs+17.4) within Foswiki::__ANON__[/var/www/foswiki11/lib/Foswiki/Macros/INCLUDE.pm:331] which was called 6 times, avg 2.90s/call: # 6 times (699µs+17.4s) by Error::subs::try at line 419 of Error.pm, avg 2.90s/call
try {
220
221 # Copy params into session level preferences. That way finalisation
222 # will apply to them. These preferences will be popped when the topic
223 # context is restored after the include.
224638µs6440µs $this->{prefs}->setSessionPreferences(%$params);
# spent 440µs making 6 calls to Foswiki::Prefs::setSessionPreferences, avg 73µs/call
225
226 # Set preferences that finalisation does *not* apply to
227653µs18162µs $this->{prefs}->setInternalPreferences(
# spent 106µs making 6 calls to Foswiki::Prefs::setInternalPreferences, avg 18µs/call # spent 37µs making 6 calls to Foswiki::Meta::web, avg 6µs/call # spent 19µs making 6 calls to Foswiki::Meta::topic, avg 3µs/call
228 INCLUDINGWEB => $includingTopicObject->web,
229 INCLUDINGTOPIC => $includingTopicObject->topic
230 );
231
232626µs656µs $text = $includedTopicObject->text;
# spent 56µs making 6 calls to Foswiki::Meta::text, avg 9µs/call
233
234 # Simplify leading, and remove trailing, newlines. If we don't remove
235 # trailing, it becomes impossible to %INCLUDE a topic into a table.
236620µs $text =~ s/^[\r\n]+/\n/;
237645µs $text =~ s/[\r\n]+$//;
238
239 # remove everything before and after the default include block unless
240 # a section is explicitly defined
24168µs if ( !$control{section} ) {
24269µs $text =~ s/.*?%STARTINCLUDE%//s;
243613µs $text =~ s/%STOPINCLUDE%.*//s;
244 }
245
246 # prevent dirty areas in included topics from being parsed
247610µs $text = takeOutBlocks( $text, 'dirtyarea', $dirtyAreas )
248 if $Foswiki::cfg{Cache}{Enabled};
249
250 # handle sections
251633µs6158µs my ( $ntext, $sections ) = parseSections($text);
# spent 158µs making 6 calls to Foswiki::parseSections, avg 26µs/call
252
25366µs my $interesting = ( defined $control{section} );
25465µs if ( $interesting || scalar(@$sections) ) {
255
256 # Rebuild the text from the interesting sections
257 $text = '';
258 foreach my $s (@$sections) {
259 if ( $control{section}
260 && $s->{type} eq 'section'
261 && $s->{name} eq $control{section} )
262 {
263 $text .=
264 substr( $ntext, $s->{start}, $s->{end} - $s->{start} );
265 $interesting = 1;
266 last;
267 }
268 elsif ( $s->{type} eq 'include' && !$control{section} ) {
269 $text .=
270 substr( $ntext, $s->{start}, $s->{end} - $s->{start} );
271 $interesting = 1;
272 }
273 }
274 }
275
276630µs if ( $interesting and ( length($text) eq 0 ) ) {
277 $text =
278 _includeWarning( $this, $control{warn}, 'topic_section_not_found',
279 $includedWeb, $includedTopic, $control{section} );
280 }
281 else {
282
283 # If there were no interesting sections, restore the whole text
28464µs $text = $ntext unless $interesting;
285
28664µs $text = applyPatternToIncludedText( $text, $control{pattern} )
287 if ( $control{pattern} );
288
289 # Do not show TOC in included topic if TOC_HIDE_IF_INCLUDED
290 # preference has been set
291634µs12576µs if ( isTrue( $this->{prefs}->getPreference('TOC_HIDE_IF_INCLUDED') )
# spent 464µs making 6 calls to Foswiki::Prefs::getPreference, avg 77µs/call # spent 112µs making 6 calls to Foswiki::isTrue, avg 19µs/call
292 )
293 {
294 $text =~ s/%TOC(?:{(.*?)})?%//g;
295 }
296
297632µs60s $this->innerExpandMacros( \$text, $includedTopicObject );
# spent 17.4s making 6 calls to Foswiki::innerExpandMacros, avg 2.89s/call, recursion: max depth 2, sum of overlapping time 17.4s
298
299 # Item9569: remove verbatim blocks from text passed to commonTagsHandler
300617µs6169µs $text = takeOutBlocks( $text, 'verbatim', $verbatim );
# spent 169µs making 6 calls to Foswiki::takeOutBlocks, avg 28µs/call
301
302 # 4th parameter tells plugin that its called for an included file
303631µs62.69ms $this->{plugins}
# spent 2.69ms making 6 calls to Foswiki::Plugins::dispatch, avg 449µs/call
304 ->dispatch( 'commonTagsHandler', $text, $includedTopic,
305 $includedWeb, 1, $includedTopicObject );
306614µs629µs putBackBlocks( \$text, $verbatim, 'verbatim' );
# spent 29µs making 6 calls to Foswiki::putBackBlocks, avg 5µs/call
307
308 # We have to expand tags again, because a plugin may have inserted
309 # additional tags.
310617µs60s $this->innerExpandMacros( \$text, $includedTopicObject );
# spent 594µs making 6 calls to Foswiki::innerExpandMacros, avg 99µs/call, recursion: max depth 2, sum of overlapping time 594µs
311
312 # If needed, fix all 'TopicNames' to 'Web.TopicNames' to get the
313 # right context so that links continue to work properly
314619µs619µs if ( $includedWeb ne $includingTopicObject->web ) {
# spent 19µs making 6 calls to Foswiki::Meta::web, avg 3µs/call
31554µs my $removed = {};
316
317596µs104.70ms $text = $this->renderer->forEachLine(
# spent 4.67ms making 5 calls to Foswiki::Render::forEachLine, avg 934µs/call # spent 29µs making 5 calls to Foswiki::renderer, avg 6µs/call
318 $text,
319 \&_fixupIncludedTopic,
320 {
321 web => $includedWeb,
322 pre => 1,
323 noautolink => 1
324 }
325 );
326
327 # handle tags again because of plugin hook
328517µs50s innerExpandMacros( $this, \$text, $includedTopicObject );
# spent 426µs making 5 calls to Foswiki::innerExpandMacros, avg 85µs/call, recursion: max depth 2, sum of overlapping time 426µs
329 }
330 }
331 }
332
# spent 3.81ms (112µs+3.70) within Foswiki::__ANON__[/var/www/foswiki11/lib/Foswiki/Macros/INCLUDE.pm:348] which was called 6 times, avg 636µs/call: # 6 times (112µs+3.70ms) by Error::subs::try at line 433 of Error.pm, avg 636µs/call
finally {
333
334 # always restore the context, even in the event of an error
335620µs delete $this->{_INCLUDES}->{$key};
336
337614µs652µs $this->{prefs}->setInternalPreferences(
# spent 52µs making 6 calls to Foswiki::Prefs::setInternalPreferences, avg 9µs/call
338 INCLUDINGWEB => $memWeb,
339 INCLUDINGTOPIC => $memTopic
340 );
341
342 # restoring dirty areas
34367µs putBackBlocks( \$text, $dirtyAreas, 'dirtyarea' )
344 if $Foswiki::cfg{Cache}{Enabled};
345
346656µs63.65ms ( $this->{webName}, $this->{topicName} ) =
# spent 3.65ms making 6 calls to Foswiki::Prefs::popTopicContext, avg 609µs/call
347 $this->{prefs}->popTopicContext();
3486398µs1253µs };
# spent 53µs making 6 calls to Error::subs::finally, avg 9µs/call # spent 17.4s making 6 calls to Error::subs::try, avg 2.90s/call, recursion: max depth 2, sum of overlapping time 17.4s
349
350699µs return $text;
351}
352
35312µs1;
354__END__