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