dvitomp fix from Akira
[mplib] / src / texk / kpathsea / xdirname.c
1 /* xdirname.c: return the directory part of a path.
2
3    Copyright 1999, 2008 Karl Berry.
4    Copyright 2005 Olaf Weber.
5
6    This library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
10
11    This library 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 GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public License
17    along with this library; if not, see <http://www.gnu.org/licenses/>.  */
18
19 /* Return directory for NAME.  This is "." if NAME contains no directory
20    separators (should never happen for selfdir), else whatever precedes
21    the final directory separator, but with multiple separators stripped.
22    For example, `xdirname ("/foo//bar.baz")' returns "/foo".  Always
23    return a new string.  */
24
25 #include <kpathsea/config.h>
26 #include <kpathsea/c-pathch.h>
27
28 string
29 xdirname P1C(const_string, name)
30 {
31     string ret;
32     unsigned limit = 0, loc;
33     
34     /* Ignore a NULL name. */
35     if (!name)
36         return NULL;
37     
38     if (NAME_BEGINS_WITH_DEVICE(name)) {
39         limit = 2;
40 #if defined(WIN32) || defined(__CYGWIN__)
41     } else if (IS_UNC_NAME(name)) {
42         for (limit = 2; name[limit] && !IS_DIR_SEP(name[limit]); limit++)
43             ;
44         if (name[limit]) {
45             for (limit++ ; name[limit] && !IS_DIR_SEP(name[limit]); limit++)
46                 ;
47             limit--;
48         } else {
49             /* malformed UNC name, backup */
50             limit = 2;
51         }
52 #endif
53     }
54     
55     for (loc = strlen (name); loc > limit && !IS_DIR_SEP (name[loc-1]); loc--)
56         ;
57     
58     if (loc == limit && limit > 0) {
59         if (limit == 2) {
60             ret = (string)xmalloc(limit + 2);
61             ret[0] = name[0];
62             ret[1] = name[1];
63             ret[2] = '.';
64             ret[3] = '\0';
65         } else {
66             ret = (string)xmalloc(limit + 2);
67             strcpy(ret, name);
68         }
69     } else {
70         /* If have ///a, must return /, so don't strip off everything.  */
71         while (loc > limit+1 && IS_DIR_SEP (name[loc-1])) {
72             loc--;
73         }
74         ret = (string)xmalloc(loc+1);
75         strncpy(ret, name, loc);
76         ret[loc] = '\0';
77     }
78     
79     return ret;
80 }
81 \f
82 #ifdef TEST
83
84 char *tab[] = {
85     "\\\\neuromancer\\fptex\\bin\\win32\\kpsewhich.exe",
86     "\\\\neuromancer\\fptex\\win32\\kpsewhich.exe",
87     "\\\\neuromancer\\fptex\\kpsewhich.exe",
88     "\\\\neuromancer\\kpsewhich.exe",
89     "p:\\bin\\win32\\kpsewhich.exe",
90     "p:\\win32\\kpsewhich.exe",
91     "p:\\kpsewhich.exe",
92     "p:bin\\win32\\kpsewhich.exe",
93     "p:win32\\kpsewhich.exe",
94     "p:kpsewhich.exe",
95     "p:///kpsewhich.exe",
96     "/usr/bin/win32/kpsewhich.exe",
97     "/usr/bin/kpsewhich.exe",
98     "/usr/kpsewhich.exe",
99     "///usr/kpsewhich.exe",
100     "///kpsewhich.exe",
101     NULL 
102 };
103
104 int main()
105 {
106     char **p;
107     for (p = tab; *p; p++)
108         printf("name %s, dirname %s\n", *p, xdirname(*p));
109     return 0;
110 }
111 #endif /* TEST */
112
113
114 /*
115 Local variables:
116 standalone-compile-command: "gcc -g -I. -I.. -DTEST variable.c kpathsea.a"
117 End:
118 */
119