| Filename | /usr/lib/x86_64-linux-gnu/perl/5.28/File/Spec/Unix.pm |
| Statements | Executed 80010 statements in 243ms |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 5620 | 4 | 3 | 82.6ms | 127ms | File::Spec::Unix::catfile (xsub) |
| 4600 | 7 | 3 | 66.4ms | 84.8ms | File::Spec::Unix::splitpath |
| 4568 | 1 | 1 | 44.7ms | 85.9ms | File::Spec::Unix::tmpdir |
| 4568 | 1 | 1 | 41.1ms | 41.1ms | File::Spec::Unix::_cached_tmpdir |
| 5623 | 6 | 3 | 31.6ms | 35.8ms | File::Spec::Unix::catdir (xsub) |
| 4585 | 2 | 1 | 20.6ms | 20.6ms | File::Spec::Unix::catpath |
| 5609 | 2 | 1 | 19.7ms | 19.7ms | File::Spec::Unix::CORE:match (opcode) |
| 1014 | 2 | 2 | 17.7ms | 19.1ms | File::Spec::Unix::file_name_is_absolute |
| 11279 | 8 | 5 | 12.7ms | 12.7ms | File::Spec::Unix::canonpath (xsub) |
| 1 | 1 | 1 | 3.27ms | 3.59ms | File::Spec::Unix::BEGIN@4 |
| 1 | 1 | 1 | 1.32ms | 1.67ms | File::Spec::Unix::BEGIN@57 |
| 1 | 1 | 1 | 30µs | 61µs | File::Spec::Unix::_tmpdir |
| 5 | 4 | 2 | 30µs | 30µs | File::Spec::Unix::splitdir |
| 1 | 1 | 1 | 18µs | 18µs | File::Spec::Unix::CORE:ftdir (opcode) |
| 2 | 1 | 1 | 12µs | 12µs | File::Spec::Unix::updir |
| 1 | 1 | 1 | 10µs | 12µs | File::Spec::Unix::BEGIN@3 |
| 1 | 1 | 1 | 8µs | 8µs | File::Spec::Unix::_cache_tmpdir |
| 1 | 1 | 1 | 6µs | 32µs | File::Spec::Unix::BEGIN@119 |
| 1 | 1 | 1 | 6µs | 14µs | File::Spec::Unix::BEGIN@83 |
| 2 | 1 | 1 | 6µs | 6µs | File::Spec::Unix::curdir |
| 1 | 1 | 1 | 5µs | 31µs | File::Spec::Unix::BEGIN@127 |
| 1 | 1 | 1 | 5µs | 30µs | File::Spec::Unix::BEGIN@60 |
| 1 | 1 | 1 | 5µs | 27µs | File::Spec::Unix::BEGIN@63 |
| 1 | 1 | 1 | 1µs | 1µs | File::Spec::Unix::CORE:ftewrite (opcode) |
| 0 | 0 | 0 | 0s | 0s | File::Spec::Unix::_collapse |
| 0 | 0 | 0 | 0s | 0s | File::Spec::Unix::_pp_canonpath |
| 0 | 0 | 0 | 0s | 0s | File::Spec::Unix::_pp_catdir |
| 0 | 0 | 0 | 0s | 0s | File::Spec::Unix::_pp_catfile |
| 0 | 0 | 0 | 0s | 0s | File::Spec::Unix::_same |
| 0 | 0 | 0 | 0s | 0s | File::Spec::Unix::abs2rel |
| 0 | 0 | 0 | 0s | 0s | File::Spec::Unix::case_tolerant |
| 0 | 0 | 0 | 0s | 0s | File::Spec::Unix::devnull |
| 0 | 0 | 0 | 0s | 0s | File::Spec::Unix::join |
| 0 | 0 | 0 | 0s | 0s | File::Spec::Unix::no_upwards |
| 0 | 0 | 0 | 0s | 0s | File::Spec::Unix::path |
| 0 | 0 | 0 | 0s | 0s | File::Spec::Unix::rel2abs |
| 0 | 0 | 0 | 0s | 0s | File::Spec::Unix::rootdir |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | package File::Spec::Unix; | ||||
| 2 | |||||
| 3 | 2 | 21µs | 2 | 14µs | # spent 12µs (10+2) within File::Spec::Unix::BEGIN@3 which was called:
# once (10µs+2µs) by Path::Tiny::BEGIN@13 at line 3 # spent 12µs making 1 call to File::Spec::Unix::BEGIN@3
# spent 2µs making 1 call to strict::import |
| 4 | 2 | 393µs | 1 | 3.59ms | # spent 3.59ms (3.27+319µs) within File::Spec::Unix::BEGIN@4 which was called:
# once (3.27ms+319µs) by Path::Tiny::BEGIN@13 at line 4 # spent 3.59ms making 1 call to File::Spec::Unix::BEGIN@4 |
| 5 | |||||
| 6 | 1 | 400ns | our $VERSION = '3.74'; | ||
| 7 | 1 | 800ns | $VERSION =~ tr/_//d; | ||
| 8 | |||||
| 9 | sub _pp_canonpath { | ||||
| 10 | my ($self,$path) = @_; | ||||
| 11 | return unless defined $path; | ||||
| 12 | |||||
| 13 | # Handle POSIX-style node names beginning with double slash (qnx, nto) | ||||
| 14 | # (POSIX says: "a pathname that begins with two successive slashes | ||||
| 15 | # may be interpreted in an implementation-defined manner, although | ||||
| 16 | # more than two leading slashes shall be treated as a single slash.") | ||||
| 17 | my $node = ''; | ||||
| 18 | my $double_slashes_special = $^O eq 'qnx' || $^O eq 'nto'; | ||||
| 19 | |||||
| 20 | if ( $double_slashes_special | ||||
| 21 | && ( $path =~ s{^(//[^/]+)/?\z}{}s || $path =~ s{^(//[^/]+)/}{/}s ) ) { | ||||
| 22 | $node = $1; | ||||
| 23 | } | ||||
| 24 | # This used to be | ||||
| 25 | # $path =~ s|/+|/|g unless ($^O eq 'cygwin'); | ||||
| 26 | # but that made tests 29, 30, 35, 46, and 213 (as of #13272) to fail | ||||
| 27 | # (Mainly because trailing "" directories didn't get stripped). | ||||
| 28 | # Why would cygwin avoid collapsing multiple slashes into one? --jhi | ||||
| 29 | $path =~ s|/{2,}|/|g; # xx////xx -> xx/xx | ||||
| 30 | $path =~ s{(?:/\.)+(?:/|\z)}{/}g; # xx/././xx -> xx/xx | ||||
| 31 | $path =~ s|^(?:\./)+||s unless $path eq "./"; # ./xx -> xx | ||||
| 32 | $path =~ s|^/(?:\.\./)+|/|; # /../../xx -> xx | ||||
| 33 | $path =~ s|^/\.\.$|/|; # /.. -> / | ||||
| 34 | $path =~ s|/\z|| unless $path eq "/"; # xx/ -> xx | ||||
| 35 | return "$node$path"; | ||||
| 36 | } | ||||
| 37 | 1 | 300ns | *canonpath = \&_pp_canonpath unless defined &canonpath; | ||
| 38 | |||||
| 39 | sub _pp_catdir { | ||||
| 40 | my $self = shift; | ||||
| 41 | |||||
| 42 | $self->canonpath(join('/', @_, '')); # '' because need a trailing '/' | ||||
| 43 | } | ||||
| 44 | 1 | 100ns | *catdir = \&_pp_catdir unless defined &catdir; | ||
| 45 | |||||
| 46 | sub _pp_catfile { | ||||
| 47 | my $self = shift; | ||||
| 48 | my $file = $self->canonpath(pop @_); | ||||
| 49 | return $file unless @_; | ||||
| 50 | my $dir = $self->catdir(@_); | ||||
| 51 | $dir .= "/" unless substr($dir,-1) eq "/"; | ||||
| 52 | return $dir.$file; | ||||
| 53 | } | ||||
| 54 | 1 | 100ns | *catfile = \&_pp_catfile unless defined &catfile; | ||
| 55 | |||||
| 56 | 2 | 17µs | # spent 6µs within File::Spec::Unix::curdir which was called 2 times, avg 3µs/call:
# 2 times (6µs+0s) by File::Path::_rmtree at line 374 of File/Path.pm, avg 3µs/call | ||
| 57 | 2 | 117µs | 2 | 1.71ms | # spent 1.67ms (1.32+346µs) within File::Spec::Unix::BEGIN@57 which was called:
# once (1.32ms+346µs) by Path::Tiny::BEGIN@13 at line 57 # spent 1.67ms making 1 call to File::Spec::Unix::BEGIN@57
# spent 40µs making 1 call to constant::import |
| 58 | |||||
| 59 | sub devnull { '/dev/null' } | ||||
| 60 | 2 | 31µs | 2 | 54µs | # spent 30µs (5+25) within File::Spec::Unix::BEGIN@60 which was called:
# once (5µs+25µs) by Path::Tiny::BEGIN@13 at line 60 # spent 30µs making 1 call to File::Spec::Unix::BEGIN@60
# spent 25µs making 1 call to constant::import |
| 61 | |||||
| 62 | sub rootdir { '/' } | ||||
| 63 | 2 | 122µs | 2 | 49µs | # spent 27µs (5+22) within File::Spec::Unix::BEGIN@63 which was called:
# once (5µs+22µs) by Path::Tiny::BEGIN@13 at line 63 # spent 27µs making 1 call to File::Spec::Unix::BEGIN@63
# spent 22µs making 1 call to constant::import |
| 64 | |||||
| 65 | 1 | 200ns | my ($tmpdir, %tmpenv); | ||
| 66 | # Cache and return the calculated tmpdir, recording which env vars | ||||
| 67 | # determined it. | ||||
| 68 | # spent 8µs within File::Spec::Unix::_cache_tmpdir which was called:
# once (8µs+0s) by File::Spec::Unix::tmpdir at line 115 | ||||
| 69 | 1 | 5µs | @tmpenv{@_[2..$#_]} = @ENV{@_[2..$#_]}; | ||
| 70 | 1 | 3µs | return $tmpdir = $_[1]; | ||
| 71 | } | ||||
| 72 | # Retrieve the cached tmpdir, checking first whether relevant env vars have | ||||
| 73 | # changed and invalidated the cache. | ||||
| 74 | # spent 41.1ms within File::Spec::Unix::_cached_tmpdir which was called 4568 times, avg 9µs/call:
# 4568 times (41.1ms+0s) by File::Spec::Unix::tmpdir at line 113, avg 9µs/call | ||||
| 75 | 4568 | 1.31ms | shift; | ||
| 76 | 4568 | 13.0ms | local $^W; | ||
| 77 | 4568 | 15.6ms | return if grep $ENV{$_} ne $tmpenv{$_}, @_; | ||
| 78 | 4568 | 26.7ms | return $tmpdir; | ||
| 79 | } | ||||
| 80 | # spent 61µs (30+31) within File::Spec::Unix::_tmpdir which was called:
# once (30µs+31µs) by File::Spec::Unix::tmpdir at line 115 | ||||
| 81 | 1 | 700ns | my $self = shift; | ||
| 82 | 1 | 2µs | my @dirlist = @_; | ||
| 83 | 4 | 258µs | 2 | 23µs | # spent 14µs (6+8) within File::Spec::Unix::BEGIN@83 which was called:
# once (6µs+8µs) by Path::Tiny::BEGIN@13 at line 83 # spent 14µs making 1 call to File::Spec::Unix::BEGIN@83
# spent 8µs making 1 call to strict::unimport |
| 84 | 1 | 2µs | if ($taint) { # Check for taint mode on perl >= 5.8.0 | ||
| 85 | require Scalar::Util; | ||||
| 86 | @dirlist = grep { ! Scalar::Util::tainted($_) } @dirlist; | ||||
| 87 | } | ||||
| 88 | elsif ($] < 5.007) { # No ${^TAINT} before 5.8 | ||||
| 89 | @dirlist = grep { !defined($_) || eval { eval('1'.substr $_,0,0) } } | ||||
| 90 | @dirlist; | ||||
| 91 | } | ||||
| 92 | |||||
| 93 | 1 | 900ns | foreach (@dirlist) { | ||
| 94 | 2 | 28µs | 2 | 19µs | next unless defined && -d && -w _; # spent 18µs making 1 call to File::Spec::Unix::CORE:ftdir
# spent 1µs making 1 call to File::Spec::Unix::CORE:ftewrite |
| 95 | 1 | 200ns | $tmpdir = $_; | ||
| 96 | 1 | 500ns | last; | ||
| 97 | } | ||||
| 98 | 1 | 200ns | $tmpdir = $self->curdir unless defined $tmpdir; | ||
| 99 | 1 | 7µs | 1 | 3µs | $tmpdir = defined $tmpdir && $self->canonpath($tmpdir); # spent 3µs making 1 call to File::Spec::Unix::canonpath |
| 100 | 1 | 6µs | 1 | 9µs | if ( !$self->file_name_is_absolute($tmpdir) ) { # spent 9µs making 1 call to File::Spec::Unix::file_name_is_absolute |
| 101 | # See [perl #120593] for the full details | ||||
| 102 | # If possible, return a full path, rather than '.' or 'lib', but | ||||
| 103 | # jump through some hoops to avoid returning a tainted value. | ||||
| 104 | ($tmpdir) = grep { | ||||
| 105 | $taint ? ! Scalar::Util::tainted($_) : | ||||
| 106 | $] < 5.007 ? eval { eval('1'.substr $_,0,0) } : 1 | ||||
| 107 | } $self->rel2abs($tmpdir), $tmpdir; | ||||
| 108 | } | ||||
| 109 | 1 | 4µs | return $tmpdir; | ||
| 110 | } | ||||
| 111 | |||||
| 112 | # spent 85.9ms (44.7+41.2) within File::Spec::Unix::tmpdir which was called 4568 times, avg 19µs/call:
# 4568 times (44.7ms+41.2ms) by File::Temp::tempfile at line 1057 of File/Temp.pm, avg 19µs/call | ||||
| 113 | 4568 | 15.0ms | 4568 | 41.1ms | my $cached = $_[0]->_cached_tmpdir('TMPDIR'); # spent 41.1ms making 4568 calls to File::Spec::Unix::_cached_tmpdir, avg 9µs/call |
| 114 | 4568 | 27.5ms | return $cached if defined $cached; | ||
| 115 | 1 | 12µs | 2 | 69µs | $_[0]->_cache_tmpdir($_[0]->_tmpdir( $ENV{TMPDIR}, "/tmp" ), 'TMPDIR'); # spent 61µs making 1 call to File::Spec::Unix::_tmpdir
# spent 8µs making 1 call to File::Spec::Unix::_cache_tmpdir |
| 116 | } | ||||
| 117 | |||||
| 118 | 2 | 16µs | # spent 12µs within File::Spec::Unix::updir which was called 2 times, avg 6µs/call:
# 2 times (12µs+0s) by File::Path::_rmtree at line 375 of File/Path.pm, avg 6µs/call | ||
| 119 | 2 | 75µs | 2 | 59µs | # spent 32µs (6+26) within File::Spec::Unix::BEGIN@119 which was called:
# once (6µs+26µs) by Path::Tiny::BEGIN@13 at line 119 # spent 32µs making 1 call to File::Spec::Unix::BEGIN@119
# spent 26µs making 1 call to constant::import |
| 120 | |||||
| 121 | sub no_upwards { | ||||
| 122 | my $self = shift; | ||||
| 123 | return grep(!/^\.{1,2}\z/s, @_); | ||||
| 124 | } | ||||
| 125 | |||||
| 126 | sub case_tolerant { 0 } | ||||
| 127 | 2 | 881µs | 2 | 56µs | # spent 31µs (5+25) within File::Spec::Unix::BEGIN@127 which was called:
# once (5µs+25µs) by Path::Tiny::BEGIN@13 at line 127 # spent 31µs making 1 call to File::Spec::Unix::BEGIN@127
# spent 25µs making 1 call to constant::import |
| 128 | |||||
| 129 | # spent 19.1ms (17.7+1.38) within File::Spec::Unix::file_name_is_absolute which was called 1014 times, avg 19µs/call:
# 1013 times (17.7ms+1.38ms) by Template::Provider::fetch at line 127 of Template/Provider.pm, avg 19µs/call
# once (7µs+2µs) by File::Spec::Unix::_tmpdir at line 100 | ||||
| 130 | 1014 | 742µs | my ($self,$file) = @_; | ||
| 131 | 1014 | 18.1ms | 1014 | 1.38ms | return scalar($file =~ m:^/:s); # spent 1.38ms making 1014 calls to File::Spec::Unix::CORE:match, avg 1µs/call |
| 132 | } | ||||
| 133 | |||||
| 134 | sub path { | ||||
| 135 | return () unless exists $ENV{PATH}; | ||||
| 136 | my @path = split(':', $ENV{PATH}); | ||||
| 137 | foreach (@path) { $_ = '.' if $_ eq '' } | ||||
| 138 | return @path; | ||||
| 139 | } | ||||
| 140 | |||||
| 141 | sub join { | ||||
| 142 | my $self = shift; | ||||
| 143 | return $self->catfile(@_); | ||||
| 144 | } | ||||
| 145 | |||||
| 146 | # spent 84.8ms (66.4+18.3) within File::Spec::Unix::splitpath which was called 4600 times, avg 18µs/call:
# 4583 times (66.2ms+18.2ms) by File::Temp::_gettemp at line 306 of File/Temp.pm, avg 18µs/call
# 6 times (121µs+37µs) by File::Copy::Recursive::fcopy at line 157 of File/Copy/Recursive.pm, avg 26µs/call
# 6 times (92µs+52µs) by File::Copy::Recursive::fcopy at line 177 of File/Copy/Recursive.pm, avg 24µs/call
# 2 times (8µs+0s) by File::Temp::_gettemp at line 277 of File/Temp.pm, avg 4µs/call
# once (15µs+0s) by File::Path::_is_subdir at line 255 of File/Path.pm
# once (6µs+0s) by File::Temp::tempdir at line 1155 of File/Temp.pm
# once (3µs+0s) by File::Path::_is_subdir at line 256 of File/Path.pm | ||||
| 147 | 4600 | 3.41ms | my ($self,$path, $nofile) = @_; | ||
| 148 | |||||
| 149 | 4600 | 7.89ms | my ($volume,$directory,$file) = ('','',''); | ||
| 150 | |||||
| 151 | 4600 | 2.43ms | if ( $nofile ) { | ||
| 152 | $directory = $path; | ||||
| 153 | } | ||||
| 154 | else { | ||||
| 155 | 4595 | 48.0ms | 4595 | 18.3ms | $path =~ m|^ ( (?: .* / (?: \.\.?\z )? )? ) ([^/]*) |xs; # spent 18.3ms making 4595 calls to File::Spec::Unix::CORE:match, avg 4µs/call |
| 156 | 4595 | 6.31ms | $directory = $1; | ||
| 157 | 4595 | 5.96ms | $file = $2; | ||
| 158 | } | ||||
| 159 | |||||
| 160 | 4600 | 19.6ms | return ($volume,$directory,$file); | ||
| 161 | } | ||||
| 162 | |||||
| 163 | # spent 30µs within File::Spec::Unix::splitdir which was called 5 times, avg 6µs/call:
# 2 times (5µs+0s) by File::Temp::_gettemp at line 281 of File/Temp.pm, avg 3µs/call
# once (13µs+0s) by File::Path::_is_subdir at line 261 of File/Path.pm
# once (9µs+0s) by File::Path::_is_subdir at line 262 of File/Path.pm
# once (2µs+0s) by File::Temp::tempdir at line 1158 of File/Temp.pm | ||||
| 164 | 5 | 59µs | return split m|/|, $_[1], -1; # Preserve trailing fields | ||
| 165 | } | ||||
| 166 | |||||
| 167 | # spent 20.6ms within File::Spec::Unix::catpath which was called 4585 times, avg 4µs/call:
# 4583 times (20.6ms+0s) by File::Temp::_gettemp at line 309 of File/Temp.pm, avg 4µs/call
# 2 times (9µs+0s) by File::Temp::_gettemp at line 298 of File/Temp.pm, avg 5µs/call | ||||
| 168 | 4585 | 4.40ms | my ($self,$volume,$directory,$file) = @_; | ||
| 169 | |||||
| 170 | 4585 | 5.77ms | if ( $directory ne '' && | ||
| 171 | $file ne '' && | ||||
| 172 | substr( $directory, -1 ) ne '/' && | ||||
| 173 | substr( $file, 0, 1 ) ne '/' | ||||
| 174 | ) { | ||||
| 175 | $directory .= "/$file" ; | ||||
| 176 | } | ||||
| 177 | else { | ||||
| 178 | 4585 | 1.87ms | $directory .= $file ; | ||
| 179 | } | ||||
| 180 | |||||
| 181 | 4585 | 17.4ms | return $directory ; | ||
| 182 | } | ||||
| 183 | |||||
| 184 | sub abs2rel { | ||||
| 185 | my($self,$path,$base) = @_; | ||||
| 186 | $base = Cwd::getcwd() unless defined $base and length $base; | ||||
| 187 | |||||
| 188 | ($path, $base) = map $self->canonpath($_), $path, $base; | ||||
| 189 | |||||
| 190 | my $path_directories; | ||||
| 191 | my $base_directories; | ||||
| 192 | |||||
| 193 | if (grep $self->file_name_is_absolute($_), $path, $base) { | ||||
| 194 | ($path, $base) = map $self->rel2abs($_), $path, $base; | ||||
| 195 | |||||
| 196 | my ($path_volume) = $self->splitpath($path, 1); | ||||
| 197 | my ($base_volume) = $self->splitpath($base, 1); | ||||
| 198 | |||||
| 199 | # Can't relativize across volumes | ||||
| 200 | return $path unless $path_volume eq $base_volume; | ||||
| 201 | |||||
| 202 | $path_directories = ($self->splitpath($path, 1))[1]; | ||||
| 203 | $base_directories = ($self->splitpath($base, 1))[1]; | ||||
| 204 | |||||
| 205 | # For UNC paths, the user might give a volume like //foo/bar that | ||||
| 206 | # strictly speaking has no directory portion. Treat it as if it | ||||
| 207 | # had the root directory for that volume. | ||||
| 208 | if (!length($base_directories) and $self->file_name_is_absolute($base)) { | ||||
| 209 | $base_directories = $self->rootdir; | ||||
| 210 | } | ||||
| 211 | } | ||||
| 212 | else { | ||||
| 213 | my $wd= ($self->splitpath(Cwd::getcwd(), 1))[1]; | ||||
| 214 | $path_directories = $self->catdir($wd, $path); | ||||
| 215 | $base_directories = $self->catdir($wd, $base); | ||||
| 216 | } | ||||
| 217 | |||||
| 218 | # Now, remove all leading components that are the same | ||||
| 219 | my @pathchunks = $self->splitdir( $path_directories ); | ||||
| 220 | my @basechunks = $self->splitdir( $base_directories ); | ||||
| 221 | |||||
| 222 | if ($base_directories eq $self->rootdir) { | ||||
| 223 | return $self->curdir if $path_directories eq $self->rootdir; | ||||
| 224 | shift @pathchunks; | ||||
| 225 | return $self->canonpath( $self->catpath('', $self->catdir( @pathchunks ), '') ); | ||||
| 226 | } | ||||
| 227 | |||||
| 228 | my @common; | ||||
| 229 | while (@pathchunks && @basechunks && $self->_same($pathchunks[0], $basechunks[0])) { | ||||
| 230 | push @common, shift @pathchunks ; | ||||
| 231 | shift @basechunks ; | ||||
| 232 | } | ||||
| 233 | return $self->curdir unless @pathchunks || @basechunks; | ||||
| 234 | |||||
| 235 | # @basechunks now contains the directories the resulting relative path | ||||
| 236 | # must ascend out of before it can descend to $path_directory. If there | ||||
| 237 | # are updir components, we must descend into the corresponding directories | ||||
| 238 | # (this only works if they are no symlinks). | ||||
| 239 | my @reverse_base; | ||||
| 240 | while( defined(my $dir= shift @basechunks) ) { | ||||
| 241 | if( $dir ne $self->updir ) { | ||||
| 242 | unshift @reverse_base, $self->updir; | ||||
| 243 | push @common, $dir; | ||||
| 244 | } | ||||
| 245 | elsif( @common ) { | ||||
| 246 | if( @reverse_base && $reverse_base[0] eq $self->updir ) { | ||||
| 247 | shift @reverse_base; | ||||
| 248 | pop @common; | ||||
| 249 | } | ||||
| 250 | else { | ||||
| 251 | unshift @reverse_base, pop @common; | ||||
| 252 | } | ||||
| 253 | } | ||||
| 254 | } | ||||
| 255 | my $result_dirs = $self->catdir( @reverse_base, @pathchunks ); | ||||
| 256 | return $self->canonpath( $self->catpath('', $result_dirs, '') ); | ||||
| 257 | } | ||||
| 258 | |||||
| 259 | sub _same { | ||||
| 260 | $_[1] eq $_[2]; | ||||
| 261 | } | ||||
| 262 | |||||
| 263 | sub rel2abs { | ||||
| 264 | my ($self,$path,$base ) = @_; | ||||
| 265 | |||||
| 266 | # Clean up $path | ||||
| 267 | if ( ! $self->file_name_is_absolute( $path ) ) { | ||||
| 268 | # Figure out the effective $base and clean it up. | ||||
| 269 | if ( !defined( $base ) || $base eq '' ) { | ||||
| 270 | $base = Cwd::getcwd(); | ||||
| 271 | } | ||||
| 272 | elsif ( ! $self->file_name_is_absolute( $base ) ) { | ||||
| 273 | $base = $self->rel2abs( $base ) ; | ||||
| 274 | } | ||||
| 275 | else { | ||||
| 276 | $base = $self->canonpath( $base ) ; | ||||
| 277 | } | ||||
| 278 | |||||
| 279 | # Glom them together | ||||
| 280 | $path = $self->catdir( $base, $path ) ; | ||||
| 281 | } | ||||
| 282 | |||||
| 283 | return $self->canonpath( $path ) ; | ||||
| 284 | } | ||||
| 285 | |||||
| 286 | # Internal method to reduce xx\..\yy -> yy | ||||
| 287 | sub _collapse { | ||||
| 288 | my($fs, $path) = @_; | ||||
| 289 | |||||
| 290 | my $updir = $fs->updir; | ||||
| 291 | my $curdir = $fs->curdir; | ||||
| 292 | |||||
| 293 | my($vol, $dirs, $file) = $fs->splitpath($path); | ||||
| 294 | my @dirs = $fs->splitdir($dirs); | ||||
| 295 | pop @dirs if @dirs && $dirs[-1] eq ''; | ||||
| 296 | |||||
| 297 | my @collapsed; | ||||
| 298 | foreach my $dir (@dirs) { | ||||
| 299 | if( $dir eq $updir and # if we have an updir | ||||
| 300 | @collapsed and # and something to collapse | ||||
| 301 | length $collapsed[-1] and # and its not the rootdir | ||||
| 302 | $collapsed[-1] ne $updir and # nor another updir | ||||
| 303 | $collapsed[-1] ne $curdir # nor the curdir | ||||
| 304 | ) | ||||
| 305 | { # then | ||||
| 306 | pop @collapsed; # collapse | ||||
| 307 | } | ||||
| 308 | else { # else | ||||
| 309 | push @collapsed, $dir; # just hang onto it | ||||
| 310 | } | ||||
| 311 | } | ||||
| 312 | |||||
| 313 | return $fs->catpath($vol, | ||||
| 314 | $fs->catdir(@collapsed), | ||||
| 315 | $file | ||||
| 316 | ); | ||||
| 317 | } | ||||
| 318 | |||||
| 319 | 1 | 8µs | 1; | ||
# spent 18µs within File::Spec::Unix::CORE:ftdir which was called:
# once (18µs+0s) by File::Spec::Unix::_tmpdir at line 94 | |||||
# spent 1µs within File::Spec::Unix::CORE:ftewrite which was called:
# once (1µs+0s) by File::Spec::Unix::_tmpdir at line 94 | |||||
sub File::Spec::Unix::CORE:match; # opcode | |||||
# spent 12.7ms within File::Spec::Unix::canonpath which was called 11279 times, avg 1µs/call:
# 9136 times (9.36ms+0s) by File::Spec::Unix::catdir or File::Spec::Unix::catfile at line 1057 of File/Temp.pm, avg 1µs/call
# 2056 times (3.20ms+0s) by File::Spec::Unix::catdir or File::Spec::Unix::catfile at line 525 of Template/Provider.pm, avg 2µs/call
# 35 times (48µs+0s) by Path::Tiny::path at line 248 of Path/Tiny.pm, avg 1µs/call
# 30 times (40µs+0s) by File::Spec::Unix::catdir or File::Spec::Unix::catfile at line 1051 of File/Temp.pm, avg 1µs/call
# 18 times (31µs+0s) by File::Spec::Unix::catdir or File::Spec::Unix::catfile at line 389 of File/Path.pm, avg 2µs/call
# 2 times (10µs+0s) by File::Spec::Unix::catdir at line 295 of File/Temp.pm, avg 5µs/call
# once (3µs+0s) by File::Spec::Unix::_tmpdir at line 99
# once (2µs+0s) by File::Spec::Unix::catdir at line 1161 of File/Temp.pm | |||||
# spent 35.8ms (31.6+4.17) within File::Spec::Unix::catdir which was called 5623 times, avg 6µs/call:
# 4568 times (25.7ms+3.19ms) by File::Spec::Unix::catfile at line 1057 of File/Temp.pm, avg 6µs/call
# 1028 times (5.76ms+946µs) by File::Spec::Unix::catfile at line 525 of Template/Provider.pm, avg 7µs/call
# 15 times (91µs+12µs) by File::Spec::Unix::catfile at line 1051 of File/Temp.pm, avg 7µs/call
# 9 times (49µs+11µs) by File::Spec::Unix::catfile at line 389 of File/Path.pm, avg 7µs/call
# 2 times (20µs+10µs) by File::Temp::_gettemp at line 295 of File/Temp.pm, avg 15µs/call
# once (13µs+2µs) by File::Temp::tempdir at line 1161 of File/Temp.pm | |||||
# spent 127ms (82.6+44.2) within File::Spec::Unix::catfile which was called 5620 times, avg 23µs/call:
# 4568 times (68.1ms+35.1ms) by File::Temp::tempfile at line 1057 of File/Temp.pm, avg 23µs/call
# 1028 times (13.8ms+8.96ms) by Template::Provider::_fetch_path at line 525 of Template/Provider.pm, avg 22µs/call
# 15 times (520µs+130µs) by File::Temp::tempfile at line 1051 of File/Temp.pm, avg 43µs/call
# 9 times (129µs+80µs) by File::Path::_rmtree at line 389 of File/Path.pm, avg 23µs/call |