Home | History | Annotate | Download | only in lib
      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 #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