Skip to content

Commit 193eda7

Browse files
dschogitster
authored andcommitted
win32: override fspathcmp() with a directory separator-aware version
On Windows, the backslash is the directory separator, even if the forward slash can be used, too, at least since Windows NT. This means that the paths `a/b` and `a\b` are equivalent, and `fspathcmp()` needs to be made aware of that fact. Note that we have to override both `fspathcmp()` and `fspathncmp()`, and the former cannot be a mere pre-processor constant that transforms calls to `fspathcmp(a, b)` into `fspathncmp(a, b, (size_t)-1)` because the function `report_collided_checkout()` in `unpack-trees.c` wants to assign `list.cmp = fspathcmp`. Also note that `fspatheq()` does _not_ need to be overridden because it calls `fspathcmp()` internally. Signed-off-by: Johannes Schindelin <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent ce68178 commit 193eda7

File tree

5 files changed

+53
-4
lines changed

5 files changed

+53
-4
lines changed

compat/win32/path-utils.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "../../git-compat-util.h"
2+
#include "../../environment.h"
23

34
int win32_has_dos_drive_prefix(const char *path)
45
{
@@ -50,3 +51,39 @@ int win32_offset_1st_component(const char *path)
5051

5152
return pos + is_dir_sep(*pos) - path;
5253
}
54+
55+
int win32_fspathncmp(const char *a, const char *b, size_t count)
56+
{
57+
int diff;
58+
59+
for (;;) {
60+
if (!count--)
61+
return 0;
62+
if (!*a)
63+
return *b ? -1 : 0;
64+
if (!*b)
65+
return +1;
66+
67+
if (is_dir_sep(*a)) {
68+
if (!is_dir_sep(*b))
69+
return -1;
70+
a++;
71+
b++;
72+
continue;
73+
} else if (is_dir_sep(*b))
74+
return +1;
75+
76+
diff = ignore_case ?
77+
(unsigned char)tolower(*a) - (int)(unsigned char)tolower(*b) :
78+
(unsigned char)*a - (int)(unsigned char)*b;
79+
if (diff)
80+
return diff;
81+
a++;
82+
b++;
83+
}
84+
}
85+
86+
int win32_fspathcmp(const char *a, const char *b)
87+
{
88+
return win32_fspathncmp(a, b, (size_t)-1);
89+
}

compat/win32/path-utils.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,9 @@ static inline int win32_has_dir_sep(const char *path)
2929
#define has_dir_sep(path) win32_has_dir_sep(path)
3030
int win32_offset_1st_component(const char *path);
3131
#define offset_1st_component win32_offset_1st_component
32+
int win32_fspathcmp(const char *a, const char *b);
33+
#define fspathcmp win32_fspathcmp
34+
int win32_fspathncmp(const char *a, const char *b, size_t count);
35+
#define fspathncmp win32_fspathncmp
3236

3337
#endif

dir.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ int count_slashes(const char *s)
9595
return cnt;
9696
}
9797

98-
int fspathcmp(const char *a, const char *b)
98+
int git_fspathcmp(const char *a, const char *b)
9999
{
100100
return ignore_case ? strcasecmp(a, b) : strcmp(a, b);
101101
}
@@ -105,7 +105,7 @@ int fspatheq(const char *a, const char *b)
105105
return !fspathcmp(a, b);
106106
}
107107

108-
int fspathncmp(const char *a, const char *b, size_t count)
108+
int git_fspathncmp(const char *a, const char *b, size_t count)
109109
{
110110
return ignore_case ? strncasecmp(a, b, count) : strncmp(a, b, count);
111111
}

dir.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -541,9 +541,9 @@ int remove_dir_recursively(struct strbuf *path, int flag);
541541
*/
542542
int remove_path(const char *path);
543543

544-
int fspathcmp(const char *a, const char *b);
544+
int git_fspathcmp(const char *a, const char *b);
545545
int fspatheq(const char *a, const char *b);
546-
int fspathncmp(const char *a, const char *b, size_t count);
546+
int git_fspathncmp(const char *a, const char *b, size_t count);
547547
unsigned int fspathhash(const char *str);
548548

549549
/*

git-compat-util.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,14 @@ static inline int git_offset_1st_component(const char *path)
506506
#define offset_1st_component git_offset_1st_component
507507
#endif
508508

509+
#ifndef fspathcmp
510+
#define fspathcmp git_fspathcmp
511+
#endif
512+
513+
#ifndef fspathncmp
514+
#define fspathncmp git_fspathncmp
515+
#endif
516+
509517
#ifndef is_valid_path
510518
#define is_valid_path(path) 1
511519
#endif

0 commit comments

Comments
 (0)