aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/mbyte.c60
-rw-r--r--src/nvim/message.c14
-rw-r--r--src/nvim/os/fs.c6
-rw-r--r--src/nvim/os/pty_process_win.c18
4 files changed, 47 insertions, 51 deletions
diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c
index fae7635d34..e40beed0dd 100644
--- a/src/nvim/mbyte.c
+++ b/src/nvim/mbyte.c
@@ -1356,45 +1356,41 @@ static int utf_strnicmp(const char_u *s1, const char_u *s2, size_t n1,
# define CP_UTF8 65001 /* magic number from winnls.h */
#endif
-/// Reassigns `strw` to a new, allocated pointer to a UTF16 string.
-int utf8_to_utf16(const char *str, wchar_t **strw)
+/// Converts string from UTF-8 to UTF-16.
+///
+/// @param utf8 UTF-8 string.
+/// @param utf8len Length of `utf8`. May be -1 if `utf8` is NUL-terminated.
+/// @param utf16[out,allocated] NUL-terminated UTF-16 string, or NULL on error
+/// @return 0 on success, or libuv error code
+int utf8_to_utf16(const char *utf8, int utf8len, wchar_t **utf16)
FUNC_ATTR_NONNULL_ALL
{
- ssize_t wchar_len = 0;
-
- // Compute the length needed to store the converted widechar string.
- wchar_len = MultiByteToWideChar(CP_UTF8,
- 0, // dwFlags: must be 0 for utf8
- str, // lpMultiByteStr: string to convert
- -1, // -1 => process up to NUL
- NULL, // lpWideCharStr: converted string
- 0); // 0 => return length, don't convert
- if (wchar_len == 0) {
- return GetLastError();
- }
-
- ssize_t buf_sz = wchar_len * sizeof(wchar_t);
-
- if (buf_sz == 0) {
- *strw = NULL;
- return 0;
+ // Compute the length needed for the converted UTF-16 string.
+ int bufsize = MultiByteToWideChar(CP_UTF8,
+ 0, // dwFlags: must be 0 for UTF-8
+ utf8, // -1: process up to NUL
+ utf8len,
+ NULL,
+ 0); // 0: get length, don't convert
+ if (bufsize == 0) {
+ *utf16 = NULL;
+ return uv_translate_sys_error(GetLastError());
}
- char *buf = xmalloc(buf_sz);
- char *pos = buf;
+ // Allocate the destination buffer adding an extra byte for the terminating
+ // NULL. If `utf8len` is not -1 MultiByteToWideChar will not add it, so
+ // we do it ourselves always, just in case.
+ *utf16 = xmalloc(sizeof(wchar_t) * (bufsize + 1));
- int r = MultiByteToWideChar(CP_UTF8,
- 0,
- str,
- -1,
- (wchar_t *)pos,
- wchar_len);
- assert(r == wchar_len);
- if (r != wchar_len) {
- EMSG2("MultiByteToWideChar failed: %d", r);
+ // Convert to UTF-16.
+ bufsize = MultiByteToWideChar(CP_UTF8, 0, utf8, utf8len, *utf16, bufsize);
+ if (bufsize == 0) {
+ xfree(*utf16);
+ *utf16 = NULL;
+ return uv_translate_sys_error(GetLastError());
}
- *strw = (wchar_t *)pos;
+ (*utf16)[bufsize] = L'\0';
return 0;
}
diff --git a/src/nvim/message.c b/src/nvim/message.c
index b043df17d3..6e935022ca 100644
--- a/src/nvim/message.c
+++ b/src/nvim/message.c
@@ -2559,10 +2559,11 @@ static int do_more_prompt(int typed_char)
#if defined(WIN32)
void mch_errmsg(char *str)
{
+ assert(str != NULL);
wchar_t *utf16str;
- int conversion_result = utf8_to_utf16((str), &utf16str);
- if (conversion_result != 0) {
- EMSG2("utf8_to_utf16 failed: %d", conversion_result);
+ int r = utf8_to_utf16(str, -1, &utf16str);
+ if (r != 0) {
+ fprintf(stderr, "utf8_to_utf16 failed: %d", r);
} else {
fwprintf(stderr, L"%ls", utf16str);
xfree(utf16str);
@@ -2572,10 +2573,11 @@ void mch_errmsg(char *str)
// Give a message. To be used when the UI is not initialized yet.
void mch_msg(char *str)
{
+ assert(str != NULL);
wchar_t *utf16str;
- int conversion_result = utf8_to_utf16((str), &utf16str);
- if (conversion_result != 0) {
- EMSG2("utf8_to_utf16 failed: %d", conversion_result);
+ int r = utf8_to_utf16(str, -1, &utf16str);
+ if (r != 0) {
+ fprintf(stderr, "utf8_to_utf16 failed: %d", r);
} else {
wprintf(L"%ls", utf16str);
xfree(utf16str);
diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c
index dcb3ef7c4a..615ab143b2 100644
--- a/src/nvim/os/fs.c
+++ b/src/nvim/os/fs.c
@@ -1180,12 +1180,10 @@ char *os_resolve_shortcut(const char *fname)
&IID_IShellLinkW, (void **)&pslw);
if (hr == S_OK) {
wchar_t *p;
- const int conversion_result = utf8_to_utf16(fname, &p);
+ const int conversion_result = utf8_to_utf16(fname, len, &p);
if (conversion_result != 0) {
EMSG2("utf8_to_utf16 failed: %d", conversion_result);
- }
-
- if (p != NULL) {
+ } else if (p != NULL) {
// Get a pointer to the IPersistFile interface.
hr = pslw->lpVtbl->QueryInterface(
pslw, &IID_IPersistFile, (void **)&ppf);
diff --git a/src/nvim/os/pty_process_win.c b/src/nvim/os/pty_process_win.c
index 290668bca3..ef48da953a 100644
--- a/src/nvim/os/pty_process_win.c
+++ b/src/nvim/os/pty_process_win.c
@@ -93,9 +93,9 @@ int pty_process_spawn(PtyProcess *ptyproc)
}
if (proc->cwd != NULL) {
- status = utf8_to_utf16(proc->cwd, &cwd);
+ status = utf8_to_utf16(proc->cwd, -1, &cwd);
if (status != 0) {
- emsg = "Failed to convert pwd form utf8 to utf16.";
+ emsg = "utf8_to_utf16 failed";
goto cleanup;
}
}
@@ -103,7 +103,7 @@ int pty_process_spawn(PtyProcess *ptyproc)
status = build_cmd_line(proc->argv, &cmd_line,
os_shell_is_cmdexe(proc->argv[0]));
if (status != 0) {
- emsg = "Failed to convert cmd line form utf8 to utf16.";
+ emsg = "build_cmd_line failed";
goto cleanup;
}
@@ -115,7 +115,7 @@ int pty_process_spawn(PtyProcess *ptyproc)
NULL, // Optional environment variables
&err);
if (spawncfg == NULL) {
- emsg = "Failed winpty_spawn_config_new.";
+ emsg = "winpty_spawn_config_new failed";
goto cleanup;
}
@@ -128,9 +128,9 @@ int pty_process_spawn(PtyProcess *ptyproc)
&err)) {
if (win_err) {
status = (int)win_err;
- emsg = "Failed spawn process.";
+ emsg = "failed to spawn process";
} else {
- emsg = "Failed winpty_spawn.";
+ emsg = "winpty_spawn 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("%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("%s: error code: %d", emsg, status);
status = translate_winpty_error(status);
}
winpty_error_free(err);
@@ -308,7 +308,7 @@ static int build_cmd_line(char **argv, wchar_t **cmd_line, bool is_cmdexe)
}
}
- int result = utf8_to_utf16(utf8_cmd_line, cmd_line);
+ int result = utf8_to_utf16(utf8_cmd_line, -1, cmd_line);
xfree(utf8_cmd_line);
return result;
}