CPAN is showing Nicholas Clark as the maintainer of VMS::Filespec, and the comments are showing Charles Baily as the maintainer.

This adds the methods needed for other Core modules to properly interpret VMS file specifications.

Also included is an update to the documentation for the existing routines.

The file vms/ext/filespec.t includes tests for the new methods
that are intended for use by most modules for when they become live.

The decc methods are there mainly just in case I need them, because they mostly affect VMS Filespec operations.

When and if this becomes accepted, I will have updates for several core modules that need to test for how VMS is currently configured to behave, and make sure that the existing behavior is preserved before I change vms.c to make these new methods live.

From my tests on Perl 5.8.7, the modules that need to be changed to test
for the existence of these new methods and if they are defined to act on the results are:

lib/Cwd.pm
lib/FindBin.pm
lib/ExtUtils/Command.pm
lib/ExtUtils/Manifest.pm
lib/ExtUtils/MM_Unix.pm
lib/ExtUtils/MM_VMS.pm
lib/File/Temp.pm
lib/File/Spec/VMS.pm
lib/Pod/Perlvms.pod
vms/perlvms.pod
ext/Cwd/t/cwd.t
ext/File/Glob/t/basic.t
ext/POSIX/t/posix.t
lib/AutoSplit.t
lib/blib.t
lib/FindBin.t
lib/h2xs.t
lib/ExtUtils/t/Command.t
lib/File/Spec/t/crossplatform.t
lib/File/Spec/t/Spec.t
t/op/defins.t

I will probably need some help with the best way to have these modules check for the mode that VMS is currently in.

I am currently assuming that any non-VMS use of VMS::Filespec will want to see the older VMS behavior returned for the new methods for testing purposes, and not want to have it simulate the setting of the various modes.

-John
[EMAIL PROTECTED]
Personal Opinion Only

--- vms/ext/Filespec.pm_25626   Wed Sep 28 00:10:43 2005
+++ vms/ext/Filespec.pm Wed Sep 28 00:06:36 2005
@@ -20,7 +20,18 @@
 $vmsdir = vmspath('my/VMS/or/Unix/directory/specification.dir');
 $unixdir = unixpath('my:[VMS.or.Unix.directory]specification.dir');
 candelete('my:[VMS.or.Unix]file.specification');
-
+$status = unix_report [($mode)];
+$status = unix_only [($mode)];
+$active_mode = posix_mode [($mode)];
+$status = case_preserve [($mode)];
+$status = efs_charset [($mode)];
+$status = vms_realpath($filespec);
+$status = is_vms_spec($filespec);
+$status = is_unix_spec($filespec);
+$value = decc_feature_support;
+$value = decc_feature_get_value('name' [, $mode]);
+$old_value = decc_feature_set_value('name' , $mode, $value);
+$deed_status = decc_feature_deed [($value)];
 =head1 DESCRIPTION
 
 This package provides routines to simplify conversion between VMS and
@@ -59,6 +70,11 @@
 expressions (as long as you don't use the C<&> form of
 subroutine call, which bypasses prototype checking).
 
+The values returned by the routines that return information about
+how the file system or DECC features should not be considered
+the default values or fixed values for them, as this will
+change with both the version of VMS, the version of Perl and
+external factors.
 
 The routines provided are:
 
@@ -72,13 +88,74 @@
 as possible.)  If an error occurs, returns C<undef> and sets C<$!>
 and C<$^E>.
 
+When rmsexpand returns a filename, it will always fit in a 255 byte
+VMS format file specification for compatibility with VMS routines
+that do not accept long filenames.  The resulting file specification
+may be in DID or FID notation.
+
 =head2 vmsify
 
