xref: /openbsd-src/gnu/usr.bin/perl/dist/PathTools/lib/File/Spec/OS2.pm (revision 3d61058aa5c692477b6d18acfbbdb653a9930ff9)
16fb12b70Safresh1package File::Spec::OS2;
26fb12b70Safresh1
36fb12b70Safresh1use strict;
49f11ffb7Safresh1use Cwd ();
56fb12b70Safresh1require File::Spec::Unix;
66fb12b70Safresh1
7*3d61058aSafresh1our $VERSION = '3.91';
8b8851fccSafresh1$VERSION =~ tr/_//d;
96fb12b70Safresh1
109f11ffb7Safresh1our @ISA = qw(File::Spec::Unix);
116fb12b70Safresh1
126fb12b70Safresh1sub devnull {
136fb12b70Safresh1    return "/dev/nul";
146fb12b70Safresh1}
156fb12b70Safresh1
166fb12b70Safresh1sub case_tolerant {
176fb12b70Safresh1    return 1;
186fb12b70Safresh1}
196fb12b70Safresh1
206fb12b70Safresh1sub file_name_is_absolute {
216fb12b70Safresh1    my ($self,$file) = @_;
226fb12b70Safresh1    return scalar($file =~ m{^([a-z]:)?[\\/]}is);
236fb12b70Safresh1}
246fb12b70Safresh1
256fb12b70Safresh1sub path {
266fb12b70Safresh1    my $path = $ENV{PATH};
276fb12b70Safresh1    $path =~ s:\\:/:g;
286fb12b70Safresh1    my @path = split(';',$path);
296fb12b70Safresh1    foreach (@path) { $_ = '.' if $_ eq '' }
306fb12b70Safresh1    return @path;
316fb12b70Safresh1}
326fb12b70Safresh1
336fb12b70Safresh1sub tmpdir {
346fb12b70Safresh1    my $cached = $_[0]->_cached_tmpdir(qw 'TMPDIR TEMP TMP');
356fb12b70Safresh1    return $cached if defined $cached;
366fb12b70Safresh1    my @d = @ENV{qw(TMPDIR TEMP TMP)};	# function call could autovivivy
376fb12b70Safresh1    $_[0]->_cache_tmpdir(
386fb12b70Safresh1	$_[0]->_tmpdir( @d, '/tmp', '/' ), qw 'TMPDIR TEMP TMP'
396fb12b70Safresh1    );
406fb12b70Safresh1}
416fb12b70Safresh1
426fb12b70Safresh1sub catdir {
436fb12b70Safresh1    my $self = shift;
446fb12b70Safresh1    my @args = @_;
456fb12b70Safresh1    foreach (@args) {
466fb12b70Safresh1	tr[\\][/];
476fb12b70Safresh1        # append a backslash to each argument unless it has one there
486fb12b70Safresh1        $_ .= "/" unless m{/$};
496fb12b70Safresh1    }
506fb12b70Safresh1    return $self->canonpath(join('', @args));
516fb12b70Safresh1}
526fb12b70Safresh1
536fb12b70Safresh1sub canonpath {
546fb12b70Safresh1    my ($self,$path) = @_;
556fb12b70Safresh1    return unless defined $path;
566fb12b70Safresh1
576fb12b70Safresh1    $path =~ s/^([a-z]:)/\l$1/s;
586fb12b70Safresh1    $path =~ s|\\|/|g;
596fb12b70Safresh1    $path =~ s|([^/])/+|$1/|g;                  # xx////xx  -> xx/xx
606fb12b70Safresh1    $path =~ s|(/\.)+/|/|g;                     # xx/././xx -> xx/xx
616fb12b70Safresh1    $path =~ s|^(\./)+(?=[^/])||s;		# ./xx      -> xx
626fb12b70Safresh1    $path =~ s|/\Z(?!\n)||
636fb12b70Safresh1             unless $path =~ m#^([a-z]:)?/\Z(?!\n)#si;# xx/       -> xx
646fb12b70Safresh1    $path =~ s{^/\.\.$}{/};                     # /..    -> /
656fb12b70Safresh1    1 while $path =~ s{^/\.\.}{};               # /../xx -> /xx
666fb12b70Safresh1    return $path;
676fb12b70Safresh1}
686fb12b70Safresh1
696fb12b70Safresh1
706fb12b70Safresh1sub splitpath {
716fb12b70Safresh1    my ($self,$path, $nofile) = @_;
726fb12b70Safresh1    my ($volume,$directory,$file) = ('','','');
736fb12b70Safresh1    if ( $nofile ) {
746fb12b70Safresh1        $path =~
756fb12b70Safresh1            m{^( (?:[a-zA-Z]:|(?:\\\\|//)[^\\/]+[\\/][^\\/]+)? )
766fb12b70Safresh1                 (.*)
776fb12b70Safresh1             }xs;
786fb12b70Safresh1        $volume    = $1;
796fb12b70Safresh1        $directory = $2;
806fb12b70Safresh1    }
816fb12b70Safresh1    else {
826fb12b70Safresh1        $path =~
836fb12b70Safresh1            m{^ ( (?: [a-zA-Z]: |
846fb12b70Safresh1                      (?:\\\\|//)[^\\/]+[\\/][^\\/]+
856fb12b70Safresh1                  )?
866fb12b70Safresh1                )
876fb12b70Safresh1                ( (?:.*[\\\\/](?:\.\.?\Z(?!\n))?)? )
886fb12b70Safresh1                (.*)
896fb12b70Safresh1             }xs;
906fb12b70Safresh1        $volume    = $1;
916fb12b70Safresh1        $directory = $2;
926fb12b70Safresh1        $file      = $3;
936fb12b70Safresh1    }
946fb12b70Safresh1
956fb12b70Safresh1    return ($volume,$directory,$file);
966fb12b70Safresh1}
976fb12b70Safresh1
986fb12b70Safresh1
996fb12b70Safresh1sub splitdir {
1006fb12b70Safresh1    my ($self,$directories) = @_ ;
1016fb12b70Safresh1    split m|[\\/]|, $directories, -1;
1026fb12b70Safresh1}
1036fb12b70Safresh1
1046fb12b70Safresh1
1056fb12b70Safresh1sub catpath {
1066fb12b70Safresh1    my ($self,$volume,$directory,$file) = @_;
1076fb12b70Safresh1
1086fb12b70Safresh1    # If it's UNC, make sure the glue separator is there, reusing
1096fb12b70Safresh1    # whatever separator is first in the $volume
1106fb12b70Safresh1    $volume .= $1
1116fb12b70Safresh1        if ( $volume =~ m@^([\\/])[\\/][^\\/]+[\\/][^\\/]+\Z(?!\n)@s &&
1126fb12b70Safresh1             $directory =~ m@^[^\\/]@s
1136fb12b70Safresh1           ) ;
1146fb12b70Safresh1
1156fb12b70Safresh1    $volume .= $directory ;
1166fb12b70Safresh1
1176fb12b70Safresh1    # If the volume is not just A:, make sure the glue separator is
1186fb12b70Safresh1    # there, reusing whatever separator is first in the $volume if possible.
1196fb12b70Safresh1    if ( $volume !~ m@^[a-zA-Z]:\Z(?!\n)@s &&
1206fb12b70Safresh1         $volume =~ m@[^\\/]\Z(?!\n)@      &&
1216fb12b70Safresh1         $file   =~ m@[^\\/]@
1226fb12b70Safresh1       ) {
1236fb12b70Safresh1        $volume =~ m@([\\/])@ ;
1246fb12b70Safresh1        my $sep = $1 ? $1 : '/' ;
1256fb12b70Safresh1        $volume .= $sep ;
1266fb12b70Safresh1    }
1276fb12b70Safresh1
1286fb12b70Safresh1    $volume .= $file ;
1296fb12b70Safresh1
1306fb12b70Safresh1    return $volume ;
1316fb12b70Safresh1}
1326fb12b70Safresh1
1336fb12b70Safresh1
1346fb12b70Safresh1sub abs2rel {
1356fb12b70Safresh1    my($self,$path,$base) = @_;
1366fb12b70Safresh1
1376fb12b70Safresh1    # Clean up $path
1386fb12b70Safresh1    if ( ! $self->file_name_is_absolute( $path ) ) {
1396fb12b70Safresh1        $path = $self->rel2abs( $path ) ;
1406fb12b70Safresh1    } else {
1416fb12b70Safresh1        $path = $self->canonpath( $path ) ;
1426fb12b70Safresh1    }
1436fb12b70Safresh1
1446fb12b70Safresh1    # Figure out the effective $base and clean it up.
1456fb12b70Safresh1    if ( !defined( $base ) || $base eq '' ) {
1469f11ffb7Safresh1	$base = Cwd::getcwd();
1476fb12b70Safresh1    } elsif ( ! $self->file_name_is_absolute( $base ) ) {
1486fb12b70Safresh1        $base = $self->rel2abs( $base ) ;
1496fb12b70Safresh1    } else {
1506fb12b70Safresh1        $base = $self->canonpath( $base ) ;
1516fb12b70Safresh1    }
1526fb12b70Safresh1
1536fb12b70Safresh1    # Split up paths
1546fb12b70Safresh1    my ( $path_volume, $path_directories, $path_file ) = $self->splitpath( $path, 1 ) ;
1556fb12b70Safresh1    my ( $base_volume, $base_directories ) = $self->splitpath( $base, 1 ) ;
1566fb12b70Safresh1    return $path unless $path_volume eq $base_volume;
1576fb12b70Safresh1
1586fb12b70Safresh1    # Now, remove all leading components that are the same
1596fb12b70Safresh1    my @pathchunks = $self->splitdir( $path_directories );
1606fb12b70Safresh1    my @basechunks = $self->splitdir( $base_directories );
1616fb12b70Safresh1
1626fb12b70Safresh1    while ( @pathchunks &&
1636fb12b70Safresh1            @basechunks &&
1646fb12b70Safresh1            lc( $pathchunks[0] ) eq lc( $basechunks[0] )
1656fb12b70Safresh1          ) {
1666fb12b70Safresh1        shift @pathchunks ;
1676fb12b70Safresh1        shift @basechunks ;
1686fb12b70Safresh1    }
1696fb12b70Safresh1
1706fb12b70Safresh1    # No need to catdir, we know these are well formed.
1716fb12b70Safresh1    $path_directories = CORE::join( '/', @pathchunks );
1726fb12b70Safresh1    $base_directories = CORE::join( '/', @basechunks );
1736fb12b70Safresh1
1746fb12b70Safresh1    # $base_directories now contains the directories the resulting relative
1756fb12b70Safresh1    # path must ascend out of before it can descend to $path_directory.  So,
1766fb12b70Safresh1    # replace all names with $parentDir
1776fb12b70Safresh1
1786fb12b70Safresh1    #FA Need to replace between backslashes...
1796fb12b70Safresh1    $base_directories =~ s|[^\\/]+|..|g ;
1806fb12b70Safresh1
1816fb12b70Safresh1    # Glue the two together, using a separator if necessary, and preventing an
1826fb12b70Safresh1    # empty result.
1836fb12b70Safresh1
1846fb12b70Safresh1    #FA Must check that new directories are not empty.
1856fb12b70Safresh1    if ( $path_directories ne '' && $base_directories ne '' ) {
1866fb12b70Safresh1        $path_directories = "$base_directories/$path_directories" ;
1876fb12b70Safresh1    } else {
1886fb12b70Safresh1        $path_directories = "$base_directories$path_directories" ;
1896fb12b70Safresh1    }
1906fb12b70Safresh1
1916fb12b70Safresh1    return $self->canonpath(
1926fb12b70Safresh1        $self->catpath( "", $path_directories, $path_file )
1936fb12b70Safresh1    ) ;
1946fb12b70Safresh1}
1956fb12b70Safresh1
1966fb12b70Safresh1
1976fb12b70Safresh1sub rel2abs {
1986fb12b70Safresh1    my ($self,$path,$base ) = @_;
1996fb12b70Safresh1
2006fb12b70Safresh1    if ( ! $self->file_name_is_absolute( $path ) ) {
2016fb12b70Safresh1
2026fb12b70Safresh1        if ( !defined( $base ) || $base eq '' ) {
2039f11ffb7Safresh1	    $base = Cwd::getcwd();
2046fb12b70Safresh1        }
2056fb12b70Safresh1        elsif ( ! $self->file_name_is_absolute( $base ) ) {
2066fb12b70Safresh1            $base = $self->rel2abs( $base ) ;
2076fb12b70Safresh1        }
2086fb12b70Safresh1        else {
2096fb12b70Safresh1            $base = $self->canonpath( $base ) ;
2106fb12b70Safresh1        }
2116fb12b70Safresh1
2126fb12b70Safresh1        my ( $path_directories, $path_file ) =
2136fb12b70Safresh1            ($self->splitpath( $path, 1 ))[1,2] ;
2146fb12b70Safresh1
2156fb12b70Safresh1        my ( $base_volume, $base_directories ) =
2166fb12b70Safresh1            $self->splitpath( $base, 1 ) ;
2176fb12b70Safresh1
2186fb12b70Safresh1        $path = $self->catpath(
2196fb12b70Safresh1            $base_volume,
2206fb12b70Safresh1            $self->catdir( $base_directories, $path_directories ),
2216fb12b70Safresh1            $path_file
2226fb12b70Safresh1        ) ;
2236fb12b70Safresh1    }
2246fb12b70Safresh1
2256fb12b70Safresh1    return $self->canonpath( $path ) ;
2266fb12b70Safresh1}
2276fb12b70Safresh1
2286fb12b70Safresh11;
2296fb12b70Safresh1__END__
2306fb12b70Safresh1
2316fb12b70Safresh1=head1 NAME
2326fb12b70Safresh1
2336fb12b70Safresh1File::Spec::OS2 - methods for OS/2 file specs
2346fb12b70Safresh1
2356fb12b70Safresh1=head1 SYNOPSIS
2366fb12b70Safresh1
2376fb12b70Safresh1 require File::Spec::OS2; # Done internally by File::Spec if needed
2386fb12b70Safresh1
2396fb12b70Safresh1=head1 DESCRIPTION
2406fb12b70Safresh1
2416fb12b70Safresh1See L<File::Spec> and L<File::Spec::Unix>.  This package overrides the
2426fb12b70Safresh1implementation of these methods, not the semantics.
2436fb12b70Safresh1
2446fb12b70Safresh1Amongst the changes made for OS/2 are...
2456fb12b70Safresh1
2466fb12b70Safresh1=over 4
2476fb12b70Safresh1
2486fb12b70Safresh1=item tmpdir
2496fb12b70Safresh1
2506fb12b70Safresh1Modifies the list of places temp directory information is looked for.
2516fb12b70Safresh1
2526fb12b70Safresh1    $ENV{TMPDIR}
2536fb12b70Safresh1    $ENV{TEMP}
2546fb12b70Safresh1    $ENV{TMP}
2556fb12b70Safresh1    /tmp
2566fb12b70Safresh1    /
2576fb12b70Safresh1
2586fb12b70Safresh1=item splitpath
2596fb12b70Safresh1
2606fb12b70Safresh1Volumes can be drive letters or UNC sharenames (\\server\share).
2616fb12b70Safresh1
2626fb12b70Safresh1=back
2636fb12b70Safresh1
2646fb12b70Safresh1=head1 COPYRIGHT
2656fb12b70Safresh1
2666fb12b70Safresh1Copyright (c) 2004 by the Perl 5 Porters.  All rights reserved.
2676fb12b70Safresh1
2686fb12b70Safresh1This program is free software; you can redistribute it and/or modify
2696fb12b70Safresh1it under the same terms as Perl itself.
2706fb12b70Safresh1
2716fb12b70Safresh1=cut
272