← Index
NYTProf Performance Profile   « line view »
For /Users/brian/bin/perls/cpan5.26.1
  Run on Sat Dec 30 01:41:10 2017
Reported on Sat Dec 30 01:44:14 2017

Filename/usr/local/perls/perl-5.26.1/lib/5.26.1/darwin-2level/File/Spec/Unix.pm
StatementsExecuted 75853 statements in 415ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
1367661072.41s4.32sFile::Spec::Unix::::catfileFile::Spec::Unix::catfile (xsub)
1373621671.35s1.61sFile::Spec::Unix::::catdirFile::Spec::Unix::catdir (xsub)
275125188568ms568msFile::Spec::Unix::::canonpathFile::Spec::Unix::canonpath (xsub)
354165371.7ms71.7msFile::Spec::Unix::::curdirFile::Spec::Unix::curdir
354132256.0ms56.0msFile::Spec::Unix::::updirFile::Spec::Unix::updir
1000215.47ms5.47msFile::Spec::Unix::::splitdirFile::Spec::Unix::splitdir
1000215.43ms5.43msFile::Spec::Unix::::splitpathFile::Spec::Unix::splitpath
11193µs165µsFile::Spec::Unix::::_tmpdirFile::Spec::Unix::_tmpdir
11153µs251µsFile::Spec::Unix::::tmpdirFile::Spec::Unix::tmpdir
11132µs32µsFile::Spec::Unix::::CORE:ftdirFile::Spec::Unix::CORE:ftdir (opcode)
11123µs23µsFile::Spec::Unix::::_cached_tmpdirFile::Spec::Unix::_cached_tmpdir
11117µs30µsFile::Spec::Unix::::file_name_is_absoluteFile::Spec::Unix::file_name_is_absolute
11113µs13µsFile::Spec::Unix::::CORE:matchFile::Spec::Unix::CORE:match (opcode)
11110µs10µsFile::Spec::Unix::::_cache_tmpdirFile::Spec::Unix::_cache_tmpdir
1117µs7µsFile::Spec::Unix::::CORE:ftewriteFile::Spec::Unix::CORE:ftewrite (opcode)
1115µs5µsFile::Spec::Unix::::rootdirFile::Spec::Unix::rootdir
0000s0sFile::Spec::Unix::::BEGINFile::Spec::Unix::BEGIN
0000s0sFile::Spec::Unix::::_collapseFile::Spec::Unix::_collapse
0000s0sFile::Spec::Unix::::_cwdFile::Spec::Unix::_cwd
0000s0sFile::Spec::Unix::::_pp_canonpathFile::Spec::Unix::_pp_canonpath
0000s0sFile::Spec::Unix::::_pp_catdirFile::Spec::Unix::_pp_catdir
0000s0sFile::Spec::Unix::::_pp_catfileFile::Spec::Unix::_pp_catfile
0000s0sFile::Spec::Unix::::_sameFile::Spec::Unix::_same
0000s0sFile::Spec::Unix::::abs2relFile::Spec::Unix::abs2rel
0000s0sFile::Spec::Unix::::case_tolerantFile::Spec::Unix::case_tolerant
0000s0sFile::Spec::Unix::::catpathFile::Spec::Unix::catpath
0000s0sFile::Spec::Unix::::devnullFile::Spec::Unix::devnull
0000s0sFile::Spec::Unix::::joinFile::Spec::Unix::join
0000s0sFile::Spec::Unix::::no_upwardsFile::Spec::Unix::no_upwards
0000s0sFile::Spec::Unix::::pathFile::Spec::Unix::path
0000s0sFile::Spec::Unix::::rel2absFile::Spec::Unix::rel2abs
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1package File::Spec::Unix;
2
3use strict;
4use vars qw($VERSION);
5
6$VERSION = '3.67';
7my $xs_version = $VERSION;
8$VERSION =~ tr/_//d;
9
10#dont try to load XSLoader and DynaLoader only to ultimately fail on miniperl
11if(!defined &canonpath && defined &DynaLoader::boot_DynaLoader) {
12 eval {#eval is questionable since we are handling potential errors like
13 #"Cwd object version 3.48 does not match bootstrap parameter 3.50
14 #at lib/DynaLoader.pm line 216." by having this eval
15 if ( $] >= 5.006 ) {
16 require XSLoader;
17 XSLoader::load("Cwd", $xs_version);
18 } else {
19 require Cwd;
20 }
21 };
22}
23
24=head1 NAME
25
26File::Spec::Unix - File::Spec for Unix, base for other File::Spec modules
27
28=head1 SYNOPSIS
29
30 require File::Spec::Unix; # Done automatically by File::Spec
31
32=head1 DESCRIPTION
33
34Methods for manipulating file specifications. Other File::Spec
35modules, such as File::Spec::Mac, inherit from File::Spec::Unix and
36override specific methods.
37
38=head1 METHODS
39
40=over 2
41
42=item canonpath()
43
44No physical check on the filesystem, but a logical cleanup of a
45path. On UNIX eliminates successive slashes and successive "/.".
46
47 $cpath = File::Spec->canonpath( $path ) ;
48
49Note that this does *not* collapse F<x/../y> sections into F<y>. This
50is by design. If F</foo> on your system is a symlink to F</bar/baz>,
51then F</foo/../quux> is actually F</bar/quux>, not F</quux> as a naive
52F<../>-removal would give you. If you want to do this kind of
53processing, you probably want C<Cwd>'s C<realpath()> function to
54actually traverse the filesystem cleaning up paths like this.
55
56=cut
57
58sub _pp_canonpath {
59 my ($self,$path) = @_;
60 return unless defined $path;
61
62 # Handle POSIX-style node names beginning with double slash (qnx, nto)
63 # (POSIX says: "a pathname that begins with two successive slashes
64 # may be interpreted in an implementation-defined manner, although
65 # more than two leading slashes shall be treated as a single slash.")
66 my $node = '';
67 my $double_slashes_special = $^O eq 'qnx' || $^O eq 'nto';
68
69
70 if ( $double_slashes_special
71 && ( $path =~ s{^(//[^/]+)/?\z}{}s || $path =~ s{^(//[^/]+)/}{/}s ) ) {
72 $node = $1;
73 }
74 # This used to be
75 # $path =~ s|/+|/|g unless ($^O eq 'cygwin');
76 # but that made tests 29, 30, 35, 46, and 213 (as of #13272) to fail
77 # (Mainly because trailing "" directories didn't get stripped).
78 # Why would cygwin avoid collapsing multiple slashes into one? --jhi
79 $path =~ s|/{2,}|/|g; # xx////xx -> xx/xx
80 $path =~ s{(?:/\.)+(?:/|\z)}{/}g; # xx/././xx -> xx/xx
81 $path =~ s|^(?:\./)+||s unless $path eq "./"; # ./xx -> xx
82 $path =~ s|^/(?:\.\./)+|/|; # /../../xx -> xx
83 $path =~ s|^/\.\.$|/|; # /.. -> /
84 $path =~ s|/\z|| unless $path eq "/"; # xx/ -> xx
85 return "$node$path";
86}
87*canonpath = \&_pp_canonpath unless defined &canonpath;
88
89=item catdir()
90
91Concatenate two or more directory names to form a complete path ending
92with a directory. But remove the trailing slash from the resulting
93string, because it doesn't look good, isn't necessary and confuses
94OS2. Of course, if this is the root directory, don't cut off the
95trailing slash :-)
96
97=cut
98
99sub _pp_catdir {
100 my $self = shift;
101
102 $self->canonpath(join('/', @_, '')); # '' because need a trailing '/'
103}
104*catdir = \&_pp_catdir unless defined &catdir;
105
106=item catfile
107
108Concatenate one or more directory names and a filename to form a
109complete path ending with a filename
110
111=cut
112
113sub _pp_catfile {
114 my $self = shift;
115 my $file = $self->canonpath(pop @_);
116 return $file unless @_;
117 my $dir = $self->catdir(@_);
118 $dir .= "/" unless substr($dir,-1) eq "/";
119 return $dir.$file;
120}
121*catfile = \&_pp_catfile unless defined &catfile;
122
123=item curdir
124
125Returns a string representation of the current directory. "." on UNIX.
126
127=cut
128
12935416248ms
# spent 71.7ms within File::Spec::Unix::curdir which was called 35416 times, avg 2µs/call: # 35412 times (71.6ms+0s) by File::Path::_rmtree at line 328 of File/Path.pm, avg 2µs/call # once (10µs+0s) by CPAN::Distribution::run_preps_on_packagedir at line 513 of CPAN/Distribution.pm # once (7µs+0s) by CPAN::CacheMgr::entries at line 68 of CPAN/CacheMgr.pm # once (3µs+0s) by CPAN::Distribution::run_preps_on_packagedir at line 531 of CPAN/Distribution.pm # once (2µs+0s) by CPAN::Distribution::store_persistent_state at line 816 of CPAN/Distribution.pm
sub curdir { '.' }
130use constant _fn_curdir => ".";
131
132=item devnull
133
134Returns a string representation of the null device. "/dev/null" on UNIX.
135
136=cut
137
138sub devnull { '/dev/null' }
139use constant _fn_devnull => "/dev/null";
140
141=item rootdir
142
143Returns a string representation of the root directory. "/" on UNIX.
144
145=cut
146
14716µs
# spent 5µs within File::Spec::Unix::rootdir which was called: # once (5µs+0s) by CPAN::shell at line 305 of CPAN.pm
sub rootdir { '/' }
148use constant _fn_rootdir => "/";
149
150=item tmpdir
151
152Returns a string representation of the first writable directory from
153the following list or the current directory if none from the list are
154writable:
155
156 $ENV{TMPDIR}
157 /tmp
158
159If running under taint mode, and if $ENV{TMPDIR}
160is tainted, it is not used.
161
162=cut
163
164my ($tmpdir, %tmpenv);
165# Cache and return the calculated tmpdir, recording which env vars
166# determined it.
167
# spent 10µs within File::Spec::Unix::_cache_tmpdir which was called: # once (10µs+0s) by File::Spec::Unix::tmpdir at line 213
sub _cache_tmpdir {
16816µs @tmpenv{@_[2..$#_]} = @ENV{@_[2..$#_]};
16915µs return $tmpdir = $_[1];
170}
171# Retrieve the cached tmpdir, checking first whether relevant env vars have
172# changed and invalidated the cache.
173
# spent 23µs within File::Spec::Unix::_cached_tmpdir which was called: # once (23µs+0s) by File::Spec::Unix::tmpdir at line 211
sub _cached_tmpdir {
17411µs shift;
175110µs local $^W;
176118µs return if grep $ENV{$_} ne $tmpenv{$_}, @_;
177 return $tmpdir;
178}
179
# spent 165µs (93+72) within File::Spec::Unix::_tmpdir which was called: # once (93µs+72µs) by File::Spec::Unix::tmpdir at line 213
sub _tmpdir {
18011µs my $self = shift;
18114µs my @dirlist = @_;
18229µs my $taint = do { no strict 'refs'; ${"\cTAINT"} };
18313µs if ($taint) { # Check for taint mode on perl >= 5.8.0
184 require Scalar::Util;
185 @dirlist = grep { ! Scalar::Util::tainted($_) } @dirlist;
186 }
187 elsif ($] < 5.007) { # No ${^TAINT} before 5.8
188 @dirlist = grep { eval { eval('1'.substr $_,0,0) } } @dirlist;
189 }
190
19112µs foreach (@dirlist) {
192178µs239µs next unless defined && -d && -w _;
# spent 32µs making 1 call to File::Spec::Unix::CORE:ftdir # spent 7µs making 1 call to File::Spec::Unix::CORE:ftewrite
19313µs $tmpdir = $_;
19411µs last;
195 }
19611µs $tmpdir = $self->curdir unless defined $tmpdir;
197117µs13µs $tmpdir = defined $tmpdir && $self->canonpath($tmpdir);
# spent 3µs making 1 call to File::Spec::Unix::canonpath
19819µs130µs if ( !$self->file_name_is_absolute($tmpdir) ) {
# spent 30µs making 1 call to File::Spec::Unix::file_name_is_absolute
199 # See [perl #120593] for the full details
200 # If possible, return a full path, rather than '.' or 'lib', but
201 # jump through some hoops to avoid returning a tainted value.
202 ($tmpdir) = grep {
203 $taint ? ! Scalar::Util::tainted($_) :
204 $] < 5.007 ? eval { eval('1'.substr $_,0,0) } : 1
205 } $self->rel2abs($tmpdir), $tmpdir;
206 }
207110µs return $tmpdir;
208}
209
210
# spent 251µs (53+198) within File::Spec::Unix::tmpdir which was called: # once (53µs+198µs) by CPAN::shell at line 305 of CPAN.pm
sub tmpdir {
211116µs123µs my $cached = $_[0]->_cached_tmpdir('TMPDIR');
# spent 23µs making 1 call to File::Spec::Unix::_cached_tmpdir
21210s return $cached if defined $cached;
213119µs2175µs $_[0]->_cache_tmpdir($_[0]->_tmpdir( $ENV{TMPDIR}, "/tmp" ), 'TMPDIR');
# spent 165µs making 1 call to File::Spec::Unix::_tmpdir # spent 10µs making 1 call to File::Spec::Unix::_cache_tmpdir
214}
215
216=item updir
217
218Returns a string representation of the parent directory. ".." on UNIX.
219
220=cut
221
22235413143ms
# spent 56.0ms within File::Spec::Unix::updir which was called 35413 times, avg 2µs/call: # 35412 times (56.0ms+0s) by File::Path::_rmtree at line 329 of File/Path.pm, avg 2µs/call # once (2µs+0s) by CPAN::Distribution::store_persistent_state at line 810 of CPAN/Distribution.pm
sub updir { '..' }
223use constant _fn_updir => "..";
224
225=item no_upwards
226
227Given a list of file names, strip out those that refer to a parent
228directory. (Does not strip symlinks, only '.', '..', and equivalents.)
229
230=cut
231
232sub no_upwards {
233 my $self = shift;
234 return grep(!/^\.{1,2}\z/s, @_);
235}
236
237=item case_tolerant
238
239Returns a true or false value indicating, respectively, that alphabetic
240is not or is significant when comparing file specifications.
241
242=cut
243
244sub case_tolerant { 0 }
245use constant _fn_case_tolerant => 0;
246
247=item file_name_is_absolute
248
249Takes as argument a path and returns true if it is an absolute path.
250
251This does not consult the local filesystem on Unix, Win32, OS/2 or Mac
252OS (Classic). It does consult the working environment for VMS (see
253L<File::Spec::VMS/file_name_is_absolute>).
254
255=cut
256
257
# spent 30µs (17+13) within File::Spec::Unix::file_name_is_absolute which was called: # once (17µs+13µs) by File::Spec::Unix::_tmpdir at line 198
sub file_name_is_absolute {
25812µs my ($self,$file) = @_;
259132µs113µs return scalar($file =~ m:^/:s);
# spent 13µs making 1 call to File::Spec::Unix::CORE:match
260}
261
262=item path
263
264Takes no argument, returns the environment variable PATH as an array.
265
266=cut
267
268sub path {
269 return () unless exists $ENV{PATH};
270 my @path = split(':', $ENV{PATH});
271 foreach (@path) { $_ = '.' if $_ eq '' }
272 return @path;
273}
274
275=item join
276
277join is the same as catfile.
278
279=cut
280
281sub join {
282 my $self = shift;
283 return $self->catfile(@_);
284}
285
286=item splitpath
287
288 ($volume,$directories,$file) = File::Spec->splitpath( $path );
289 ($volume,$directories,$file) = File::Spec->splitpath( $path,
290 $no_file );
291
292Splits a path into volume, directory, and filename portions. On systems
293with no concept of volume, returns '' for volume.
294
295For systems with no syntax differentiating filenames from directories,
296assumes that the last file is a path unless $no_file is true or a
297trailing separator or /. or /.. is present. On Unix this means that $no_file
298true makes this return ( '', $path, '' ).
299
300The directory portion may or may not be returned with a trailing '/'.
301
302The results can be passed to L</catpath()> to get back a path equivalent to
303(usually identical to) the original path.
304
305=cut
306
307
# spent 5.43ms within File::Spec::Unix::splitpath which was called 1000 times, avg 5µs/call: # 500 times (3.89ms+0s) by File::Path::_is_subdir at line 223 of File/Path.pm, avg 8µs/call # 500 times (1.54ms+0s) by File::Path::_is_subdir at line 224 of File/Path.pm, avg 3µs/call
sub splitpath {
3081000969µs my ($self,$path, $nofile) = @_;
309
3101000918µs my ($volume,$directory,$file) = ('','','');
311
3121000577µs if ( $nofile ) {
313 $directory = $path;
314 }
315 else {
316 $path =~ m|^ ( (?: .* / (?: \.\.?\z )? )? ) ([^/]*) |xs;
317 $directory = $1;
318 $file = $2;
319 }
320
321100014.7ms return ($volume,$directory,$file);
322}
323
324
325=item splitdir
326
327The opposite of L</catdir()>.
328
329 @dirs = File::Spec->splitdir( $directories );
330
331$directories must be only the directory portion of the path on systems
332that have the concept of a volume or that have path syntax that differentiates
333files from directories.
334
335Unlike just splitting the directories on the separator, empty
336directory names (C<''>) can be returned, because these are significant
337on some OSs.
338
339On Unix,
340
341 File::Spec->splitdir( "/a/b//c/" );
342
343Yields:
344
345 ( '', 'a', 'b', '', 'c', '' )
346
347=cut
348
349
# spent 5.47ms within File::Spec::Unix::splitdir which was called 1000 times, avg 5µs/call: # 500 times (4.26ms+0s) by File::Path::_is_subdir at line 229 of File/Path.pm, avg 9µs/call # 500 times (1.21ms+0s) by File::Path::_is_subdir at line 230 of File/Path.pm, avg 2µs/call
sub splitdir {
35010007.16ms return split m|/|, $_[1], -1; # Preserve trailing fields
351}
352
353
354=item catpath()
355
356Takes volume, directory and file portions and returns an entire path. Under
357Unix, $volume is ignored, and directory and file are concatenated. A '/' is
358inserted if needed (though if the directory portion doesn't start with
359'/' it is not added). On other OSs, $volume is significant.
360
361=cut
362
363sub catpath {
364 my ($self,$volume,$directory,$file) = @_;
365
366 if ( $directory ne '' &&
367 $file ne '' &&
368 substr( $directory, -1 ) ne '/' &&
369 substr( $file, 0, 1 ) ne '/'
370 ) {
371 $directory .= "/$file" ;
372 }
373 else {
374 $directory .= $file ;
375 }
376
377 return $directory ;
378}
379
380=item abs2rel
381
382Takes a destination path and an optional base path returns a relative path
383from the base path to the destination path:
384
385 $rel_path = File::Spec->abs2rel( $path ) ;
386 $rel_path = File::Spec->abs2rel( $path, $base ) ;
387
388If $base is not present or '', then L<cwd()|Cwd> is used. If $base is
389relative, then it is converted to absolute form using
390L</rel2abs()>. This means that it is taken to be relative to
391L<cwd()|Cwd>.
392
393On systems that have a grammar that indicates filenames, this ignores the
394$base filename. Otherwise all path components are assumed to be
395directories.
396
397If $path is relative, it is converted to absolute form using L</rel2abs()>.
398This means that it is taken to be relative to L<cwd()|Cwd>.
399
400No checks against the filesystem are made, so the result may not be correct if
401C<$base> contains symbolic links. (Apply
402L<Cwd::abs_path()|Cwd/abs_path> beforehand if that
403is a concern.) On VMS, there is interaction with the working environment, as
404logicals and macros are expanded.
405
406Based on code written by Shigio Yamaguchi.
407
408=cut
409
410sub abs2rel {
411 my($self,$path,$base) = @_;
412 $base = $self->_cwd() unless defined $base and length $base;
413
414 ($path, $base) = map $self->canonpath($_), $path, $base;
415
416 my $path_directories;
417 my $base_directories;
418
419 if (grep $self->file_name_is_absolute($_), $path, $base) {
420 ($path, $base) = map $self->rel2abs($_), $path, $base;
421
422 my ($path_volume) = $self->splitpath($path, 1);
423 my ($base_volume) = $self->splitpath($base, 1);
424
425 # Can't relativize across volumes
426 return $path unless $path_volume eq $base_volume;
427
428 $path_directories = ($self->splitpath($path, 1))[1];
429 $base_directories = ($self->splitpath($base, 1))[1];
430
431 # For UNC paths, the user might give a volume like //foo/bar that
432 # strictly speaking has no directory portion. Treat it as if it
433 # had the root directory for that volume.
434 if (!length($base_directories) and $self->file_name_is_absolute($base)) {
435 $base_directories = $self->rootdir;
436 }
437 }
438 else {
439 my $wd= ($self->splitpath($self->_cwd(), 1))[1];
440 $path_directories = $self->catdir($wd, $path);
441 $base_directories = $self->catdir($wd, $base);
442 }
443
444 # Now, remove all leading components that are the same
445 my @pathchunks = $self->splitdir( $path_directories );
446 my @basechunks = $self->splitdir( $base_directories );
447
448 if ($base_directories eq $self->rootdir) {
449 return $self->curdir if $path_directories eq $self->rootdir;
450 shift @pathchunks;
451 return $self->canonpath( $self->catpath('', $self->catdir( @pathchunks ), '') );
452 }
453
454 my @common;
455 while (@pathchunks && @basechunks && $self->_same($pathchunks[0], $basechunks[0])) {
456 push @common, shift @pathchunks ;
457 shift @basechunks ;
458 }
459 return $self->curdir unless @pathchunks || @basechunks;
460
461 # @basechunks now contains the directories the resulting relative path
462 # must ascend out of before it can descend to $path_directory. If there
463 # are updir components, we must descend into the corresponding directories
464 # (this only works if they are no symlinks).
465 my @reverse_base;
466 while( defined(my $dir= shift @basechunks) ) {
467 if( $dir ne $self->updir ) {
468 unshift @reverse_base, $self->updir;
469 push @common, $dir;
470 }
471 elsif( @common ) {
472 if( @reverse_base && $reverse_base[0] eq $self->updir ) {
473 shift @reverse_base;
474 pop @common;
475 }
476 else {
477 unshift @reverse_base, pop @common;
478 }
479 }
480 }
481 my $result_dirs = $self->catdir( @reverse_base, @pathchunks );
482 return $self->canonpath( $self->catpath('', $result_dirs, '') );
483}
484
485sub _same {
486 $_[1] eq $_[2];
487}
488
489=item rel2abs()
490
491Converts a relative path to an absolute path.
492
493 $abs_path = File::Spec->rel2abs( $path ) ;
494 $abs_path = File::Spec->rel2abs( $path, $base ) ;
495
496If $base is not present or '', then L<cwd()|Cwd> is used. If $base is
497relative, then it is converted to absolute form using
498L</rel2abs()>. This means that it is taken to be relative to
499L<cwd()|Cwd>.
500
501On systems that have a grammar that indicates filenames, this ignores
502the $base filename. Otherwise all path components are assumed to be
503directories.
504
505If $path is absolute, it is cleaned up and returned using L</canonpath()>.
506
507No checks against the filesystem are made. On VMS, there is
508interaction with the working environment, as logicals and
509macros are expanded.
510
511Based on code written by Shigio Yamaguchi.
512
513=cut
514
515sub rel2abs {
516 my ($self,$path,$base ) = @_;
517
518 # Clean up $path
519 if ( ! $self->file_name_is_absolute( $path ) ) {
520 # Figure out the effective $base and clean it up.
521 if ( !defined( $base ) || $base eq '' ) {
522 $base = $self->_cwd();
523 }
524 elsif ( ! $self->file_name_is_absolute( $base ) ) {
525 $base = $self->rel2abs( $base ) ;
526 }
527 else {
528 $base = $self->canonpath( $base ) ;
529 }
530
531 # Glom them together
532 $path = $self->catdir( $base, $path ) ;
533 }
534
535 return $self->canonpath( $path ) ;
536}
537
538=back
539
540=head1 COPYRIGHT
541
542Copyright (c) 2004 by the Perl 5 Porters. All rights reserved.
543
544This program is free software; you can redistribute it and/or modify
545it under the same terms as Perl itself.
546
547Please submit bug reports and patches to [email protected].
548
549=head1 SEE ALSO
550
551L<File::Spec>
552
553=cut
554
555# Internal routine to File::Spec, no point in making this public since
556# it is the standard Cwd interface. Most of the platform-specific
557# File::Spec subclasses use this.
558sub _cwd {
559 require Cwd;
560 Cwd::getcwd();
561}
562
563
564# Internal method to reduce xx\..\yy -> yy
565sub _collapse {
566 my($fs, $path) = @_;
567
568 my $updir = $fs->updir;
569 my $curdir = $fs->curdir;
570
571 my($vol, $dirs, $file) = $fs->splitpath($path);
572 my @dirs = $fs->splitdir($dirs);
573 pop @dirs if @dirs && $dirs[-1] eq '';
574
575 my @collapsed;
576 foreach my $dir (@dirs) {
577 if( $dir eq $updir and # if we have an updir
578 @collapsed and # and something to collapse
579 length $collapsed[-1] and # and its not the rootdir
580 $collapsed[-1] ne $updir and # nor another updir
581 $collapsed[-1] ne $curdir # nor the curdir
582 )
583 { # then
584 pop @collapsed; # collapse
585 }
586 else { # else
587 push @collapsed, $dir; # just hang onto it
588 }
589 }
590
591 return $fs->catpath($vol,
592 $fs->catdir(@collapsed),
593 $file
594 );
595}
596
597
5981;
 
# spent 32µs within File::Spec::Unix::CORE:ftdir which was called: # once (32µs+0s) by File::Spec::Unix::_tmpdir at line 192
sub File::Spec::Unix::CORE:ftdir; # opcode
# spent 7µs within File::Spec::Unix::CORE:ftewrite which was called: # once (7µs+0s) by File::Spec::Unix::_tmpdir at line 192
sub File::Spec::Unix::CORE:ftewrite; # opcode
# spent 13µs within File::Spec::Unix::CORE:match which was called: # once (13µs+0s) by File::Spec::Unix::file_name_is_absolute at line 259
sub File::Spec::Unix::CORE:match; # opcode
# spent 568ms within File::Spec::Unix::canonpath which was called 275125 times, avg 2µs/call: # 273192 times (564ms+0s) by File::Spec::Unix::catdir or File::Spec::Unix::catfile at line 343 of File/Path.pm, avg 2µs/call # 996 times (2.66ms+0s) by CPAN::CacheMgr::_clean_cache at line 152 of CPAN/CacheMgr.pm, avg 3µs/call # 591 times (849µs+0s) by File::Spec::Unix::catdir at line 76 of CPAN/CacheMgr.pm, avg 1µs/call # 256 times (287µs+0s) by File::Spec::Unix::catdir or File::Spec::Unix::catfile at line 74 of CPAN/CacheMgr.pm, avg 1µs/call # 36 times (135µs+0s) by File::Spec::Unix::catdir or File::Spec::Unix::catfile at line 573 of CPAN/Distribution.pm, avg 4µs/call # 36 times (112µs+0s) by File::Spec::Unix::catdir or File::Spec::Unix::catfile at line 574 of CPAN/Distribution.pm, avg 3µs/call # 2 times (4µs+0s) by File::Spec::Unix::catdir or File::Spec::Unix::catfile at line 571 of CPAN/Index.pm, avg 2µs/call # 2 times (4µs+0s) by File::Spec::Unix::catdir or File::Spec::Unix::catfile at line 430 of CPAN/Distribution.pm, avg 2µs/call # 2 times (4µs+0s) by File::Spec::Unix::catdir or File::Spec::Unix::catfile at line 705 of CPAN.pm, avg 2µs/call # 2 times (3µs+0s) by File::Spec::Unix::catdir or File::Spec::Unix::catfile at line 1414 of CPAN/Distribution.pm, avg 2µs/call # 2 times (2µs+0s) by File::Spec::Unix::catdir or File::Spec::Unix::catfile at line 506 of CPAN/HandleConfig.pm, avg 1µs/call # 2 times (2µs+0s) by File::Spec::Unix::catdir or File::Spec::Unix::catfile at line 30 of CPAN/FTP.pm, avg 1µs/call # once (4µs+0s) by File::Spec::Unix::catdir at line 531 of CPAN/Distribution.pm # once (3µs+0s) by File::Spec::Unix::_tmpdir at line 197 # once (3µs+0s) by File::Spec::Unix::catdir at line 810 of CPAN/Distribution.pm # once (2µs+0s) by File::Spec::Unix::catdir at line 542 of CPAN/HandleConfig.pm # once (2µs+0s) by File::Spec::Unix::catdir at line 564 of CPAN/Distribution.pm # once (2µs+0s) by File::Spec::Unix::catdir at line 816 of CPAN/Distribution.pm
sub File::Spec::Unix::canonpath; # xsub
# spent 1.61s (1.35+256ms) within File::Spec::Unix::catdir which was called 137362 times, avg 12µs/call: # 136596 times (1.35s+255ms) by File::Spec::Unix::catfile at line 343 of File/Path.pm, avg 12µs/call # 591 times (4.09ms+849µs) by CPAN::CacheMgr::entries at line 76 of CPAN/CacheMgr.pm, avg 8µs/call # 128 times (547µs+109µs) by File::Spec::Unix::catfile at line 74 of CPAN/CacheMgr.pm, avg 5µs/call # 18 times (304µs+47µs) by File::Spec::Unix::catfile at line 574 of CPAN/Distribution.pm, avg 20µs/call # 18 times (133µs+43µs) by File::Spec::Unix::catfile at line 573 of CPAN/Distribution.pm, avg 10µs/call # once (25µs+4µs) by CPAN::Distribution::run_preps_on_packagedir at line 531 of CPAN/Distribution.pm # once (25µs+2µs) by CPAN::HandleConfig::cpan_home_dir_candidates at line 542 of CPAN/HandleConfig.pm # once (17µs+2µs) by CPAN::Distribution::run_preps_on_packagedir at line 564 of CPAN/Distribution.pm # once (16µs+3µs) by CPAN::Distribution::store_persistent_state at line 810 of CPAN/Distribution.pm # once (15µs+2µs) by File::Spec::Unix::catfile at line 430 of CPAN/Distribution.pm # once (11µs+1µs) by File::Spec::Unix::catfile at line 571 of CPAN/Index.pm # once (9µs+2µs) by CPAN::Distribution::store_persistent_state at line 816 of CPAN/Distribution.pm # once (7µs+1000ns) by File::Spec::Unix::catfile at line 1414 of CPAN/Distribution.pm # once (7µs+1000ns) by File::Spec::Unix::catfile at line 705 of CPAN.pm # once (6µs+1000ns) by File::Spec::Unix::catfile at line 506 of CPAN/HandleConfig.pm # once (6µs+1000ns) by File::Spec::Unix::catfile at line 30 of CPAN/FTP.pm
sub File::Spec::Unix::catdir; # xsub
# spent 4.32s (2.41+1.91) within File::Spec::Unix::catfile which was called 136766 times, avg 32µs/call: # 136596 times (2.41s+1.91s) by File::Path::_rmtree at line 343 of File/Path.pm, avg 32µs/call # 128 times (1.16ms+834µs) by CPAN::CacheMgr::entries at line 74 of CPAN/CacheMgr.pm, avg 16µs/call # 18 times (602µs+416µs) by CPAN::Distribution::run_preps_on_packagedir at line 574 of CPAN/Distribution.pm, avg 57µs/call # 18 times (288µs+268µs) by CPAN::Distribution::run_preps_on_packagedir at line 573 of CPAN/Distribution.pm, avg 31µs/call # once (28µs+15µs) by CPAN::Index::read_metadata_cache at line 571 of CPAN/Index.pm # once (23µs+19µs) by CPAN::Distribution::get_file_onto_local_disk at line 430 of CPAN/Distribution.pm # once (17µs+11µs) by CPAN::checklock at line 705 of CPAN.pm # once (16µs+8µs) by CPAN::HandleConfig::_try_loading at line 506 of CPAN/HandleConfig.pm # once (13µs+10µs) by CPAN::Distribution::verifyCHECKSUM at line 1414 of CPAN/Distribution.pm # once (14µs+8µs) by CPAN::FTP::_ftp_statistics at line 30 of CPAN/FTP.pm
sub File::Spec::Unix::catfile; # xsub