-Converts a file specification to VMS syntax.
+Converts a file specification to VMS syntax, if it is detected to
+be originally a UNIX filename.
+
+A path delimiter or the special C<.> or C<..> directories or the absense
+of VMS file specification delimiters or if the C<efs_charset> is enabled,
+the absence of those special delimiters for it is required to force a
+conversion.
+
+Note that the conversion from VMS syntax to UNIX syntax may not be
+able to be reversed to the the original file specification by
+C<unixify>.  Try to avoid converting file specifications from UNIX to
+VMS format and then converting it back.
+
+A special note about file names with no path or type component on VMS.
+Such files usually have an implied type based on the intended use of the
+file.  To prevent the usage of such an implied type, a trailing period
+for a C<null> type is required.
+
+If a UNIX syntax name has no period in the name component to designate
+a pipe, it is ambigous to VMS as to what the resulting filename should
+be until the file is used.
+
+When the C<efs_charset> mode is enabled, a UNIX syntax name with a
+trailing C<.> should be converted to a VMS syntax name with a trailing
+C<^.>.  Otherwise if there is no other period in the name portion of the
+file, the trailing period will be maintained, otherwise the trailing
+period should be converted to an C<_>.
+
+A cautious programmer will take note of the word C<should> for these
+special names, as they are not currently in the Perl tests.
+
+At the time of this writing vmsify and related routines can not detect
+that UNIX glob characters imply a UNIX filename in the absence of path
+delimiters.  This may get fixed in the future, in the meantime, prepending
+a C<./> if and only if there are no other UNIX path delimiters will cause
+the UNIX glob characters to be interpreted.  If ./ is added to a file
+specification with other UNIX directory characters, it may trigger
+another bug in the handling of UNIX glob characters.
 
 =head2 unixify
 
-Converts a file specification to Unix syntax.
+Converts a file specification to Unix syntax if it is detected to
+be originally a VMS file specification.  If a file specification
+can not be converted to a VMS file name, it will be left as is.
+The MakeMaker module depends on this behavior.
+
+Note that the conversion from VMS syntax to UNIX syntax may not
+be able to be reversed to the original file specification by
+C<vmsify>.  Try to avoid converting files from UNIX syntax to VMS
+syntax and then back to UNIX syntax.
+
+A VMS syntax name with a trailing C<.> and no file extension is present,
+the trailing C<.> should be removed from the resulting UNIX syntax
+specification.
+
+When C<efs_charset> is enabled, the C<;> needs to be used as a VMS version
+delimiter as otherwise it is not possible to determine where the filename
+ends and the version number starts.
+
+See the also the description in the C<vmsify> section for other
+important information.
 
 =head2 pathify
 
@@ -91,6 +168,9 @@
 F<.DIR;1>.  For compatibility with Unix usage, the type and version
 may also be omitted.
 
+When VMS is in case sensitive mode for the filesystem, the F<.DIR> must
+be in upper case.
+
 =head2 fileify
 
 Converts a directory specification to the file specification of the
@@ -101,6 +181,9 @@
 C<pathify>, the input file specification must have a type and
 version of F<.DIR;1>, or the type and version must be omitted.
 
+When VMS is in case sensitive mode for the filesystem, the F<.DIR> must
+be in upper case.
+
 =head2 vmspath
 
 Acts like C<pathify>, but insures the returned path uses VMS syntax.
@@ -119,16 +202,191 @@
 these restrictions may be removed in the future if the functionality of
 C<candelete> becomes part of the Perl core.
 
