xref: /dflybsd-src/contrib/grep/lib/basename-lgpl.c (revision 91b9ed38d3db6a8a8ac5b66da1d43e6e331e259a)
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 Marino last_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 Marino base_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