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 <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:

committed by
Junio C Hamano

parent
ce68178a0a
commit
193eda7507
@ -1,4 +1,5 @@
|
|||||||
#include "../../git-compat-util.h"
|
#include "../../git-compat-util.h"
|
||||||
|
#include "../../environment.h"
|
||||||
|
|
||||||
int win32_has_dos_drive_prefix(const char *path)
|
int win32_has_dos_drive_prefix(const char *path)
|
||||||
{
|
{
|
||||||
@ -50,3 +51,39 @@ int win32_offset_1st_component(const char *path)
|
|||||||
|
|
||||||
return pos + is_dir_sep(*pos) - path;
|
return pos + is_dir_sep(*pos) - path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int win32_fspathncmp(const char *a, const char *b, size_t count)
|
||||||
|
{
|
||||||
|
int diff;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
if (!count--)
|
||||||
|
return 0;
|
||||||
|
if (!*a)
|
||||||
|
return *b ? -1 : 0;
|
||||||
|
if (!*b)
|
||||||
|
return +1;
|
||||||
|
|
||||||
|
if (is_dir_sep(*a)) {
|
||||||
|
if (!is_dir_sep(*b))
|
||||||
|
return -1;
|
||||||
|
a++;
|
||||||
|
b++;
|
||||||
|
continue;
|
||||||
|
} else if (is_dir_sep(*b))
|
||||||
|
return +1;
|
||||||
|
|
||||||
|
diff = ignore_case ?
|
||||||
|
(unsigned char)tolower(*a) - (int)(unsigned char)tolower(*b) :
|
||||||
|
(unsigned char)*a - (int)(unsigned char)*b;
|
||||||
|
if (diff)
|
||||||
|
return diff;
|
||||||
|
a++;
|
||||||
|
b++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int win32_fspathcmp(const char *a, const char *b)
|
||||||
|
{
|
||||||
|
return win32_fspathncmp(a, b, (size_t)-1);
|
||||||
|
}
|
||||||
|
@ -29,5 +29,9 @@ static inline int win32_has_dir_sep(const char *path)
|
|||||||
#define has_dir_sep(path) win32_has_dir_sep(path)
|
#define has_dir_sep(path) win32_has_dir_sep(path)
|
||||||
int win32_offset_1st_component(const char *path);
|
int win32_offset_1st_component(const char *path);
|
||||||
#define offset_1st_component win32_offset_1st_component
|
#define offset_1st_component win32_offset_1st_component
|
||||||
|
int win32_fspathcmp(const char *a, const char *b);
|
||||||
|
#define fspathcmp win32_fspathcmp
|
||||||
|
int win32_fspathncmp(const char *a, const char *b, size_t count);
|
||||||
|
#define fspathncmp win32_fspathncmp
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
4
dir.c
4
dir.c
@ -95,7 +95,7 @@ int count_slashes(const char *s)
|
|||||||
return cnt;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fspathcmp(const char *a, const char *b)
|
int git_fspathcmp(const char *a, const char *b)
|
||||||
{
|
{
|
||||||
return ignore_case ? strcasecmp(a, b) : strcmp(a, b);
|
return ignore_case ? strcasecmp(a, b) : strcmp(a, b);
|
||||||
}
|
}
|
||||||
@ -105,7 +105,7 @@ int fspatheq(const char *a, const char *b)
|
|||||||
return !fspathcmp(a, b);
|
return !fspathcmp(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
int fspathncmp(const char *a, const char *b, size_t count)
|
int git_fspathncmp(const char *a, const char *b, size_t count)
|
||||||
{
|
{
|
||||||
return ignore_case ? strncasecmp(a, b, count) : strncmp(a, b, count);
|
return ignore_case ? strncasecmp(a, b, count) : strncmp(a, b, count);
|
||||||
}
|
}
|
||||||
|
4
dir.h
4
dir.h
@ -541,9 +541,9 @@ int remove_dir_recursively(struct strbuf *path, int flag);
|
|||||||
*/
|
*/
|
||||||
int remove_path(const char *path);
|
int remove_path(const char *path);
|
||||||
|
|
||||||
int fspathcmp(const char *a, const char *b);
|
int git_fspathcmp(const char *a, const char *b);
|
||||||
int fspatheq(const char *a, const char *b);
|
int fspatheq(const char *a, const char *b);
|
||||||
int fspathncmp(const char *a, const char *b, size_t count);
|
int git_fspathncmp(const char *a, const char *b, size_t count);
|
||||||
unsigned int fspathhash(const char *str);
|
unsigned int fspathhash(const char *str);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -506,6 +506,14 @@ static inline int git_offset_1st_component(const char *path)
|
|||||||
#define offset_1st_component git_offset_1st_component
|
#define offset_1st_component git_offset_1st_component
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef fspathcmp
|
||||||
|
#define fspathcmp git_fspathcmp
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef fspathncmp
|
||||||
|
#define fspathncmp git_fspathncmp
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef is_valid_path
|
#ifndef is_valid_path
|
||||||
#define is_valid_path(path) 1
|
#define is_valid_path(path) 1
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user