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