changeset 16172:6b0836727cf3 v8.1.1091

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 <Bram@vim.org> 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)
author Bram Moolenaar <Bram@vim.org>
date Sat, 30 Mar 2019 20:15:05 +0100
parents 99532bf924ff
children 1b998e6cd49b
files src/misc1.c src/testdir/test_let.vim src/version.c
diffstat 3 files changed, 57 insertions(+), 47 deletions(-) [+]
line wrap: on
line diff
--- 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
     }
 
     /*
--- 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
--- 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,