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)
diff --git a/src/message.c b/src/message.c
index 063fada..4aa15eb 100644
--- a/src/message.c
+++ b/src/message.c
@@ -2570,57 +2570,45 @@
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 @@
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 @@
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
- ||
-# endif
-# endif
-# ifdef FEAT_GUI
!(gui.in_use || gui.starting)
-# endif
+# 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_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 @@
*p = ' ';
}
}
-#endif
+# endif
--len; /* don't count the NUL at the end */
error_ga.ga_len += len;
}
+#endif
}
/*
@@ -3009,7 +3025,27 @@
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 @@
}
# endif
mch_errmsg(str);
+#endif
}
#endif /* USE_MCH_ERRMSG */