+=head2 unix_report
+
+Returns or sets the DECC library into a mode where it supports the
+default of file specifications being into UNIX mode.  If Perl does not
+support this mode, then this routine will always return FALSE.
+
+If the version of Perl does not support this mode, it will return
+FALSE.
+
+Note that many Perl scripts and modules that make assumptions
+about past behavior of OpenVMS may not work with this mode.
+
+The unix_report mode implies that the following DECC features are
+set:
+
+  DECC$FILENAME_UNIX_REPORT
+  DECC$FILENAME_UNIX_NO_VERSION
+  DECC$READDIR_DROPDOTNOTYPE
+  DECC$EFS_CASE_PRESERVE
+  DECC$EFS_CHARSET
+
+This mode may allow Perl scripts designed to run on UNIX systems
+to run on VMS with out needed VMS specific modifications.
+
+=head2 unix_only
+
+Returns or sets the DECC library into a mode where it assumes that
+all file specifications are in UNIX syntax and does no conversion.
+If the Perl Interpreter does not support this mode, then this
+routine will always return FALSE.
+
+The unix_only setting implies the UNIX report mode is also set.
+
+If the version of Perl does not support this mode, it will return
+FALSE.
+
+Note that many Perl scripts and modules that make assumptions
+about past behavior of OpenVMS may not work with this mode.
+Change with caution.
+
+This mode may allow Perl scripts designed to run on UNIX systems
+to run on VMS with out needed VMS specific modifications.
+
+=head2 posix_mode
+
+These modes will be available on a future version of OpenVMS
+for 64 bit platforms.  With these modes, the handling of POSIX
+style path names is done by the OpenVMS operating system and
+not by the C library.
+
+Note that many Perl scripts and modules that make assumptions
+about past behavior of OpenVMS may not work with this mode.
+Change with caution.
+
+If the version of Perl does not support this mode, it will return
+0, which indicates that this mode is not active.
+
+This mode may allow Perl scripts designed to run on UNIX systems
+to run on VMS with out needed VMS specific modifications.
+
+=head2 case_preserve
+
+Returns or sets if Perl interpreter is in the mode
+where it preserves the case of VMS file specifications.
+
+If the version of Perl does not support this mode, it will return
+FALSE.
+
+When this mode is active, the DECC$EFS_CASE_PRESERVE feature
+is enabled by versions of Perl that support it.
+
+=head2 efs_charset
+
+Returns or sets if the Perl interpreter is in the mode
+where it will accept file specifications with Extended
+character sets.
+
+If the version of Perl does not support this mode, it will return
+FALSE.
+
+When this mode is active, the DECC$EFS_CHARSET feature
+is enabled by versions of Perl that support it.
+
+=head2 is_vms_spec
+
+Returns if the file specification is detected to be in VMS syntax.
+The quick test for VMS syntax is the presence of the VMS directory
+and version delimiters are present and that UNIX directory delimiters
+are not.  When the EFS character set is enabled, that test is not
+sufficient.
+
+If the version of Perl does not support a more comprehensive test
+the simple test in this module will be used.
+
+It is also possible that it can not be absolutely determined if a file
+specification is UNIX or VMS if directory components are not present.
+
+When the EFS Character set is enabled, some file specifications
+with out directory delimiters will have different meanings depending
+on if they are interpreted as VMS or UNIX.
+
+This routine will return a positive value if it is possible that this
+is a VMS file specification.
+
+=head2 is_unix_spec
+
+Returns if the file specification is detected to be in UNIX syntax.
+The quick test for UNIX syntax is the absense of the VMS directory
+and version delimiters, and the optional presence of UNIX directory
+delimiters.
+
+If the version of Perl does not support a more comprehensive test
+the simple test in this module will be used.
+
+When the EFS Character set is enabled, some file specifications
+with out directory delimiters will have different meanings depending
+on if they are interpreted as VMS or UNIX.
+
+This routine will return a positive value if it is possible that this
+is a UNIX file specification.
+
+=head2 vms_realpath
+
+When supported this exposes the VMS CRTL realpath() function, otherwise
+it returns an error.  When Perl on VMS supports symbolic links, this
+function will be needed by the Cwd module for performance reasons.
+
+=head2 decc_feature_support
+
+If the Perl interpreter has support for selected DECC feature settings
+this will return TRUE, otherwise it will return FALSE.
+
+Note that the DECC feature settings will affect the behavior of Perl
+even on versions of Perl that do not support them.
+
+
+=head2 decc_feature_get_value
+
+Returns the setting of a DECC library feature value.  This is a wrapper
+for the decc$feature_get_value() routine on those Perl versions that support
+it.  Otherwise the $ENV hash is used for simulation.
+
+The settings for some DECC library features are cached by the Perl
+versions that directly support the use of the enhanced features.  So this
+routine should be the only one used to obtain the values that the
+Perl Interpreter is using internally.
+
+=head2 decc_feature_set_value
+
+Changes the setting of a DECC library feature value.  This is a wrapper
+for the decc$feature_set_value() routine on those Perl versions that
+support it.  Otherwise it returns FALSE.
+
+The settings for some DECC library features are cached by the Perl
+versions that directly support the use of the enhanced features.  So this
+routine should be the only one used to set the values so that internal
+values Perl Interpreter is using are also changed if appropriate.
+
+=head2 decc_feature_deed
+
+Sets or reports if changes to the DECC feature values by these routines
+are inherited by child processes.  Features are inherited by setting
+the DECC feature logical names.
+
+
 =head1 REVISION
 
