[PATCH 2 of 3] exewrapper: convert to _tcsxxx functions for Unicode compatability

Matt Harbison mharbison72 at gmail.com
Fri Oct 19 18:56:47 EDT 2018


# HG changeset patch
# User Matt Harbison <matt_harbison at yahoo.com>
# Date 1539988333 14400
#      Fri Oct 19 18:32:13 2018 -0400
# Node ID b5a4766f29dd828a64a156d3d9e275b4bbe649a2
# Parent  30eace8f67557ccf4359f4c30e414093059fb27b
exewrapper: convert to _tcsxxx functions for Unicode compatability

This fixes more than 50 tests on py3 on Windows when enabled, mostly hooks and
such that invoked `hg` directly.  187 left to go.

I skipped doing the abort printing with Unicode because of apparent issues with
MinGW [1].  It may be moot though, as MinGW isn't listed as a supported compiler
after 3.4 [2].

[1] https://stackoverflow.com/questions/17700797/printf-wprintf-s-s-ls-char-and-wchar-errors-not-announced-by-a-compil
[2] https://wiki.python.org/moin/WindowsCompilers

diff --git a/mercurial/exewrapper.c b/mercurial/exewrapper.c
--- a/mercurial/exewrapper.c
+++ b/mercurial/exewrapper.c
@@ -8,6 +8,7 @@
 */
 
 #include <stdio.h>
+#include <tchar.h>
 #include <windows.h>
 
 #include "hgpythonlib.h"
@@ -21,38 +22,42 @@ int strcpy_s(char *d, size_t n, const ch
 {
 	return !strncpy(d, s, n);
 }
+
+#define _tcscpy_s strcpy_s
+#define _tcscat_s strcat_s
+#define _countof(array) (sizeof(array)/sizeof(array[0]))
 #endif
 
-static char pyscript[MAX_PATH + 10];
-static char pyhome[MAX_PATH + 10];
-static char pydllfile[MAX_PATH + 10];
+static TCHAR pyscript[MAX_PATH + 10];
+static TCHAR pyhome[MAX_PATH + 10];
+static TCHAR pydllfile[MAX_PATH + 10];
 
-int main(int argc, char *argv[])
+int _tmain(int argc, TCHAR *argv[])
 {
-	char *p;
+	TCHAR *p;
 	int ret;
 	int i;
 	int n;
-	char **pyargv;
+	TCHAR **pyargv;
 	WIN32_FIND_DATA fdata;
 	HANDLE hfind;
 	const char *err;
 	HMODULE pydll;
-	void(__cdecl * Py_SetPythonHome)(char *home);
-	int(__cdecl * Py_Main)(int argc, char *argv[]);
+	void(__cdecl * Py_SetPythonHome)(TCHAR *home);
+	int(__cdecl * Py_Main)(int argc, TCHAR *argv[]);
 
-	if (GetModuleFileName(NULL, pyscript, sizeof(pyscript)) == 0) {
+	if (GetModuleFileName(NULL, pyscript, _countof(pyscript)) == 0) {
 		err = "GetModuleFileName failed";
 		goto bail;
 	}
 
-	p = strrchr(pyscript, '.');
+	p = _tcsrchr(pyscript, '.');
 	if (p == NULL) {
 		err = "malformed module filename";
 		goto bail;
 	}
 	*p = 0; /* cut trailing ".exe" */
-	strcpy_s(pyhome, sizeof(pyhome), pyscript);
+	_tcscpy_s(pyhome, _countof(pyhome), pyscript);
 
 	hfind = FindFirstFile(pyscript, &fdata);
 	if (hfind != INVALID_HANDLE_VALUE) {
@@ -60,12 +65,12 @@ int main(int argc, char *argv[])
 		FindClose(hfind);
 	} else {
 		/* file pyscript isn't there, take <pyscript>exe.py */
-		strcat_s(pyscript, sizeof(pyscript), "exe.py");
+		_tcscat_s(pyscript, _countof(pyscript), _T("exe.py"));
 	}
 
 	pydll = NULL;
 
-	p = strrchr(pyhome, '\\');
+	p = _tcsrchr(pyhome, _T('\\'));
 	if (p == NULL) {
 		err = "can't find backslash in module filename";
 		goto bail;
@@ -73,19 +78,19 @@ int main(int argc, char *argv[])
 	*p = 0; /* cut at directory */
 
 	/* check for private Python of HackableMercurial */
-	strcat_s(pyhome, sizeof(pyhome), "\\hg-python");
+	_tcscat_s(pyhome, _countof(pyhome), _T("\\hg-python"));
 
 	hfind = FindFirstFile(pyhome, &fdata);
 	if (hfind != INVALID_HANDLE_VALUE) {
 		/* Path .\hg-python exists. We are probably in HackableMercurial
 		scenario, so let's load python dll from this dir. */
 		FindClose(hfind);
-		strcpy_s(pydllfile, sizeof(pydllfile), pyhome);
-		strcat_s(pydllfile, sizeof(pydllfile), "\\" HGPYTHONLIB ".dll");
+		_tcscpy_s(pydllfile, _countof(pydllfile), pyhome);
+		_tcscat_s(pydllfile, _countof(pydllfile), _T("\\") _T(HGPYTHONLIB)
+					_T(".dll"));
 		pydll = LoadLibrary(pydllfile);
 		if (pydll == NULL) {
-			err = "failed to load private Python DLL " HGPYTHONLIB
-			      ".dll";
+			err = "failed to load private Python DLL " HGPYTHONLIB ".dll";
 			goto bail;
 		}
 		Py_SetPythonHome =
@@ -98,7 +103,7 @@ int main(int argc, char *argv[])
 	}
 
 	if (pydll == NULL) {
-		pydll = LoadLibrary(HGPYTHONLIB ".dll");
+		pydll = LoadLibrary(_T(HGPYTHONLIB) _T(".dll"));
 		if (pydll == NULL) {
 			err = "failed to load Python DLL " HGPYTHONLIB ".dll";
 			goto bail;
@@ -118,7 +123,7 @@ int main(int argc, char *argv[])
 	place. So we optionally accept the pyscript as the first argument
 	(argv[1]), letting our exe taking the role of the python interpreter.
 	*/
-	if (argc >= 2 && strcmp(argv[1], pyscript) == 0) {
+	if (argc >= 2 && _tcscmp(argv[1], pyscript) == 0) {
 		/*
 		pyscript is already in the args, so there is no need to copy
 		the args and we can directly call the python interpreter with
@@ -132,7 +137,7 @@ int main(int argc, char *argv[])
 	name of our exe (argv[0]) in the position where the python.exe
 	canonically is, and insert the pyscript next.
 	*/
-	pyargv = malloc((argc + 5) * sizeof(char *));
+	pyargv = malloc((argc + 5) * sizeof(TCHAR *));
 	if (pyargv == NULL) {
 		err = "not enough memory";
 		goto bail;


More information about the Mercurial-devel mailing list