File Coverage

blib/lib/File/Spec/OS2.pm
Criterion Covered Total %
statement 70 93 75.2
branch 18 34 52.9
condition 10 24 41.6
subroutine 11 15 73.3
pod 12 12 100.0
total 121 178 67.9


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