1 | /* basename.c -- return the last element in a file name |
2 | |
3 | Copyright (C) 1990, 1998-2001, 2003-2006, 2009-2019 Free Software |
4 | Foundation, Inc. |
5 | |
6 | This program is free software: you can redistribute it and/or modify |
7 | it under the terms of the GNU General Public License as published by |
8 | the Free Software Foundation; either version 3 of the License, or |
9 | (at your option) any later version. |
10 | |
11 | This program is distributed in the hope that it will be useful, |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | GNU General Public License for more details. |
15 | |
16 | You should have received a copy of the GNU General Public License |
17 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ |
18 | |
19 | #include <config.h> |
20 | |
21 | #include "dirname.h" |
22 | |
23 | #include <string.h> |
24 | #include "xalloc.h" |
25 | #include "xstrndup.h" |
26 | |
27 | char * |
28 | base_name (char const *name) |
29 | { |
30 | char const *base = last_component (name); |
31 | size_t length; |
32 | |
33 | /* If there is no last component, then name is a file system root or the |
34 | empty string. */ |
35 | if (! *base) |
36 | return xstrndup (name, base_len (name)); |
37 | |
38 | /* Collapse a sequence of trailing slashes into one. */ |
39 | length = base_len (base); |
40 | if (ISSLASH (base[length])) |
41 | length++; |
42 | |
43 | /* On systems with drive letters, "a/b:c" must return "./b:c" rather |
44 | than "b:c" to avoid confusion with a drive letter. On systems |
45 | with pure POSIX semantics, this is not an issue. */ |
46 | if (FILE_SYSTEM_PREFIX_LEN (base)) |
47 | { |
48 | char *p = xmalloc (length + 3); |
49 | p[0] = '.'; |
50 | p[1] = '/'; |
51 | memcpy (p + 2, base, length); |
52 | p[length + 2] = '\0'; |
53 | return p; |
54 | } |
55 | |
56 | /* Finally, copy the basename. */ |
57 | return xstrndup (base, length); |
58 | } |
59 | |