perl 5.003_04: lib/Test/Harness.pm
[p5sagit/p5-mst-13.2.git] / lib / File / Basename.pm
CommitLineData
a0d0e21e 1package File::Basename;
2
f06db76b 3=head1 NAME
4
5Basename - parse file specifications
6
7fileparse - split a pathname into pieces
8
9basename - extract just the filename from a path
10
11dirname - extract just the directory from a path
12
13=head1 SYNOPSIS
14
15 use File::Basename;
16
17 ($name,$path,$suffix) = fileparse($fullname,@suffixlist)
18 fileparse_set_fstype($os_string);
19 $basename = basename($fullname,@suffixlist);
20 $dirname = dirname($fullname);
21
22 ($name,$path,$suffix) = fileparse("lib/File/Basename.pm","\.pm");
23 fileparse_set_fstype("VMS");
24 $basename = basename("lib/File/Basename.pm",".pm");
25 $dirname = dirname("lib/File/Basename.pm");
26
27=head1 DESCRIPTION
28
29These routines allow you to parse file specifications into useful
30pieces using the syntax of different operating systems.
31
32=over 4
33
34=item fileparse_set_fstype
35
36You select the syntax via the routine fileparse_set_fstype().
37If the argument passed to it contains one of the substrings
38"VMS", "MSDOS", or "MacOS", the file specification syntax of that
39operating system is used in future calls to fileparse(),
40basename(), and dirname(). If it contains none of these
41substrings, UNIX syntax is used. This pattern matching is
42case-insensitive. If you've selected VMS syntax, and the file
43specification you pass to one of these routines contains a "/",
44they assume you are using UNIX emulation and apply the UNIX syntax
45rules instead, for that function call only.
46
47If you haven't called fileparse_set_fstype(), the syntax is chosen
f0c6ccdf 48by examining the builtin variable C<$^O> according to these rules.
f06db76b 49
50=item fileparse
51
52The fileparse() routine divides a file specification into three
53parts: a leading B<path>, a file B<name>, and a B<suffix>. The
54B<path> contains everything up to and including the last directory
55separator in the input file specification. The remainder of the input
56file specification is then divided into B<name> and B<suffix> based on
57the optional patterns you specify in C<@suffixlist>. Each element of
58this list is interpreted as a regular expression, and is matched
59against the end of B<name>. If this succeeds, the matching portion of
60B<name> is removed and prepended to B<suffix>. By proper use of
61C<@suffixlist>, you can remove file types or versions for examination.
62
63You are guaranteed that if you concatenate B<path>, B<name>, and
7e2183d3 64B<suffix> together in that order, the result will denote the same
65file as the input file specification.
f06db76b 66
67=back
68
69=head1 EXAMPLES
70
71Using UNIX file syntax:
72
7e2183d3 73 ($base,$path,$type) = fileparse('/virgil/aeneid/draft.book7',
f06db76b 74 '\.book\d+');
75
76would yield
77
78 $base eq 'draft'
7e2183d3 79 $path eq '/virgil/aeneid/',
f06db76b 80 $tail eq '.book7'
81
82Similarly, using VMS syntax:
83
84 ($name,$dir,$type) = fileparse('Doc_Root:[Help]Rhetoric.Rnh',
85 '\..*');
86
87would yield
88
89 $name eq 'Rhetoric'
90 $dir eq 'Doc_Root:[Help]'
91 $type eq '.Rnh'
92
93=item C<basename>
94
95The basename() routine returns the first element of the list produced
96by calling fileparse() with the same arguments. It is provided for
97compatibility with the UNIX shell command basename(1).
98
99=item C<dirname>
100
101The dirname() routine returns the directory portion of the input file
102specification. When using VMS or MacOS syntax, this is identical to the
103second element of the list produced by calling fileparse() with the same
7e2183d3 104input file specification. (Under VMS, if there is no directory information
105in the input file specification, then the current default device and
106directory are returned.) When using UNIX or MSDOS syntax, the return
f06db76b 107value conforms to the behavior of the UNIX shell command dirname(1). This
108is usually the same as the behavior of fileparse(), but differs in some
109cases. For example, for the input file specification F<lib/>, fileparse()
110considers the directory name to be F<lib/>, while dirname() considers the
111directory name to be F<.>).
112
113=cut
114
f0c6ccdf 115require 5.002;
a0d0e21e 116require Exporter;
117@ISA = qw(Exporter);
748a9306 118@EXPORT = qw(fileparse fileparse_set_fstype basename dirname);
7e2183d3 119#use strict;
120#use vars qw($VERSION $Fileparse_fstype);
121$VERSION = "2.3";
122
a0d0e21e 123
124# fileparse_set_fstype() - specify OS-based rules used in future
125# calls to routines in this package
126#
127# Currently recognized values: VMS, MSDOS, MacOS
128# Any other name uses Unix-style rules
129
130sub fileparse_set_fstype {
748a9306 131 my($old) = $Fileparse_fstype;
132 $Fileparse_fstype = $_[0] if $_[0];
133 $old;
a0d0e21e 134}
135
136# fileparse() - parse file specification
137#
7e2183d3 138# Version 2.3 4-Jul-1996 Charles Bailey bailey@genetics.upenn.edu
a0d0e21e 139
140
141sub fileparse {
142 my($fullname,@suffices) = @_;
143 my($fstype) = $Fileparse_fstype;
7e2183d3 144 my($dirpath,$tail,$suffix,$basename);
a0d0e21e 145
146 if ($fstype =~ /^VMS/i) {
147 if ($fullname =~ m#/#) { $fstype = '' } # We're doing Unix emulation
148 else {
149 ($dirpath,$basename) = ($fullname =~ /(.*[:>\]])?(.*)/);
a0d0e21e 150 }
151 }
152 if ($fstype =~ /^MSDOS/i) {
7e2183d3 153 ($dirpath,$basename) = ($fullname =~ /(.*[:\\])?(.*)/);
154 $dirpath .= '.\\' unless $dirpath =~ /\\$/;
a0d0e21e 155 }
7e2183d3 156 elsif ($fstype =~ /^MacOS/i) {
a0d0e21e 157 ($dirpath,$basename) = ($fullname =~ /(.*:)?(.*)/);
158 }
748a9306 159 elsif ($fstype !~ /^VMS/i) { # default to Unix
a0d0e21e 160 ($dirpath,$basename) = ($fullname =~ m#(.*/)?(.*)#);
f0c6ccdf 161 $dirpath = './' unless $dirpath;
a0d0e21e 162 }
163
164 if (@suffices) {
f06db76b 165 $tail = '';
a0d0e21e 166 foreach $suffix (@suffices) {
7e2183d3 167 if ($basename =~ /([\x00-\xff]*?)($suffix)$/) {
168 $tail = $2 . $tail;
169 $basename = $1;
a0d0e21e 170 }
171 }
172 }
173
748a9306 174 wantarray ? ($basename,$dirpath,$tail) : $basename;
a0d0e21e 175
176}
177
178
179# basename() - returns first element of list returned by fileparse()
180
181sub basename {
748a9306 182 my($name) = shift;
183 (fileparse($name, map("\Q$_\E",@_)))[0];
a0d0e21e 184}
7e2183d3 185
a0d0e21e 186
187# dirname() - returns device and directory portion of file specification
188# Behavior matches that of Unix dirname(1) exactly for Unix and MSDOS
748a9306 189# filespecs except for names ending with a separator, e.g., "/xx/yy/".
190# This differs from the second element of the list returned
a0d0e21e 191# by fileparse() in that the trailing '/' (Unix) or '\' (MSDOS) (and
192# the last directory name if the filespec ends in a '/' or '\'), is lost.
193
194sub dirname {
195 my($basename,$dirname) = fileparse($_[0]);
196 my($fstype) = $Fileparse_fstype;
197
198 if ($fstype =~ /VMS/i) {
748a9306 199 if ($_[0] =~ m#/#) { $fstype = '' }
7e2183d3 200 else { return $dirname || $ENV{DEFAULT} }
a0d0e21e 201 }
202 if ($fstype =~ /MacOS/i) { return $dirname }
203 elsif ($fstype =~ /MSDOS/i) {
204 if ( $dirname =~ /:\\$/) { return $dirname }
205 chop $dirname;
7e2183d3 206 $dirname =~ s:[^\\]+$:: unless length($basename);
207 $dirname = '.' unless length($dirname);
a0d0e21e 208 }
209 else {
7e2183d3 210 if ( $dirname =~ m:^/+$:) { return '/'; }
a0d0e21e 211 chop $dirname;
7e2183d3 212 $dirname =~ s:[^/]+$:: unless length($basename);
213 $dirname =~ s:/+$:: ;
214 $dirname = '.' unless length($dirname);
a0d0e21e 215 }
216
217 $dirname;
218}
219
f0c6ccdf 220$Fileparse_fstype = $^O;
a0d0e21e 221
2221;