← Index
NYTProf Performance Profile   « block view • line view • sub view »
For /usr/local/src/github.com/foswiki/core/bin/view
  Run on Sun Dec 4 17:17:59 2011
Reported on Sun Dec 4 17:26:34 2011

Filename/usr/local/src/github.com/foswiki/core/lib/Foswiki/Attrs.pm
StatementsExecuted 11858 statements in 68.8ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
5858442.6ms57.1msFoswiki::Attrs::::newFoswiki::Attrs::new
2652617.04ms7.04msFoswiki::Attrs::::CORE:substFoswiki::Attrs::CORE:subst (opcode)
744526.45ms6.45msFoswiki::Attrs::::removeFoswiki::Attrs::remove
1727313.71ms3.71msFoswiki::Attrs::::CORE:regcompFoswiki::Attrs::CORE:regcomp (opcode)
764311.92ms1.92msFoswiki::Attrs::::CORE:substcontFoswiki::Attrs::CORE:substcont (opcode)
871211.87ms1.87msFoswiki::Attrs::::CORE:matchFoswiki::Attrs::CORE:match (opcode)
20111.49ms1.71msFoswiki::Attrs::::stringifyFoswiki::Attrs::stringify
2011118µs118µsFoswiki::Attrs::::CORE:sortFoswiki::Attrs::CORE:sort (opcode)
11153µs70µsFoswiki::Attrs::::BEGIN@49Foswiki::Attrs::BEGIN@49
11137µs75µsFoswiki::Attrs::::BEGIN@50Foswiki::Attrs::BEGIN@50
11130µs106µsFoswiki::Attrs::::BEGIN@51Foswiki::Attrs::BEGIN@51
0000s0sFoswiki::Attrs::::extractValueFoswiki::Attrs::extractValue
0000s0sFoswiki::Attrs::::getFoswiki::Attrs::get
0000s0sFoswiki::Attrs::::isEmptyFoswiki::Attrs::isEmpty
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
2
3=begin TML
4
5---+ package Foswiki::Attrs
6
7Class of attribute sets, designed for parsing and storing attribute values
8from a macro e.g. =%<nop>MACRO{"joe" fred="bad" joe="mad"}%=
9
10An attribute set is a hash containing an entry for each parameter. The
11default parameter (unnamed quoted string) is named <code>_<nop>DEFAULT</code> in the hash.
12
13Attributes declared later in the string will override those of the same
14name defined earlier. The one exception to this is the _DEFAULT key, where
15the _first_ instance is always taken.
16
17As well as the default Foswiki syntax (parameter values double-quoted)
18this class also parses single-quoted values, unquoted spaceless
19values, spaces around the =, and commas as well as spaces separating values.
20The extended syntax has to be enabled by passing the =$friendly= parameter
21to =new=.
22
23API version $Date$ (revision $Rev$)
24
25*Since* _date_ indicates where functions or parameters have been added since
26the baseline of the API (TWiki release 4.2.3). The _date_ indicates the
27earliest date of a Foswiki release that will support that function or
28parameter.
29
30*Deprecated* _date_ indicates where a function or parameters has been
31[[http://en.wikipedia.org/wiki/Deprecation][deprecated]]. Deprecated
32functions will still work, though they should
33_not_ be called in new plugins and should be replaced in older plugins
34as soon as possible. Deprecated parameters are simply ignored in Foswiki
35releases after _date_.
36
37*Until* _date_ indicates where a function or parameter has been removed.
38The _date_ indicates the latest date at which Foswiki releases still supported
39the function or parameter.
40
41=cut
42
43# THIS PACKAGE IS PART OF THE PUBLISHED API USED BY EXTENSION AUTHORS.
44# DO NOT CHANGE THE EXISTING APIS (well thought out extensions are OK)
45# AND ENSURE ALL POD DOCUMENTATION IS COMPLETE AND ACCURATE.
46
47package Foswiki::Attrs;
48
49272µs288µs
# spent 70µs (53+17) within Foswiki::Attrs::BEGIN@49 which was called: # once (53µs+17µs) by Foswiki::Store::VC::Handler::_getTOPICINFO at line 49
use strict;
# spent 70µs making 1 call to Foswiki::Attrs::BEGIN@49 # spent 17µs making 1 call to strict::import
50262µs2114µs
# spent 75µs (37+39) within Foswiki::Attrs::BEGIN@50 which was called: # once (37µs+39µs) by Foswiki::Store::VC::Handler::_getTOPICINFO at line 50
use warnings;
# spent 75µs making 1 call to Foswiki::Attrs::BEGIN@50 # spent 38µs making 1 call to warnings::import
5121.60ms2182µs
# spent 106µs (30+76) within Foswiki::Attrs::BEGIN@51 which was called: # once (30µs+76µs) by Foswiki::Store::VC::Handler::_getTOPICINFO at line 51
use Assert;
# spent 106µs making 1 call to Foswiki::Attrs::BEGIN@51 # spent 76µs making 1 call to Assert::import
52
5312µsour $VERSION = '$Rev$';
54
5512µsour $ERRORKEY = '_ERROR';
5612µsour $DEFAULTKEY = '_DEFAULT';
5711µsour $RAWKEY = '_RAW';
5811µsour $MARKER = "\0";
59
60=begin TML
61
62---++ ClassMethod new ($string) => \%attrsObjectRef
63
64 * =$string= - String containing attribute specification
65
66Parse a standard attribute string containing name=value pairs and create a new
67attributes object. The value may be a word or a quoted string. If there is an
68error during parsing, the parse will complete but $attrs->{_ERROR} will be
69set in the new object. $attrs->{_RAW} will always contain the full unprocessed
70$string.
71
72=cut
73
74
# spent 57.1ms (42.6+14.4) within Foswiki::Attrs::new which was called 585 times, avg 98µs/call: # 359 times (24.4ms+8.79ms) by Foswiki::_expandMacroOnTopicRendering at line 3065 of /usr/local/src/github.com/foswiki/core/lib/Foswiki.pm, avg 92µs/call # 142 times (10.00ms+3.10ms) by Foswiki::Templates::expandTemplate at line 127 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Templates.pm, avg 92µs/call # 30 times (2.18ms+601µs) by Foswiki::parseSections at line 2308 of /usr/local/src/github.com/foswiki/core/lib/Foswiki.pm, avg 93µs/call # 30 times (2.02ms+561µs) by Foswiki::parseSections at line 2340 of /usr/local/src/github.com/foswiki/core/lib/Foswiki.pm, avg 86µs/call # 13 times (2.84ms+983µs) by Foswiki::Store::VC::Handler::_getTOPICINFO at line 270 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Store/VC/Handler.pm, avg 294µs/call # 5 times (363µs+96µs) by Foswiki::Templates::_expandTrivialTemplate at line 103 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Templates.pm, avg 92µs/call # 3 times (615µs+224µs) by Foswiki::Func::extractParameters at line 2944 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Func.pm, avg 280µs/call # 3 times (256µs+78µs) by Foswiki::_expandMacroOnTopicRendering at line 3069 of /usr/local/src/github.com/foswiki/core/lib/Foswiki.pm, avg 111µs/call
sub new {
75843057.8ms my ( $class, $string, $friendly ) = @_;
76 my $this = bless( {}, $class );
77
78 $this->{$RAWKEY} = $string;
79
80 return $this unless defined($string);
81
825271.21ms $string =~ s/\\(["'])/$MARKER.sprintf("%.2u", ord($1))/ge; # escapes
# spent 1.02ms making 468 calls to Foswiki::Attrs::CORE:subst, avg 2µs/call # spent 186µs making 59 calls to Foswiki::Attrs::CORE:substcont, avg 3µs/call
83
84 my $sep = ( $friendly ? "[\\s,]" : "\\s" );
85 my $first = 1;
86
8710393.51ms if ( !$friendly && $string =~ s/^\s*\"(.*?)\"\s*(\w+\s*=\s*\"|$)/$2/s ) {
# spent 1.94ms making 393 calls to Foswiki::Attrs::CORE:subst, avg 5µs/call # spent 1.57ms making 646 calls to Foswiki::Attrs::CORE:substcont, avg 2µs/call
88 $this->{$DEFAULTKEY} = $1;
89 }
90468959µs while ( $string =~ m/\S/s ) {
# spent 959µs making 468 calls to Foswiki::Attrs::CORE:match, avg 2µs/call
91
92 # name="value" pairs
9314395.06ms if ( $string =~ s/^$sep*(\w+)\s*=\s*\"(.*?)\"//is ) {
# spent 2.09ms making 518 calls to Foswiki::Attrs::CORE:subst, avg 4µs/call # spent 2.05ms making 518 calls to Foswiki::Attrs::CORE:regcomp, avg 4µs/call # spent 914µs making 403 calls to Foswiki::Attrs::CORE:match, avg 2µs/call
94 $this->{$1} = $2;
95 $first = 0;
96 }
97
98 # simple double-quoted value with no name, sets the default
99 elsif ( $string =~ s/^$sep*\"(.*?)\"//os ) {
100 $this->{$DEFAULTKEY} = $1
101 unless defined( $this->{$DEFAULTKEY} );
102 $first = 0;
103 }
104
105 elsif ($friendly) {
106
107 # name='value' pairs
10830151µs if ( $string =~ s/^$sep*(\w+)\s*=\s*'(.*?)'//is ) {
# spent 91µs making 15 calls to Foswiki::Attrs::CORE:regcomp, avg 6µs/call # spent 60µs making 15 calls to Foswiki::Attrs::CORE:subst, avg 4µs/call
109 $this->{$1} = $2;
110 }
111
112 # name=value pairs
113 elsif ( $string =~ s/^$sep*(\w+)\s*=\s*([^\s,\}\'\"]*)//is ) {
114 $this->{$1} = $2;
115 }
116
117 # simple single-quoted value with no name, sets the default
118 elsif ( $string =~ s/^$sep*'(.*?)'//os ) {
119 $this->{$DEFAULTKEY} = $1
120 unless defined( $this->{$DEFAULTKEY} );
121 }
122
123 # simple name with no value (boolean, or _DEFAULT)
124 elsif ( $string =~ s/^$sep*([a-z]\w*)\b//is ) {
125 my $key = $1;
126 $this->{$key} = 1;
127 }
128
129 # otherwise the whole string - sans padding - is the default
130 else {
131
132 # SMELL: unchecked implicit untaint?
133 if ( $string =~ m/^\s*(.*?)\s*$/s
134 && !defined( $this->{$DEFAULTKEY} ) )
135 {
136 $this->{$DEFAULTKEY} = $1;
137 }
138 last;
139 }
140 }
141
142 # SMELL: unchecked implicit untaint?
143 elsif ( $string =~ m/^\s*(.*?)\s*$/s ) {
144 $this->{$DEFAULTKEY} = $1 if ($first);
145 last;
146 }
147 }
148 foreach my $k ( keys %$this ) {
14924473.55ms $this->{$k} =~ s/$MARKER(\d\d)/chr($1)/geo; # escapes
# spent 1.82ms making 1194 calls to Foswiki::Attrs::CORE:subst, avg 2µs/call # spent 1.56ms making 1194 calls to Foswiki::Attrs::CORE:regcomp, avg 1µs/call # spent 163µs making 59 calls to Foswiki::Attrs::CORE:substcont, avg 3µs/call
150 }
151 return $this;
152}
153
154=begin TML
155
156---++ ObjectMethod isEmpty() -> boolean
157
158Return false if attribute set is not empty.
159
160=cut
161
162sub isEmpty {
163 my $this = shift;
164
165 foreach my $k ( keys %$this ) {
166 return 0 if $k ne $RAWKEY;
167 }
168 return 1;
169}
170
171=begin TML
172
173---++ ObjectMethod remove($key) -> $value
174
175 * =$key= - Attribute to remove
176Remove an attr value from the map, return old value. After a call to
177=remove= the attribute is no longer defined.
178
179=cut
180
181
# spent 6.45ms within Foswiki::Attrs::remove which was called 744 times, avg 9µs/call: # 156 times (1.47ms+0s) by Foswiki::Templates::tmplP at line 152 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Templates.pm, avg 9µs/call # 156 times (1.33ms+0s) by Foswiki::Templates::tmplP at line 153 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Templates.pm, avg 9µs/call # 156 times (1.28ms+0s) by Foswiki::Templates::tmplP at line 154 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Templates.pm, avg 8µs/call # 156 times (1.25ms+0s) by Foswiki::Templates::tmplP at line 155 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Templates.pm, avg 8µs/call # 120 times (1.13ms+0s) by Foswiki::INCLUDE at line 127 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Macros/INCLUDE.pm, avg 9µs/call
sub remove {
18229767.47ms my ( $this, $attr ) = @_;
183 my $val = $this->{$attr};
184 delete( $this->{$attr} ) if ( exists $this->{$attr} );
185 return $val;
186}
187
188=begin TML
189
190---++ ObjectMethod stringify() -> $string
191
192Generate a printed form for the map, using strict
193attribute syntax, with only the single-quote extension
194syntax observed (no {} brackets, though).
195
196=cut
197
198
# spent 1.71ms (1.49+221µs) within Foswiki::Attrs::stringify which was called 20 times, avg 86µs/call: # 20 times (1.49ms+221µs) by Foswiki::INCLUDE at line 122 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Macros/INCLUDE.pm, avg 86µs/call
sub stringify {
1994401.73ms my $this = shift;
200 my $key;
201 my @ss;
20220118µs foreach $key ( sort keys %$this ) {
# spent 118µs making 20 calls to Foswiki::Attrs::CORE:sort, avg 6µs/call
203 if ( $key ne $ERRORKEY && $key ne $RAWKEY ) {
204 my $es = ( $key eq $DEFAULTKEY ) ? '' : $key . '=';
205 my $val = $this->{$key};
20664103µs $val =~ s/"/\\"/g;
# spent 103µs making 64 calls to Foswiki::Attrs::CORE:subst, avg 2µs/call
207 push( @ss, $es . '"' . $val . '"' );
208 }
209 }
210 return join( ' ', @ss );
211}
212
213# ---++ StaticMethod extractValue() -> $string
214#
215# Legacy support, formerly known as extractNameValuePair. This
216# static method uses context information to determine how a value
217# string is to be parsed. For example, if you have an attribute string
218# like this:
219#
220# "abc def="ghi" jkl" def="qqq"
221#
222# then call extractValue( "def" ), it will return "ghi".
223
224sub extractValue {
225 my ( $str, $name ) = @_;
226
227 my $value = '';
228 return $value unless ($str);
229 $str =~ s/\\\"/\\$MARKER/g; # escape \"
230
231 if ($name) {
232
233 # format is: %VAR{ ... name = "value" }%
234 if ( $str =~ /(^|[^\S])$name\s*=\s*\"([^\"]*)\"/ ) {
235 $value = $2 if defined $2; # distinguish between '' and "0"
236 }
237
238 }
239 else {
240
241 # test if format: { "value" ... }
242 # SMELL: unchecked implicit untaint?
243 if ( $str =~ /(^|\=\s*\"[^\"]*\")\s*\"(.*?)\"\s*(\w+\s*=\s*\"|$)/ ) {
244
245 # is: %VAR{ "value" }%
246 # or: %VAR{ "value" param="etc" ... }%
247 # or: %VAR{ ... = "..." "value" ... }%
248 # Note: "value" may contain embedded double quotes
249 $value = $2 if defined $2; # distinguish between '' and "0";
250
251 }
252 elsif ( ( $str =~ /^\s*\w+\s*=\s*\"([^\"]*)/ ) && ($1) ) {
253
254 # is: %VAR{ name = "value" }%
255 # do nothing, is not a standalone var
256
257 }
258 else {
259
260 # format is: %VAR{ value }%
261 $value = $str;
262 }
263 }
264 $value =~ s/\\$MARKER/\"/go; # resolve \"
265 return $value;
266}
267
268# ---++ ObjectMethod get($key) -> $value
269#
270# | $key | Attribute to get |
271# Get an attr value from the map.
272#
273# Synonymous with $attrs->{$key}. Retained mainly for compatibility with
274# the old AttrsContrib.
275sub get {
276 my ( $this, $field ) = @_;
277 return $this->{$field};
278}
279
28018µs1;
281__END__
 
# spent 1.87ms within Foswiki::Attrs::CORE:match which was called 871 times, avg 2µs/call: # 468 times (959µs+0s) by Foswiki::Attrs::new at line 90, avg 2µs/call # 403 times (914µs+0s) by Foswiki::Attrs::new at line 93, avg 2µs/call
sub Foswiki::Attrs::CORE:match; # opcode
# spent 3.71ms within Foswiki::Attrs::CORE:regcomp which was called 1727 times, avg 2µs/call: # 1194 times (1.56ms+0s) by Foswiki::Attrs::new at line 149, avg 1µs/call # 518 times (2.05ms+0s) by Foswiki::Attrs::new at line 93, avg 4µs/call # 15 times (91µs+0s) by Foswiki::Attrs::new at line 108, avg 6µs/call
sub Foswiki::Attrs::CORE:regcomp; # opcode
# spent 118µs within Foswiki::Attrs::CORE:sort which was called 20 times, avg 6µs/call: # 20 times (118µs+0s) by Foswiki::Attrs::stringify at line 202, avg 6µs/call
sub Foswiki::Attrs::CORE:sort; # opcode
# spent 7.04ms within Foswiki::Attrs::CORE:subst which was called 2652 times, avg 3µs/call: # 1194 times (1.82ms+0s) by Foswiki::Attrs::new at line 149, avg 2µs/call # 518 times (2.09ms+0s) by Foswiki::Attrs::new at line 93, avg 4µs/call # 468 times (1.02ms+0s) by Foswiki::Attrs::new at line 82, avg 2µs/call # 393 times (1.94ms+0s) by Foswiki::Attrs::new at line 87, avg 5µs/call # 64 times (103µs+0s) by Foswiki::Attrs::stringify at line 206, avg 2µs/call # 15 times (60µs+0s) by Foswiki::Attrs::new at line 108, avg 4µs/call
sub Foswiki::Attrs::CORE:subst; # opcode
# spent 1.92ms within Foswiki::Attrs::CORE:substcont which was called 764 times, avg 3µs/call: # 646 times (1.57ms+0s) by Foswiki::Attrs::new at line 87, avg 2µs/call # 59 times (186µs+0s) by Foswiki::Attrs::new at line 82, avg 3µs/call # 59 times (163µs+0s) by Foswiki::Attrs::new at line 149, avg 3µs/call
sub Foswiki::Attrs::CORE:substcont; # opcode