Imported Upstream version 0.19.7
[platform/upstream/gettext.git] / gettext-tools / libgettextpo / basename.c
1 /* Return the name-within-directory of a file name.
2    Copyright (C) 1996-2002, 2004, 2006, 2010, 2012, 2015 Free Software
3    Foundation, Inc.
4
5    NOTE: The canonical source of this file is maintained with the GNU C Library.
6    Bugs can be reported to bug-glibc@gnu.org.
7
8    This program is free software: you can redistribute it and/or modify it
9    under the terms of the GNU General Public License as published by the
10    Free Software Foundation; either version 3 of the License, or any
11    later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20
21 #include <config.h>
22
23 /* Specification.  */
24 #include "basename.h"
25
26 #if !(__GLIBC__ >= 2 || defined __UCLIBC__)
27
28 #include <stdio.h>
29 #include <assert.h>
30
31 #if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__
32   /* Win32, Cygwin, OS/2, DOS */
33 # define HAS_DEVICE(P) \
34     ((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) \
35      && (P)[1] == ':')
36 # define FILE_SYSTEM_PREFIX_LEN(P) (HAS_DEVICE (P) ? 2 : 0)
37 # define ISSLASH(C) ((C) == '/' || (C) == '\\')
38 #endif
39
40 #ifndef FILE_SYSTEM_PREFIX_LEN
41 # define FILE_SYSTEM_PREFIX_LEN(Filename) 0
42 #endif
43
44 #ifndef ISSLASH
45 # define ISSLASH(C) ((C) == '/')
46 #endif
47
48 #ifndef _LIBC
49 /* We cannot generally use the name 'basename' since XPG defines an unusable
50    variant of the function but we cannot use it.  */
51 # undef basename
52 # define basename gnu_basename
53 #endif
54
55 /* In general, we can't use the builtin 'basename' function if available,
56    since it has different meanings in different environments.
57    In some environments the builtin 'basename' modifies its argument.
58    If NAME is all slashes, be sure to return '/'.  */
59
60 char *
61 basename (char const *name)
62 {
63   char const *base = name += FILE_SYSTEM_PREFIX_LEN (name);
64   int all_slashes = 1;
65   char const *p;
66
67   for (p = name; *p; p++)
68     {
69       if (ISSLASH (*p))
70         base = p + 1;
71       else
72         all_slashes = 0;
73     }
74
75   /* If NAME is all slashes, arrange to return '/'.  */
76   if (*base == '\0' && ISSLASH (*name) && all_slashes)
77     --base;
78
79   /* Make sure the last byte is not a slash.  */
80   assert (all_slashes || !ISSLASH (*(p - 1)));
81
82   return (char *) base;
83 }
84
85 #endif