1 package File
::Spec
::Epoc
;
6 require File::Spec::Unix;
7 @ISA = qw(File::Spec::Unix);
11 File::Spec::Epoc - methods for Epoc file specs
15 require File::Spec::Epoc; # Done internally by File::Spec if needed
19 See File::Spec::Unix for a documentation of the methods provided
20 there. This package overrides the implementation of these methods, not
23 This package is still work in progress ;-)
31 Returns a string representation of the null device.
41 Returns a string representation of a temporay directory:
47 return "C:/System/temp";
54 sub file_name_is_absolute
{
55 my ($self,$file) = @_;
56 return scalar($file =~ m{^([a-z?]:)?[\\/]}is);
61 Takes no argument, returns the environment variable PATH as an array. Since
62 there is no search path supported, it returns undef, sorry.
71 No physical check on the filesystem, but a logical cleanup of a
72 path. On UNIX eliminated successive slashes and successive "/.".
77 my ($self,$path) = @_;
78 $path =~ s/^([a-z]:)/\u$1/s;
80 $path =~ s
|/+|/|g
unless($^O
eq 'cygwin' or $^O
eq 'msys'); # xx////xx -> xx/xx
81 $path =~ s
|(/\.)+/|/|g; # xx/././xx -> xx
/xx
82 $path =~ s
|^(\
./)+||s unless $path eq "./"; # ./xx -> xx
83 $path =~ s|^/(\.\./)+|/|s; # /../../xx -> xx
84 $path =~ s|/\z|| unless $path eq "/"; # xx/ -> xx
90 ($volume,$directories,$file) = File::Spec->splitpath( $path );
91 ($volume,$directories,$file) = File::Spec->splitpath( $path, $no_file );
93 Splits a path in to volume, directory, and filename portions. Assumes that
94 the last file is a path unless the path ends in '\\', '\\.', '\\..'
95 or $no_file is true. On Win32 this means that $no_file true makes this return
96 ( $volume, $path, undef ).
98 Separators accepted are \ and /.
100 The results can be passed to L</catpath> to get back a path equivalent to
101 (usually identical to) the original path.
106 my ($self,$path, $nofile) = @_;
107 my ($volume,$directory,$file) = ('','','');
110 m{^( (?:[a-zA-Z?]:|(?:\\\\|//)[^\\/]+[\\/][^\\/]+)? )
118 m{^ ( (?: [a-zA-Z?]: |
119 (?:\\\\|//)[^\\/]+[\\/][^\\/]+
122 ( (?:.*[\\\\/](?:\.\.?\z)?)? )
130 return ($volume,$directory,$file);
136 The opposite of L</catdir()>.
138 @dirs = File::Spec->splitdir( $directories );
140 $directories must be only the directory portion of the path on systems
141 that have the concept of a volume or that have path syntax that differentiates
142 files from directories.
144 Unlike just splitting the directories on the separator, leading empty and
145 trailing directory entries can be returned, because these are significant
148 File::Spec->splitdir( "/a/b
/c
" );
152 ( '', 'a', 'b', '', 'c', '' )
157 my ($self,$directories) = @_ ;
159 # split() likes to forget about trailing null fields, so here we
160 # check to be sure that there will not be any before handling the
163 if ( $directories !~ m|[\\/]\z| ) {
164 return split( m|[\\/]|, $directories );
168 # since there was a trailing separator, add a file name to the end,
169 # then do the split, then replace it with ''.
171 my( @directories )= split( m|[\\/]|, "${directories
}dummy
" ) ;
172 $directories[ $#directories ]= '' ;
173 return @directories ;
180 Takes volume, directory and file portions and returns an entire path. Under
181 Unix, $volume is ignored, and this is just like catfile(). On other OSs,
182 the $volume become significant.
187 my ($self,$volume,$directory,$file) = @_;
189 # If it's UNC, make sure the glue separator is there, reusing
190 # whatever separator is first in the $volume
192 if ( $volume =~ m@^([\\/])[\\/][^\\/]+[\\/][^\\/]+\z@s &&
193 $directory =~ m@^[^\\/]@s
196 $volume .= $directory ;
198 # If the volume is not just A:, make sure the glue separator is
199 # there, reusing whatever separator is first in the $volume if possible.
200 if ( $volume !~ m@^[a-zA-Z]:\z@s &&
201 $volume =~ m@[^\\/]\z@ &&
204 $volume =~ m@([\\/])@ ;
205 my $sep = $1 ? $1 : '\\' ;
217 Takes a destination path and an optional base path returns a relative path
218 from the base path to the destination path:
220 $rel_path = File::Spec->abs2rel( $destination ) ;
221 $rel_path = File::Spec->abs2rel( $destination, $base ) ;
223 If $base is not present or '', then L</cwd()> is used. If $base is relative,
224 then it is converted to absolute form using L</rel2abs()>. This means that it
225 is taken to be relative to L<cwd()>.
227 On systems with the concept of a volume, this assumes that both paths
228 are on the $destination volume, and ignores the $base volume.
230 On systems that have a grammar that indicates filenames, this ignores the
231 $base filename as well. Otherwise all path components are assumed to be
234 If $path is relative, it is converted to absolute form using L</rel2abs()>.
235 This means that it is taken to be relative to L</cwd()>.
237 Based on code written by Shigio Yamaguchi.
239 No checks against the filesystem are made.
244 my($self,$path,$base) = @_;
247 if ( ! $self->file_name_is_absolute( $path ) ) {
248 $path = $self->rel2abs( $path ) ;
251 $path = $self->canonpath( $path ) ;
254 # Figure out the effective $base and clean it up.
255 if ( ! $self->file_name_is_absolute( $base ) ) {
256 $base = $self->rel2abs( $base ) ;
258 elsif ( !defined( $base ) || $base eq '' ) {
262 $base = $self->canonpath( $base ) ;
266 my ( $path_volume, $path_directories, $path_file ) =
267 $self->splitpath( $path, 1 ) ;
269 my ( undef, $base_directories, undef ) =
270 $self->splitpath( $base, 1 ) ;
272 # Now, remove all leading components that are the same
273 my @pathchunks = $self->splitdir( $path_directories );
274 my @basechunks = $self->splitdir( $base_directories );
276 while ( @pathchunks &&
278 lc( $pathchunks[0] ) eq lc( $basechunks[0] )
284 # No need to catdir, we know these are well formed.
285 $path_directories = CORE::join( '\\', @pathchunks );
286 $base_directories = CORE::join( '\\', @basechunks );
288 # $base_directories now contains the directories the resulting relative
289 # path must ascend out of before it can descend to $path_directory. So,
290 # replace all names with $parentDir
292 #FA Need to replace between backslashes...
293 $base_directories =~ s|[^\\]+|..|g ;
295 # Glue the two together, using a separator if necessary, and preventing an
298 #FA Must check that new directories are not empty.
299 if ( $path_directories ne '' && $base_directories ne '' ) {
300 $path_directories = "$base_directories\\$path_directories" ;
302 $path_directories = "$base_directories$path_directories" ;
305 # It makes no sense to add a relative path to a UNC volume
306 $path_volume = '' unless $path_volume =~ m{^[A-Z]:}is ;
308 return $self->canonpath(
309 $self->catpath($path_volume, $path_directories, $path_file )
315 Converts a relative path to an absolute path.
317 $abs_path = File::Spec->rel2abs( $destination ) ;
318 $abs_path = File::Spec->rel2abs( $destination, $base ) ;
320 If $base is not present or '', then L<cwd()> is used. If $base is relative,
321 then it is converted to absolute form using L</rel2abs()>. This means that it
322 is taken to be relative to L</cwd()>.
324 Assumes that both paths are on the $base volume, and ignores the
327 On systems that have a grammar that indicates filenames, this ignores the
328 $base filename as well. Otherwise all path components are assumed to be
331 If $path is absolute, it is cleaned up and returned using L</canonpath()>.
333 Based on code written by Shigio Yamaguchi.
335 No checks against the filesystem are made.
340 my ($self,$path,$base ) = @_;
342 if ( ! $self->file_name_is_absolute( $path ) ) {
344 if ( !defined( $base ) || $base eq '' ) {
347 elsif ( ! $self->file_name_is_absolute( $base ) ) {
348 $base = $self->rel2abs( $base ) ;
351 $base = $self->canonpath( $base ) ;
354 my ( undef, $path_directories, $path_file ) =
355 $self->splitpath( $path, 1 ) ;
357 my ( $base_volume, $base_directories, undef ) =
358 $self->splitpath( $base, 1 ) ;
360 $path = $self->catpath(
362 $self->catdir( $base_directories, $path_directories ),
367 return $self->canonpath( $path ) ;