Skip to content

Commit d8c0607

Browse files
committed
path: extract win32_path_prefix function
Extract code which determines if a path is at a Windows system's root. This incluses drive prefixes (e.g. "C:\") as well as network computer names (e.g. "//computername/").
1 parent 887c193 commit d8c0607

File tree

1 file changed

+33
-23
lines changed

1 file changed

+33
-23
lines changed

src/path.c

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -110,14 +110,42 @@ int git_path_basename_r(git_buf *buffer, const char *path)
110110
return result;
111111
}
112112

113+
/*
114+
* Determine if the path is a Windows prefix and, if so, returns
115+
* its actual lentgh. If it is not a prefix, returns -1.
116+
*/
117+
static int win32_prefix_length(const char *path, int len)
118+
{
119+
#ifndef GIT_WIN32
120+
GIT_UNUSED(path);
121+
GIT_UNUSED(len);
122+
#else
123+
/*
124+
* Mimic unix behavior where '/.git' returns '/': 'C:/.git' will return
125+
* 'C:/' here
126+
*/
127+
if (len == 2 && LOOKS_LIKE_DRIVE_PREFIX(path))
128+
return 3;
129+
130+
/*
131+
* Similarly checks if we're dealing with a network computer name
132+
* '//computername/.git' will return '//computername/'
133+
*/
134+
if (looks_like_network_computer_name(path, len))
135+
return len + 1;
136+
#endif
137+
138+
return -1;
139+
}
140+
113141
/*
114142
* Based on the Android implementation, BSD licensed.
115143
* Check http://android.git.kernel.org/
116144
*/
117145
int git_path_dirname_r(git_buf *buffer, const char *path)
118146
{
119147
const char *endp;
120-
int result, len;
148+
int len;
121149

122150
/* Empty or NULL string gets treated as "." */
123151
if (path == NULL || *path == '\0') {
@@ -146,35 +174,17 @@ int git_path_dirname_r(git_buf *buffer, const char *path)
146174
endp--;
147175
} while (endp > path && *endp == '/');
148176

149-
/* Cast is safe because max path < max int */
150-
len = (int)(endp - path + 1);
151-
152-
#ifdef GIT_WIN32
153-
/* Mimic unix behavior where '/.git' returns '/': 'C:/.git' will return
154-
'C:/' here */
155-
156-
if (len == 2 && LOOKS_LIKE_DRIVE_PREFIX(path)) {
157-
len = 3;
158-
goto Exit;
159-
}
160-
161-
/* Similarly checks if we're dealing with a network computer name
162-
'//computername/.git' will return '//computername/' */
163-
164-
if (looks_like_network_computer_name(path, len)) {
165-
len++;
177+
if ((len = win32_prefix_length(path, endp - path + 1)) > 0)
166178
goto Exit;
167-
}
168179

169-
#endif
180+
/* Cast is safe because max path < max int */
181+
len = (int)(endp - path + 1);
170182

171183
Exit:
172-
result = len;
173-
174184
if (buffer != NULL && git_buf_set(buffer, path, len) < 0)
175185
return -1;
176186

177-
return result;
187+
return len;
178188
}
179189

180190

0 commit comments

Comments
 (0)