1N/AFile::Spec::VMS - methods for VMS file specs 1N/A require File::Spec::VMS; # Done internally by File::Spec if needed 1N/ASee File::Spec::Unix for a documentation of the methods provided 1N/Athere. This package overrides the implementation of these methods, not 1N/A=item eliminate_macros 1N/AExpands MM[KS]/Make macros in a text string, using the contents of 1N/Aidentically named elements of C<%$self>, and returns the result 1N/Aas a file specification in Unix syntax. 1N/A # perform m##g in scalar context so it acts as an iterator 1N/A while ($
npath =~ m
#(.*?)\$\((\S+?)\)(.*)#gs) { 1N/A print "Note: can't expand macro \$($macro) containing ",
ref($
self->{$
macro}),
1N/A "\n\t(using MMK-specific deferred substitutuon; MMS will break)\n";
1N/ACatchall routine to clean up problem MM[SK]/Make macros. Expands macros 1N/Ain any directory specification, in order to avoid juxtaposing two 1N/AVMS-syntax directories when MM[SK] is run. Also expands expressions which 1N/Aare all macro, so that we can tell how long the expansion is, and avoid 1N/Aoverrunning DCL's command buffer when MM[KS] is running. 1N/AIf optional second argument has a TRUE value, then the return string is 1N/Aa VMS-syntax directory specification, if it is FALSE, the return string 1N/Ais a VMS-syntax file specification, and if it is not specified, fixpath() 1N/Achecks to see whether it matches the name of a directory in the current 1N/Adefault directory, and returns a directory or file specification accordingly. 1N/A if ($
path =~ m
#^\$\([^\)]+\)\Z(?!\n)#s || $path =~ m#[/:>\]]#) { 1N/A # is it a dir or just a name? 1N/A # No hints, so we try to guess 1N/A # Trim off root dirname if it's had other dirs inserted in front of it. 1N/A # Special case for VMS absolute directory specs: these will have had device 1N/A # prepended during trip through Unix syntax in eliminate_macros(), since 1N/A # Unix syntax has no way to express "absolute from the top of this device's 1N/A=head2 Methods always loaded 1N/A=item canonpath (override) 1N/ARemoves redundant portions of file specifications according to VMS syntax. 1N/A $
path =~ s/([\[<])
000000\./$
1/g;
# [000000.foo ==> [foo 1N/A $
path =~ s/([^-]+)\.(\]\[|><)?
000000([\]\>])/$
1$
3/g;
# foo.000000] ==> foo] 1N/A $
path =~ s-\]\[--g; $
path =~ s/><//g;
# foo.][bar ==> foo.bar 1N/A 1 while $
path =~ s{([\[<-])\.-}{$
1-};
# [.-.- ==> [-- 1N/A $
path =~ s/\.[^\[<\.]+\.-([\]\>])/$
1/;
# bar.foo.-] ==> bar] 1N/A $
path =~ s/([\[<])(-+)/$
1 .
"\cx" x
length($
2)/e;
# encode leading '-'s 1N/A $
path =~ s/([\[<\.])([^\[<\.\
cx]+)\.-\.?/$
1/g;
# bar.-.foo ==> foo 1N/A $
path =~ s/([\[<])(\
cx+)/$
1 .
'-' x
length($
2)/e;
# then decode 1N/A $
path =~ s/^[\[<\]>]{
2}//;
# []foo ==> foo 1N/AConcatenates a list of file specifications, and returns the result as a 1N/AVMS-syntax directory specification. No check is made for "impossible" 1N/Acases (e.g. elements other than the first being absolute filespecs). 1N/A # Special case for VMS absolute directory specs: these will have had device 1N/A # prepended during trip through Unix syntax in eliminate_macros(), since 1N/A # Unix syntax has no way to express "absolute from the top of this device's 1N/AConcatenates a list of file specifications, and returns the result as a 1N/AVMS-syntax file specification. 1N/A=item curdir (override) 1N/AReturns a string representation of the current directory: '[]' 1N/A=item devnull (override) 1N/AReturns a string representation of the null device: '_NLA0:' 1N/A=item rootdir (override) 1N/AReturns a string representation of the root directory: 'SYS$DISK:[000000]' 1N/A return 'SYS$DISK:[000000]';
1N/A=item tmpdir (override) 1N/AReturns a string representation of the first writable directory 1N/Afrom the following list or '' if none are writable: 1N/ASince perl 5.8.0, if running under taint mode, and if $ENV{TMPDIR} 1N/Ais tainted, it is not used. 1N/A=item updir (override) 1N/AReturns a string representation of the parent directory: '[-]' 1N/A=item case_tolerant (override) 1N/AVMS file specification syntax is case-tolerant. 1N/A=item path (override) 1N/ATranslate logical name DCL$PATH as a searchlist, rather than trying 1N/Ato C<split> string value of C<$ENV{'PATH'}>. 1N/A=item file_name_is_absolute (override) 1N/AChecks for VMS directory spec as well as Unix separators. 1N/A # If it's a logical name, expand it. 1N/A=item splitpath (override) 1N/ASplits using VMS syntax. 1N/A return ($
1 ||
'',$
2 ||
'',$
3);
1N/A=item splitdir (override) 1N/ASplit dirspec using VMS syntax. 1N/A $
dirs[
0] =~ s/^[\[<]//s; $
dirs[-
1] =~ s/[\]>]\Z(?!\n)//s;
1N/A=item catpath (override) 1N/AConstruct a complete filespec using VMS syntax 1N/A # We look for a volume in $dev, then in $dir, but not both 1N/A else { $
dev .=
':' unless $
dev eq '' or $
dev =~ /:\Z(?!\n)/; }
1N/A=item abs2rel (override) 1N/AUse VMS syntax when converting filespecs. 1N/A # Are we even starting $path on the same (node::)device as $base? Note that 1N/A # logical paths or nodename differences may be on the "same device" 1N/A # but the comparison that ignores device differences so as to concatenate 1N/A # [---] up directory specs is not even a good idea in cases where there is 1N/A # a logical path difference between $path and $base nodename and/or device. 1N/A # Hence we fall back to returning the absolute $path spec 1N/A # if there is a case blind device (or node) difference of any sort 1N/A # and we do not even try to call $parse() or consult %ENV for $trnlnm() 1N/A # (this module needs to run on non VMS platforms after all). 1N/A # Now, remove all leading components that are the same 1N/A # @basechunks now contains the directories to climb out of, 1N/A # @pathchunks now has the directories to descend in to. 1N/A=item rel2abs (override) 1N/AUse VMS syntax when converting filespecs. 1N/A if (
join(
'', @_ ) =~ m{/} ) ;
1N/A # Clean up and split up $path 1N/A # Figure out the effective $base and clean it up. 1N/ASee L<File::Spec> and L<File::Spec::Unix>. This package overrides the 1N/Aimplementation of these methods, not the semantics. 1N/AAn explanation of VMS file specs can be found at