use strict;
use warnings;
use warnings::register;
-our $VERSION = '1.10';
+our $VERSION = '1.11';
require Exporter;
require Cwd;
finddepth(\&wanted, @directories);
finddepth(\%options, @directories);
-C<finddepth()> works just like C<find()> except that is invokes the
+C<finddepth()> works just like C<find()> except that it invokes the
C<&wanted> function for a directory I<after> invoking it for the
directory's contents. It does a postorder traversal instead of a
preorder traversal, working from the bottom of the directory tree up
=back
+The above variables have all been localized and may be changed without
+effecting data outside of the wanted function.
+
For example, when examining the file F</some/path/foo.ext> you will have:
$File::Find::dir = /some/path/
/etc / /etc
/etc/x /etc /etc/x
-Do not modify these variables. If you want to use C<$_>, it must
-be restored to its initial value before returning from the
-function. C<local> may be used for this purpose:
-
- sub callback {
- open my $fh, '<', $_ or die "Cannot open $_ for input: $!\n";
- local $_; # localize $_ for the remainder of the routine
- while (<$fh>) {
- # manipulate $_
- }
- # $_ will be restored upon leaving
- }
When <follow> or <follow_fast> are in effect, there is
also a C<$File::Find::fullname>. The function may set
local *_ = \my $a;
my $cwd = $wanted->{bydepth} ? Cwd::fastcwd() : Cwd::getcwd();
+ if ($Is_VMS) {
+ # VMS returns this by default in VMS format which just doesn't
+ # work for the rest of this module.
+ $cwd = VMS::Filespec::unixpath($cwd);
+
+ # Apparently this is not expected to have a trailing space.
+ # To attempt to make VMS/UNIX conversions mostly reversable,
+ # a trailing slash is needed. The run-time functions ignore the
+ # resulting double slash, but it causes the perl tests to fail.
+ $cwd =~ s#/\z##;
+
+ # This comes up in upper case now, but should be lower.
+ # In the future this could be exact case, no need to change.
+ }
my $cwd_untainted = $cwd;
my $check_t_cwd = 1;
$wanted_callback = $wanted->{wanted};
$abs_dir = $cwd;
}
else { # care about any ../
+ $top_item =~ s/\.dir\z//i if $Is_VMS;
$abs_dir = contract_name("$cwd/",$top_item);
}
}
}
if (-d _) {
+ $top_item =~ s/\.dir\z//i if $Is_VMS;
_find_dir_symlnk($wanted, $abs_dir, $top_item);
$Is_Dir= 1;
}
$dir_pref= ($p_dir =~ /:$/) ? $p_dir : "$p_dir:"; # preface
} elsif ($^O eq 'MSWin32') {
$dir_pref = ($p_dir =~ m|\w:/$| ? $p_dir : "$p_dir/" );
+ } elsif ($^O eq 'VMS') {
+
+ # VMS is returning trailing .dir on directories
+ # and trailing . on files and symbolic links
+ # in UNIX syntax.
+ #
+
+ $p_dir =~ s/\.(dir)?$//i unless $p_dir eq '.';
+
+ $dir_pref = ($p_dir =~ m/[\]>]+$/ ? $p_dir : "$p_dir/" );
}
else {
$dir_pref= ( $p_dir eq '/' ? '/' : "$p_dir/" );
if ($nlink == 2 && !$no_nlink) {
# This dir has no subdirectories.
for my $FN (@filenames) {
+ if ($Is_VMS) {
+ # Big hammer here - Compensate for VMS trailing . and .dir
+ # No win situation until this is changed, but this
+ # will handle the majority of the cases with breaking the fewest
+
+ $FN =~ s/\.dir\z//i;
+ $FN =~ s#\.$## if ($FN ne '.');
+ }
next if $FN =~ $File::Find::skip_pattern;
$name = $dir_pref . $FN; # $File::Find::name
$dir_name = ($p_dir =~ m|\w:/$| ? "$p_dir$dir_rel" : "$p_dir/$dir_rel");
$dir_pref = "$dir_name/";
}
+ elsif ($^O eq 'VMS') {
+ if ($p_dir =~ m/[\]>]+$/) {
+ $dir_name = $p_dir;
+ $dir_name =~ s/([\]>]+)$/.$dir_rel$1/;
+ $dir_pref = $dir_name;
+ }
+ else {
+ $dir_name = "$p_dir/$dir_rel";
+ $dir_pref = "$dir_name/";
+ }
+ }
else {
$dir_name = ($p_dir eq '/' ? "/$dir_rel" : "$p_dir/$dir_rel");
$dir_pref = "$dir_name/";
closedir(DIR);
for my $FN (@filenames) {
+ if ($Is_VMS) {
+ # Big hammer here - Compensate for VMS trailing . and .dir
+ # No win situation until this is changed, but this
+ # will handle the majority of the cases with breaking the fewest.
+
+ $FN =~ s/\.dir\z//i;
+ $FN =~ s#\.$## if ($FN ne '.');
+ }
next if $FN =~ $File::Find::skip_pattern;
# follow symbolic links / do an lstat
# ignore if invalid symlink
unless (defined $new_loc) {
- if ($dangling_symlinks) {
+ if (!defined -l _ && $dangling_symlinks) {
if (ref $dangling_symlinks eq 'CODE') {
$dangling_symlinks->($FN, $dir_pref);
} else {
}
if (-d _) {
+ if ($Is_VMS) {
+ $FN =~ s/\.dir\z//i;
+ $FN =~ s#\.$## if ($FN ne '.');
+ $new_loc =~ s/\.dir\z//i;
+ $new_loc =~ s#\.$## if ($new_loc ne '.');
+ }
push @Stack,[$new_loc,$updir_loc,$dir_name,$FN,1];
}
else {