Git fork

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>

authored by

Johannes Schindelin and committed by
Junio C Hamano
193eda75 ce68178a

+53 -4
+37
compat/win32/path-utils.c
··· 1 1 #include "../../git-compat-util.h" 2 + #include "../../environment.h" 2 3 3 4 int win32_has_dos_drive_prefix(const char *path) 4 5 { ··· 50 51 51 52 return pos + is_dir_sep(*pos) - path; 52 53 } 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 + }
+4
compat/win32/path-utils.h
··· 29 29 #define has_dir_sep(path) win32_has_dir_sep(path) 30 30 int win32_offset_1st_component(const char *path); 31 31 #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 32 36 33 37 #endif
+2 -2
dir.c
··· 95 95 return cnt; 96 96 } 97 97 98 - int fspathcmp(const char *a, const char *b) 98 + int git_fspathcmp(const char *a, const char *b) 99 99 { 100 100 return ignore_case ? strcasecmp(a, b) : strcmp(a, b); 101 101 } ··· 105 105 return !fspathcmp(a, b); 106 106 } 107 107 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) 109 109 { 110 110 return ignore_case ? strncasecmp(a, b, count) : strncmp(a, b, count); 111 111 }
+2 -2
dir.h
··· 541 541 */ 542 542 int remove_path(const char *path); 543 543 544 - int fspathcmp(const char *a, const char *b); 544 + int git_fspathcmp(const char *a, const char *b); 545 545 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); 547 547 unsigned int fspathhash(const char *str); 548 548 549 549 /*
+8
git-compat-util.h
··· 506 506 #define offset_1st_component git_offset_1st_component 507 507 #endif 508 508 509 + #ifndef fspathcmp 510 + #define fspathcmp git_fspathcmp 511 + #endif 512 + 513 + #ifndef fspathncmp 514 + #define fspathncmp git_fspathncmp 515 + #endif 516 + 509 517 #ifndef is_valid_path 510 518 #define is_valid_path(path) 1 511 519 #endif