diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/main.c | 2 | ||||
-rw-r--r-- | src/nvim/mbyte.c | 67 | ||||
-rw-r--r-- | src/nvim/os/env.c | 4 | ||||
-rw-r--r-- | src/nvim/os/fs.c | 2 | ||||
-rw-r--r-- | src/nvim/os/pty_process_win.c | 18 |
5 files changed, 50 insertions, 43 deletions
diff --git a/src/nvim/main.c b/src/nvim/main.c index 27b6a6bfc5..e7c45b1a7b 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -237,7 +237,7 @@ int main(int argc, char **argv) char **argv = xmalloc((size_t)argc * sizeof(char *)); for (int i = 0; i < argc; i++) { char *buf = NULL; - utf16_to_utf8(argv_w[i], &buf); + utf16_to_utf8(argv_w[i], -1, &buf); assert(buf); argv[i] = buf; } diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c index e40beed0dd..29b8dc0ef2 100644 --- a/src/nvim/mbyte.c +++ b/src/nvim/mbyte.c @@ -1385,8 +1385,7 @@ int utf8_to_utf16(const char *utf8, int utf8len, wchar_t **utf16) // Convert to UTF-16. bufsize = MultiByteToWideChar(CP_UTF8, 0, utf8, utf8len, *utf16, bufsize); if (bufsize == 0) { - xfree(*utf16); - *utf16 = NULL; + XFREE_CLEAR(*utf16); return uv_translate_sys_error(GetLastError()); } @@ -1394,41 +1393,49 @@ int utf8_to_utf16(const char *utf8, int utf8len, wchar_t **utf16) return 0; } -/// Reassigns `str` to a new, allocated pointer to a UTF8 string. -int utf16_to_utf8(const wchar_t *strw, char **str) +/// Converts string from UTF-16 to UTF-8. +/// +/// @param utf16 UTF-16 string. +/// @param utf16len Length of `utf16`. May be -1 if `utf16` is NUL-terminated. +/// @param utf8[out,allocated] NUL-terminated UTF-8 string, or NULL on error +/// @return 0 on success, or libuv error code +int utf16_to_utf8(const wchar_t *utf16, int utf16len, char **utf8) FUNC_ATTR_NONNULL_ALL { - *str = NULL; - // Compute the space required to store the string as UTF-8. - DWORD utf8_len = WideCharToMultiByte(CP_UTF8, - 0, - strw, - -1, - NULL, - 0, - NULL, - NULL); - if (utf8_len == 0) { - return GetLastError(); + // Compute the space needed for the converted UTF-8 string. + DWORD bufsize = WideCharToMultiByte(CP_UTF8, + 0, + utf16, + utf16len, + NULL, + 0, + NULL, + NULL); + if (bufsize == 0) { + *utf8 = NULL; + return uv_translate_sys_error(GetLastError()); } - *str = xmallocz(utf8_len); + // Allocate the destination buffer adding an extra byte for the terminating + // NULL. If `utf16len` is not -1 WideCharToMultiByte will not add it, so + // we do it ourselves always, just in case. + *utf8 = xmalloc(bufsize + 1); // Convert to UTF-8. - utf8_len = WideCharToMultiByte(CP_UTF8, - 0, - strw, - -1, - *str, - utf8_len, - NULL, - NULL); - if (utf8_len == 0) { - XFREE_CLEAR(*str); - return GetLastError(); - } - (*str)[utf8_len] = '\0'; + bufsize = WideCharToMultiByte(CP_UTF8, + 0, + utf16, + utf16len, + *utf8, + bufsize, + NULL, + NULL); + if (bufsize == 0) { + XFREE_CLEAR(*utf8); + return uv_translate_sys_error(GetLastError()); + } + (*utf8)[bufsize] = '\0'; return 0; } diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c index 62457e155c..669475fa72 100644 --- a/src/nvim/os/env.c +++ b/src/nvim/os/env.c @@ -178,7 +178,7 @@ char *os_getenvname_at_index(size_t index) for (wchar_t *it = env; *it != L'\0' || *(it + 1) != L'\0'; it++) { if (index == current_index) { char *utf8_str; - int conversion_result = utf16_to_utf8(it, &utf8_str); + int conversion_result = utf16_to_utf8(it, -1, &utf8_str); if (conversion_result != 0) { EMSG2("utf16_to_utf8 failed: %d", conversion_result); break; @@ -258,7 +258,7 @@ void os_get_hostname(char *hostname, size_t size) host_utf16[host_wsize] = '\0'; char *host_utf8; - int conversion_result = utf16_to_utf8(host_utf16, &host_utf8); + int conversion_result = utf16_to_utf8(host_utf16, -1, &host_utf8); if (conversion_result != 0) { EMSG2("utf16_to_utf8 failed: %d", conversion_result); return; diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index 615ab143b2..ad14fc2d5e 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -1208,7 +1208,7 @@ char *os_resolve_shortcut(const char *fname) ZeroMemory(wsz, MAX_PATH * sizeof(wchar_t)); hr = pslw->lpVtbl->GetPath(pslw, wsz, MAX_PATH, &ffdw, 0); if (hr == S_OK && wsz[0] != NUL) { - const int conversion_result = utf16_to_utf8(wsz, &rfname); + const int conversion_result = utf16_to_utf8(wsz, -1, &rfname); if (conversion_result != 0) { EMSG2("utf16_to_utf8 failed: %d", conversion_result); } diff --git a/src/nvim/os/pty_process_win.c b/src/nvim/os/pty_process_win.c index ef48da953a..183219bd3e 100644 --- a/src/nvim/os/pty_process_win.c +++ b/src/nvim/os/pty_process_win.c @@ -51,26 +51,26 @@ int pty_process_spawn(PtyProcess *ptyproc) cfg = winpty_config_new(WINPTY_FLAG_ALLOW_CURPROC_DESKTOP_CREATION, &err); if (cfg == NULL) { - emsg = "Failed, winpty_config_new."; + emsg = "winpty_config_new failed"; goto cleanup; } winpty_config_set_initial_size(cfg, ptyproc->width, ptyproc->height); winpty_object = winpty_open(cfg, &err); if (winpty_object == NULL) { - emsg = "Failed, winpty_open."; + emsg = "winpty_open failed"; goto cleanup; } - status = utf16_to_utf8(winpty_conin_name(winpty_object), &in_name); + status = utf16_to_utf8(winpty_conin_name(winpty_object), -1, &in_name); if (status != 0) { - emsg = "Failed to convert in_name from utf16 to utf8."; + emsg = "utf16_to_utf8(winpty_conin_name) failed"; goto cleanup; } - status = utf16_to_utf8(winpty_conout_name(winpty_object), &out_name); + status = utf16_to_utf8(winpty_conout_name(winpty_object), -1, &out_name); if (status != 0) { - emsg = "Failed to convert out_name from utf16 to utf8."; + emsg = "utf16_to_utf8(winpty_conout_name) failed"; goto cleanup; } @@ -95,7 +95,7 @@ int pty_process_spawn(PtyProcess *ptyproc) if (proc->cwd != NULL) { status = utf8_to_utf16(proc->cwd, -1, &cwd); if (status != 0) { - emsg = "utf8_to_utf16 failed"; + emsg = "utf8_to_utf16(proc->cwd) failed"; goto cleanup; } } @@ -160,11 +160,11 @@ int pty_process_spawn(PtyProcess *ptyproc) cleanup: if (status) { // In the case of an error of MultiByteToWideChar or CreateProcessW. - ELOG("%s: error code: %d", emsg, status); + ELOG("pty_process_spawn: %s: error code: %d", emsg, status); status = os_translate_sys_error(status); } else if (err != NULL) { status = (int)winpty_error_code(err); - ELOG("%s: error code: %d", emsg, status); + ELOG("pty_process_spawn: %s: error code: %d", emsg, status); status = translate_winpty_error(status); } winpty_error_free(err); |