1 /* basename.c -- return the last element in a file name 2 3 Copyright (C) 1990, 1998-2001, 2003-2006, 2009-2018 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