| 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 | Portable::LoadYaml::_load_scalar | 
| 1 | 1 | 1 | 0s | 0s | Portable::LoadYaml::BEGIN@5 | 
| 1 | 1 | 1 | 0s | 0s | Portable::LoadYaml::BEGIN@6 | 
| 1 | 1 | 1 | 0s | 0s | Portable::LoadYaml::BEGIN@7 | 
| 1 | 1 | 1 | 0s | 0s | Portable::LoadYaml::BEGIN@78 | 
| 1 | 1 | 1 | 0s | 0s | Portable::LoadYaml::CORE:close (opcode) | 
| 1 | 1 | 1 | 0s | 0s | Portable::LoadYaml::CORE:fteread (opcode) | 
| 1 | 1 | 1 | 0s | 0s | Portable::LoadYaml::CORE:ftfile (opcode) | 
| 1 | 1 | 1 | 0s | 0s | Portable::LoadYaml::CORE:ftis (opcode) | 
| 906 | 17 | 1 | 0s | 0s | Portable::LoadYaml::CORE:match (opcode) | 
| 1 | 1 | 1 | 0s | 0s | Portable::LoadYaml::CORE:open (opcode) | 
| 5 | 5 | 1 | 0s | 0s | Portable::LoadYaml::CORE:qr (opcode) | 
| 1 | 1 | 1 | 0s | 0s | Portable::LoadYaml::CORE:readline (opcode) | 
| 473 | 3 | 1 | 0s | 0s | Portable::LoadYaml::CORE:regcomp (opcode) | 
| 586 | 6 | 1 | 0s | 0s | Portable::LoadYaml::CORE:subst (opcode) | 
| 1 | 1 | 1 | 0s | 0s | Portable::LoadYaml::_load_array | 
| 1 | 1 | 1 | 0s | 15.6ms | Portable::LoadYaml::_load_file | 
| 6 | 2 | 1 | 0s | 15.6ms | Portable::LoadYaml::_load_hash (recurses: max depth 1, inclusive time 15.6ms) | 
| 1 | 1 | 1 | 0s | 15.6ms | Portable::LoadYaml::_load_string | 
| 0 | 0 | 0 | 0s | 0s | Portable::LoadYaml::_unquote_double | 
| 32 | 1 | 1 | 0s | 0s | Portable::LoadYaml::_unquote_single | 
| 1 | 1 | 1 | 0s | 15.6ms | Portable::LoadYaml::load_file | 
| 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  |