195b7b453SJohn Marino /* basename.c -- return the last element in a file name 295b7b453SJohn Marino 3*09d4459fSDaniel Fojt Copyright (C) 1990, 1998-2001, 2003-2006, 2009-2020 Free Software 495b7b453SJohn Marino Foundation, Inc. 595b7b453SJohn Marino 695b7b453SJohn Marino This program is free software: you can redistribute it and/or modify 795b7b453SJohn Marino it under the terms of the GNU General Public License as published by 895b7b453SJohn Marino the Free Software Foundation; either version 3 of the License, or 995b7b453SJohn Marino (at your option) any later version. 1095b7b453SJohn Marino 1195b7b453SJohn Marino This program is distributed in the hope that it will be useful, 1295b7b453SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of 1395b7b453SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1495b7b453SJohn Marino GNU General Public License for more details. 1595b7b453SJohn Marino 1695b7b453SJohn Marino You should have received a copy of the GNU General Public License 17*09d4459fSDaniel Fojt along with this program. If not, see <https://www.gnu.org/licenses/>. */ 1895b7b453SJohn Marino 1995b7b453SJohn Marino #include <config.h> 2095b7b453SJohn Marino 2195b7b453SJohn Marino #include "dirname.h" 2295b7b453SJohn Marino 2395b7b453SJohn Marino #include <string.h> 2495b7b453SJohn Marino 2595b7b453SJohn Marino /* Return the address of the last file name component of NAME. If 2695b7b453SJohn Marino NAME has no relative file name components because it is a file 2795b7b453SJohn Marino system root, return the empty string. */ 2895b7b453SJohn Marino 2995b7b453SJohn Marino char * last_component(char const * name)3095b7b453SJohn Marinolast_component (char const *name) 3195b7b453SJohn Marino { 3295b7b453SJohn Marino char const *base = name + FILE_SYSTEM_PREFIX_LEN (name); 3395b7b453SJohn Marino char const *p; 3495b7b453SJohn Marino bool saw_slash = false; 3595b7b453SJohn Marino 3695b7b453SJohn Marino while (ISSLASH (*base)) 3795b7b453SJohn Marino base++; 3895b7b453SJohn Marino 3995b7b453SJohn Marino for (p = base; *p; p++) 4095b7b453SJohn Marino { 4195b7b453SJohn Marino if (ISSLASH (*p)) 4295b7b453SJohn Marino saw_slash = true; 4395b7b453SJohn Marino else if (saw_slash) 4495b7b453SJohn Marino { 4595b7b453SJohn Marino base = p; 4695b7b453SJohn Marino saw_slash = false; 4795b7b453SJohn Marino } 4895b7b453SJohn Marino } 4995b7b453SJohn Marino 5095b7b453SJohn Marino return (char *) base; 5195b7b453SJohn Marino } 5295b7b453SJohn Marino 5395b7b453SJohn Marino /* Return the length of the basename NAME. Typically NAME is the 5495b7b453SJohn Marino value returned by base_name or last_component. Act like strlen 5595b7b453SJohn Marino (NAME), except omit all trailing slashes. */ 5695b7b453SJohn Marino 5795b7b453SJohn Marino size_t base_len(char const * name)5895b7b453SJohn Marinobase_len (char const *name) 5995b7b453SJohn Marino { 6095b7b453SJohn Marino size_t len; 6195b7b453SJohn Marino size_t prefix_len = FILE_SYSTEM_PREFIX_LEN (name); 6295b7b453SJohn Marino 6395b7b453SJohn Marino for (len = strlen (name); 1 < len && ISSLASH (name[len - 1]); len--) 6495b7b453SJohn Marino continue; 6595b7b453SJohn Marino 6695b7b453SJohn Marino if (DOUBLE_SLASH_IS_DISTINCT_ROOT && len == 1 6795b7b453SJohn Marino && ISSLASH (name[0]) && ISSLASH (name[1]) && ! name[2]) 6895b7b453SJohn Marino return 2; 6995b7b453SJohn Marino 7095b7b453SJohn Marino if (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE && prefix_len 7195b7b453SJohn Marino && len == prefix_len && ISSLASH (name[prefix_len])) 7295b7b453SJohn Marino return prefix_len + 1; 7395b7b453SJohn Marino 7495b7b453SJohn Marino return len; 7595b7b453SJohn Marino } 76