forked from aniani/vim
patch 8.0.0280: problem setting multi-byte environment var on MS-Windows
Problem: On MS-Windows setting an environment variable with multi-byte strings does not work well. Solution: Use wputenv when possible. (Taro Muraoka, Ken Takata)
This commit is contained in:
@@ -515,6 +515,7 @@ static char *null_libintl_textdomain(const char *);
|
||||
static char *null_libintl_bindtextdomain(const char *, const char *);
|
||||
static char *null_libintl_bind_textdomain_codeset(const char *, const char *);
|
||||
static int null_libintl_putenv(const char *);
|
||||
static int null_libintl_wputenv(const wchar_t *);
|
||||
|
||||
static HINSTANCE hLibintlDLL = NULL;
|
||||
char *(*dyn_libintl_gettext)(const char *) = null_libintl_gettext;
|
||||
@@ -526,6 +527,7 @@ char *(*dyn_libintl_bindtextdomain)(const char *, const char *)
|
||||
char *(*dyn_libintl_bind_textdomain_codeset)(const char *, const char *)
|
||||
= null_libintl_bind_textdomain_codeset;
|
||||
int (*dyn_libintl_putenv)(const char *) = null_libintl_putenv;
|
||||
int (*dyn_libintl_wputenv)(const wchar_t *) = null_libintl_wputenv;
|
||||
|
||||
int
|
||||
dyn_libintl_init(void)
|
||||
@@ -591,9 +593,14 @@ dyn_libintl_init(void)
|
||||
/* _putenv() function for the libintl.dll is optional. */
|
||||
hmsvcrt = find_imported_module_by_funcname(hLibintlDLL, "getenv");
|
||||
if (hmsvcrt != NULL)
|
||||
{
|
||||
dyn_libintl_putenv = (void *)GetProcAddress(hmsvcrt, "_putenv");
|
||||
if (dyn_libintl_putenv == NULL || dyn_libintl_putenv == putenv)
|
||||
dyn_libintl_wputenv = (void *)GetProcAddress(hmsvcrt, "_wputenv");
|
||||
}
|
||||
if (dyn_libintl_putenv == NULL || dyn_libintl_putenv == _putenv)
|
||||
dyn_libintl_putenv = null_libintl_putenv;
|
||||
if (dyn_libintl_wputenv == NULL || dyn_libintl_wputenv == _wputenv)
|
||||
dyn_libintl_wputenv = null_libintl_wputenv;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -610,6 +617,7 @@ dyn_libintl_end(void)
|
||||
dyn_libintl_bindtextdomain = null_libintl_bindtextdomain;
|
||||
dyn_libintl_bind_textdomain_codeset = null_libintl_bind_textdomain_codeset;
|
||||
dyn_libintl_putenv = null_libintl_putenv;
|
||||
dyn_libintl_wputenv = null_libintl_wputenv;
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
@@ -658,6 +666,13 @@ null_libintl_putenv(const char *envstring)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
null_libintl_wputenv(const wchar_t *envstring)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* DYNAMIC_GETTEXT */
|
||||
|
||||
/* This symbol is not defined in older versions of the SDK or Visual C++ */
|
||||
@@ -6985,3 +7000,43 @@ fix_arg_enc(void)
|
||||
set_alist_count();
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
mch_setenv(char *var, char *value, int x)
|
||||
{
|
||||
char_u *envbuf;
|
||||
|
||||
envbuf = alloc((unsigned)(STRLEN(var) + STRLEN(value) + 2));
|
||||
if (envbuf == NULL)
|
||||
return -1;
|
||||
|
||||
sprintf((char *)envbuf, "%s=%s", var, value);
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
|
||||
{
|
||||
WCHAR *p = enc_to_utf16(envbuf, NULL);
|
||||
|
||||
vim_free(envbuf);
|
||||
if (p == NULL)
|
||||
return -1;
|
||||
_wputenv(p);
|
||||
# ifdef libintl_wputenv
|
||||
libintl_wputenv(p);
|
||||
# endif
|
||||
/* Unlike Un*x systems, we can free the string for _wputenv(). */
|
||||
vim_free(p);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
_putenv((char *)envbuf);
|
||||
# ifdef libintl_putenv
|
||||
libintl_putenv((char *)envbuf);
|
||||
# endif
|
||||
/* Unlike Un*x systems, we can free the string for _putenv(). */
|
||||
vim_free(envbuf);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user