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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
diff --git a/src/path.c b/src/path.c
index bffde93..0e9e04d 100644
--- a/src/path.c
+++ b/src/path.c
@@ -111,13 +111,41 @@ Exit:
}
/*
+ * Determine if the path is a Windows prefix and, if so, returns
+ * its actual lentgh. If it is not a prefix, returns -1.
+ */
+static int win32_prefix_length(const char *path, int len)
+{
+#ifndef GIT_WIN32
+ GIT_UNUSED(path);
+ GIT_UNUSED(len);
+#else
+ /*
+ * Mimic unix behavior where '/.git' returns '/': 'C:/.git' will return
+ * 'C:/' here
+ */
+ if (len == 2 && LOOKS_LIKE_DRIVE_PREFIX(path))
+ return 3;
+
+ /*
+ * Similarly checks if we're dealing with a network computer name
+ * '//computername/.git' will return '//computername/'
+ */
+ if (looks_like_network_computer_name(path, len))
+ return len + 1;
+#endif
+
+ return -1;
+}
+
+/*
* Based on the Android implementation, BSD licensed.
* Check http://android.git.kernel.org/
*/
int git_path_dirname_r(git_buf *buffer, const char *path)
{
const char *endp;
- int result, len;
+ int len;
/* Empty or NULL string gets treated as "." */
if (path == NULL || *path == '\0') {
@@ -146,35 +174,17 @@ int git_path_dirname_r(git_buf *buffer, const char *path)
endp--;
} while (endp > path && *endp == '/');
- /* Cast is safe because max path < max int */
- len = (int)(endp - path + 1);
-
-#ifdef GIT_WIN32
- /* Mimic unix behavior where '/.git' returns '/': 'C:/.git' will return
- 'C:/' here */
-
- if (len == 2 && LOOKS_LIKE_DRIVE_PREFIX(path)) {
- len = 3;
- goto Exit;
- }
-
- /* Similarly checks if we're dealing with a network computer name
- '//computername/.git' will return '//computername/' */
-
- if (looks_like_network_computer_name(path, len)) {
- len++;
+ if ((len = win32_prefix_length(path, endp - path + 1)) > 0)
goto Exit;
- }
-#endif
+ /* Cast is safe because max path < max int */
+ len = (int)(endp - path + 1);
Exit:
- result = len;
-
if (buffer != NULL && git_buf_set(buffer, path, len) < 0)
return -1;
- return result;
+ return len;
}