mirror of
https://github.com/neovim/neovim.git
synced 2025-09-27 13:38:34 +00:00
173
src/nvim/mbyte.c
173
src/nvim/mbyte.c
@@ -2062,7 +2062,7 @@ enc_locale_copy_enc:
|
||||
return enc_canonize((char_u *)buf);
|
||||
}
|
||||
|
||||
# if defined(USE_ICONV)
|
||||
# if defined(HAVE_ICONV)
|
||||
|
||||
|
||||
/*
|
||||
@@ -2083,13 +2083,6 @@ void * my_iconv_open(char_u *to, char_u *from)
|
||||
if (iconv_working == kBroken)
|
||||
return (void *)-1; /* detected a broken iconv() previously */
|
||||
|
||||
#ifdef DYNAMIC_ICONV
|
||||
// Check if the iconv.dll can be found.
|
||||
if (!iconv_enabled(true)) {
|
||||
return (void *)-1;
|
||||
}
|
||||
#endif
|
||||
|
||||
fd = iconv_open((char *)enc_skip(to), (char *)enc_skip(from));
|
||||
|
||||
if (fd != (iconv_t)-1 && iconv_working == kUnknown) {
|
||||
@@ -2196,152 +2189,7 @@ static char_u *iconv_string(const vimconv_T *const vcp, char_u *str,
|
||||
return result;
|
||||
}
|
||||
|
||||
# if defined(DYNAMIC_ICONV)
|
||||
// Dynamically load the "iconv.dll" on Win32.
|
||||
|
||||
#ifndef DYNAMIC_ICONV // just generating prototypes
|
||||
# define HINSTANCE int
|
||||
#endif
|
||||
static HINSTANCE hIconvDLL = 0;
|
||||
static HINSTANCE hMsvcrtDLL = 0;
|
||||
|
||||
# ifndef DYNAMIC_ICONV_DLL
|
||||
# define DYNAMIC_ICONV_DLL "iconv.dll"
|
||||
# define DYNAMIC_ICONV_DLL_ALT "libiconv-2.dll"
|
||||
# endif
|
||||
# ifndef DYNAMIC_MSVCRT_DLL
|
||||
# define DYNAMIC_MSVCRT_DLL "msvcrt.dll"
|
||||
# endif
|
||||
|
||||
/*
|
||||
* Get the address of 'funcname' which is imported by 'hInst' DLL.
|
||||
*/
|
||||
static void * get_iconv_import_func(HINSTANCE hInst,
|
||||
const char *funcname)
|
||||
{
|
||||
PBYTE pImage = (PBYTE)hInst;
|
||||
PIMAGE_DOS_HEADER pDOS = (PIMAGE_DOS_HEADER)hInst;
|
||||
PIMAGE_NT_HEADERS pPE;
|
||||
PIMAGE_IMPORT_DESCRIPTOR pImpDesc;
|
||||
PIMAGE_THUNK_DATA pIAT; /* Import Address Table */
|
||||
PIMAGE_THUNK_DATA pINT; /* Import Name Table */
|
||||
PIMAGE_IMPORT_BY_NAME pImpName;
|
||||
|
||||
if (pDOS->e_magic != IMAGE_DOS_SIGNATURE)
|
||||
return NULL;
|
||||
pPE = (PIMAGE_NT_HEADERS)(pImage + pDOS->e_lfanew);
|
||||
if (pPE->Signature != IMAGE_NT_SIGNATURE)
|
||||
return NULL;
|
||||
pImpDesc = (PIMAGE_IMPORT_DESCRIPTOR)(pImage
|
||||
+ pPE->OptionalHeader.DataDirectory[
|
||||
IMAGE_DIRECTORY_ENTRY_IMPORT]
|
||||
.VirtualAddress);
|
||||
for (; pImpDesc->FirstThunk; ++pImpDesc) {
|
||||
if (!pImpDesc->OriginalFirstThunk)
|
||||
continue;
|
||||
pIAT = (PIMAGE_THUNK_DATA)(pImage + pImpDesc->FirstThunk);
|
||||
pINT = (PIMAGE_THUNK_DATA)(pImage + pImpDesc->OriginalFirstThunk);
|
||||
for (; pIAT->u1.Function; ++pIAT, ++pINT) {
|
||||
if (IMAGE_SNAP_BY_ORDINAL(pINT->u1.Ordinal))
|
||||
continue;
|
||||
pImpName = (PIMAGE_IMPORT_BY_NAME)(pImage
|
||||
+ (UINT_PTR)(pINT->u1.AddressOfData));
|
||||
if (strcmp(pImpName->Name, funcname) == 0)
|
||||
return (void *)pIAT->u1.Function;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Load library "name".
|
||||
HINSTANCE vimLoadLib(char *name)
|
||||
{
|
||||
HINSTANCE dll = NULL;
|
||||
|
||||
// NOTE: Do not use mch_dirname() and mch_chdir() here, they may call
|
||||
// vimLoadLib() recursively, which causes a stack overflow.
|
||||
wchar_t old_dirw[MAXPATHL];
|
||||
|
||||
// Path to exe dir.
|
||||
char *buf = xstrdup((char *)get_vim_var_str(VV_PROGPATH));
|
||||
// ptrdiff_t len = ;
|
||||
// assert(len > 0);
|
||||
buf[path_tail_with_sep(buf) - buf] = '\0';
|
||||
|
||||
if (GetCurrentDirectoryW(MAXPATHL, old_dirw) != 0) {
|
||||
// Change directory to where the executable is, both to make
|
||||
// sure we find a .dll there and to avoid looking for a .dll
|
||||
// in the current directory.
|
||||
SetCurrentDirectory((LPCSTR)buf);
|
||||
// TODO(justinmk): use uv_dlopen instead. see os_libcall
|
||||
dll = LoadLibrary(name);
|
||||
SetCurrentDirectoryW(old_dirw);
|
||||
}
|
||||
|
||||
return dll;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Try opening the iconv.dll and return TRUE if iconv() can be used.
|
||||
*/
|
||||
bool iconv_enabled(bool verbose)
|
||||
{
|
||||
if (hIconvDLL != 0 && hMsvcrtDLL != 0)
|
||||
return true;
|
||||
hIconvDLL = vimLoadLib(DYNAMIC_ICONV_DLL);
|
||||
if (hIconvDLL == 0) /* sometimes it's called libiconv.dll */
|
||||
hIconvDLL = vimLoadLib(DYNAMIC_ICONV_DLL_ALT);
|
||||
if (hIconvDLL != 0)
|
||||
hMsvcrtDLL = vimLoadLib(DYNAMIC_MSVCRT_DLL);
|
||||
if (hIconvDLL == 0 || hMsvcrtDLL == 0) {
|
||||
/* Only give the message when 'verbose' is set, otherwise it might be
|
||||
* done whenever a conversion is attempted. */
|
||||
if (verbose && p_verbose > 0) {
|
||||
verbose_enter();
|
||||
EMSG2(_(e_loadlib),
|
||||
hIconvDLL == 0 ? DYNAMIC_ICONV_DLL : DYNAMIC_MSVCRT_DLL);
|
||||
verbose_leave();
|
||||
}
|
||||
iconv_end();
|
||||
return false;
|
||||
}
|
||||
|
||||
iconv = (void *)GetProcAddress(hIconvDLL, "libiconv");
|
||||
iconv_open = (void *)GetProcAddress(hIconvDLL, "libiconv_open");
|
||||
iconv_close = (void *)GetProcAddress(hIconvDLL, "libiconv_close");
|
||||
iconvctl = (void *)GetProcAddress(hIconvDLL, "libiconvctl");
|
||||
iconv_errno = get_iconv_import_func(hIconvDLL, "_errno");
|
||||
if (iconv_errno == NULL)
|
||||
iconv_errno = (void *)GetProcAddress(hMsvcrtDLL, "_errno");
|
||||
if (iconv == NULL || iconv_open == NULL || iconv_close == NULL
|
||||
|| iconvctl == NULL || iconv_errno == NULL) {
|
||||
iconv_end();
|
||||
if (verbose && p_verbose > 0) {
|
||||
verbose_enter();
|
||||
EMSG2(_(e_loadfunc), "for libiconv");
|
||||
verbose_leave();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void iconv_end(void)
|
||||
{
|
||||
if (hIconvDLL != 0) {
|
||||
// TODO(justinmk): use uv_dlclose instead.
|
||||
FreeLibrary(hIconvDLL);
|
||||
}
|
||||
if (hMsvcrtDLL != 0) {
|
||||
FreeLibrary(hMsvcrtDLL);
|
||||
}
|
||||
hIconvDLL = 0;
|
||||
hMsvcrtDLL = 0;
|
||||
}
|
||||
|
||||
# endif /* DYNAMIC_ICONV */
|
||||
# endif /* USE_ICONV */
|
||||
# endif // HAVE_ICONV
|
||||
|
||||
|
||||
|
||||
@@ -2372,10 +2220,11 @@ int convert_setup_ext(vimconv_T *vcp, char_u *from, bool from_unicode_is_utf8,
|
||||
int from_is_utf8;
|
||||
int to_is_utf8;
|
||||
|
||||
/* Reset to no conversion. */
|
||||
# ifdef USE_ICONV
|
||||
if (vcp->vc_type == CONV_ICONV && vcp->vc_fd != (iconv_t)-1)
|
||||
// Reset to no conversion.
|
||||
# ifdef HAVE_ICONV
|
||||
if (vcp->vc_type == CONV_ICONV && vcp->vc_fd != (iconv_t)-1) {
|
||||
iconv_close(vcp->vc_fd);
|
||||
}
|
||||
# endif
|
||||
*vcp = (vimconv_T)MBYTE_NONE_CONV;
|
||||
|
||||
@@ -2410,9 +2259,9 @@ int convert_setup_ext(vimconv_T *vcp, char_u *from, bool from_unicode_is_utf8,
|
||||
/* Internal utf-8 -> latin9 conversion. */
|
||||
vcp->vc_type = CONV_TO_LATIN9;
|
||||
}
|
||||
# ifdef USE_ICONV
|
||||
else {
|
||||
/* Use iconv() for conversion. */
|
||||
# ifdef HAVE_ICONV
|
||||
else { // NOLINT(readability/braces)
|
||||
// Use iconv() for conversion.
|
||||
vcp->vc_fd = (iconv_t)my_iconv_open(
|
||||
to_is_utf8 ? (char_u *)"utf-8" : to,
|
||||
from_is_utf8 ? (char_u *)"utf-8" : from);
|
||||
@@ -2564,8 +2413,8 @@ char_u * string_convert_ext(const vimconv_T *const vcp, char_u *ptr,
|
||||
*lenp = (size_t)(d - retval);
|
||||
break;
|
||||
|
||||
# ifdef USE_ICONV
|
||||
case CONV_ICONV: /* conversion with vcp->vc_fd */
|
||||
# ifdef HAVE_ICONV
|
||||
case CONV_ICONV: // conversion with vcp->vc_fd
|
||||
retval = iconv_string(vcp, ptr, len, unconvlenp, lenp);
|
||||
break;
|
||||
# endif
|
||||
|
Reference in New Issue
Block a user