Filename | C:/tmp64ng/perl/vendor/lib/Portable/LoadYaml.pm |
Statements | Executed 2103 statements in 15.6ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
99 | 2 | 1 | 15.6ms | 15.6ms | _load_scalar | Portable::LoadYaml::
1 | 1 | 1 | 0s | 0s | BEGIN@5 | Portable::LoadYaml::
1 | 1 | 1 | 0s | 0s | BEGIN@6 | Portable::LoadYaml::
1 | 1 | 1 | 0s | 0s | BEGIN@7 | Portable::LoadYaml::
1 | 1 | 1 | 0s | 0s | BEGIN@78 | Portable::LoadYaml::
1 | 1 | 1 | 0s | 0s | CORE:close (opcode) | Portable::LoadYaml::
1 | 1 | 1 | 0s | 0s | CORE:fteread (opcode) | Portable::LoadYaml::
1 | 1 | 1 | 0s | 0s | CORE:ftfile (opcode) | Portable::LoadYaml::
1 | 1 | 1 | 0s | 0s | CORE:ftis (opcode) | Portable::LoadYaml::
906 | 17 | 1 | 0s | 0s | CORE:match (opcode) | Portable::LoadYaml::
1 | 1 | 1 | 0s | 0s | CORE:open (opcode) | Portable::LoadYaml::
5 | 5 | 1 | 0s | 0s | CORE:qr (opcode) | Portable::LoadYaml::
1 | 1 | 1 | 0s | 0s | CORE:readline (opcode) | Portable::LoadYaml::
473 | 3 | 1 | 0s | 0s | CORE:regcomp (opcode) | Portable::LoadYaml::
586 | 6 | 1 | 0s | 0s | CORE:subst (opcode) | Portable::LoadYaml::
1 | 1 | 1 | 0s | 0s | _load_array | Portable::LoadYaml::
1 | 1 | 1 | 0s | 15.6ms | _load_file | Portable::LoadYaml::
6 | 2 | 1 | 0s | 15.6ms | _load_hash (recurses: max depth 1, inclusive time 15.6ms) | Portable::LoadYaml::
1 | 1 | 1 | 0s | 15.6ms | _load_string | Portable::LoadYaml::
0 | 0 | 0 | 0s | 0s | _unquote_double | Portable::LoadYaml::
32 | 1 | 1 | 0s | 0s | _unquote_single | Portable::LoadYaml::
1 | 1 | 1 | 0s | 15.6ms | load_file | Portable::LoadYaml::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package Portable::LoadYaml; | ||||
2 | |||||
3 | ### UGLY HACK: these functions where completely copied from Parse::CPAN::Meta | ||||
4 | |||||
5 | 2 | 0s | 1 | 0s | # spent 0s within Portable::LoadYaml::BEGIN@5 which was called:
# once (0s+0s) by Portable::BEGIN@54 at line 5 # spent 0s making 1 call to Portable::LoadYaml::BEGIN@5 |
6 | 2 | 0s | 2 | 0s | # spent 0s within Portable::LoadYaml::BEGIN@6 which was called:
# once (0s+0s) by Portable::BEGIN@54 at line 6 # spent 0s making 1 call to Portable::LoadYaml::BEGIN@6
# spent 0s making 1 call to strict::import |
7 | 2 | 0s | 2 | 0s | # spent 0s within Portable::LoadYaml::BEGIN@7 which was called:
# once (0s+0s) by Portable::BEGIN@54 at line 7 # spent 0s making 1 call to Portable::LoadYaml::BEGIN@7
# spent 0s making 1 call to warnings::import |
8 | |||||
9 | 1 | 0s | our $VERSION = '1.22'; | ||
10 | |||||
11 | # spent 15.6ms (0s+15.6) within Portable::LoadYaml::load_file which was called:
# once (0s+15.6ms) by Portable::default at line 206 of Portable.pm | ||||
12 | 1 | 0s | my $file = shift; | ||
13 | 1 | 0s | 1 | 15.6ms | my $self = __PACKAGE__->_load_file($file); # spent 15.6ms making 1 call to Portable::LoadYaml::_load_file |
14 | 1 | 0s | return $self->[-1]; | ||
15 | } | ||||
16 | |||||
17 | ##################################################################### | ||||
18 | # Constants | ||||
19 | |||||
20 | # Printed form of the unprintable characters in the lowest range | ||||
21 | # of ASCII characters, listed by ASCII ordinal position. | ||||
22 | 1 | 0s | my @UNPRINTABLE = qw( | ||
23 | 0 x01 x02 x03 x04 x05 x06 a | ||||
24 | b t n v f r x0E x0F | ||||
25 | x10 x11 x12 x13 x14 x15 x16 x17 | ||||
26 | x18 x19 x1A e x1C x1D x1E x1F | ||||
27 | ); | ||||
28 | |||||
29 | # Printable characters for escapes | ||||
30 | 1 | 0s | my %UNESCAPES = ( | ||
31 | 0 => "\x00", z => "\x00", N => "\x85", | ||||
32 | a => "\x07", b => "\x08", t => "\x09", | ||||
33 | n => "\x0a", v => "\x0b", f => "\x0c", | ||||
34 | r => "\x0d", e => "\x1b", '\\' => '\\', | ||||
35 | ); | ||||
36 | |||||
37 | # These 3 values have special meaning when unquoted and using the | ||||
38 | # default YAML schema. They need quotes if they are strings. | ||||
39 | 1 | 0s | my %QUOTE = map { $_ => 1 } qw{ | ||
40 | null true false | ||||
41 | }; | ||||
42 | |||||
43 | # The commented out form is simpler, but overloaded the Perl regex | ||||
44 | # engine due to recursion and backtracking problems on strings | ||||
45 | # larger than 32,000ish characters. Keep it for reference purposes. | ||||
46 | # qr/\"((?:\\.|[^\"])*)\"/ | ||||
47 | 1 | 0s | 1 | 0s | my $re_capture_double_quoted = qr/\"([^\\"]*(?:\\.[^\\"]*)*)\"/; # spent 0s making 1 call to Portable::LoadYaml::CORE:qr |
48 | 1 | 0s | 1 | 0s | my $re_capture_single_quoted = qr/\'([^\']*(?:\'\'[^\']*)*)\'/; # spent 0s making 1 call to Portable::LoadYaml::CORE:qr |
49 | # unquoted re gets trailing space that needs to be stripped | ||||
50 | 1 | 0s | 1 | 0s | my $re_capture_unquoted_key = qr/([^:]+(?::+\S[^:]*)*)(?=\s*\:(?:\s+|$))/; # spent 0s making 1 call to Portable::LoadYaml::CORE:qr |
51 | 1 | 0s | 1 | 0s | my $re_trailing_comment = qr/(?:\s+\#.*)?/; # spent 0s making 1 call to Portable::LoadYaml::CORE:qr |
52 | 1 | 0s | 1 | 0s | my $re_key_value_separator = qr/\s*:(?:\s+(?:\#.*)?|$)/; # spent 0s making 1 call to Portable::LoadYaml::CORE:qr |
53 | |||||
54 | ### | ||||
55 | # Loader functions: | ||||
56 | |||||
57 | # Create an object from a file | ||||
58 | # spent 15.6ms (0s+15.6) within Portable::LoadYaml::_load_file which was called:
# once (0s+15.6ms) by Portable::LoadYaml::load_file at line 13 | ||||
59 | 1 | 0s | my $class = ref $_[0] ? ref shift : shift; | ||
60 | |||||
61 | # Check the file | ||||
62 | 1 | 0s | my $file = shift or $class->_error( 'You did not specify a file name' ); | ||
63 | 1 | 0s | 1 | 0s | $class->_error( "File '$file' does not exist" ) # spent 0s making 1 call to Portable::LoadYaml::CORE:ftis |
64 | unless -e $file; | ||||
65 | 1 | 0s | 1 | 0s | $class->_error( "'$file' is a directory, not a file" ) # spent 0s making 1 call to Portable::LoadYaml::CORE:ftfile |
66 | unless -f _; | ||||
67 | 1 | 0s | 1 | 0s | $class->_error( "Insufficient permissions to read '$file'" ) # spent 0s making 1 call to Portable::LoadYaml::CORE:fteread |
68 | unless -r _; | ||||
69 | |||||
70 | # Open unbuffered | ||||
71 | 1 | 0s | 1 | 0s | open( my $fh, "<:unix", $file ); # spent 0s making 1 call to Portable::LoadYaml::CORE:open |
72 | 1 | 0s | unless ( $fh ) { | ||
73 | $class->_error("Failed to open file '$file': $!"); | ||||
74 | } | ||||
75 | |||||
76 | # slurp the contents | ||||
77 | 1 | 0s | my $contents = eval { | ||
78 | 2 | 0s | 2 | 0s | # spent 0s within Portable::LoadYaml::BEGIN@78 which was called:
# once (0s+0s) by Portable::BEGIN@54 at line 78 # spent 0s making 1 call to Portable::LoadYaml::BEGIN@78
# spent 0s making 1 call to warnings::import |
79 | 1 | 0s | local $/; | ||
80 | <$fh> | ||||
81 | 1 | 0s | 1 | 0s | }; # spent 0s making 1 call to Portable::LoadYaml::CORE:readline |
82 | 1 | 0s | if ( my $err = $@ ) { | ||
83 | $class->_error("Error reading from file '$file': $err"); | ||||
84 | } | ||||
85 | |||||
86 | # close the file (release the lock) | ||||
87 | 1 | 0s | 1 | 0s | unless ( close $fh ) { # spent 0s making 1 call to Portable::LoadYaml::CORE:close |
88 | $class->_error("Failed to close file '$file': $!"); | ||||
89 | } | ||||
90 | |||||
91 | 1 | 0s | 1 | 15.6ms | $class->_load_string( $contents ); # spent 15.6ms making 1 call to Portable::LoadYaml::_load_string |
92 | } | ||||
93 | |||||
94 | # Create an object from a string | ||||
95 | # spent 15.6ms (0s+15.6) within Portable::LoadYaml::_load_string which was called:
# once (0s+15.6ms) by Portable::LoadYaml::_load_file at line 91 | ||||
96 | 1 | 0s | my $class = ref $_[0] ? ref shift : shift; | ||
97 | 1 | 0s | my $self = bless [], $class; | ||
98 | 1 | 0s | my $string = $_[0]; | ||
99 | 1 | 0s | eval { | ||
100 | 1 | 0s | unless ( defined $string ) { | ||
101 | die \"Did not provide a string to load"; | ||||
102 | } | ||||
103 | |||||
104 | # Check if Perl has it marked as characters, but it's internally | ||||
105 | # inconsistent. E.g. maybe latin1 got read on a :utf8 layer | ||||
106 | 1 | 0s | 1 | 0s | if ( utf8::is_utf8($string) && ! utf8::valid($string) ) { # spent 0s making 1 call to utf8::is_utf8 |
107 | die \<<'...'; | ||||
108 | Read an invalid UTF-8 string (maybe mixed UTF-8 and 8-bit character set). | ||||
109 | Did you decode with lax ":utf8" instead of strict ":encoding(UTF-8)"? | ||||
110 | ... | ||||
111 | } | ||||
112 | |||||
113 | # Ensure Unicode character semantics, even for 0x80-0xff | ||||
114 | 1 | 0s | 1 | 0s | utf8::upgrade($string); # spent 0s making 1 call to utf8::upgrade |
115 | |||||
116 | # Check for and strip any leading UTF-8 BOM | ||||
117 | 1 | 0s | 1 | 0s | $string =~ s/^\x{FEFF}//; # spent 0s making 1 call to Portable::LoadYaml::CORE:subst |
118 | |||||
119 | # Check for some special cases | ||||
120 | 1 | 0s | return $self unless length $string; | ||
121 | |||||
122 | # Split the file into lines | ||||
123 | 107 | 0s | 106 | 0s | my @lines = grep { ! /^\s*(?:\#.*)?\z/ } # spent 0s making 106 calls to Portable::LoadYaml::CORE:match, avg 0s/call |
124 | split /(?:\015{1,2}\012|\015|\012)/, $string; | ||||
125 | |||||
126 | # Strip the initial YAML header | ||||
127 | 1 | 0s | 1 | 0s | @lines and $lines[0] =~ /^\%YAML[: ][\d\.]+.*\z/ and shift @lines; # spent 0s making 1 call to Portable::LoadYaml::CORE:match |
128 | |||||
129 | # A nibbling parser | ||||
130 | 1 | 0s | my $in_document = 0; | ||
131 | 1 | 0s | while ( @lines ) { | ||
132 | # Do we have a document header? | ||||
133 | 1 | 0s | 1 | 0s | if ( $lines[0] =~ /^---\s*(?:(.+)\s*)?\z/ ) { # spent 0s making 1 call to Portable::LoadYaml::CORE:match |
134 | # Handle scalar documents | ||||
135 | 1 | 0s | shift @lines; | ||
136 | 1 | 0s | if ( defined $1 and $1 !~ /^(?:\#.+|\%YAML[: ][\d\.]+)\z/ ) { | ||
137 | push @$self, | ||||
138 | $self->_load_scalar( "$1", [ undef ], \@lines ); | ||||
139 | next; | ||||
140 | } | ||||
141 | 1 | 0s | $in_document = 1; | ||
142 | } | ||||
143 | |||||
144 | 1 | 0s | 3 | 0s | if ( ! @lines or $lines[0] =~ /^(?:---|\.\.\.)/ ) { # spent 0s making 3 calls to Portable::LoadYaml::CORE:match, avg 0s/call |
145 | # A naked document | ||||
146 | push @$self, undef; | ||||
147 | while ( @lines and $lines[0] !~ /^---/ ) { | ||||
148 | shift @lines; | ||||
149 | } | ||||
150 | $in_document = 0; | ||||
151 | |||||
152 | # XXX The final '-+$' is to look for -- which ends up being an | ||||
153 | # error later. | ||||
154 | } elsif ( ! $in_document && @$self ) { | ||||
155 | # only the first document can be explicit | ||||
156 | die \"failed to classify the line '$lines[0]'"; | ||||
157 | } elsif ( $lines[0] =~ /^\s*\-(?:\s|$|-+$)/ ) { | ||||
158 | # An array at the root | ||||
159 | my $document = [ ]; | ||||
160 | push @$self, $document; | ||||
161 | $self->_load_array( $document, [ 0 ], \@lines ); | ||||
162 | |||||
163 | } elsif ( $lines[0] =~ /^(\s*)\S/ ) { | ||||
164 | # A hash at the root | ||||
165 | 1 | 0s | my $document = { }; | ||
166 | 1 | 0s | push @$self, $document; | ||
167 | 1 | 0s | 1 | 15.6ms | $self->_load_hash( $document, [ length($1) ], \@lines ); # spent 15.6ms making 1 call to Portable::LoadYaml::_load_hash |
168 | |||||
169 | } else { | ||||
170 | # Shouldn't get here. @lines have whitespace-only lines | ||||
171 | # stripped, and previous match is a line with any | ||||
172 | # non-whitespace. So this clause should only be reachable via | ||||
173 | # a perlbug where \s is not symmetric with \S | ||||
174 | |||||
175 | # uncoverable statement | ||||
176 | die \"failed to classify the line '$lines[0]'"; | ||||
177 | } | ||||
178 | } | ||||
179 | }; | ||||
180 | 1 | 0s | if ( ref $@ eq 'SCALAR' ) { | ||
181 | $self->_error(${$@}); | ||||
182 | } elsif ( $@ ) { | ||||
183 | $self->_error($@); | ||||
184 | } | ||||
185 | |||||
186 | 1 | 0s | return $self; | ||
187 | } | ||||
188 | |||||
189 | # spent 0s within Portable::LoadYaml::_unquote_single which was called 32 times, avg 0s/call:
# 32 times (0s+0s) by Portable::LoadYaml::_load_scalar at line 218, avg 0s/call | ||||
190 | 32 | 0s | my ($self, $string) = @_; | ||
191 | 32 | 0s | return '' unless length $string; | ||
192 | 8 | 0s | 8 | 0s | $string =~ s/\'\'/\'/g; # spent 0s making 8 calls to Portable::LoadYaml::CORE:subst, avg 0s/call |
193 | 8 | 0s | return $string; | ||
194 | } | ||||
195 | |||||
196 | sub _unquote_double { | ||||
197 | my ($self, $string) = @_; | ||||
198 | return '' unless length $string; | ||||
199 | $string =~ s/\\"/"/g; | ||||
200 | $string =~ | ||||
201 | s{\\([Nnever\\fartz0b]|x([0-9a-fA-F]{2}))} | ||||
202 | {(length($1)>1)?pack("H2",$2):$UNESCAPES{$1}}gex; | ||||
203 | return $string; | ||||
204 | } | ||||
205 | |||||
206 | # Load a YAML scalar string to the actual Perl scalar | ||||
207 | sub _load_scalar { | ||||
208 | 99 | 0s | my ($self, $string, $indent, $lines) = @_; | ||
209 | |||||
210 | # Trim trailing whitespace | ||||
211 | 99 | 0s | 99 | 0s | $string =~ s/\s*\z//; # spent 0s making 99 calls to Portable::LoadYaml::CORE:subst, avg 0s/call |
212 | |||||
213 | # Explitic null/undef | ||||
214 | 99 | 0s | return undef if $string eq '~'; | ||
215 | |||||
216 | # Single quote | ||||
217 | 98 | 0s | 196 | 0s | if ( $string =~ /^$re_capture_single_quoted$re_trailing_comment\z/ ) { # spent 0s making 98 calls to Portable::LoadYaml::CORE:match, avg 0s/call
# spent 0s making 98 calls to Portable::LoadYaml::CORE:regcomp, avg 0s/call |
218 | 32 | 0s | 32 | 0s | return $self->_unquote_single($1); # spent 0s making 32 calls to Portable::LoadYaml::_unquote_single, avg 0s/call |
219 | } | ||||
220 | |||||
221 | # Double quote. | ||||
222 | 66 | 0s | 132 | 0s | if ( $string =~ /^$re_capture_double_quoted$re_trailing_comment\z/ ) { # spent 0s making 66 calls to Portable::LoadYaml::CORE:match, avg 0s/call
# spent 0s making 66 calls to Portable::LoadYaml::CORE:regcomp, avg 0s/call |
223 | return $self->_unquote_double($1); | ||||
224 | } | ||||
225 | |||||
226 | # Special cases | ||||
227 | 66 | 0s | 66 | 0s | if ( $string =~ /^[\'\"!&]/ ) { # spent 0s making 66 calls to Portable::LoadYaml::CORE:match, avg 0s/call |
228 | die \"does not support a feature in line '$string'"; | ||||
229 | } | ||||
230 | 66 | 15.6ms | 66 | 0s | return {} if $string =~ /^{}(?:\s+\#.*)?\z/; # spent 0s making 66 calls to Portable::LoadYaml::CORE:match, avg 0s/call |
231 | 66 | 0s | 66 | 0s | return [] if $string =~ /^\[\](?:\s+\#.*)?\z/; # spent 0s making 66 calls to Portable::LoadYaml::CORE:match, avg 0s/call |
232 | |||||
233 | # Regular unquoted string | ||||
234 | 66 | 0s | 66 | 0s | if ( $string !~ /^[>|]/ ) { # spent 0s making 66 calls to Portable::LoadYaml::CORE:match, avg 0s/call |
235 | 66 | 0s | 132 | 0s | die \"found illegal characters in plain scalar: '$string'" # spent 0s making 132 calls to Portable::LoadYaml::CORE:match, avg 0s/call |
236 | if $string =~ /^(?:-(?:\s|$)|[\@\%\`])/ or | ||||
237 | $string =~ /:(?:\s|$)/; | ||||
238 | 66 | 0s | 66 | 0s | $string =~ s/\s+#.*\z//; # spent 0s making 66 calls to Portable::LoadYaml::CORE:subst, avg 0s/call |
239 | 66 | 0s | return $string; | ||
240 | } | ||||
241 | |||||
242 | # Error | ||||
243 | die \"failed to find multi-line scalar content" unless @$lines; | ||||
244 | |||||
245 | # Check the indent depth | ||||
246 | $lines->[0] =~ /^(\s*)/; | ||||
247 | $indent->[-1] = length("$1"); | ||||
248 | if ( defined $indent->[-2] and $indent->[-1] <= $indent->[-2] ) { | ||||
249 | die \"found bad indenting in line '$lines->[0]'"; | ||||
250 | } | ||||
251 | |||||
252 | # Pull the lines | ||||
253 | my @multiline = (); | ||||
254 | while ( @$lines ) { | ||||
255 | $lines->[0] =~ /^(\s*)/; | ||||
256 | last unless length($1) >= $indent->[-1]; | ||||
257 | push @multiline, substr(shift(@$lines), length($1)); | ||||
258 | } | ||||
259 | |||||
260 | my $j = (substr($string, 0, 1) eq '>') ? ' ' : "\n"; | ||||
261 | my $t = (substr($string, 1, 1) eq '-') ? '' : "\n"; | ||||
262 | return join( $j, @multiline ) . $t; | ||||
263 | } | ||||
264 | |||||
265 | # Load an array | ||||
266 | # spent 0s within Portable::LoadYaml::_load_array which was called:
# once (0s+0s) by Portable::LoadYaml::_load_hash at line 410 | ||||
267 | 1 | 0s | my ($self, $array, $indent, $lines) = @_; | ||
268 | |||||
269 | 1 | 0s | while ( @$lines ) { | ||
270 | # Check for a new document | ||||
271 | 2 | 0s | 2 | 0s | if ( $lines->[0] =~ /^(?:---|\.\.\.)/ ) { # spent 0s making 2 calls to Portable::LoadYaml::CORE:match, avg 0s/call |
272 | while ( @$lines and $lines->[0] !~ /^---/ ) { | ||||
273 | shift @$lines; | ||||
274 | } | ||||
275 | return 1; | ||||
276 | } | ||||
277 | |||||
278 | # Check the indent level | ||||
279 | 2 | 0s | 2 | 0s | $lines->[0] =~ /^(\s*)/; # spent 0s making 2 calls to Portable::LoadYaml::CORE:match, avg 0s/call |
280 | 2 | 0s | if ( length($1) < $indent->[-1] ) { | ||
281 | return 1; | ||||
282 | } elsif ( length($1) > $indent->[-1] ) { | ||||
283 | die \"found bad indenting in line '$lines->[0]'"; | ||||
284 | } | ||||
285 | |||||
286 | 2 | 0s | 6 | 0s | if ( $lines->[0] =~ /^(\s*\-\s+)[^\'\"]\S*\s*:(?:\s+|$)/ ) { # spent 0s making 6 calls to Portable::LoadYaml::CORE:match, avg 0s/call |
287 | # Inline nested hash | ||||
288 | my $indent2 = length("$1"); | ||||
289 | $lines->[0] =~ s/-/ /; | ||||
290 | push @$array, { }; | ||||
291 | $self->_load_hash( $array->[-1], [ @$indent, $indent2 ], $lines ); | ||||
292 | |||||
293 | } elsif ( $lines->[0] =~ /^\s*\-\s*\z/ ) { | ||||
294 | shift @$lines; | ||||
295 | unless ( @$lines ) { | ||||
296 | push @$array, undef; | ||||
297 | return 1; | ||||
298 | } | ||||
299 | if ( $lines->[0] =~ /^(\s*)\-/ ) { | ||||
300 | my $indent2 = length("$1"); | ||||
301 | if ( $indent->[-1] == $indent2 ) { | ||||
302 | # Null array entry | ||||
303 | push @$array, undef; | ||||
304 | } else { | ||||
305 | # Naked indenter | ||||
306 | push @$array, [ ]; | ||||
307 | $self->_load_array( | ||||
308 | $array->[-1], [ @$indent, $indent2 ], $lines | ||||
309 | ); | ||||
310 | } | ||||
311 | |||||
312 | } elsif ( $lines->[0] =~ /^(\s*)\S/ ) { | ||||
313 | push @$array, { }; | ||||
314 | $self->_load_hash( | ||||
315 | $array->[-1], [ @$indent, length("$1") ], $lines | ||||
316 | ); | ||||
317 | |||||
318 | } else { | ||||
319 | die \"failed to classify line '$lines->[0]'"; | ||||
320 | } | ||||
321 | |||||
322 | } elsif ( $lines->[0] =~ /^\s*\-(\s*)(.+?)\s*\z/ ) { | ||||
323 | # Array entry with a value | ||||
324 | 2 | 0s | shift @$lines; | ||
325 | 2 | 0s | 2 | 0s | push @$array, $self->_load_scalar( # spent 0s making 2 calls to Portable::LoadYaml::_load_scalar, avg 0s/call |
326 | "$2", [ @$indent, undef ], $lines | ||||
327 | ); | ||||
328 | |||||
329 | } elsif ( defined $indent->[-2] and $indent->[-1] == $indent->[-2] ) { | ||||
330 | # This is probably a structure like the following... | ||||
331 | # --- | ||||
332 | # foo: | ||||
333 | # - list | ||||
334 | # bar: value | ||||
335 | # | ||||
336 | # ... so lets return and let the hash parser handle it | ||||
337 | return 1; | ||||
338 | |||||
339 | } else { | ||||
340 | die \"failed to classify line '$lines->[0]'"; | ||||
341 | } | ||||
342 | } | ||||
343 | |||||
344 | 1 | 0s | return 1; | ||
345 | } | ||||
346 | |||||
347 | # Load a hash | ||||
348 | sub _load_hash { | ||||
349 | 6 | 0s | my ($self, $hash, $indent, $lines) = @_; | ||
350 | |||||
351 | 6 | 0s | while ( @$lines ) { | ||
352 | # Check for a new document | ||||
353 | 107 | 0s | 107 | 0s | if ( $lines->[0] =~ /^(?:---|\.\.\.)/ ) { # spent 0s making 107 calls to Portable::LoadYaml::CORE:match, avg 0s/call |
354 | while ( @$lines and $lines->[0] !~ /^---/ ) { | ||||
355 | shift @$lines; | ||||
356 | } | ||||
357 | return 1; | ||||
358 | } | ||||
359 | |||||
360 | # Check the indent level | ||||
361 | 107 | 0s | 107 | 0s | $lines->[0] =~ /^(\s*)/; # spent 0s making 107 calls to Portable::LoadYaml::CORE:match, avg 0s/call |
362 | 107 | 0s | if ( length($1) < $indent->[-1] ) { | ||
363 | return 1; | ||||
364 | } elsif ( length($1) > $indent->[-1] ) { | ||||
365 | die \"found bad indenting in line '$lines->[0]'"; | ||||
366 | } | ||||
367 | |||||
368 | # Find the key | ||||
369 | 103 | 0s | my $key; | ||
370 | |||||
371 | # Quoted keys | ||||
372 | 103 | 0s | 618 | 0s | if ( $lines->[0] =~ # spent 0s making 309 calls to Portable::LoadYaml::CORE:regcomp, avg 0s/call
# spent 0s making 309 calls to Portable::LoadYaml::CORE:subst, avg 0s/call |
373 | s/^\s*$re_capture_single_quoted$re_key_value_separator// | ||||
374 | ) { | ||||
375 | $key = $self->_unquote_single($1); | ||||
376 | } | ||||
377 | elsif ( $lines->[0] =~ | ||||
378 | s/^\s*$re_capture_double_quoted$re_key_value_separator// | ||||
379 | ) { | ||||
380 | $key = $self->_unquote_double($1); | ||||
381 | } | ||||
382 | elsif ( $lines->[0] =~ | ||||
383 | s/^\s*$re_capture_unquoted_key$re_key_value_separator// | ||||
384 | ) { | ||||
385 | 103 | 0s | $key = $1; | ||
386 | 103 | 0s | 103 | 0s | $key =~ s/\s+$//; # spent 0s making 103 calls to Portable::LoadYaml::CORE:subst, avg 0s/call |
387 | } | ||||
388 | elsif ( $lines->[0] =~ /^\s*\?/ ) { | ||||
389 | die \"does not support a feature in line '$lines->[0]'"; | ||||
390 | } | ||||
391 | else { | ||||
392 | die \"failed to classify line '$lines->[0]'"; | ||||
393 | } | ||||
394 | |||||
395 | # Do we have a value? | ||||
396 | 103 | 0s | 97 | 15.6ms | if ( length $lines->[0] ) { # spent 15.6ms making 97 calls to Portable::LoadYaml::_load_scalar, avg 161µs/call |
397 | # Yes | ||||
398 | $hash->{$key} = $self->_load_scalar( | ||||
399 | shift(@$lines), [ @$indent, undef ], $lines | ||||
400 | ); | ||||
401 | } else { | ||||
402 | # An indent | ||||
403 | 6 | 0s | shift @$lines; | ||
404 | 6 | 0s | unless ( @$lines ) { | ||
405 | $hash->{$key} = undef; | ||||
406 | return 1; | ||||
407 | } | ||||
408 | 6 | 0s | 11 | 0s | if ( $lines->[0] =~ /^(\s*)-/ ) { # spent 0s making 11 calls to Portable::LoadYaml::CORE:match, avg 0s/call |
409 | 1 | 0s | $hash->{$key} = []; | ||
410 | 1 | 0s | 1 | 0s | $self->_load_array( # spent 0s making 1 call to Portable::LoadYaml::_load_array |
411 | $hash->{$key}, [ @$indent, length($1) ], $lines | ||||
412 | ); | ||||
413 | } elsif ( $lines->[0] =~ /^(\s*)./ ) { | ||||
414 | 5 | 0s | my $indent2 = length("$1"); | ||
415 | 5 | 0s | if ( $indent->[-1] >= $indent2 ) { | ||
416 | # Null hash entry | ||||
417 | $hash->{$key} = undef; | ||||
418 | } else { | ||||
419 | 5 | 0s | $hash->{$key} = {}; | ||
420 | 5 | 0s | 5 | 0s | $self->_load_hash( # spent 15.6ms making 5 calls to Portable::LoadYaml::_load_hash, avg 3.12ms/call, recursion: max depth 1, sum of overlapping time 15.6ms |
421 | $hash->{$key}, [ @$indent, length($1) ], $lines | ||||
422 | ); | ||||
423 | } | ||||
424 | } | ||||
425 | } | ||||
426 | } | ||||
427 | |||||
428 | 2 | 0s | return 1; | ||
429 | } | ||||
430 | |||||
431 | 1 | 0s | 1; | ||
# spent 0s within Portable::LoadYaml::CORE:close which was called:
# once (0s+0s) by Portable::LoadYaml::_load_file at line 87 | |||||
# spent 0s within Portable::LoadYaml::CORE:fteread which was called:
# once (0s+0s) by Portable::LoadYaml::_load_file at line 67 | |||||
# spent 0s within Portable::LoadYaml::CORE:ftfile which was called:
# once (0s+0s) by Portable::LoadYaml::_load_file at line 65 | |||||
# spent 0s within Portable::LoadYaml::CORE:ftis which was called:
# once (0s+0s) by Portable::LoadYaml::_load_file at line 63 | |||||
# spent 0s within Portable::LoadYaml::CORE:match which was called 906 times, avg 0s/call:
# 132 times (0s+0s) by Portable::LoadYaml::_load_scalar at line 235, avg 0s/call
# 107 times (0s+0s) by Portable::LoadYaml::_load_hash at line 353, avg 0s/call
# 107 times (0s+0s) by Portable::LoadYaml::_load_hash at line 361, avg 0s/call
# 106 times (0s+0s) by Portable::LoadYaml::_load_string at line 123, avg 0s/call
# 98 times (0s+0s) by Portable::LoadYaml::_load_scalar at line 217, avg 0s/call
# 66 times (0s+0s) by Portable::LoadYaml::_load_scalar at line 230, avg 0s/call
# 66 times (0s+0s) by Portable::LoadYaml::_load_scalar at line 222, avg 0s/call
# 66 times (0s+0s) by Portable::LoadYaml::_load_scalar at line 231, avg 0s/call
# 66 times (0s+0s) by Portable::LoadYaml::_load_scalar at line 234, avg 0s/call
# 66 times (0s+0s) by Portable::LoadYaml::_load_scalar at line 227, avg 0s/call
# 11 times (0s+0s) by Portable::LoadYaml::_load_hash at line 408, avg 0s/call
# 6 times (0s+0s) by Portable::LoadYaml::_load_array at line 286, avg 0s/call
# 3 times (0s+0s) by Portable::LoadYaml::_load_string at line 144, avg 0s/call
# 2 times (0s+0s) by Portable::LoadYaml::_load_array at line 271, avg 0s/call
# 2 times (0s+0s) by Portable::LoadYaml::_load_array at line 279, avg 0s/call
# once (0s+0s) by Portable::LoadYaml::_load_string at line 127
# once (0s+0s) by Portable::LoadYaml::_load_string at line 133 | |||||
# spent 0s within Portable::LoadYaml::CORE:open which was called:
# once (0s+0s) by Portable::LoadYaml::_load_file at line 71 | |||||
# spent 0s within Portable::LoadYaml::CORE:qr which was called 5 times, avg 0s/call:
# once (0s+0s) by Portable::BEGIN@54 at line 51
# once (0s+0s) by Portable::BEGIN@54 at line 48
# once (0s+0s) by Portable::BEGIN@54 at line 47
# once (0s+0s) by Portable::BEGIN@54 at line 50
# once (0s+0s) by Portable::BEGIN@54 at line 52 | |||||
# spent 0s within Portable::LoadYaml::CORE:readline which was called:
# once (0s+0s) by Portable::LoadYaml::_load_file at line 81 | |||||
# spent 0s within Portable::LoadYaml::CORE:regcomp which was called 473 times, avg 0s/call:
# 309 times (0s+0s) by Portable::LoadYaml::_load_hash at line 372, avg 0s/call
# 98 times (0s+0s) by Portable::LoadYaml::_load_scalar at line 217, avg 0s/call
# 66 times (0s+0s) by Portable::LoadYaml::_load_scalar at line 222, avg 0s/call | |||||
# spent 0s within Portable::LoadYaml::CORE:subst which was called 586 times, avg 0s/call:
# 309 times (0s+0s) by Portable::LoadYaml::_load_hash at line 372, avg 0s/call
# 103 times (0s+0s) by Portable::LoadYaml::_load_hash at line 386, avg 0s/call
# 99 times (0s+0s) by Portable::LoadYaml::_load_scalar at line 211, avg 0s/call
# 66 times (0s+0s) by Portable::LoadYaml::_load_scalar at line 238, avg 0s/call
# 8 times (0s+0s) by Portable::LoadYaml::_unquote_single at line 192, avg 0s/call
# once (0s+0s) by Portable::LoadYaml::_load_string at line 117 |