# HG changeset patch # User Bram Moolenaar # Date 1553973305 -3600 # Node ID 6b0836727cf32996edebbb6b4c707114a6c4c607 # Parent 99532bf924ff5da6692b17e76fefa672583c1330 patch 8.1.1091: MS-Windows: cannot use multi-byte chars in environment var commit https://github.com/vim/vim/commit/f0908e6fe18943ad4453d7d6772fa43049aff4bc Author: Bram Moolenaar Date: Sat Mar 30 20:11:50 2019 +0100 patch 8.1.1091: MS-Windows: cannot use multi-byte chars in environment var Problem: MS-Windows: cannot use multi-byte chars in environment var. Solution: Use the wide API. (Ken Takata, closes https://github.com/vim/vim/issues/4008) diff --git a/src/misc1.c b/src/misc1.c --- a/src/misc1.c +++ b/src/misc1.c @@ -4301,41 +4301,46 @@ expand_env_esc( char_u * vim_getenv(char_u *name, int *mustfree) { - char_u *p; + char_u *p = NULL; char_u *pend; int vimruntime; - -#if defined(MSWIN) - /* use "C:/" when $HOME is not set */ +#ifdef MSWIN + WCHAR *wn, *wp; + + // use "C:/" when $HOME is not set if (STRCMP(name, "HOME") == 0) return homedir; -#endif - + + // Use Wide function + wn = enc_to_utf16(name, NULL); + if (wn == NULL) + return NULL; + + wp = _wgetenv(wn); + vim_free(wn); + + if (wp != NULL && *wp == NUL) // empty is the same as not set + wp = NULL; + + if (wp != NULL) + { + p = utf16_to_enc(wp, NULL); + if (p == NULL) + return NULL; + + *mustfree = TRUE; + return p; + } +#else p = mch_getenv(name); - if (p != NULL && *p == NUL) /* empty is the same as not set */ + if (p != NULL && *p == NUL) // empty is the same as not set p = NULL; if (p != NULL) - { -#if defined(MSWIN) - if (enc_utf8) - { - int len; - char_u *pp = NULL; - - /* Convert from active codepage to UTF-8. Other conversions are - * not done, because they would fail for non-ASCII characters. */ - acp_to_enc(p, (int)STRLEN(p), &pp, &len); - if (pp != NULL) - { - p = pp; - *mustfree = TRUE; - } - } -#endif return p; - } - +#endif + + // handling $VIMRUNTIME and $VIM is below, bail out if it's another name. vimruntime = (STRCMP(name, "VIMRUNTIME") == 0); if (!vimruntime && STRCMP(name, "VIM") != 0) return NULL; @@ -4350,8 +4355,25 @@ vim_getenv(char_u *name, int *mustfree) #endif ) { +#ifdef MSWIN + // Use Wide function + wp = _wgetenv(L"VIM"); + if (wp != NULL && *wp == NUL) // empty is the same as not set + wp = NULL; + if (wp != NULL) + { + char_u *q = utf16_to_enc(wp, NULL); + if (q != NULL) + { + p = vim_version_dir(q); + *mustfree = TRUE; + if (p == NULL) + p = q; + } + } +#else p = mch_getenv((char_u *)"VIM"); - if (p != NULL && *p == NUL) /* empty is the same as not set */ + if (p != NULL && *p == NUL) // empty is the same as not set p = NULL; if (p != NULL) { @@ -4360,27 +4382,8 @@ vim_getenv(char_u *name, int *mustfree) *mustfree = TRUE; else p = mch_getenv((char_u *)"VIM"); - -#if defined(MSWIN) - if (enc_utf8) - { - int len; - char_u *pp = NULL; - - /* Convert from active codepage to UTF-8. Other conversions - * are not done, because they would fail for non-ASCII - * characters. */ - acp_to_enc(p, (int)STRLEN(p), &pp, &len); - if (pp != NULL) - { - if (*mustfree) - vim_free(p); - p = pp; - *mustfree = TRUE; - } - } -#endif } +#endif } /* diff --git a/src/testdir/test_let.vim b/src/testdir/test_let.vim --- a/src/testdir/test_let.vim +++ b/src/testdir/test_let.vim @@ -146,3 +146,8 @@ func Test_let_varg_fail() call assert_fails('call s:set_varg8(1)', 'E742:') call s:set_varg9([0]) endfunction + +func Test_let_utf8_environment() + let $a = 'ĀĒĪŌŪあいうえお' + call assert_equal('ĀĒĪŌŪあいうえお', $a) +endfunc diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -776,6 +776,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1091, +/**/ 1090, /**/ 1089,