Skip to content

Commit 19b403f

Browse files
committed
Update relpath implementation
1 parent 6bc5ad5 commit 19b403f

File tree

1 file changed

+26
-17
lines changed

1 file changed

+26
-17
lines changed

patch/depfile_build.c

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,25 @@ char *relpath(const char *cwd, const char *dst)
149149
const char *dst_p = dst;
150150
const char *cwd_p = cwd;
151151

152+
#ifndef _WIN32
153+
static const char sep = '/';
154+
static const char *sep_parent = "../";
155+
#else
156+
static const char sep = '\\';
157+
static const char *sep_parent = "..\\";
158+
// Strip drive letter if it matches
159+
#define X(x) (x[0] >= 'A' && x[0] <= 'Z' && x[1] == ':' && x[2] == sep)
160+
if (X(dst_p) && X(cwd_p) && strncmp(dst_p, cwd_p, 3) == 0) {
161+
dst_p += 2;
162+
cwd_p += 2;
163+
}
164+
#undef X
165+
#endif
166+
152167
// Strip any leading path components
153168
for (;;) {
154-
if (*dst_p != '/') break;
155-
char *c = strchr(dst_p + 1, '/');
169+
if (*dst_p != sep) break;
170+
char *c = strchr(dst_p + 1, sep);
156171
if (!c) break;
157172
int l = c - dst_p;
158173
if (strncmp(dst_p, cwd_p, l) != 0) break;
@@ -163,16 +178,16 @@ char *relpath(const char *cwd, const char *dst)
163178
int l = 0;
164179
if (strcmp(dst_p, cwd_p) == 0) {
165180
dst_p = ".";
166-
} else if (*dst_p == '/') {
167-
dst_p++; l++;
168-
while ((cwd_p = strchr(cwd_p + 1, '/'))) l++;
181+
} else if (*dst_p == sep) {
182+
dst_p++;
183+
for (; (cwd_p = strchr(cwd_p, sep)); cwd_p++) l++;
169184
}
170185

171186
// Allocate and build final string
172187
int dst_p_len = strlen(dst_p) + 1;
173188
char *dst_m = malloc(3 * l + dst_p_len);
174189
if (!dst_m) return NULL;
175-
for (int i = 0; i < l; i++) memcpy(dst_m + 3 * i, "../", 3);
190+
for (int i = 0; i < l; i++) memcpy(dst_m + 3 * i, sep_parent, 3);
176191
memcpy(dst_m + 3 * l, dst_p, dst_p_len);
177192

178193
return dst_m;
@@ -264,21 +279,15 @@ __cdecl void depfile_build(char *header_struct, char *depfile_struct, mwstring *
264279
char *cwd = getcwd(NULL, 0);
265280
if (!cwd) goto outofmem;
266281

267-
char *cwd_p = cwd;
268-
char *hdr_p = header_full;
269-
#ifdef _WIN32
270-
// Strip drive letter and convert to unix
271-
if (path_has_drv(cwd_p)) cwd_p += 2;
272-
if (path_has_drv(hdr_p)) hdr_p += 2;
273-
for (char *c = cwd_p; (c = strchr(c, '\\')); c++) *c = '/';
274-
for (char *c = hdr_p; (c = strchr(c, '\\')); c++) *c = '/';
275-
#endif
282+
fprintf(stderr, "cwd: %s\n", cwd);
283+
fprintf(stderr, "header_full: %s\n", header_full);
276284

277-
// Make relative path and truncate it
278-
char *rel = relpath(cwd_p, hdr_p);
285+
// Make relative path, truncate it, and always use forward slashes
286+
char *rel = relpath(cwd, header_full);
279287
if (!memccpy(header_full, rel, '\0', sizeof(header_full))) {
280288
header_full[sizeof(header_full) - 1] = '\0';
281289
}
290+
for (char *c = header_full; (c = strchr(c, '\\')); c++) *c = '/';
282291
free(rel);
283292
free(cwd);
284293
#endif

0 commit comments

Comments
 (0)