aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/main.c2
-rw-r--r--src/nvim/mbyte.c67
-rw-r--r--src/nvim/os/env.c4
-rw-r--r--src/nvim/os/fs.c2
-rw-r--r--src/nvim/os/pty_process_win.c18
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);