win: enable DYNAMIC_ICONV

This commit is contained in:
Justin M. Keyes 2018-06-05 14:34:51 -04:00
parent 90e3dd9220
commit b7032cf1e3
2 changed files with 44 additions and 6 deletions

View File

@ -55,7 +55,7 @@ endif()
option(ENABLE_LIBINTL "enable libintl" ON) option(ENABLE_LIBINTL "enable libintl" ON)
if(MSVC) if(MSVC)
# TODO(justinmk): need bundled iconv for MSVC. add_definitions(-DDYNAMIC_ICONV)
option(ENABLE_LIBICONV "enable libiconv" OFF) option(ENABLE_LIBICONV "enable libiconv" OFF)
else() else()
option(ENABLE_LIBICONV "enable libiconv" ON) option(ENABLE_LIBICONV "enable libiconv" ON)

View File

@ -37,6 +37,8 @@
#ifdef HAVE_LOCALE_H #ifdef HAVE_LOCALE_H
# include <locale.h> # include <locale.h>
#endif #endif
#include "nvim/eval.h"
#include "nvim/path.h"
#include "nvim/iconv.h" #include "nvim/iconv.h"
#include "nvim/mbyte.h" #include "nvim/mbyte.h"
#include "nvim/charset.h" #include "nvim/charset.h"
@ -72,6 +74,9 @@ struct interval {
# include "unicode_tables.generated.h" # include "unicode_tables.generated.h"
#endif #endif
char_u e_loadlib[] = "E370: Could not load library %s";
char_u e_loadfunc[] = "E448: Could not load library function %s";
// To speed up BYTELEN(); keep a lookup table to quickly get the length in // To speed up BYTELEN(); keep a lookup table to quickly get the length in
// bytes of a UTF-8 character from the first byte of a UTF-8 string. Bytes // bytes of a UTF-8 character from the first byte of a UTF-8 string. Bytes
// which are illegal when used as the first byte have a 1. The NUL byte has // which are illegal when used as the first byte have a 1. The NUL byte has
@ -2038,9 +2043,10 @@ void * my_iconv_open(char_u *to, char_u *from)
return (void *)-1; /* detected a broken iconv() previously */ return (void *)-1; /* detected a broken iconv() previously */
#ifdef DYNAMIC_ICONV #ifdef DYNAMIC_ICONV
/* Check if the iconv.dll can be found. */ // Check if the iconv.dll can be found.
if (!iconv_enabled(true)) if (!iconv_enabled(true)) {
return (void *)-1; return (void *)-1;
}
#endif #endif
fd = iconv_open((char *)enc_skip(to), (char *)enc_skip(from)); fd = iconv_open((char *)enc_skip(to), (char *)enc_skip(from));
@ -2162,7 +2168,7 @@ static HINSTANCE hMsvcrtDLL = 0;
# ifndef DYNAMIC_ICONV_DLL # ifndef DYNAMIC_ICONV_DLL
# define DYNAMIC_ICONV_DLL "iconv.dll" # define DYNAMIC_ICONV_DLL "iconv.dll"
# define DYNAMIC_ICONV_DLL_ALT "libiconv.dll" # define DYNAMIC_ICONV_DLL_ALT "libiconv-2.dll"
# endif # endif
# ifndef DYNAMIC_MSVCRT_DLL # ifndef DYNAMIC_MSVCRT_DLL
# define DYNAMIC_MSVCRT_DLL "msvcrt.dll" # define DYNAMIC_MSVCRT_DLL "msvcrt.dll"
@ -2208,6 +2214,35 @@ static void * get_iconv_import_func(HINSTANCE hInst,
return NULL; 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 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. * Try opening the iconv.dll and return TRUE if iconv() can be used.
*/ */
@ -2255,10 +2290,13 @@ bool iconv_enabled(bool verbose)
void iconv_end(void) void iconv_end(void)
{ {
if (hIconvDLL != 0) if (hIconvDLL != 0) {
// TODO(justinmk): use uv_dlclose instead.
FreeLibrary(hIconvDLL); FreeLibrary(hIconvDLL);
if (hMsvcrtDLL != 0) }
if (hMsvcrtDLL != 0) {
FreeLibrary(hMsvcrtDLL); FreeLibrary(hMsvcrtDLL);
}
hIconvDLL = 0; hIconvDLL = 0;
hMsvcrtDLL = 0; hMsvcrtDLL = 0;
} }