(root)/
glibc-2.38/
stdlib/
xpg_basename.c
       1  /* Return basename of given pathname according to the weird XPG specification.
       2     Copyright (C) 1997-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #include <string.h>
      20  #include <libgen.h>
      21  
      22  
      23  char *
      24  __xpg_basename (char *filename)
      25  {
      26    char *p;
      27  
      28    if (filename == NULL || filename[0] == '\0')
      29      /* We return a pointer to a static string containing ".".  */
      30      p = (char *) ".";
      31    else
      32      {
      33        p = strrchr (filename, '/');
      34  
      35        if (p == NULL)
      36  	/* There is no slash in the filename.  Return the whole string.  */
      37  	p = filename;
      38        else
      39  	{
      40  	  if (p[1] == '\0')
      41  	    {
      42  	      /* We must remove trailing '/'.  */
      43  	      while (p > filename && p[-1] == '/')
      44  		--p;
      45  
      46  	      /* Now we can be in two situations:
      47  		 a) the string only contains '/' characters, so we return
      48  		    '/'
      49  		 b) p points past the last component, but we have to remove
      50  		    the trailing slash.  */
      51  	      if (p > filename)
      52  		{
      53  		  *p-- = '\0';
      54  		  while (p > filename && p[-1] != '/')
      55  		    --p;
      56  		}
      57  	      else
      58  		/* The last slash we already found is the right position
      59  		   to return.  */
      60  		while (p[1] != '\0')
      61  		  ++p;
      62  	    }
      63  	  else
      64  	    /* Go to the first character of the name.  */
      65  	    ++p;
      66  	}
      67      }
      68  
      69    return p;
      70  }