File Coverage

blib/lib/File/Spec/OS2.pm
Criterion Covered Total %
statement 70 92 76.0
branch 18 34 52.9
condition 10 24 41.6
subroutine 11 14 78.5
pod 12 12 100.0
total 121 176 68.7


line stmt bran cond sub pod time code
1             package File::Spec::OS2;
2              
3 2     2   1802 use strict;
  2         3  
  2         43  
4 2     2   8 use Cwd ();
  2         3  
  2         2522  
5             require File::Spec::Unix;
6              
7             our $VERSION = '3.74';
8             $VERSION =~ tr/_//d;
9              
10             our @ISA = qw(File::Spec::Unix);
11              
12             sub devnull {
13 0     0 1 0 return "/dev/nul";
14             }
15              
16             sub case_tolerant {
17 1     1 1 551 return 1;
18             }
19              
20             sub file_name_is_absolute {
21 23     23 1 31 my ($self,$file) = @_;
22 23         65 return scalar($file =~ m{^([a-z]:)?[\\/]}is);
23             }
24              
25             sub path {
26 0     0 1 0 my $path = $ENV{PATH};
27 0         0 $path =~ s:\\:/:g;
28 0         0 my @path = split(';',$path);
29 0 0       0 foreach (@path) { $_ = '.' if $_ eq '' }
  0         0  
30 0         0 return @path;
31             }
32              
33             sub tmpdir {
34 0     0 1 0 my $cached = $_[0]->_cached_tmpdir(qw 'TMPDIR TEMP TMP');
35 0 0       0 return $cached if defined $cached;
36 0         0 my @d = @ENV{qw(TMPDIR TEMP TMP)}; # function call could autovivivy
37 0         0 $_[0]->_cache_tmpdir(
38             $_[0]->_tmpdir( @d, '/tmp', '/' ), qw 'TMPDIR TEMP TMP'
39             );
40             }
41              
42             sub catdir {
43 20     20 1 3135 my $self = shift;
44 20         37 my @args = @_;
45 20         43 foreach (@args) {
46 42         61 tr[\\][/];
47             # append a backslash to each argument unless it has one there
48 42 100       106 $_ .= "/" unless m{/$};
49             }
50 20         57 return $self->canonpath(join('', @args));
51             }
52              
53             sub canonpath {
54 53     53 1 3147 my ($self,$path) = @_;
55 53 100       82 return unless defined $path;
56              
57 51         62 $path =~ s/^([a-z]:)/\l$1/s;
58 51         54 $path =~ s|\\|/|g;
59 51         201 $path =~ s|([^/])/+|$1/|g; # xx////xx -> xx/xx
60 51         78 $path =~ s|(/\.)+/|/|g; # xx/././xx -> xx/xx
61 51         60 $path =~ s|^(\./)+(?=[^/])||s; # ./xx -> xx
62 51 50       178 $path =~ s|/\Z(?!\n)||
63             unless $path =~ m#^([a-z]:)?/\Z(?!\n)#si;# xx/ -> xx
64 51         67 $path =~ s{^/\.\.$}{/}; # /.. -> /
65 51         82 1 while $path =~ s{^/\.\.}{}; # /../xx -> /xx
66 51         174 return $path;
67             }
68              
69              
70             sub splitpath {
71 20     20 1 39 my ($self,$path, $nofile) = @_;
72 20         28 my ($volume,$directory,$file) = ('','','');
73 20 100       25 if ( $nofile ) {
74 12         27 $path =~
75             m{^( (?:[a-zA-Z]:|(?:\\\\|//)[^\\/]+[\\/][^\\/]+)? )
76             (.*)
77             }xs;
78 12         15 $volume = $1;
79 12         15 $directory = $2;
80             }
81             else {
82 8         23 $path =~
83             m{^ ( (?: [a-zA-Z]: |
84             (?:\\\\|//)[^\\/]+[\\/][^\\/]+
85             )?
86             )
87             ( (?:.*[\\\\/](?:\.\.?\Z(?!\n))?)? )
88             (.*)
89             }xs;
90 8         12 $volume = $1;
91 8         10 $directory = $2;
92 8         9 $file = $3;
93             }
94              
95 20         42 return ($volume,$directory,$file);
96             }
97              
98              
99             sub splitdir {
100 5     5 1 8 my ($self,$directories) = @_ ;
101 5         15 split m|[\\/]|, $directories, -1;
102             }
103              
104              
105             sub catpath {
106 11     11 1 22 my ($self,$volume,$directory,$file) = @_;
107              
108             # If it's UNC, make sure the glue separator is there, reusing
109             # whatever separator is first in the $volume
110 11 50 33     20 $volume .= $1
111             if ( $volume =~ m@^([\\/])[\\/][^\\/]+[\\/][^\\/]+\Z(?!\n)@s &&
112             $directory =~ m@^[^\\/]@s
113             ) ;
114              
115 11         15 $volume .= $directory ;
116              
117             # If the volume is not just A:, make sure the glue separator is
118             # there, reusing whatever separator is first in the $volume if possible.
119 11 100 33     56 if ( $volume !~ m@^[a-zA-Z]:\Z(?!\n)@s &&
      66        
120             $volume =~ m@[^\\/]\Z(?!\n)@ &&
121             $file =~ m@[^\\/]@
122             ) {
123 2         4 $volume =~ m@([\\/])@ ;
124 2 50       7 my $sep = $1 ? $1 : '/' ;
125 2         4 $volume .= $sep ;
126             }
127              
128 11         13 $volume .= $file ;
129              
130 11         19 return $volume ;
131             }
132              
133              
134             sub abs2rel {
135 6     6 1 28 my($self,$path,$base) = @_;
136              
137             # Clean up $path
138 6 50       12 if ( ! $self->file_name_is_absolute( $path ) ) {
139 0         0 $path = $self->rel2abs( $path ) ;
140             } else {
141 6         11 $path = $self->canonpath( $path ) ;
142             }
143              
144             # Figure out the effective $base and clean it up.
145 6 50 33     20 if ( !defined( $base ) || $base eq '' ) {
    50          
146 0         0 $base = Cwd::getcwd();
147             } elsif ( ! $self->file_name_is_absolute( $base ) ) {
148 0         0 $base = $self->rel2abs( $base ) ;
149             } else {
150 6         10 $base = $self->canonpath( $base ) ;
151             }
152              
153             # Split up paths
154 6         13 my ( $path_volume, $path_directories, $path_file ) = $self->splitpath( $path, 1 ) ;
155 6         9 my ( $base_volume, $base_directories ) = $self->splitpath( $base, 1 ) ;
156 6 100       35 return $path unless $path_volume eq $base_volume;
157              
158             # Now, remove all leading components that are the same
159 2         4 my @pathchunks = $self->splitdir( $path_directories );
160 2         5 my @basechunks = $self->splitdir( $base_directories );
161              
162 2   66     13 while ( @pathchunks &&
      66        
163             @basechunks &&
164             lc( $pathchunks[0] ) eq lc( $basechunks[0] )
165             ) {
166 4         6 shift @pathchunks ;
167 4         12 shift @basechunks ;
168             }
169              
170             # No need to catdir, we know these are well formed.
171 2         4 $path_directories = CORE::join( '/', @pathchunks );
172 2         3 $base_directories = CORE::join( '/', @basechunks );
173              
174             # $base_directories now contains the directories the resulting relative
175             # path must ascend out of before it can descend to $path_directory. So,
176             # replace all names with $parentDir
177              
178             #FA Need to replace between backslashes...
179 2         3 $base_directories =~ s|[^\\/]+|..|g ;
180              
181             # Glue the two together, using a separator if necessary, and preventing an
182             # empty result.
183              
184             #FA Must check that new directories are not empty.
185 2 50 33     7 if ( $path_directories ne '' && $base_directories ne '' ) {
186 0         0 $path_directories = "$base_directories/$path_directories" ;
187             } else {
188 2         3 $path_directories = "$base_directories$path_directories" ;
189             }
190              
191 2         5 return $self->canonpath(
192             $self->catpath( "", $path_directories, $path_file )
193             ) ;
194             }
195              
196              
197             sub rel2abs {
198 10     10 1 46 my ($self,$path,$base ) = @_;
199              
200 10 50       13 if ( ! $self->file_name_is_absolute( $path ) ) {
201              
202 0 0 0     0 if ( !defined( $base ) || $base eq '' ) {
    0          
203 0         0 $base = Cwd::getcwd();
204             }
205             elsif ( ! $self->file_name_is_absolute( $base ) ) {
206 0         0 $base = $self->rel2abs( $base ) ;
207             }
208             else {
209 0         0 $base = $self->canonpath( $base ) ;
210             }
211              
212 0         0 my ( $path_directories, $path_file ) =
213             ($self->splitpath( $path, 1 ))[1,2] ;
214              
215 0         0 my ( $base_volume, $base_directories ) =
216             $self->splitpath( $base, 1 ) ;
217              
218 0         0 $path = $self->catpath(
219             $base_volume,
220             $self->catdir( $base_directories, $path_directories ),
221             $path_file
222             ) ;
223             }
224              
225 10         18 return $self->canonpath( $path ) ;
226             }
227              
228             1;
229             __END__