source: trunk/src/kmk/w32/pathstuff.c@ 3060

Last change on this file since 3060 was 3060, checked in by bird, 8 years ago

kmk,lib: ported kmk_touch to windows (nt).

  • Property svn:eol-style set to native
File size: 8.5 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 "make.h"
19#include <string.h>
20#include <stdlib.h>
21#include "pathstuff.h"
22#if 1 /* bird */
23# include "nt_fullpath.h"
24#endif
25
26/*
27 * Convert delimiter separated vpath to Canonical format.
28 */
29char *
30convert_vpath_to_windows32(char *Path, char to_delim)
31{
32 char *etok; /* token separator for old Path */
33
34 /*
35 * Convert all spaces to delimiters. Note that pathnames which
36 * contain blanks get trounced here. Use 8.3 format as a workaround.
37 */
38 for (etok = Path; etok && *etok; etok++)
39 if (isblank ((unsigned char) *etok))
40 *etok = to_delim;
41
42 return (convert_Path_to_windows32(Path, to_delim));
43}
44
45/*
46 * Convert delimiter separated path to Canonical format.
47 */
48char *
49convert_Path_to_windows32(char *Path, char to_delim)
50{
51 char *etok; /* token separator for old Path */
52 char *p; /* points to element of old Path */
53
54 /* is this a multi-element Path ? */
55 /* FIXME: Perhaps use ":;\"" in strpbrk to convert all quotes to
56 delimiters as well, as a way to handle quoted directories in
57 PATH? */
58 for (p = Path, etok = strpbrk(p, ":;");
59 etok;
60 etok = strpbrk(p, ":;"))
61 if ((etok - p) == 1) {
62 if (*(etok - 1) == ';' ||
63 *(etok - 1) == ':') {
64 etok[-1] = to_delim;
65 etok[0] = to_delim;
66 p = ++etok;
67 continue; /* ignore empty bucket */
68 } else if (!isalpha ((unsigned char) *p)) {
69 /* found one to count, handle things like '.' */
70 *etok = to_delim;
71 p = ++etok;
72 } else if ((*etok == ':') && (etok = strpbrk(etok+1, ":;"))) {
73 /* found one to count, handle drive letter */
74 *etok = to_delim;
75 p = ++etok;
76 } else
77 /* all finished, force abort */
78 p += strlen(p);
79 } else if (*p == '"') { /* a quoted directory */
80 for (p++; *p && *p != '"'; p++) /* skip quoted part */
81 ;
82 etok = strpbrk(p, ":;"); /* find next delimiter */
83 if (etok) {
84 *etok = to_delim;
85 p = ++etok;
86 } else
87 p += strlen(p);
88 } else {
89 /* found another one, no drive letter */
90 *etok = to_delim;
91 p = ++etok;
92 }
93
94 return Path;
95}
96
97/*
98 * Convert to forward slashes. Resolve to full pathname optionally
99 */
100char *
101w32ify(const char *filename, int resolve)
102{
103 static char w32_path[FILENAME_MAX];
104 char *p;
105
106#if 1 /* bird */
107 if (resolve) {
108 nt_fullpath_cached(filename, w32_path, sizeof(w32_path));
109 } else {
110 w32_path[0] = '\0';
111 strncat(w32_path, filename, sizeof(w32_path));
112 }
113#else /* !bird */
114 if (resolve) {
115 _fullpath(w32_path, filename, sizeof (w32_path));
116 } else
117 strncpy(w32_path, filename, sizeof (w32_path));
118#endif /* !bird */
119
120 for (p = w32_path; p && *p; p++)
121 if (*p == '\\')
122 *p = '/';
123
124 return w32_path;
125}
126
127char *
128getcwd_fs(char* buf, int len)
129{
130 char *p = getcwd(buf, len);
131
132 if (p) {
133 char *q = w32ify(buf, 0);
134#if 1 /* bird */
135 buf[0] = '\0';
136 strncat(buf, q, len);
137#else /* !bird */
138 strncpy(buf, q, len);
139#endif /* !bird */
140 }
141
142 return p;
143}
144
145#ifdef unused
146/*
147 * Convert delimiter separated pathnames (e.g. PATH) or single file pathname
148 * (e.g. c:/foo, c:\bar) to NutC format. If we are handed a string that
149 * _NutPathToNutc() fails to convert, just return the path we were handed
150 * and assume the caller will know what to do with it (It was probably
151 * a mistake to try and convert it anyway due to some of the bizarre things
152 * that might look like pathnames in makefiles).
153 */
154char *
155convert_path_to_nutc(char *path)
156{
157 int count; /* count of path elements */
158 char *nutc_path; /* new NutC path */
159 int nutc_path_len; /* length of buffer to allocate for new path */
160 char *pathp; /* pointer to nutc_path used to build it */
161 char *etok; /* token separator for old path */
162 char *p; /* points to element of old path */
163 char sep; /* what flavor of separator used in old path */
164 char *rval;
165
166 /* is this a multi-element path ? */
167 for (p = path, etok = strpbrk(p, ":;"), count = 0;
168 etok;
169 etok = strpbrk(p, ":;"))
170 if ((etok - p) == 1) {
171 if (*(etok - 1) == ';' ||
172 *(etok - 1) == ':') {
173 p = ++etok;
174 continue; /* ignore empty bucket */
175 } else if (etok = strpbrk(etok+1, ":;"))
176 /* found one to count, handle drive letter */
177 p = ++etok, count++;
178 else
179 /* all finished, force abort */
180 p += strlen(p);
181 } else
182 /* found another one, no drive letter */
183 p = ++etok, count++;
184
185 if (count) {
186 count++; /* x1;x2;x3 <- need to count x3 */
187
188 /*
189 * Hazard a guess on how big the buffer needs to be.
190 * We have to convert things like c:/foo to /c=/foo.
191 */
192 nutc_path_len = strlen(path) + (count*2) + 1;
193 nutc_path = xmalloc(nutc_path_len);
194 pathp = nutc_path;
195 *pathp = '\0';
196
197 /*
198 * Loop through PATH and convert one elemnt of the path at at
199 * a time. Single file pathnames will fail this and fall
200 * to the logic below loop.
201 */
202 for (p = path, etok = strpbrk(p, ":;");
203 etok;
204 etok = strpbrk(p, ":;")) {
205
206 /* don't trip up on device specifiers or empty path slots */
207 if ((etok - p) == 1)
208 if (*(etok - 1) == ';' ||
209 *(etok - 1) == ':') {
210 p = ++etok;
211 continue;
212 } else if ((etok = strpbrk(etok+1, ":;")) == NULL)
213 break; /* thing found was a WINDOWS32 pathname */
214
215 /* save separator */
216 sep = *etok;
217
218 /* terminate the current path element -- temporarily */
219 *etok = '\0';
220
221#ifdef __NUTC__
222 /* convert to NutC format */
223 if (_NutPathToNutc(p, pathp, 0) == FALSE) {
224 free(nutc_path);
225 rval = savestring(path, strlen(path));
226 return rval;
227 }
228#else
229 *pathp++ = '/';
230 *pathp++ = p[0];
231 *pathp++ = '=';
232 *pathp++ = '/';
233 strcpy(pathp, &p[2]);
234#endif
235
236 pathp += strlen(pathp);
237 *pathp++ = ':'; /* use Unix style path separtor for new path */
238 *pathp = '\0'; /* make sure we are null terminaed */
239
240 /* restore path separator */
241 *etok = sep;
242
243 /* point p to first char of next path element */
244 p = ++etok;
245
246 }
247 } else {
248 nutc_path_len = strlen(path) + 3;
249 nutc_path = xmalloc(nutc_path_len);
250 pathp = nutc_path;
251 *pathp = '\0';
252 p = path;
253 }
254
255 /*
256 * OK, here we handle the last element in PATH (e.g. c of a;b;c)
257 * or the path was a single filename and will be converted
258 * here. Note, testing p here assures that we don't trip up
259 * on paths like a;b; which have trailing delimiter followed by
260 * nothing.
261 */
262 if (*p != '\0') {
263#ifdef __NUTC__
264 if (_NutPathToNutc(p, pathp, 0) == FALSE) {
265 free(nutc_path);
266 rval = savestring(path, strlen(path));
267 return rval;
268 }
269#else
270 *pathp++ = '/';
271 *pathp++ = p[0];
272 *pathp++ = '=';
273 *pathp++ = '/';
274 strcpy(pathp, &p[2]);
275#endif
276 } else
277 *(pathp-1) = '\0'; /* we're already done, don't leave trailing : */
278
279 rval = savestring(nutc_path, strlen(nutc_path));
280 free(nutc_path);
281 return rval;
282}
283
284#endif
Note: See TracBrowser for help on using the repository browser.