basename.c revision 7e7bd3dccbfe8f79e25e5c1554b5bc3a9aaca321
/* basename.c -- return the last element in a file name
Copyright (C) 1990, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006 Free
Software Foundation, Inc.
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
#include <config.h>
#include "dirname.h"
#include <string.h>
#include "xalloc.h"
#include "xstrndup.h"
/* Return the address of the last file name component of NAME. If
NAME has no relative file name components because it is a file
system root, return the empty string. */
char *
last_component (char const *name)
{
char const *p;
bool saw_slash = false;
base++;
for (p = base; *p; p++)
{
if (ISSLASH (*p))
saw_slash = true;
else if (saw_slash)
{
base = p;
saw_slash = false;
}
}
return (char *) base;
}
/* In general, we can't use the builtin `basename' function if available,
since it has different meanings in different environments.
In some environments the builtin `basename' modifies its argument.
Return the last file name component of NAME, allocated with
xmalloc. On systems with drive letters, a leading "./"
distinguishes relative names that would otherwise look like a drive
letter. Unlike POSIX basename(), NAME cannot be NULL,
base_name("") returns "", and the first trailing slash is not
stripped.
If lstat (NAME) would succeed, then { chdir (dir_name (NAME));
lstat (base_name (NAME)); } will access the same file. Likewise,
if the sequence { chdir (dir_name (NAME));
rename (base_name (NAME), "foo"); } succeeds, you have renamed NAME
to "foo" in the same directory NAME was in. */
char *
{
/* If there is no last component, then name is a file system root or the
empty string. */
if (! *base)
/* Collapse a sequence of trailing slashes into one. */
length++;
/* On systems with drive letters, `a/b:c' must return `./b:c' rather
than `b:c' to avoid confusion with a drive letter. On systems
with pure POSIX semantics, this is not an issue. */
if (FILE_SYSTEM_PREFIX_LEN (base))
{
p[0] = '.';
p[1] = '/';
return p;
}
/* Finally, copy the basename. */
}
/* Return the length of the basename NAME. Typically NAME is the
value returned by base_name or last_component. Act like strlen
(NAME), except omit all trailing slashes. */
{
continue;
return 2;
return prefix_len + 1;
return len;
}