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