summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2020-03-08 18:11:45 +0000
committerEdward Thomson <ethomson@edwardthomson.com>2020-03-10 20:10:20 +0000
commitf2b114ba828b561c63164dcfcc2707f11e31c8d8 (patch)
tree4d2c1b5cccd38e6358c1ed57039cf24c6058b0da /src
parentfb7da15452f7069e6bfa7d39b7703e32eaa84d34 (diff)
downloadlibgit2-f2b114ba828b561c63164dcfcc2707f11e31c8d8.tar.gz
win32: introduce relative path handling function
Add a function that takes a (possibly) relative UTF-8 path and emits a UTF-16 path with forward slashes translated to backslashes. If the given path is, in fact, absolute, it will be translated to absolute path handling rules.
Diffstat (limited to 'src')
-rw-r--r--src/win32/path_w32.c29
-rw-r--r--src/win32/path_w32.h14
2 files changed, 41 insertions, 2 deletions
diff --git a/src/win32/path_w32.c b/src/win32/path_w32.c
index eda85abf4..18b43e728 100644
--- a/src/win32/path_w32.c
+++ b/src/win32/path_w32.c
@@ -25,6 +25,9 @@
#define path__is_unc(p) \
(((p)[0] == '\\' && (p)[1] == '\\') || ((p)[0] == '/' && (p)[1] == '/'))
+#define path__startswith_slash(p) \
+ ((p)[0] == '\\' || (p)[0] == '/')
+
GIT_INLINE(int) path__cwd(wchar_t *path, int size)
{
int len;
@@ -221,7 +224,7 @@ int git_win32_path_from_utf8(git_win32_path out, const char *src)
goto on_error;
}
/* Absolute paths omitting the drive letter */
- else if (src[0] == '\\' || src[0] == '/') {
+ else if (path__startswith_slash(src)) {
if (path__cwd(dest, MAX_PATH) < 0)
goto on_error;
@@ -257,6 +260,30 @@ on_error:
return -1;
}
+int git_win32_path_relative_from_utf8(git_win32_path out, const char *src)
+{
+ wchar_t *dest = out, *p;
+ int len;
+
+ /* Handle absolute paths */
+ if (git_path_is_absolute(src) ||
+ path__is_nt_namespace(src) ||
+ path__is_unc(src) ||
+ path__startswith_slash(src)) {
+ return git_win32_path_from_utf8(out, src);
+ }
+
+ if ((len = git__utf8_to_16(dest, MAX_PATH, src)) < 0)
+ return -1;
+
+ for (p = dest; p < (dest + len); p++) {
+ if (*p == L'/')
+ *p = L'\\';
+ }
+
+ return len;
+}
+
int git_win32_path_to_utf8(git_win32_utf8_path dest, const wchar_t *src)
{
char *out = dest;
diff --git a/src/win32/path_w32.h b/src/win32/path_w32.h
index 6d546f2f8..dab8b96fa 100644
--- a/src/win32/path_w32.h
+++ b/src/win32/path_w32.h
@@ -11,7 +11,9 @@
#include "vector.h"
/**
- * Create a Win32 path (in UCS-2 format) from a UTF-8 string.
+ * Create a Win32 path (in UCS-2 format) from a UTF-8 string. If the given
+ * path is relative, then it will be turned into an absolute path by having
+ * the current working directory prepended.
*
* @param dest The buffer to receive the wide string.
* @param src The UTF-8 string to convert.
@@ -20,6 +22,16 @@
extern int git_win32_path_from_utf8(git_win32_path dest, const char *src);
/**
+ * Create a Win32 path (in UCS-2 format) from a UTF-8 string. If the given
+ * path is relative, then it will not be turned into an absolute path.
+ *
+ * @param dest The buffer to receive the wide string.
+ * @param src The UTF-8 string to convert.
+ * @return The length of the wide string, in characters (not counting the NULL terminator), or < 0 for failure
+ */
+extern int git_win32_path_relative_from_utf8(git_win32_path dest, const char *src);
+
+/**
* Canonicalize a Win32 UCS-2 path so that it is suitable for delivery to the
* Win32 APIs: remove multiple directory separators, squashing to a single one,
* strip trailing directory separators, ensure directory separators are all