[PATCH 1/3] chcp: Add internationalization support

Hugh McMaster hugh.mcmaster at outlook.com
Tue Nov 23 06:41:38 CST 2021


Signed-off-by: Hugh McMaster <hugh.mcmaster at outlook.com>
---
 programs/chcp.com/Makefile.in |  5 ++-
 programs/chcp.com/chcp.rc     | 29 ++++++++++++++
 programs/chcp.com/main.c      | 75 ++++++++++++++++++++++++++++++++---
 programs/chcp.com/resource.h  | 24 +++++++++++
 4 files changed, 127 insertions(+), 6 deletions(-)
 create mode 100644 programs/chcp.com/chcp.rc
 create mode 100644 programs/chcp.com/resource.h

diff --git a/programs/chcp.com/Makefile.in b/programs/chcp.com/Makefile.in
index 46ed25f3cea..2f6d273990a 100644
--- a/programs/chcp.com/Makefile.in
+++ b/programs/chcp.com/Makefile.in
@@ -1,6 +1,9 @@
-MODULE    = chcp.com
+MODULE = chcp.com
+DELAYIMPORTS = user32
 
 EXTRADLLFLAGS = -mconsole -municode
 
 C_SRCS = \
 	main.c
+
+RC_SRCS = chcp.rc
diff --git a/programs/chcp.com/chcp.rc b/programs/chcp.com/chcp.rc
new file mode 100644
index 00000000000..04d90d05942
--- /dev/null
+++ b/programs/chcp.com/chcp.rc
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2021 Hugh McMaster
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "resource.h"
+
+#pragma makedep po
+
+LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
+
+STRINGTABLE
+{
+    STRING_ACTIVE_CODE_PAGE, "Active code page: %1!u!\n"
+    STRING_INVALID_CODE_PAGE, "Invalid code page\n"
+}
diff --git a/programs/chcp.com/main.c b/programs/chcp.com/main.c
index 6ace10cf93e..5b3486a4366 100644
--- a/programs/chcp.com/main.c
+++ b/programs/chcp.com/main.c
@@ -16,20 +16,85 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-#include "wine/debug.h"
+#include <windows.h>
+#include <stdlib.h>
+#include "resource.h"
 
-#include "wincon.h"
-#include "stdlib.h"
+#include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(chcp);
 
+static void output_writeconsole(const WCHAR *str, DWORD wlen)
+{
+    DWORD count, ret;
+
+    ret = WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), str, wlen, &count, NULL);
+    if (!ret)
+    {
+        DWORD len;
+        char  *msgA;
+
+        /* On Windows WriteConsoleW() fails if the output is redirected. So fall
+         * back to WriteFile(), assuming the console encoding is still the right
+         * one in that case.
+         */
+        len = WideCharToMultiByte(GetConsoleOutputCP(), 0, str, wlen, NULL, 0, NULL, NULL);
+        msgA = malloc(len);
+
+        WideCharToMultiByte(GetConsoleOutputCP(), 0, str, wlen, msgA, len, NULL, NULL);
+        WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), msgA, len, &count, FALSE);
+        free(msgA);
+    }
+}
+
+static void output_formatstring(const WCHAR *fmt, va_list va_args)
+{
+    WCHAR *str;
+    DWORD len;
+
+    len = FormatMessageW(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ALLOCATE_BUFFER,
+                         fmt, 0, 0, (WCHAR *)&str, 0, &va_args);
+    if (!len && GetLastError() != ERROR_NO_WORK_DONE)
+    {
+        WINE_FIXME("Could not format string: le=%u, fmt=%s\n", GetLastError(), wine_dbgstr_w(fmt));
+        return;
+    }
+    output_writeconsole(str, len);
+    LocalFree(str);
+}
+
+static void WINAPIV output_message(unsigned int id, ...)
+{
+    WCHAR *fmt = NULL;
+    int len;
+    va_list va_args;
+
+    if (!(len = LoadStringW(GetModuleHandleW(NULL), id, (WCHAR *)&fmt, 0)))
+    {
+        WINE_FIXME("LoadString failed with %d\n", GetLastError());
+        return;
+    }
+
+    len++;
+    fmt = malloc(len * sizeof(WCHAR));
+    if (!fmt) return;
+
+    LoadStringW(GetModuleHandleW(NULL), id, fmt, len);
+
+    va_start(va_args, id);
+    output_formatstring(fmt, va_args);
+    va_end(va_args);
+
+    free(fmt);
+}
+
 int __cdecl wmain(int argc, WCHAR *argv[])
 {
     int i;
 
     if (argc == 1)
     {
-        printf("Active code page: %d\n", GetConsoleCP());
+        output_message(STRING_ACTIVE_CODE_PAGE, GetConsoleCP());
         return 0;
     }
     else if (argc == 2)
@@ -39,7 +104,7 @@ int __cdecl wmain(int argc, WCHAR *argv[])
 
         if (!success)
         {
-            printf("Invalid code page\n");
+            output_message(STRING_INVALID_CODE_PAGE);
         }
         return !success;
     }
diff --git a/programs/chcp.com/resource.h b/programs/chcp.com/resource.h
new file mode 100644
index 00000000000..200cbb11d18
--- /dev/null
+++ b/programs/chcp.com/resource.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2021 Hugh McMaster
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <windef.h>
+
+/* Translation IDs */
+
+#define STRING_ACTIVE_CODE_PAGE   100
+#define STRING_INVALID_CODE_PAGE  101
-- 
2.34.0




More information about the wine-devel mailing list