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

Filename/var/www/foswiki11/lib/Foswiki/Attrs.pm
StatementsExecuted 15155 statements in 30.2ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
6616414.6ms14.6msFoswiki::Attrs::::newFoswiki::Attrs::new
1262522.28ms2.28msFoswiki::Attrs::::removeFoswiki::Attrs::remove
711120µs120µsFoswiki::Attrs::::stringifyFoswiki::Attrs::stringify
11124µs56µsFoswiki::Attrs::::BEGIN@47Foswiki::Attrs::BEGIN@47
11116µs32µsFoswiki::Attrs::::BEGIN@48Foswiki::Attrs::BEGIN@48
11115µs46µsFoswiki::Attrs::::BEGIN@49Foswiki::Attrs::BEGIN@49
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
23*Since* _date_ indicates where functions or parameters have been added since
24the baseline of the API (TWiki release 4.2.3). The _date_ indicates the
25earliest date of a Foswiki release that will support that function or
26parameter.
27
28*Deprecated* _date_ indicates where a function or parameters has been
29[[http://en.wikipedia.org/wiki/Deprecation][deprecated]]. Deprecated
30functions will still work, though they should
31_not_ be called in new plugins and should be replaced in older plugins
32as soon as possible. Deprecated parameters are simply ignored in Foswiki
33releases after _date_.
34
35*Until* _date_ indicates where a function or parameter has been removed.
36The _date_ indicates the latest date at which Foswiki releases still supported
37the function or parameter.
38
39=cut
40
41# THIS PACKAGE IS PART OF THE PUBLISHED API USED BY EXTENSION AUTHORS.
42# DO NOT CHANGE THE EXISTING APIS (well thought out extensions are OK)
43# AND ENSURE ALL POD DOCUMENTATION IS COMPLETE AND ACCURATE.
44
45package Foswiki::Attrs;
46
47242µs289µs
# spent 56µs (24+32) within Foswiki::Attrs::BEGIN@47 which was called: # once (24µs+32µs) by Foswiki::Store::VC::Handler::_getTOPICINFO at line 47
use strict;
# spent 56µs making 1 call to Foswiki::Attrs::BEGIN@47 # spent 32µs making 1 call to strict::import
48231µs249µs
# spent 32µs (16+16) within Foswiki::Attrs::BEGIN@48 which was called: # once (16µs+16µs) by Foswiki::Store::VC::Handler::_getTOPICINFO at line 48
use warnings;
# spent 32µs making 1 call to Foswiki::Attrs::BEGIN@48 # spent 16µs making 1 call to warnings::import
492911µs277µs
# spent 46µs (15+31) within Foswiki::Attrs::BEGIN@49 which was called: # once (15µs+31µs) by Foswiki::Store::VC::Handler::_getTOPICINFO at line 49
use Assert;
# spent 46µs making 1 call to Foswiki::Attrs::BEGIN@49 # spent 31µs making 1 call to Assert::import
50
511700nsour $ERRORKEY = '_ERROR';
521300nsour $DEFAULTKEY = '_DEFAULT';
531300nsour $RAWKEY = '_RAW';
541200nsour $MARKER = "\0";
55
56=begin TML
57
58---++ ClassMethod new ($string) => \%attrsObjectRef
59
60 * =$string= - String containing attribute specification
61
62Parse a standard attribute string containing name=value pairs and create a new
63attributes object. The value may be a word or a quoted string. If there is an
64error during parsing, the parse will complete but $attrs->{_ERROR} will be
65set in the new object. $attrs->{_RAW} will always contain the full unprocessed
66$string.
67
68=cut
69
70
# spent 14.6ms within Foswiki::Attrs::new which was called 661 times, avg 22µs/call: # 343 times (7.77ms+0s) by Foswiki::_expandMacroOnTopicRendering at line 3159 of /var/www/foswiki11/lib/Foswiki.pm, avg 23µs/call # 303 times (5.06ms+0s) by Foswiki::Templates::expandTemplate at line 127 of /var/www/foswiki11/lib/Foswiki/Templates.pm, avg 17µs/call # 11 times (1.53ms+0s) by Foswiki::Store::VC::Handler::_getTOPICINFO at line 270 of /var/www/foswiki11/lib/Foswiki/Store/VC/Handler.pm, avg 139µs/call # 2 times (120µs+0s) by Foswiki::Func::extractParameters at line 3005 of /var/www/foswiki11/lib/Foswiki/Func.pm, avg 60µs/call # once (65µs+0s) by Foswiki::_expandMacroOnTopicRendering at line 3163 of /var/www/foswiki11/lib/Foswiki.pm # once (34µs+0s) by Foswiki::Templates::_expandTrivialTemplate at line 103 of /var/www/foswiki11/lib/Foswiki/Templates.pm
sub new {
71661785µs my ( $class, $string, $friendly ) = @_;
72661825µs my $this = bless( {}, $class );
73
74661746µs $this->{$RAWKEY} = $string;
75
76661497µs return $this unless defined($string);
77
78546512µs $string =~ s/\\(["'])/$MARKER.sprintf("%.2u", ord($1))/ge; # escapes
79
80546295µs my $sep = ( $friendly ? "[\\s,]" : "\\s" );
81546161µs my $first = 1;
82
835461.91ms if ( !$friendly && $string =~ s/^\s*\"(.*?)\"\s*(\w+\s*=\s*\"|$)/$2/s ) {
84 $this->{$DEFAULTKEY} = $1;
85 }
86546678µs while ( $string =~ m/\S/s ) {
87
88 # name="value" pairs
896783.26ms if ( $string =~ s/^$sep*(\w+)\s*=\s*\"(.*?)\"//is ) {
90451740µs $this->{$1} = $2;
91451126µs $first = 0;
92 }
93
94 # simple double-quoted value with no name, sets the default
95 elsif ( $string =~ s/^$sep*\"(.*?)\"//os ) {
964193µs $this->{$DEFAULTKEY} = $1
97 unless defined( $this->{$DEFAULTKEY} );
984119µs $first = 0;
99 }
100
101 elsif ($friendly) {
102
103 # name='value' pairs
104894µs if ( $string =~ s/^$sep*(\w+)\s*=\s*'(.*?)'//is ) {
105 $this->{$1} = $2;
106 }
107
108 # name=value pairs
109 elsif ( $string =~ s/^$sep*(\w+)\s*=\s*([^\s,\}\'\"]*)//is ) {
110 $this->{$1} = $2;
111 }
112
113 # simple single-quoted value with no name, sets the default
114 elsif ( $string =~ s/^$sep*'(.*?)'//os ) {
115 $this->{$DEFAULTKEY} = $1
116 unless defined( $this->{$DEFAULTKEY} );
117 }
118
119 # simple name with no value (boolean, or _DEFAULT)
120 elsif ( $string =~ s/^$sep*([a-z]\w*)\b//is ) {
121 my $key = $1;
122 $this->{$key} = 1;
123 }
124
125 # otherwise the whole string - sans padding - is the default
126 else {
127
128 # SMELL: unchecked implicit untaint?
129 if ( $string =~ m/^\s*(.*?)\s*$/s
130 && !defined( $this->{$DEFAULTKEY} ) )
131 {
132 $this->{$DEFAULTKEY} = $1;
133 }
134 last;
135 }
136 }
137
138 # SMELL: unchecked implicit untaint?
139 elsif ( $string =~ m/^\s*(.*?)\s*$/s ) {
140178286µs $this->{$DEFAULTKEY} = $1 if ($first);
14117890µs last;
142 }
143 }
1445461.25ms foreach my $k ( keys %$this ) {
14515171.37ms $this->{$k} =~ s/$MARKER(\d\d)/chr($1)/geo; # escapes
146 }
1475461.87ms return $this;
148}
149
150=begin TML
151
152---++ ObjectMethod isEmpty() -> boolean
153
154Return false if attribute set is not empty.
155
156=cut
157
158sub isEmpty {
159 my $this = shift;
160
161 foreach my $k ( keys %$this ) {
162 return 0 if $k ne $RAWKEY;
163 }
164 return 1;
165}
166
167=begin TML
168
169---++ ObjectMethod remove($key) -> $value
170
171 * =$key= - Attribute to remove
172Remove an attr value from the map, return old value. After a call to
173=remove= the attribute is no longer defined.
174
175=cut
176
177
# spent 2.28ms within Foswiki::Attrs::remove which was called 1262 times, avg 2µs/call: # 305 times (815µs+0s) by Foswiki::Templates::tmplP at line 154 of /var/www/foswiki11/lib/Foswiki/Templates.pm, avg 3µs/call # 305 times (488µs+0s) by Foswiki::Templates::tmplP at line 155 of /var/www/foswiki11/lib/Foswiki/Templates.pm, avg 2µs/call # 305 times (439µs+0s) by Foswiki::Templates::tmplP at line 156 of /var/www/foswiki11/lib/Foswiki/Templates.pm, avg 1µs/call # 305 times (422µs+0s) by Foswiki::Templates::tmplP at line 157 of /var/www/foswiki11/lib/Foswiki/Templates.pm, avg 1µs/call # 42 times (111µs+0s) by Foswiki::INCLUDE at line 127 of /var/www/foswiki11/lib/Foswiki/Macros/INCLUDE.pm, avg 3µs/call
sub remove {
1781262435µs my ( $this, $attr ) = @_;
1791262376µs my $val = $this->{$attr};
1801262406µs delete( $this->{$attr} ) if ( exists $this->{$attr} );
181126212.3ms return $val;
182}
183
184=begin TML
185
186---++ ObjectMethod stringify() -> $string
187
188Generate a printed form for the map, using strict
189attribute syntax, with only the single-quote extension
190syntax observed (no {} brackets, though).
191
192=cut
193
194
# spent 120µs within Foswiki::Attrs::stringify which was called 7 times, avg 17µs/call: # 7 times (120µs+0s) by Foswiki::INCLUDE at line 122 of /var/www/foswiki11/lib/Foswiki/Macros/INCLUDE.pm, avg 17µs/call
sub stringify {
19573µs my $this = shift;
1967800ns my $key;
19772µs my @ss;
198733µs foreach $key ( sort keys %$this ) {
1991613µs if ( $key ne $ERRORKEY && $key ne $RAWKEY ) {
20099µs my $es = ( $key eq $DEFAULTKEY ) ? '' : $key . '=';
20197µs my $val = $this->{$key};
20298µs $val =~ s/"/\\"/g;
203916µs push( @ss, $es . '"' . $val . '"' );
204 }
205 }
206741µs return join( ' ', @ss );
207}
208
209# ---++ StaticMethod extractValue() -> $string
210#
211# Legacy support, formerly known as extractNameValuePair. This
212# static method uses context information to determine how a value
213# string is to be parsed. For example, if you have an attribute string
214# like this:
215#
216# "abc def="ghi" jkl" def="qqq"
217#
218# then call extractValue( "def" ), it will return "ghi".
219
220sub extractValue {
221 my ( $str, $name ) = @_;
222
223 my $value = '';
224 return $value unless ($str);
225 $str =~ s/\\\"/\\$MARKER/g; # escape \"
226
227 if ($name) {
228
229 # format is: %VAR{ ... name = "value" }%
230 if ( $str =~ /(^|[^\S])$name\s*=\s*\"([^\"]*)\"/ ) {
231 $value = $2 if defined $2; # distinguish between '' and "0"
232 }
233
234 }
235 else {
236
237 # test if format: { "value" ... }
238 # SMELL: unchecked implicit untaint?
239 if ( $str =~ /(^|\=\s*\"[^\"]*\")\s*\"(.*?)\"\s*(\w+\s*=\s*\"|$)/ ) {
240
241 # is: %VAR{ "value" }%
242 # or: %VAR{ "value" param="etc" ... }%
243 # or: %VAR{ ... = "..." "value" ... }%
244 # Note: "value" may contain embedded double quotes
245 $value = $2 if defined $2; # distinguish between '' and "0";
246
247 }
248 elsif ( ( $str =~ /^\s*\w+\s*=\s*\"([^\"]*)/ ) && ($1) ) {
249
250 # is: %VAR{ name = "value" }%
251 # do nothing, is not a standalone var
252
253 }
254 else {
255
256 # format is: %VAR{ value }%
257 $value = $str;
258 }
259 }
260 $value =~ s/\\$MARKER/\"/go; # resolve \"
261 return $value;
262}
263
264# ---++ ObjectMethod get($key) -> $value
265#
266# | $key | Attribute to get |
267# Get an attr value from the map.
268#
269# Synonymous with $attrs->{$key}. Retained mainly for compatibility with
270# the old AttrsContrib.
271sub get {
272 my ( $this, $field ) = @_;
273 return $this->{$field};
274}
275
27614µs1;
277__END__