Raw
1 #define USE_THE_REPOSITORY_VARIABLE
2
3 #include "../../git-compat-util.h"
4 #include "../../environment.h"
5
6 int win32_has_dos_drive_prefix(const char *path)
7 {
8 int i;
9
10 /*
11 * Does it start with an ASCII letter (i.e. highest bit not set),
12 * followed by a colon?
13 */
14 if (!(0x80 & (unsigned char)*path))
15 return *path && path[1] == ':' ? 2 : 0;
16
17 /*
18 * While drive letters must be letters of the English alphabet, it is
19 * possible to assign virtually _any_ Unicode character via `subst` as
20 * a drive letter to "virtual drives". Even `1`, or `ä`. Or fun stuff
21 * like this:
22 *
23 * subst ֍: %USERPROFILE%\Desktop
24 */
25 for (i = 1; i < 4 && (0x80 & (unsigned char)path[i]); i++)
26 ; /* skip first UTF-8 character */
27 return path[i] == ':' ? i + 1 : 0;
28 }
29
30 int win32_skip_dos_drive_prefix(char **path)
31 {
32 int ret = has_dos_drive_prefix(*path);
33 *path += ret;
34 return ret;
35 }
36
37 int win32_offset_1st_component(const char *path)
38 {
39 char *pos = (char *)path;
40
41 /* unc paths */
42 if (!skip_dos_drive_prefix(&pos) &&
43 is_dir_sep(pos[0]) && is_dir_sep(pos[1])) {
44 /* skip server name */
45 pos = strpbrk(pos + 2, "\\/");
46 if (!pos)
47 return 0; /* Error: malformed unc path */
48
49 do {
50 pos++;
51 } while (*pos && !is_dir_sep(*pos));
52 }
53
54 return pos + is_dir_sep(*pos) - path;
55 }
56
57 int win32_fspathncmp(const char *a, const char *b, size_t count)
58 {
59 int diff;
60
61 for (;;) {
62 if (!count--)
63 return 0;
64 if (!*a)
65 return *b ? -1 : 0;
66 if (!*b)
67 return +1;
68
69 if (is_dir_sep(*a)) {
70 if (!is_dir_sep(*b))
71 return -1;
72 a++;
73 b++;
74 continue;
75 } else if (is_dir_sep(*b))
76 return +1;
77
78 diff = ignore_case ?
79 (unsigned char)tolower(*a) - (int)(unsigned char)tolower(*b) :
80 (unsigned char)*a - (int)(unsigned char)*b;
81 if (diff)
82 return diff;
83 a++;
84 b++;
85 }
86 }
87
88 int win32_fspathcmp(const char *a, const char *b)
89 {
90 return win32_fspathncmp(a, b, (size_t)-1);
91 }