-This document was last revised 22-Feb-1996, for Perl 5.002.
+This document was last revised 25-Sep-2005, for Perl 5.8.8.
+
+=head1 FUTURE DIRECTIONS
+
+There are some UNIX file specifications that can represent several
+possible VMS file specifications.
+
+The accuracy of the routines that convert VMS and UNIX to or from
+each other may be improved if additional hints can be passed to them
+as optional parameters.  The properties of those hints has not yet
+been determined.
 
 =cut
 
 package VMS::Filespec;
 require 5.002;
 
-our $VERSION = '1.11';
+our $VERSION = '1.12';
 
 # If you want to use this package on a non-VMS system,
 # uncomment the following line.
@@ -137,7 +395,12 @@
 
 @ISA = qw( Exporter );
 @EXPORT = qw( &vmsify &unixify &pathify &fileify
-              &vmspath &unixpath &candelete &rmsexpand );
+              &vmspath &unixpath &candelete &rmsexpand
+             &unix_report &unix_only &posix_mode
+             &case_preserve &efs_charset &is_vms_spec
+             &is_unix_spec &vms_realpath, &decc_feature_support
+             &decc_feature_get_value &decc_features_set_value
+             &decc_feature_deed);
 
 1;
 
@@ -348,4 +611,88 @@
     return (-w fileify($parent));
   }
   else { return (-w '[-]'); }
+}
+
+# for now for most of these just return undefined, as that is the state of 
older
+# versions of Perl that do not provide these functions.
+
+sub unix_report ($) {
+   return undef;
+}
+
+sub unix_only ($) {
+   return undef;
+}
+
+sub posix_mode ($) {
+   return undef;
+}
+
+sub case_preserve ($) {
+   return undef;
+}
+
+sub efs_charset ($) {
+   return undef;
+}
+
+
+sub is_vms_spec ($) {
+  my($fspec) = @_;
+  return 0 if ($fspec eq '.') || ($fspec eq '..');
+  # if []:;<> present then true.
+  return 1 if $fspec =~ m#[:>\]]#;
+  # if / present than false.
+  return 1 if $fspec !~ m#[/]#;
+  return 0;
+}
+
+sub is_unix_spec($) {
+  my($fspec) = @_;
+  return 1 if ($fspec eq '.') || ($fspec eq '..');
+  # if / present than true
+  return 1 if $fspec =~ m#[/]#;
+  # if []:<> present then false.
+  return 1 if $fspec !~ m#[:>\]]#;
+  return 0;
+}
+
+sub vms_realpath($) {
+   return -1;
+}
+
+sub decc_feature_support {
+   return undef;
+}
+
+sub decc_feature_get_value ($;$) {
+    my ($feature, $mode) = @_;
+   # look for DECC$ prefix on feature name?
+    return $ENV{$feature} if (defined $feature);
+    return undef;
+}
+
+sub decc_feature_set_value ($;$;$) {
+   my ($feature, $mode, $value) = @_;
+   my $old_value;
+
+   return undef if !defined $mode;
+   return undef if !defined $value;
+   return undef if !defined $feature;
+
+   # look for DECC$ prefix on feature name.
+
+#   $old_value = decc_feature_get_value($feature, $mode);
+#   if ($mode == 1 && defined $feature) {
+#      $ENV{$feature} = $value;
+#   }
+   return $old_value;
+
+}
+
+# if decc_feature routines not supported then all
+# changes are through logical names and must be
+# inherited by children.
+sub decc_feature_deed($) {
+    return 1;
 }
--- vms/ext/Filespec.t_25626    Wed Sep 28 00:11:06 2005
+++ vms/ext/Filespec.t  Tue Sep 27 22:09:45 2005
@@ -1,6 +1,8 @@
 #!./perl
 
-BEGIN { unshift(@INC,'../lib') if -d '../lib'; }
+#BEGIN { unshift(@INC,'../lib') if -d '../lib'; }
+
+print STDERR "#Test \n";
 
 use VMS::Filespec;
 use File::Spec;
@@ -13,7 +15,60 @@
 }
 
 require './test.pl';
