Mailing List Archive

problems with File::Basename
Dear Charles Bailey

A number of problems with File::Basename
I'm sorry if they have been fixed in more recent releases (I have
Version 2.2 13-Oct-1994). I may have already told you about point
5 previously.

1) The UNIX example does not work as stated in the documentation

#($base,$path,$type) = fileparse('/virgil/aeneid/draft.book7',
# '\.book\d+');
# would yield $base == 'draft',
# $path == '/virgil/aeneid', and
# $tail == '.book7'.

But does yield an extra '/' in $path
$path == '/virgil/aeneid/'

2) The pod documentation has 'You are guaranteed that if you
concatenate path, name and suffix together in that order then the
result will be identical to the input file specification'.

If the input file has no file separator (e.g. 'test.c') then the
concatenation is wrong ('test.c' becomes '.test.c'). I suggest that
'test.c' should give './test.c'.

3) The code for MSDOS filesystems should separate on [:\\]

4) The results of dirname() do not agree with the dirname command
when the input ends in '/' or has repeated '/'s.

% perl5 -wle 'use File::Basename; for(@ARGV) {print dirname $_};' \
/usr/lib /usr/lib/ /usr/lib// /usr/lib//README
/usr
/usr/
/usr/lib/
/usr/lib/
% foreach x ( /usr/lib /usr/lib/ /usr/lib// /usr/lib//README )
? dirname $x
? end
/usr
/usr
/usr
/usr/lib
%

5) Spurious warning (with -w)
% perl5 -wle 'use File::Basename; fileparse("test.c","\.c");'
Use of uninitialized value at /home/rmb/perl/modules/File/Basename.pm line 87.
%

Robin Barker

Patches
*** /usr/local/lib/perl5/File/Basename.pm Fri Oct 21 14:20:02 1994
--- /home/rmb/lib/perl5/File/Basename.pm Thu Sep 7 15:05:01 1995
***************
*** 46,52 ****
# ($base,$path,$type) = fileparse('/virgil/aeneid/draft.book7',
# '\.book\d+');
# would yield $base == 'draft',
# $tail == '.book7'.
# Similarly, on a system running VMS,
# ($name,$dir,$type) = fileparse('Doc_Root:[Help]Rhetoric.Rnh','\..*');
--- 46,52 ----
# ($base,$path,$type) = fileparse('/virgil/aeneid/draft.book7',
# '\.book\d+');
# would yield $base == 'draft',
# $tail == '.book7'.
# Similarly, on a system running VMS,
# ($name,$dir,$type) = fileparse('Doc_Root:[Help]Rhetoric.Rnh','\..*');
***************
*** 70,77 ****
}
}
if ($fstype =~ /^MSDOS/i) {
! ($dirpath,$basename) = ($fullname =~ /(.*\\)?(.*)/);
! $dirpath = '.' unless $dirpath;
}
elsif ($fstype =~ /^MAC/i) {
($dirpath,$basename) = ($fullname =~ /(.*:)?(.*)/);
--- 70,77 ----
}
}
if ($fstype =~ /^MSDOS/i) {
! ($dirpath,$basename) = ($fullname =~ /(.*[\\:])?(.*)/);
! $dirpath = '.\\' unless $dirpath;
}
elsif ($fstype =~ /^MAC/i) {
($dirpath,$basename) = ($fullname =~ /(.*:)?(.*)/);
***************
*** 78,87 ****
}
else { # default to Unix
($dirpath,$basename) = ($fullname =~ m#(.*/)?(.*)#);
! $dirpath = '.' unless $dirpath;
}

if (@suffices) {
foreach $suffix (@suffices) {
if ($basename =~ /($suffix)$/) {
$tail = $1 . $tail;
--- 78,88 ----
}
else { # default to Unix
($dirpath,$basename) = ($fullname =~ m#(.*/)?(.*)#);
! $dirpath = './' unless $dirpath;
}

if (@suffices) {
+ $tail = '';
foreach $suffix (@suffices) {
if ($basename =~ /($suffix)$/) {
$tail = $1 . $tail;
***************
*** 118,133 ****
}
if ($fstype =~ /MacOS/i) { return $dirname }
elsif ($fstype =~ /MSDOS/i) {
! if ( $dirname =~ /:\\$/) { return $dirname }
! chop $dirname;
! $dirname =~ s:[^/]+$:: unless $basename;
! $dirname = '.' unless $dirname;
}
else {
! if ( $dirname eq '/') { return $dirname }
! chop $dirname;
! $dirname =~ s:[^/]+$:: unless $basename;
! $dirname = '.' unless $dirname;
}

$dirname;
--- 119,156 ----
}
if ($fstype =~ /MacOS/i) { return $dirname }
elsif ($fstype =~ /MSDOS/i) {
! if( $dirname =~ s/(^|:)\\+$/$1\\/ ) { return $dirname }
! if( $dirname =~ /:$/ ) { return $dirname }
! $dirname =~ s/\\+$// or die "dirname '$dirname' should end in '\'";
! unless( $basename ) {
! $dirname =~ s/[^:\\]+$// or
! die "No component to remove from dirname '$dirname'";
! if( $dirname ) {
! $dirname =~ /:$/ or
! $dirname =~ s/(^|:)\\+$/$1\\/ or
! $dirname =~ s/\\+$// or
! die "dirname '$dirname' should end in '/'";
! }
! else {
! $dirname = '.';
! }
! }
}
else {
! if( $dirname =~ s:^/+$:/: ) { return $dirname }
! $dirname =~ s:/+$:: or die "dirname '$dirname' should end in '/'";
! unless( $basename ) {
! $dirname =~ s:[^/]+$:: or
! die "No component to remove from dirname '$dirname'";
! if( $dirname ) {
! $dirname =~ s:^/+$:/: or
! $dirname =~ s:/+$:: or
! die "dirname '$dirname' should end in '/'";
! }
! else {
! $dirname = '.';
! }
! }
}

$dirname;


*** /usr/local/perl/pod/modpods/Basename.pod Mon Dec 5 12:05:27 1994
--- /home/rmb/perl/pod/modpods/Basename.pod Thu Sep 7 15:19:52 1995
***************
*** 60,67 ****
C<@suffixlist>, you can remove file types or versions for examination.

You are guaranteed that if you concatenate B<path>, B<name>, and
! B<suffix> together in that order, the result will be identical to the
! input file specification.

=back

--- 60,67 ----
C<@suffixlist>, you can remove file types or versions for examination.

You are guaranteed that if you concatenate B<path>, B<name>, and
! B<suffix> together in that order, the result will specify the same file
! as the input file specification.

=back

***************
*** 75,81 ****
would yield

$base eq 'draft'
! $path eq '/virgil/aeneid',
$tail eq '.book7'

Similarly, using VMS syntax:
--- 75,81 ----
would yield

$base eq 'draft'
! $path eq '/virgil/aeneid/',
$tail eq '.book7'

Similarly, using VMS syntax: