diff options
author | Justin M. Keyes <justinkz@gmail.com> | 2016-05-29 03:59:37 -0400 |
---|---|---|
committer | Justin M. Keyes <justinkz@gmail.com> | 2016-07-30 15:28:12 -0400 |
commit | 6b33e9b10348dc05440dbb3e1d55318983ef644f (patch) | |
tree | 1cbad4435505893295ede962782f9b7f6da49041 | |
parent | 771d42e426c8c634e6907d501502760dc745b6aa (diff) | |
download | rneovim-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.c | 59 |
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); |