-plan(tests => scalar([EMAIL PROTECTED])+6);
+plan(tests => scalar([EMAIL PROTECTED])+13);
+
+my $tfunc, $rslt;
+my $todo = "# TODO";
+my $have_is_vms_spec;
+my $have_is_unix_spec;
+
+$tfunc = 'is_vms_spec';
+$rslt = eval "$tfunc";
+if (defined $rslt) {
+  is($@, '', "eval ${tfunc}");
+}
+else {
+  is('undef','', "$todo ${tfunc} not implmented.");
+}
+
+$tfunc = 'is_unix_spec';
+$rslt = eval "$tfunc";
+if (defined $rslt) {
+  is($@, '', "eval ${tfunc}");
+}
+else {
+  is('undef','', "$todo ${tfunc} not implmented.");
+}
+
+sub my_is_vms_spec($) {
+  my($fspec) = @_;
+  if (defined $have_is_vms_spec) {
+    return is_vms_spec($fspec);
+  }
+  else {
+    return 0 if ($fspec eq '.') || ($fspec eq '..');
+    # if []:;<> present then true.
+    return 1 if $fspec =~ m#[:>\]]#;
+    # if / present than false.
+    return 1 if $fspec !~ m#[/]#;
+    return 0;
+  }
+}
+
+sub my_is_unix_spec($) {
+  my($fspec) = @_;
+  if (defined $have_is_unix_spec) {
+    return is_unix_spec($fspec);
+  }
+  else {
+    return 1 if ($fspec eq '.') || ($fspec eq '..');
+    # if / present than true
+    return 1 if $fspec =~ m#[/]#;
+    # if []:<> present then false.
+    return 1 if $fspec !~ m#[:>\]]#;
+    return 0;
+  }
+}
 
 foreach $test (@tests) {
   ($arg,$func,$expect) = split(/\s+/,$test);
@@ -39,11 +94,58 @@
    'cant:[get.there]from.here;2')                     || print $defwarn;
 
 
+$tfunc = qw(unix_report);
+$rslt = eval "$tfunc";
+if (defined $rslt) {
+  is($@, '', "eval ${tfunc}");
+}
+else {
+  is('undef','', "$todo ${tfunc} not implmented.");
+}
+
+$tfunc = 'unix_only';
+$rslt = eval "$tfunc";
+if (defined $rslt) {
+  is($@, '', "eval ${tfunc}");
+}
+else {
+  is('undef','', "$todo ${tfunc} not implmented.");
+}
+
+$tfunc = 'posix_mode';
+$rslt = eval "$tfunc";
+if (defined $rslt) {
+  is($@, '', "eval ${tfunc}");
+}
+else {
+  is('undef','', "$todo ${tfunc} not implmented.");
+}
+
+$tfunc = 'case_preserve';
+$rslt = eval "$tfunc";
+if (defined $rslt) {
+  is($@, '', "eval ${tfunc}")
+}
+else {
+  is('undef','', "$todo ${tfunc} not implmented.");
+}
+
+$tfunc = 'efs_charset';
+$rslt = eval "$tfunc";
+if (defined $rslt) {
+  is($@, '', "eval ${tfunc}");
+}
+else {
+  is('undef','', "$todo ${tfunc} not implmented.");
+}
+
+
 # Make sure we're using redirected mkdir, which strips trailing '/', since
 # the CRTL's mkdir can't handle this.
 ok(mkdir('testdir/',0777),      'using redirected mkdir()');
 ok(rmdir('testdir/'),           '    rmdir()');
 
+
 __DATA__
 
 # lots of underscores used to minimize collision with existing logical names
@@ -129,3 +231,15 @@
 # Our override of File::Spec->canonpath can do some strange things
 __dev:[__dir.000000]__foo     File::Spec->canonpath   __dev:[__dir.000000]__foo
 __dev:[__dir.][000000]__foo   File::Spec->canonpath   __dev:[__dir]__foo
+
+# what is the filespec?
+__dev:[__dir]__foo my_is_vms_spec 1
+__dev:[__dir]__foo my_is_unix_spec 0
+__dev/__dir/__foo my_is_vms_spec 0
+__dev/__dir__foo my_is_unix_spec 1
+__foo my_is_vms_spec 1
+__foo my_is_unix_spec 1
+.. my_is_vms_spec 0
+.. my_is_unix_spec 1
+. my_is_vms_spec 0
+. my_is_unix_spec 1

Reply via email to