Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / tools / perl-5.8.0 / lib / 5.8.0 / File / Spec / Win32.pm
CommitLineData
86530b38
AT
1package File::Spec::Win32;
2
3use strict;
4use Cwd;
5use vars qw(@ISA $VERSION);
6require File::Spec::Unix;
7
8$VERSION = '1.3';
9
10@ISA = qw(File::Spec::Unix);
11
12=head1 NAME
13
14File::Spec::Win32 - methods for Win32 file specs
15
16=head1 SYNOPSIS
17
18 require File::Spec::Win32; # Done internally by File::Spec if needed
19
20=head1 DESCRIPTION
21
22See File::Spec::Unix for a documentation of the methods provided
23there. This package overrides the implementation of these methods, not
24the semantics.
25
26=over 4
27
28=item devnull
29
30Returns a string representation of the null device.
31
32=cut
33
34sub devnull {
35 return "nul";
36}
37
38=item tmpdir
39
40Returns a string representation of the first existing directory
41from the following list:
42
43 $ENV{TMPDIR}
44 $ENV{TEMP}
45 $ENV{TMP}
46 SYS:/temp
47 C:/temp
48 /tmp
49 /
50
51The SYS:/temp is preferred in Novell NetWare.
52
53Since Perl 5.8.0, if running under taint mode, and if the environment
54variables are tainted, they are not used.
55
56=cut
57
58my $tmpdir;
59sub tmpdir {
60 return $tmpdir if defined $tmpdir;
61 my $self = shift;
62 my @dirlist = (@ENV{qw(TMPDIR TEMP TMP)}, qw(C:/temp /tmp /));
63 {
64 no strict 'refs';
65 if (${"\cTAINT"}) { # Check for taint mode on perl >= 5.8.0
66 require Scalar::Util;
67 @dirlist = grep { ! Scalar::Util::tainted $_ } @dirlist;
68 }
69 }
70 foreach (@dirlist) {
71 next unless defined && -d;
72 $tmpdir = $_;
73 last;
74 }
75 $tmpdir = '' unless defined $tmpdir;
76 $tmpdir = $self->canonpath($tmpdir);
77 return $tmpdir;
78}
79
80sub case_tolerant {
81 return 1;
82}
83
84sub file_name_is_absolute {
85 my ($self,$file) = @_;
86 return scalar($file =~ m{^([a-z]:)?[\\/]}is);
87}
88
89=item catfile
90
91Concatenate one or more directory names and a filename to form a
92complete path ending with a filename
93
94=cut
95
96sub catfile {
97 my $self = shift;
98 my $file = pop @_;
99 return $file unless @_;
100 my $dir = $self->catdir(@_);
101 $dir .= "\\" unless substr($dir,-1) eq "\\";
102 return $dir.$file;
103}
104
105sub path {
106 my $path = $ENV{'PATH'} || $ENV{'Path'} || $ENV{'path'};
107 my @path = split(';',$path);
108 foreach (@path) { $_ = '.' if $_ eq '' }
109 return @path;
110}
111
112=item canonpath
113
114No physical check on the filesystem, but a logical cleanup of a
115path. On UNIX eliminated successive slashes and successive "/.".
116
117=cut
118
119sub canonpath {
120 my ($self,$path) = @_;
121 $path =~ s/^([a-z]:)/\u$1/s;
122 $path =~ s|/|\\|g;
123 $path =~ s|([^\\])\\+|$1\\|g; # xx\\\\xx -> xx\xx
124 $path =~ s|(\\\.)+\\|\\|g; # xx\.\.\xx -> xx\xx
125 $path =~ s|^(\.\\)+||s unless $path eq ".\\"; # .\xx -> xx
126 $path =~ s|\\\Z(?!\n)||
127 unless $path =~ m#^([A-Z]:)?\\\Z(?!\n)#s; # xx\ -> xx
128 return $path;
129}
130
131=item splitpath
132
133 ($volume,$directories,$file) = File::Spec->splitpath( $path );
134 ($volume,$directories,$file) = File::Spec->splitpath( $path, $no_file );
135
136Splits a path in to volume, directory, and filename portions. Assumes that
137the last file is a path unless the path ends in '\\', '\\.', '\\..'
138or $no_file is true. On Win32 this means that $no_file true makes this return
139( $volume, $path, undef ).
140
141Separators accepted are \ and /.
142
143Volumes can be drive letters or UNC sharenames (\\server\share).
144
145The results can be passed to L</catpath> to get back a path equivalent to
146(usually identical to) the original path.
147
148=cut
149
150sub splitpath {
151 my ($self,$path, $nofile) = @_;
152 my ($volume,$directory,$file) = ('','','');
153 if ( $nofile ) {
154 $path =~
155 m{^( (?:[a-zA-Z]:|(?:\\\\|//)[^\\/]+[\\/][^\\/]+)? )
156 (.*)
157 }xs;
158 $volume = $1;
159 $directory = $2;
160 }
161 else {
162 $path =~
163 m{^ ( (?: [a-zA-Z]: |
164 (?:\\\\|//)[^\\/]+[\\/][^\\/]+
165 )?
166 )
167 ( (?:.*[\\\\/](?:\.\.?\Z(?!\n))?)? )
168 (.*)
169 }xs;
170 $volume = $1;
171 $directory = $2;
172 $file = $3;
173 }
174
175 return ($volume,$directory,$file);
176}
177
178
179=item splitdir
180
181The opposite of L<catdir()|File::Spec/catdir()>.
182
183 @dirs = File::Spec->splitdir( $directories );
184
185$directories must be only the directory portion of the path on systems
186that have the concept of a volume or that have path syntax that differentiates
187files from directories.
188
189Unlike just splitting the directories on the separator, leading empty and
190trailing directory entries can be returned, because these are significant
191on some OSs. So,
192
193 File::Spec->splitdir( "/a/b/c" );
194
195Yields:
196
197 ( '', 'a', 'b', '', 'c', '' )
198
199=cut
200
201sub splitdir {
202 my ($self,$directories) = @_ ;
203 #
204 # split() likes to forget about trailing null fields, so here we
205 # check to be sure that there will not be any before handling the
206 # simple case.
207 #
208 if ( $directories !~ m|[\\/]\Z(?!\n)| ) {
209 return split( m|[\\/]|, $directories );
210 }
211 else {
212 #
213 # since there was a trailing separator, add a file name to the end,
214 # then do the split, then replace it with ''.
215 #
216 my( @directories )= split( m|[\\/]|, "${directories}dummy" ) ;
217 $directories[ $#directories ]= '' ;
218 return @directories ;
219 }
220}
221
222
223=item catpath
224
225Takes volume, directory and file portions and returns an entire path. Under
226Unix, $volume is ignored, and this is just like catfile(). On other OSs,
227the $volume become significant.
228
229=cut
230
231sub catpath {
232 my ($self,$volume,$directory,$file) = @_;
233
234 # If it's UNC, make sure the glue separator is there, reusing
235 # whatever separator is first in the $volume
236 $volume .= $1
237 if ( $volume =~ m@^([\\/])[\\/][^\\/]+[\\/][^\\/]+\Z(?!\n)@s &&
238 $directory =~ m@^[^\\/]@s
239 ) ;
240
241 $volume .= $directory ;
242
243 # If the volume is not just A:, make sure the glue separator is
244 # there, reusing whatever separator is first in the $volume if possible.
245 if ( $volume !~ m@^[a-zA-Z]:\Z(?!\n)@s &&
246 $volume =~ m@[^\\/]\Z(?!\n)@ &&
247 $file =~ m@[^\\/]@
248 ) {
249 $volume =~ m@([\\/])@ ;
250 my $sep = $1 ? $1 : '\\' ;
251 $volume .= $sep ;
252 }
253
254 $volume .= $file ;
255
256 return $volume ;
257}
258
259
260sub abs2rel {
261 my($self,$path,$base) = @_;
262
263 # Clean up $path
264 if ( ! $self->file_name_is_absolute( $path ) ) {
265 $path = $self->rel2abs( $path ) ;
266 }
267 else {
268 $path = $self->canonpath( $path ) ;
269 }
270
271 # Figure out the effective $base and clean it up.
272 if ( !defined( $base ) || $base eq '' ) {
273 $base = cwd() ;
274 }
275 elsif ( ! $self->file_name_is_absolute( $base ) ) {
276 $base = $self->rel2abs( $base ) ;
277 }
278 else {
279 $base = $self->canonpath( $base ) ;
280 }
281
282 # Split up paths
283 my ( undef, $path_directories, $path_file ) =
284 $self->splitpath( $path, 1 ) ;
285
286 my $base_directories = ($self->splitpath( $base, 1 ))[1] ;
287
288 # Now, remove all leading components that are the same
289 my @pathchunks = $self->splitdir( $path_directories );
290 my @basechunks = $self->splitdir( $base_directories );
291
292 while ( @pathchunks &&
293 @basechunks &&
294 lc( $pathchunks[0] ) eq lc( $basechunks[0] )
295 ) {
296 shift @pathchunks ;
297 shift @basechunks ;
298 }
299
300 # No need to catdir, we know these are well formed.
301 $path_directories = CORE::join( '\\', @pathchunks );
302 $base_directories = CORE::join( '\\', @basechunks );
303
304 # $base_directories now contains the directories the resulting relative
305 # path must ascend out of before it can descend to $path_directory. So,
306 # replace all names with $parentDir
307
308 #FA Need to replace between backslashes...
309 $base_directories =~ s|[^\\]+|..|g ;
310
311 # Glue the two together, using a separator if necessary, and preventing an
312 # empty result.
313
314 #FA Must check that new directories are not empty.
315 if ( $path_directories ne '' && $base_directories ne '' ) {
316 $path_directories = "$base_directories\\$path_directories" ;
317 } else {
318 $path_directories = "$base_directories$path_directories" ;
319 }
320
321 return $self->canonpath(
322 $self->catpath( "", $path_directories, $path_file )
323 ) ;
324}
325
326
327sub rel2abs {
328 my ($self,$path,$base ) = @_;
329
330 if ( ! $self->file_name_is_absolute( $path ) ) {
331
332 if ( !defined( $base ) || $base eq '' ) {
333 $base = cwd() ;
334 }
335 elsif ( ! $self->file_name_is_absolute( $base ) ) {
336 $base = $self->rel2abs( $base ) ;
337 }
338 else {
339 $base = $self->canonpath( $base ) ;
340 }
341
342 my ( $path_directories, $path_file ) =
343 ($self->splitpath( $path, 1 ))[1,2] ;
344
345 my ( $base_volume, $base_directories ) =
346 $self->splitpath( $base, 1 ) ;
347
348 $path = $self->catpath(
349 $base_volume,
350 $self->catdir( $base_directories, $path_directories ),
351 $path_file
352 ) ;
353 }
354
355 return $self->canonpath( $path ) ;
356}
357
358=back
359
360=head2 Note For File::Spec::Win32 Maintainers
361
362Novell NetWare inherits its File::Spec behaviour from File::Spec::Win32.
363
364=head1 SEE ALSO
365
366L<File::Spec>
367
368=cut
369
3701;