diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/main.c | 2 | ||||
-rw-r--r-- | src/nvim/mbyte.c | 129 | ||||
-rw-r--r-- | src/nvim/message.c | 14 | ||||
-rw-r--r-- | src/nvim/os/env.c | 4 | ||||
-rw-r--r-- | src/nvim/os/fs.c | 18 | ||||
-rw-r--r-- | src/nvim/os/fs_defs.h | 6 | ||||
-rw-r--r-- | src/nvim/os/os_defs.h | 7 | ||||
-rw-r--r-- | src/nvim/os/pty_process_win.c | 30 |
8 files changed, 104 insertions, 106 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 fae7635d34..29b8dc0ef2 100644 --- a/src/nvim/mbyte.c +++ b/src/nvim/mbyte.c @@ -1356,83 +1356,86 @@ 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_CLEAR(*utf16); + return uv_translate_sys_error(GetLastError()); } - *strw = (wchar_t *)pos; + (*utf16)[bufsize] = L'\0'; 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(); - } - - *str = xmallocz(utf8_len); + // 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()); + } + + // 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/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/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 dcb3ef7c4a..ae922e4040 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -293,7 +293,7 @@ static bool is_executable(const char *name, char **abspath) /// Checks if file `name` is executable under any of these conditions: /// - extension is in $PATHEXT and `name` is executable /// - result of any $PATHEXT extension appended to `name` is executable -static bool is_executable_ext(char *name, char **abspath) +static bool is_executable_ext(const char *name, char **abspath) FUNC_ATTR_NONNULL_ARG(1) { const bool is_unix_shell = strstr((char *)path_tail(p_sh), "sh") != NULL; @@ -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); - if (conversion_result != 0) { - EMSG2("utf8_to_utf16 failed: %d", conversion_result); - } - - if (p != NULL) { + const int r = utf8_to_utf16(fname, -1, &p); + if (r != 0) { + EMSG2("utf8_to_utf16 failed: %d", r); + } else if (p != NULL) { // Get a pointer to the IPersistFile interface. hr = pslw->lpVtbl->QueryInterface( pslw, &IID_IPersistFile, (void **)&ppf); @@ -1210,9 +1208,9 @@ 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); - if (conversion_result != 0) { - EMSG2("utf16_to_utf8 failed: %d", conversion_result); + const int r2 = utf16_to_utf8(wsz, -1, &rfname); + if (r2 != 0) { + EMSG2("utf16_to_utf8 failed: %d", r2); } } diff --git a/src/nvim/os/fs_defs.h b/src/nvim/os/fs_defs.h index 68e5c74ee1..f4929b12b1 100644 --- a/src/nvim/os/fs_defs.h +++ b/src/nvim/os/fs_defs.h @@ -21,12 +21,6 @@ typedef struct { uv_dirent_t ent; ///< @private The entry information. } Directory; -/// Converts libuv error (negative int) to error description string. -#define os_strerror uv_strerror - -/// Converts system error code to libuv error code. -#define os_translate_sys_error uv_translate_sys_error - // Values returned by os_nodetype() #define NODE_NORMAL 0 // file or directory, check with os_isdir() #define NODE_WRITABLE 1 // something we can write to (character diff --git a/src/nvim/os/os_defs.h b/src/nvim/os/os_defs.h index c29af5c160..c8ac4218f6 100644 --- a/src/nvim/os/os_defs.h +++ b/src/nvim/os/os_defs.h @@ -32,11 +32,12 @@ # include <strings.h> #endif -/// Function to convert libuv error to char * error description -/// -/// negative libuv error codes are returned by a number of os functions. +/// Converts libuv error (negative int) to error description string. #define os_strerror uv_strerror +/// Converts system error code to libuv error code. +#define os_translate_sys_error uv_translate_sys_error + #ifdef WIN32 # define os_strtok strtok_s #else diff --git a/src/nvim/os/pty_process_win.c b/src/nvim/os/pty_process_win.c index 290668bca3..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; } @@ -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(proc->cwd) 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("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); @@ -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; } |