changeset 15822:9745c25da3bc v8.1.0918

patch 8.1.0918: MS-Windows: startup messages are not converted commit https://github.com/vim/vim/commit/9b5c1fcdeae75f82a2083fafbbf75ab220f6ac1e Author: Bram Moolenaar <Bram@vim.org> Date: Thu Feb 14 14:08:04 2019 +0100 patch 8.1.0918: MS-Windows: startup messages are not converted Problem: MS-Windows: startup messages are not converted. Solution: Convert messages when the current codepage differs from 'encoding'. (Yasuhiro Matsumoto, closes #3914)
author Bram Moolenaar <Bram@vim.org>
date Thu, 14 Feb 2019 14:15:15 +0100
parents 1c1897fe1cc2
children 5798cba2079a
files src/message.c src/os_mswin.c src/version.c src/vim.h
diffstat 4 files changed, 104 insertions(+), 61 deletions(-) [+]
line wrap: on
line diff
--- a/src/message.c
+++ b/src/message.c
@@ -2570,57 +2570,45 @@ msg_use_printf(void)
 msg_puts_printf(char_u *str, int maxlen)
 {
     char_u	*s = str;
-    char_u	buf[4];
-    char_u	*p;
+    char_u	*buf = NULL;
+    char_u	*p = s;
+
 #ifdef WIN3264
-# if !defined(FEAT_GUI_MSWIN)
-    char_u	*ccp = NULL;
-
-# endif
     if (!(silent_mode && p_verbose == 0))
-	mch_settmode(TMODE_COOK);	/* handle '\r' and '\n' correctly */
-
-# if !defined(FEAT_GUI_MSWIN)
-    if (enc_codepage >= 0 && (int)GetConsoleCP() != enc_codepage)
-    {
-	int	inlen = (int)STRLEN(str);
-	int	outlen;
-	WCHAR	*widestr = (WCHAR *)enc_to_utf16(str, &inlen);
-
-	if (widestr != NULL)
-	{
-	    WideCharToMultiByte_alloc(GetConsoleCP(), 0, widestr, inlen,
-						 (LPSTR *)&ccp, &outlen, 0, 0);
-	    vim_free(widestr);
-	    s = str = ccp;
-	}
-    }
-# endif
+	mch_settmode(TMODE_COOK);	/* handle CR and NL correctly */
 #endif
     while ((maxlen < 0 || (int)(s - str) < maxlen) && *s != NUL)
     {
 	if (!(silent_mode && p_verbose == 0))
 	{
-	    /* NL --> CR NL translation (for Unix, not for "--version") */
-	    p = &buf[0];
-	    if (*s == '\n' && !info_message)
-		*p++ = '\r';
-#if defined(USE_CR)
-	    else
+	    // NL --> CR NL translation (for Unix, not for "--version")
+	    if (*s == NL)
+	    {
+		int n = (int)(s - p);
+
+		buf = alloc(n + 3);
+		memcpy(buf, p, n);
+		if (!info_message)
+		    buf[n++] = CAR;
+#ifdef USE_CR
+		else
 #endif
-		*p++ = *s;
-	    *p = '\0';
-	    if (info_message)	/* informative message, not an error */
-		mch_msg((char *)buf);
-	    else
-		mch_errmsg((char *)buf);
+		    buf[n++] = NL;
+		buf[n++] = NUL;
+		if (info_message)   // informative message, not an error
+		    mch_msg((char *)buf);
+		else
+		    mch_errmsg((char *)buf);
+		vim_free(buf);
+		p = s + 1;
+	    }
 	}
 
-	/* primitive way to compute the current column */
+	// primitive way to compute the current column
 #ifdef FEAT_RIGHTLEFT
 	if (cmdmsg_rl)
 	{
-	    if (*s == '\r' || *s == '\n')
+	    if (*s == CAR || *s == NL)
 		msg_col = Columns - 1;
 	    else
 		--msg_col;
@@ -2628,19 +2616,27 @@ msg_puts_printf(char_u *str, int maxlen)
 	else
 #endif
 	{
-	    if (*s == '\r' || *s == '\n')
+	    if (*s == CAR || *s == NL)
 		msg_col = 0;
 	    else
 		++msg_col;
 	}
 	++s;
     }
-    msg_didout = TRUE;	    /* assume that line is not empty */
+
+    if (*p != NUL && !(silent_mode && p_verbose == 0))
+    {
+	if (maxlen > 0 && STRLEN(p) > (size_t)maxlen)
+	    p[maxlen] = 0;
+	if (info_message)
+	    mch_msg((char *)p);
+	else
+	    mch_errmsg((char *)p);
+    }
+
+    msg_didout = TRUE;	    // assume that line is not empty
 
 #ifdef WIN3264
-# if !defined(FEAT_GUI_MSWIN)
-    vim_free(ccp);
-# endif
     if (!(silent_mode && p_verbose == 0))
 	mch_settmode(TMODE_RAW);
 #endif
@@ -2941,32 +2937,51 @@ do_more_prompt(int typed_char)
     void
 mch_errmsg(char *str)
 {
+#if defined(WIN3264) && !defined(FEAT_GUI_MSWIN)
+    int	    len = STRLEN(str);
+    DWORD   nwrite = 0;
+    DWORD   mode = 0;
+    HANDLE  h = GetStdHandle(STD_ERROR_HANDLE);
+
+    if (GetConsoleMode(h, &mode) && enc_codepage >= 0
+	    && (int)GetConsoleCP() != enc_codepage)
+    {
+	WCHAR	*w = enc_to_utf16((char_u *)str, &len);
+
+	WriteConsoleW(h, w, len, &nwrite, NULL);
+	vim_free(w);
+    }
+    else
+    {
+	fprintf(stderr, "%s", str);
+    }
+#else
     int		len;
 
-#if (defined(UNIX) || defined(FEAT_GUI)) && !defined(ALWAYS_USE_GUI)
+# if (defined(UNIX) || defined(FEAT_GUI)) && !defined(ALWAYS_USE_GUI)
     /* On Unix use stderr if it's a tty.
      * When not going to start the GUI also use stderr.
      * On Mac, when started from Finder, stderr is the console. */
     if (
-# ifdef UNIX
-#  ifdef MACOS_X
+#  ifdef UNIX
+#   ifdef MACOS_X
 	    (isatty(2) && strcmp("/dev/console", ttyname(2)) != 0)
-#  else
+#   else
 	    isatty(2)
+#   endif
+#   ifdef FEAT_GUI
+	    ||
+#   endif
 #  endif
 #  ifdef FEAT_GUI
-	    ||
+	    !(gui.in_use || gui.starting)
 #  endif
-# endif
-# ifdef FEAT_GUI
-	    !(gui.in_use || gui.starting)
-# endif
 	    )
     {
 	fprintf(stderr, "%s", str);
 	return;
     }
-#endif
+# endif
 
     /* avoid a delay for a message that isn't there */
     emsg_on_display = FALSE;
@@ -2981,7 +2996,7 @@ mch_errmsg(char *str)
     {
 	mch_memmove((char_u *)error_ga.ga_data + error_ga.ga_len,
 							  (char_u *)str, len);
-#ifdef UNIX
+# ifdef UNIX
 	/* remove CR characters, they are displayed */
 	{
 	    char_u	*p;
@@ -2995,10 +3010,11 @@ mch_errmsg(char *str)
 		*p = ' ';
 	    }
 	}
-#endif
+# endif
 	--len;		/* don't count the NUL at the end */
 	error_ga.ga_len += len;
     }
+#endif
 }
 
 /*
@@ -3009,7 +3025,27 @@ mch_errmsg(char *str)
     void
 mch_msg(char *str)
 {
-#if (defined(UNIX) || defined(FEAT_GUI)) && !defined(ALWAYS_USE_GUI)
+#if defined(WIN3264) && !defined(FEAT_GUI_MSWIN)
+    int	    len = STRLEN(str);
+    DWORD   nwrite = 0;
+    DWORD   mode;
+    HANDLE  h = GetStdHandle(STD_OUTPUT_HANDLE);
+
+
+    if (GetConsoleMode(h, &mode) && enc_codepage >= 0
+	    && (int)GetConsoleCP() != enc_codepage)
+    {
+	WCHAR	*w = enc_to_utf16((char_u *)str, &len);
+
+	WriteConsoleW(h, w, len, &nwrite, NULL);
+	vim_free(w);
+    }
+    else
+    {
+	printf("%s", str);
+    }
+#else
+# if (defined(UNIX) || defined(FEAT_GUI)) && !defined(ALWAYS_USE_GUI)
     /* On Unix use stdout if we have a tty.  This allows "vim -h | more" and
      * uses mch_errmsg() when started from the desktop.
      * When not going to start the GUI also use stdout.
@@ -3035,6 +3071,7 @@ mch_msg(char *str)
     }
 # endif
     mch_errmsg(str);
+#endif
 }
 #endif /* USE_MCH_ERRMSG */
 
--- a/src/os_mswin.c
+++ b/src/os_mswin.c
@@ -675,6 +675,7 @@ mch_suspend(void)
 # undef display_errors
 #endif
 
+#ifdef FEAT_GUI
 /*
  * Display the saved error message(s).
  */
@@ -690,13 +691,9 @@ display_errors(void)
 	    if (!isspace(*p))
 	    {
 		(void)gui_mch_dialog(
-#ifdef FEAT_GUI
 				     gui.starting ? VIM_INFO :
-#endif
 					     VIM_ERROR,
-#ifdef FEAT_GUI
 				     gui.starting ? (char_u *)_("Message") :
-#endif
 					     (char_u *)_("Error"),
 				     (char_u *)p, (char_u *)_("&Ok"),
 					1, NULL, FALSE);
@@ -705,6 +702,13 @@ display_errors(void)
 	ga_clear(&error_ga);
     }
 }
+#else
+    void
+display_errors(void)
+{
+    FlushFileBuffers(GetStdHandle(STD_ERROR_HANDLE));
+}
+#endif
 #endif
 
 
--- a/src/version.c
+++ b/src/version.c
@@ -784,6 +784,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    918,
+/**/
     917,
 /**/
     916,
--- a/src/vim.h
+++ b/src/vim.h
@@ -2093,7 +2093,7 @@ typedef enum {
  * functions of these names. The declarations would break if the defines had
  * been seen at that stage.  But it must be before globals.h, where error_ga
  * is declared. */
-#if !defined(FEAT_GUI_W32) && !defined(FEAT_GUI_X11) \
+#if !defined(MSWIN) && !defined(FEAT_GUI_X11) \
 	&& !defined(FEAT_GUI_GTK) && !defined(FEAT_GUI_MAC) && !defined(PROTO)
 # define mch_errmsg(str)	fprintf(stderr, "%s", (str))
 # define display_errors()	fflush(stderr)