DEFUN("file-basename", Ffile_basename, 1, 2, 0, /*
Return the basename of FILENAME sans its base directory.
-If EXTENSION is non-nil the extension is also removed if it matches the regexp.
-EXTENSION can be a list of regexps.
-For example, in a Unix-syntax file name,
-this is everything after the last slash,
-or the entire name if it contains no slash.
-It ignores trailing slash.
+
+If EXTENSION is non-nil the extension is also removed if it matches
+the regexp. EXTENSION can be a list of regexps.
+
+For example, in a Unix-syntax file name, this is everything after the
+last slash, or the entire name if it contains no slash.
+It ignores trailing slash unless filename is '/' in which case it
+returns '/'.
+
+Concatenating the string returned by file-dirname, a "/", and the
+string returned by file-basename yields a complete pathname.
+
+Sample returns (POSIX 1003.1 compliant):
+
+filename file-dirname file-basename
+/usr/lib /usr lib
+/usr/lib/ /usr lib
+/usr/ / usr
+usr . usr
+/ / /
+. . .
+./ . .
+.. . ..
+
*/
(filename, extension))
{
beg = XSTRING_DATA(filename);
end = p = beg + XSTRING_LENGTH(filename);
if ( IS_ANY_SEP(p[-1]) ) {
- p--;
- end--;
+ p--;
+ end--;
+ if (p == beg) {
+ return filename;
+ }
}
while (p != beg && !IS_ANY_SEP(p[-1]))
p--;
DEFUN("file-dirname", Ffile_dirname, 1, 1, 0, /*
-Return the directory component in file name FILENAME.
-Return nil if FILENAME does not include a directory.
-Otherwise return a directory spec.
-Given a Unix syntax file name, returns a string ending in slash.
-It ignores the trailing slash in FILENAME.
+Return the directory component in file name FILENAME as a directory
+spec.
+
+Given a Unix syntax file name, returns a string ending in slash. It
+ignores the trailing slash in FILENAME.
+
+Concatenating the string returned by file-dirname, a "/", and the
+string returned by file-basename yields a complete pathname.
+
+Sample returns (POSIX 1003.1 compliant):
+
+filename file-dirname file-basename
+/usr/lib /usr lib
+/usr/lib/ /usr lib
+/usr/ / usr
+usr . usr
+/ / /
+. . .
+./ . .
+.. . ..
+
*/
(filename))
{
/* This function can GC. GC checked 2000-07-28 ben */
- Bufbyte *beg, *p, *end;
- Lisp_Object handler;
-
+ Lisp_Object handler, result;
+ const char *res;
CHECK_STRING(filename);
/* If the file name has special constructs in it,
return call2_check_string_or_nil(handler, Qfile_dirname,
filename);
- beg = XSTRING_DATA(filename);
- end = p = beg + XSTRING_LENGTH(filename);
- if ( IS_ANY_SEP(p[-1]) ) {
- p--;
- end--;
- }
- while (p != beg && !IS_ANY_SEP(p[-1])
- )
- p--;
-
- if ( beg == p )
- return Qnil;
- return make_string(beg, p-beg);
+ res = xdirname((char*)XSTRING_DATA(filename));
+ result = make_string((const Bufbyte*)res, xstrlen(res));
+ xfree(res);
+ return result;
}