VirtualBox

source: kBuild/trunk/src/kmk/w32/pathstuff.c@ 2591

Last change on this file since 2591 was 2591, checked in by bird, 13 years ago

kmk: Merged in changes from GNU make 3.82. Previous GNU make base version was gnumake-2008-10-28-CVS.

  • Property svn:eol-style set to native
File size: 9.6 KB
Line 
1/* Path conversion for Windows pathnames.
2Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
32007, 2008, 2009, 2010 Free Software Foundation, Inc.
4This file is part of GNU Make.
5
6GNU Make is free software; you can redistribute it and/or modify it under the
7terms of the GNU General Public License as published by the Free Software
8Foundation; either version 3 of the License, or (at your option) any later
9version.
10
11GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13A PARTICULAR PURPOSE. See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License along with
16this program. If not, see <http://www.gnu.org/licenses/>. */
17
18#include <Windows.h> /* bird */
19#include "make.h"
20#include <string.h>
21#include <stdlib.h>
22#include "pathstuff.h"
23
24/*
25 * Convert delimiter separated vpath to Canonical format.
26 */
27char *
28convert_vpath_to_windows32(char *Path, char to_delim)
29{
30 char *etok; /* token separator for old Path */
31
32 /*
33 * Convert all spaces to delimiters. Note that pathnames which
34 * contain blanks get trounced here. Use 8.3 format as a workaround.
35 */
36 for (etok = Path; etok && *etok; etok++)
37 if (isblank ((unsigned char) *etok))
38 *etok = to_delim;
39
40 return (convert_Path_to_windows32(Path, to_delim));
41}
42
43/*
44 * Convert delimiter separated path to Canonical format.
45 */
46char *
47convert_Path_to_windows32(char *Path, char to_delim)
48{
49 char *etok; /* token separator for old Path */
50 char *p; /* points to element of old Path */
51
52 /* is this a multi-element Path ? */
53 /* FIXME: Perhaps use ":;\"" in strpbrk to convert all quotes to
54 delimiters as well, as a way to handle quoted directories in
55 PATH? */
56 for (p = Path, etok = strpbrk(p, ":;");
57 etok;
58 etok = strpbrk(p, ":;"))
59 if ((etok - p) == 1) {
60 if (*(etok - 1) == ';' ||
61 *(etok - 1) == ':') {
62 etok[-1] = to_delim;
63 etok[0] = to_delim;
64 p = ++etok;
65 continue; /* ignore empty bucket */
66 } else if (!isalpha ((unsigned char) *p)) {
67 /* found one to count, handle things like '.' */
68 *etok = to_delim;
69 p = ++etok;
70 } else if ((*etok == ':') && (etok = strpbrk(etok+1, ":;"))) {
71 /* found one to count, handle drive letter */
72 *etok = to_delim;
73 p = ++etok;
74 } else
75 /* all finished, force abort */
76 p += strlen(p);
77 } else if (*p == '"') { /* a quoted directory */
78 for (p++; *p && *p != '"'; p++) /* skip quoted part */
79 ;
80 etok = strpbrk(p, ":;"); /* find next delimiter */
81 if (etok) {
82 *etok = to_delim;
83 p = ++etok;
84 } else
85 p += strlen(p);
86 } else {
87 /* found another one, no drive letter */
88 *etok = to_delim;
89 p = ++etok;
90 }
91
92 return Path;
93}
94
95#if 1 /* bird */
96extern void nt_fullpath(const char *pszPath, char *pszFull, size_t cchFull);
97#endif
98
99/*
100 * Convert to forward slashes. Resolve to full pathname optionally
101 */
102char *
103w32ify(const char *filename, int resolve)
104{
105 static char w32_path[FILENAME_MAX];
106 char *p;
107
108#if 1 /* bird */
109 if (resolve) {
110 nt_fullpath(filename, w32_path, sizeof(w32_path));
111 } else {
112 w32_path[0] = '\0';
113 strncat(w32_path, filename, sizeof(w32_path));
114 }
115#else /* !bird */
116 if (resolve) {
117 _fullpath(w32_path, filename, sizeof (w32_path));
118 } else
119 strncpy(w32_path, filename, sizeof (w32_path));
120#endif /* !bird */
121
122 for (p = w32_path; p && *p; p++)
123 if (*p == '\\')
124 *p = '/';
125
126 return w32_path;
127}
128
129char *
130getcwd_fs(char* buf, int len)
131{
132 char *p = getcwd(buf, len);
133
134 if (p) {
135 char *q = w32ify(buf, 0);
136#if 1 /* bird */
137 buf[0] = '\0';
138 strncat(buf, q, len);
139#else /* !bird */
140 strncpy(buf, q, len);
141#endif /* !bird */
142 }
143
144 return p;
145}
146
147#undef stat
148/*
149 * Workaround for directory names with trailing slashes.
150 * Added by bird reasons stated.
151 */
152int
153my_stat(const char *path, struct stat *st)
154{
155 int rc = stat(path, st);
156 if ( rc != 0
157 && errno == ENOENT
158 && *path != '\0')
159 {
160 char *slash = strchr(path, '\0') - 1;
161 if (*slash == '/' || *slash == '\\')
162 {
163 size_t len_path = slash - path + 1;
164 char *tmp = alloca(len_path + 4);
165 memcpy(tmp, path, len_path);
166 tmp[len_path] = '.';
167 tmp[len_path + 1] = '\0';
168 errno = 0;
169 rc = stat(tmp, st);
170 if ( rc == 0
171 && !S_ISDIR(st->st_mode))
172 {
173 errno = ENOTDIR;
174 rc = -1;
175 }
176 }
177 }
178#ifdef KMK_PRF
179 {
180 int err = errno;
181 fprintf(stderr, "stat(%s,) -> %d/%d\n", path, rc, errno);
182 errno = err;
183 }
184#endif
185 return rc;
186}
187
188#ifdef unused
189/*
190 * Convert delimiter separated pathnames (e.g. PATH) or single file pathname
191 * (e.g. c:/foo, c:\bar) to NutC format. If we are handed a string that
192 * _NutPathToNutc() fails to convert, just return the path we were handed
193 * and assume the caller will know what to do with it (It was probably
194 * a mistake to try and convert it anyway due to some of the bizarre things
195 * that might look like pathnames in makefiles).
196 */
197char *
198convert_path_to_nutc(char *path)
199{
200 int count; /* count of path elements */
201 char *nutc_path; /* new NutC path */
202 int nutc_path_len; /* length of buffer to allocate for new path */
203 char *pathp; /* pointer to nutc_path used to build it */
204 char *etok; /* token separator for old path */
205 char *p; /* points to element of old path */
206 char sep; /* what flavor of separator used in old path */
207 char *rval;
208
209 /* is this a multi-element path ? */
210 for (p = path, etok = strpbrk(p, ":;"), count = 0;
211 etok;
212 etok = strpbrk(p, ":;"))
213 if ((etok - p) == 1) {
214 if (*(etok - 1) == ';' ||
215 *(etok - 1) == ':') {
216 p = ++etok;
217 continue; /* ignore empty bucket */
218 } else if (etok = strpbrk(etok+1, ":;"))
219 /* found one to count, handle drive letter */
220 p = ++etok, count++;
221 else
222 /* all finished, force abort */
223 p += strlen(p);
224 } else
225 /* found another one, no drive letter */
226 p = ++etok, count++;
227
228 if (count) {
229 count++; /* x1;x2;x3 <- need to count x3 */
230
231 /*
232 * Hazard a guess on how big the buffer needs to be.
233 * We have to convert things like c:/foo to /c=/foo.
234 */
235 nutc_path_len = strlen(path) + (count*2) + 1;
236 nutc_path = xmalloc(nutc_path_len);
237 pathp = nutc_path;
238 *pathp = '\0';
239
240 /*
241 * Loop through PATH and convert one elemnt of the path at at
242 * a time. Single file pathnames will fail this and fall
243 * to the logic below loop.
244 */
245 for (p = path, etok = strpbrk(p, ":;");
246 etok;
247 etok = strpbrk(p, ":;")) {
248
249 /* don't trip up on device specifiers or empty path slots */
250 if ((etok - p) == 1)
251 if (*(etok - 1) == ';' ||
252 *(etok - 1) == ':') {
253 p = ++etok;
254 continue;
255 } else if ((etok = strpbrk(etok+1, ":;")) == NULL)
256 break; /* thing found was a WINDOWS32 pathname */
257
258 /* save separator */
259 sep = *etok;
260
261 /* terminate the current path element -- temporarily */
262 *etok = '\0';
263
264#ifdef __NUTC__
265 /* convert to NutC format */
266 if (_NutPathToNutc(p, pathp, 0) == FALSE) {
267 free(nutc_path);
268 rval = savestring(path, strlen(path));
269 return rval;
270 }
271#else
272 *pathp++ = '/';
273 *pathp++ = p[0];
274 *pathp++ = '=';
275 *pathp++ = '/';
276 strcpy(pathp, &p[2]);
277#endif
278
279 pathp += strlen(pathp);
280 *pathp++ = ':'; /* use Unix style path separtor for new path */
281 *pathp = '\0'; /* make sure we are null terminaed */
282
283 /* restore path separator */
284 *etok = sep;
285
286 /* point p to first char of next path element */
287 p = ++etok;
288
289 }
290 } else {
291 nutc_path_len = strlen(path) + 3;
292 nutc_path = xmalloc(nutc_path_len);
293 pathp = nutc_path;
294 *pathp = '\0';
295 p = path;
296 }
297
298 /*
299 * OK, here we handle the last element in PATH (e.g. c of a;b;c)
300 * or the path was a single filename and will be converted
301 * here. Note, testing p here assures that we don't trip up
302 * on paths like a;b; which have trailing delimiter followed by
303 * nothing.
304 */
305 if (*p != '\0') {
306#ifdef __NUTC__
307 if (_NutPathToNutc(p, pathp, 0) == FALSE) {
308 free(nutc_path);
309 rval = savestring(path, strlen(path));
310 return rval;
311 }
312#else
313 *pathp++ = '/';
314 *pathp++ = p[0];
315 *pathp++ = '=';
316 *pathp++ = '/';
317 strcpy(pathp, &p[2]);
318#endif
319 } else
320 *(pathp-1) = '\0'; /* we're already done, don't leave trailing : */
321
322 rval = savestring(nutc_path, strlen(nutc_path));
323 free(nutc_path);
324 return rval;
325}
326
327#endif
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette