Michael G Schwern wrote:
John E. Malmberg wrote:
Are you going to have time to look at the patches that I submitted to
MakeMaker and Test::Simple?
These are to support VMS when the DECC$FILENAME_UNIX_REPORT and
DECC$EFS_CHARSET and related options are active.
These options make Perl on VMS look more like Unix, including returning
filenames in Unix syntax. Path tools has already been updated to work
in this mode.
I had a look at this, and I can't apply it. It was bad enough having special
case code for VMS, now there's three different styles of VMS to be considered.
Yes there are three major sets:
1. Traditional mode which is limited in the character set available,
which includes several serious bugs in the conversion of Unix format
file specifications to and from VMS format. These bugs can not be fixed
in this mode because other programs may depend on them being present.
In several cases, the Unix file specifications produced are invalid and
can not be used, except for special VMS code that has been added to deal
with the bugs.
Some of the bugs in the traditional mode are from the assumption that
the equations ($path == vmsify(unixify($path))) and ($path ==
unixify(vmsify($path))) will always evaluate to true.
This is not the case on VMS and never has been the case for all file
specifications. The file $foo that results from $foo =
vmsify(unixify($bar)) may not even resolve to the same directory as
$bar, let alone the same file.
In short, you only want to vmsify or unixify a filespec once, just
before it is used to access a path or a file. You can not unixify a VMS
file specification with the expectation that you can vmsify it back to
the original file or the reverse.
That has never fully worked, and can not be made to fully work.
In order to use the Traditional VMS mode, Perl programs usually need to
also have VMS specific code in them.
2. Extended character set, VMS format, which requires that the bugs in
the Unix to VMS conversions not be present.
This is because with the restricted character set, the illegal Unix
names were obvious and could be handled, but with the extended character
set, those Unix names could be valid, even though they are usually not.
This exposes many cases where vmsify(unixify) or unixify(vmsify) was
being used and totally failing, since files that were previously ignored
were now being used.
A side effect of this is that VMS can preserve the case of the filename
similar to how Windows does.
Many Perl programs will now just work on VMS in this mode, unless they
have some explicit UNIX requirement.
3. Unix compatibility mode. This is where VMS both case preserves the
results, but also the library routines will returns results
There is also a mode where the VMS C library will not accept VMS syntax
filenames, but assumes Unix. I have not tried to get that mode to work.
While the Unix compatibility is not perfect, it is good enough for many
Perl scripts written with only UNIX in mind to work on VMS with zero
modifications.
While there are three main modes, there many feature settings that
control them, and each of those modes are a result of preset combinations.
It is not the case that all perl programs need to check the mode that
VMS is in. It is only a small set of perl programs.
1. Test programs that need to explicitly know what syntax a filename is
going to be.
2. Library routines that have to support the traditional VMS mode, and
should also work in the two other modes.
3. Library routines that generate scripts/makefiles or native command lines.
It the future, Perl on VMS will be optionally supporting Unix shells
like bash as a default instead of just DCL.
Here's the mass of detection code:
use VMS::Feature;
my $vms_unix_rpt = VMS::Feature::current("filename_unix_report");
my $vms_efs = VMS::Feature::current("efs_charset");
my $vms_case = VMS::Feature::current("efs_case_preserve");
$Is{VMS_mode} = 0 if $vms_unix_rpt;
$Is{VMS_unix} = 1 if $vms_unix_rpt;
$Is{VMS_lc} = 0 if $vms_case;
$Is{VMS_noefs} = 0 if $vms_efs;
That mercifully doesn't include the work around if VMS::Feature isn't there.
There's no way to expect Perl programmers to stick all that in their code just
to accommodate VMS.
But this diff here illustrates the real problem:
- is( $mm->{INSTALLVENDORMAN1DIR}, File::Spec->catdir('foo','bar'),
+ my $expect = File::Spec->catdir('foo','bar');
+ $expect = VMS::Filespec::vmspath($expect) if $Is_VMS;
+ is( $mm->{INSTALLVENDORMAN1DIR}, $expect,
'installvendorman1dir (in %Config) not modified' );
Now every call to File::Spec, which is supposed to generate a portable path,
has to have extra code tacked onto the end to do more work. If that's
necessary then File::Spec::VMS should be doing it.
File::Spec::VMS traditionally has not generated a portable path. It
only does that now in when the extended character set option is active.
It is only a small set of Perl programs that have benefited from it
converting some file specifications to VMS format. I have found more
cases of programs that have required that VMS specific code be added to
them to compensate for this conversion in one way or another than I have
found programs actually expect it and need it to happen.
In conclusion, this should all be built into File::Spec::VMS.
The problem is that unless the end program explicitly needs a VMS
filespec, having File::Spec::VMS convert a Unix path syntax to VMS path
syntax breaks most Perl programs that have not been specically modified
to support VMS. Without that conversion, they generally will just work.
This is because most programs in addition to using the File::Spec
routines are also assuming that they can just use string manipulation to
manipulate the components of a path, because it just works for them.
It is only the case where something is building a VMS specific Make
script or building a DCL command file that a filename needs to
specifically be converted to VMS path syntax.
While having File::Spec::VMS convert filenames to VMS format may help a
few modules, in the majority of the cases that conversion breaks
portability.
For portability, there should be a set of routines that generically
convert from UNIX syntax to native syntax and reverse that can be called
when a script/makefile is being generated, or a native command line is
being generated. This is because most Perl scripts / libraries assume a
UNIX syntax, and most implementations of the C library and their perl
routines will accept either native or Unix paths.
Regards,
-John
wb8...@qsl.net
Personal Opinion Only