1 /* basename.c -- return the last element in a file name 2 3 Copyright (C) 1990, 1998-2001, 2003-2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */ 18 19 #include <config.h> 20 21 #include "dirname.h" 22 23 #include <string.h> 24 25 /* Return the address of the last file name component of NAME. If 26 NAME has no relative file name components because it is a file 27 system root, return the empty string. */ 28 29 char * last_component(char const * name)30last_component (char const *name) 31 { 32 char const *base = name + FILE_SYSTEM_PREFIX_LEN (name); 33 char const *p; 34 bool saw_slash = false; 35 36 while (ISSLASH (*base)) 37 base++; 38 39 for (p = base; *p; p++) 40 { 41 if (ISSLASH (*p)) 42 saw_slash = true; 43 else if (saw_slash) 44 { 45 base = p; 46 saw_slash = false; 47 } 48 } 49 50 return (char *) base; 51 } 52 53 /* Return the length of the basename NAME. Typically NAME is the 54 value returned by base_name or last_component. Act like strlen 55 (NAME), except omit all trailing slashes. */ 56 57 size_t base_len(char const * name)58base_len (char const *name) 59 { 60 size_t len; 61 size_t prefix_len = FILE_SYSTEM_PREFIX_LEN (name); 62 63 for (len = strlen (name); 1 < len && ISSLASH (name[len - 1]); len--) 64 continue; 65 66 if (DOUBLE_SLASH_IS_DISTINCT_ROOT && len == 1 67 && ISSLASH (name[0]) && ISSLASH (name[1]) && ! name[2]) 68 return 2; 69 70 if (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE && prefix_len 71 && len == prefix_len && ISSLASH (name[prefix_len])) 72 return prefix_len + 1; 73 74 return len; 75 } 76