aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2016-05-29 03:59:37 -0400
committerJustin M. Keyes <justinkz@gmail.com>2016-07-30 15:28:12 -0400
commit6b33e9b10348dc05440dbb3e1d55318983ef644f (patch)
tree1cbad4435505893295ede962782f9b7f6da49041
parent771d42e426c8c634e6907d501502760dc745b6aa (diff)
downloadrneovim-6b33e9b10348dc05440dbb3e1d55318983ef644f.tar.gz
rneovim-6b33e9b10348dc05440dbb3e1d55318983ef644f.tar.bz2
rneovim-6b33e9b10348dc05440dbb3e1d55318983ef644f.zip
utf8_to_utf16: adapt libuv's fs__capture_path
-rw-r--r--src/nvim/os/fs.c59
1 files changed, 51 insertions, 8 deletions
diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c
index 2199b83108..cd3cb03afe 100644
--- a/src/nvim/os/fs.c
+++ b/src/nvim/os/fs.c
@@ -922,7 +922,7 @@ bool os_fileid_equal(const FileID *file_id_1, const FileID *file_id_2)
/// @param file_info Pointer to a `FileInfo`
/// @return `true` if the `FileID` and the `FileInfo` represent te same file.
bool os_fileid_equal_fileinfo(const FileID *file_id,
- const FileInfo *file_info)
+ const FileInfo *file_info)
FUNC_ATTR_NONNULL_ALL
{
return file_id->inode == file_info->stat.st_ino
@@ -931,6 +931,49 @@ bool os_fileid_equal_fileinfo(const FileID *file_id,
#ifdef WIN32
# include <shlobj.h>
+#ifndef CP_UTF8
+# define CP_UTF8 65001 /* magic number from winnls.h */
+#endif
+
+static int utf8_to_utf16(const char *path, const WCHAR **pathw)
+ FUNC_ATTR_NONNULL_ALL
+{
+ ssize_t buf_sz = 0, path_len, pathw_len = 0;
+
+ // Compute the length needed to store the converted widechar string.
+ pathw_len = MultiByteToWideChar(CP_UTF8,
+ 0, // dwFlags: must be 0 for utf8
+ path, // lpMultiByteStr: string to convert
+ -1,
+ NULL, // lpWideCharStr: converted string
+ 0); // 0 => return length, don't convert
+ if (pathw_len == 0) {
+ return GetLastError();
+ }
+
+ buf_sz += pathw_len * sizeof(WCHAR);
+
+ if (buf_sz == 0) {
+ *pathw = NULL;
+ return 0;
+ }
+
+ char* buf = xmalloc(buf_sz);
+ char* pos = buf;
+
+ DWORD r = MultiByteToWideChar(CP_UTF8,
+ 0,
+ path,
+ -1,
+ (WCHAR*) pos,
+ pathw_len);
+ assert(r == (DWORD) pathw_len);
+ *pathw = (WCHAR*) pos;
+ pos += r * sizeof(WCHAR);
+
+ return 0;
+}
+
/// When "fname" is the name of a shortcut (*.lnk) resolve the file it points
/// to and return that name in allocated memory.
/// Otherwise NULL is returned.
@@ -962,19 +1005,19 @@ char_u * os_resolve_shortcut(char_u *fname)
# ifdef FEAT_MBYTE
if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) {
// create a link manager object and request its interface
- hr = CoCreateInstance(
- &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
- &IID_IShellLinkW, (void**)&pslw);
- if (hr == S_OK)
- {
- WCHAR *p = enc_to_utf16(fname, NULL);
+ hr = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
+ &IID_IShellLinkW, (void**)&pslw);
+ if (hr == S_OK) {
+ WCHAR **p;
+ int len = utf8_to_utf16((char *)fname, p);
if (p != NULL) {
// Get a pointer to the IPersistFile interface.
hr = pslw->lpVtbl->QueryInterface(
pslw, &IID_IPersistFile, (void**)&ppf);
- if (hr != S_OK)
+ if (hr != S_OK) {
goto shortcut_errorw;
+ }
// "load" the name and resolve the link
hr = ppf->lpVtbl->Load(ppf, p, STGM_READ);