diff options
author | Edward Thomson <ethomson@edwardthomson.com> | 2020-03-08 18:11:45 +0000 |
---|---|---|
committer | Edward Thomson <ethomson@edwardthomson.com> | 2020-03-10 20:10:20 +0000 |
commit | f2b114ba828b561c63164dcfcc2707f11e31c8d8 (patch) | |
tree | 4d2c1b5cccd38e6358c1ed57039cf24c6058b0da /src | |
parent | fb7da15452f7069e6bfa7d39b7703e32eaa84d34 (diff) | |
download | libgit2-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.c | 29 | ||||
-rw-r--r-- | src/win32/path_w32.h | 14 |
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 |