Mercurial > hg
comparison mercurial/exewrapper.c @ 40396:973ff03d9bc0
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
author | Matt Harbison <matt_harbison@yahoo.com> |
---|---|
date | Fri, 19 Oct 2018 18:32:13 -0400 |
parents | aca727359ec5 |
children | 36ba91e06948 |
comparison
equal
deleted
inserted
replaced
40395:aca727359ec5 | 40396:973ff03d9bc0 |
---|---|
6 This software may be used and distributed according to the terms of the | 6 This software may be used and distributed according to the terms of the |
7 GNU General Public License version 2 or any later version. | 7 GNU General Public License version 2 or any later version. |
8 */ | 8 */ |
9 | 9 |
10 #include <stdio.h> | 10 #include <stdio.h> |
11 #include <tchar.h> | |
11 #include <windows.h> | 12 #include <windows.h> |
12 | 13 |
13 #include "hgpythonlib.h" | 14 #include "hgpythonlib.h" |
14 | 15 |
15 #ifdef __GNUC__ | 16 #ifdef __GNUC__ |
19 } | 20 } |
20 int strcpy_s(char *d, size_t n, const char *s) | 21 int strcpy_s(char *d, size_t n, const char *s) |
21 { | 22 { |
22 return !strncpy(d, s, n); | 23 return !strncpy(d, s, n); |
23 } | 24 } |
25 | |
26 #define _tcscpy_s strcpy_s | |
27 #define _tcscat_s strcat_s | |
28 #define _countof(array) (sizeof(array)/sizeof(array[0])) | |
24 #endif | 29 #endif |
25 | 30 |
26 static char pyscript[MAX_PATH + 10]; | 31 static TCHAR pyscript[MAX_PATH + 10]; |
27 static char pyhome[MAX_PATH + 10]; | 32 static TCHAR pyhome[MAX_PATH + 10]; |
28 static char pydllfile[MAX_PATH + 10]; | 33 static TCHAR pydllfile[MAX_PATH + 10]; |
29 | 34 |
30 int main(int argc, char *argv[]) | 35 int _tmain(int argc, TCHAR *argv[]) |
31 { | 36 { |
32 char *p; | 37 TCHAR *p; |
33 int ret; | 38 int ret; |
34 int i; | 39 int i; |
35 int n; | 40 int n; |
36 char **pyargv; | 41 TCHAR **pyargv; |
37 WIN32_FIND_DATA fdata; | 42 WIN32_FIND_DATA fdata; |
38 HANDLE hfind; | 43 HANDLE hfind; |
39 const char *err; | 44 const char *err; |
40 HMODULE pydll; | 45 HMODULE pydll; |
41 void(__cdecl * Py_SetPythonHome)(char *home); | 46 void(__cdecl * Py_SetPythonHome)(TCHAR *home); |
42 int(__cdecl * Py_Main)(int argc, char *argv[]); | 47 int(__cdecl * Py_Main)(int argc, TCHAR *argv[]); |
43 | 48 |
44 if (GetModuleFileName(NULL, pyscript, sizeof(pyscript)) == 0) { | 49 if (GetModuleFileName(NULL, pyscript, _countof(pyscript)) == 0) { |
45 err = "GetModuleFileName failed"; | 50 err = "GetModuleFileName failed"; |
46 goto bail; | 51 goto bail; |
47 } | 52 } |
48 | 53 |
49 p = strrchr(pyscript, '.'); | 54 p = _tcsrchr(pyscript, '.'); |
50 if (p == NULL) { | 55 if (p == NULL) { |
51 err = "malformed module filename"; | 56 err = "malformed module filename"; |
52 goto bail; | 57 goto bail; |
53 } | 58 } |
54 *p = 0; /* cut trailing ".exe" */ | 59 *p = 0; /* cut trailing ".exe" */ |
55 strcpy_s(pyhome, sizeof(pyhome), pyscript); | 60 _tcscpy_s(pyhome, _countof(pyhome), pyscript); |
56 | 61 |
57 hfind = FindFirstFile(pyscript, &fdata); | 62 hfind = FindFirstFile(pyscript, &fdata); |
58 if (hfind != INVALID_HANDLE_VALUE) { | 63 if (hfind != INVALID_HANDLE_VALUE) { |
59 /* pyscript exists, close handle */ | 64 /* pyscript exists, close handle */ |
60 FindClose(hfind); | 65 FindClose(hfind); |
61 } else { | 66 } else { |
62 /* file pyscript isn't there, take <pyscript>exe.py */ | 67 /* file pyscript isn't there, take <pyscript>exe.py */ |
63 strcat_s(pyscript, sizeof(pyscript), "exe.py"); | 68 _tcscat_s(pyscript, _countof(pyscript), _T("exe.py")); |
64 } | 69 } |
65 | 70 |
66 pydll = NULL; | 71 pydll = NULL; |
67 | 72 |
68 p = strrchr(pyhome, '\\'); | 73 p = _tcsrchr(pyhome, _T('\\')); |
69 if (p == NULL) { | 74 if (p == NULL) { |
70 err = "can't find backslash in module filename"; | 75 err = "can't find backslash in module filename"; |
71 goto bail; | 76 goto bail; |
72 } | 77 } |
73 *p = 0; /* cut at directory */ | 78 *p = 0; /* cut at directory */ |
74 | 79 |
75 /* check for private Python of HackableMercurial */ | 80 /* check for private Python of HackableMercurial */ |
76 strcat_s(pyhome, sizeof(pyhome), "\\hg-python"); | 81 _tcscat_s(pyhome, _countof(pyhome), _T("\\hg-python")); |
77 | 82 |
78 hfind = FindFirstFile(pyhome, &fdata); | 83 hfind = FindFirstFile(pyhome, &fdata); |
79 if (hfind != INVALID_HANDLE_VALUE) { | 84 if (hfind != INVALID_HANDLE_VALUE) { |
80 /* Path .\hg-python exists. We are probably in HackableMercurial | 85 /* Path .\hg-python exists. We are probably in HackableMercurial |
81 scenario, so let's load python dll from this dir. */ | 86 scenario, so let's load python dll from this dir. */ |
82 FindClose(hfind); | 87 FindClose(hfind); |
83 strcpy_s(pydllfile, sizeof(pydllfile), pyhome); | 88 _tcscpy_s(pydllfile, _countof(pydllfile), pyhome); |
84 strcat_s(pydllfile, sizeof(pydllfile), "\\" HGPYTHONLIB ".dll"); | 89 _tcscat_s(pydllfile, _countof(pydllfile), _T("\\") _T(HGPYTHONLIB) |
90 _T(".dll")); | |
85 pydll = LoadLibrary(pydllfile); | 91 pydll = LoadLibrary(pydllfile); |
86 if (pydll == NULL) { | 92 if (pydll == NULL) { |
87 err = "failed to load private Python DLL " HGPYTHONLIB | 93 err = "failed to load private Python DLL " HGPYTHONLIB ".dll"; |
88 ".dll"; | |
89 goto bail; | 94 goto bail; |
90 } | 95 } |
91 Py_SetPythonHome = | 96 Py_SetPythonHome = |
92 (void *)GetProcAddress(pydll, "Py_SetPythonHome"); | 97 (void *)GetProcAddress(pydll, "Py_SetPythonHome"); |
93 if (Py_SetPythonHome == NULL) { | 98 if (Py_SetPythonHome == NULL) { |
96 } | 101 } |
97 Py_SetPythonHome(pyhome); | 102 Py_SetPythonHome(pyhome); |
98 } | 103 } |
99 | 104 |
100 if (pydll == NULL) { | 105 if (pydll == NULL) { |
101 pydll = LoadLibrary(HGPYTHONLIB ".dll"); | 106 pydll = LoadLibrary(_T(HGPYTHONLIB) _T(".dll")); |
102 if (pydll == NULL) { | 107 if (pydll == NULL) { |
103 err = "failed to load Python DLL " HGPYTHONLIB ".dll"; | 108 err = "failed to load Python DLL " HGPYTHONLIB ".dll"; |
104 goto bail; | 109 goto bail; |
105 } | 110 } |
106 } | 111 } |
116 already be there, if the script spawned a child process of itself, in | 121 already be there, if the script spawned a child process of itself, in |
117 the same way as it got called, that is, with the pyscript already in | 122 the same way as it got called, that is, with the pyscript already in |
118 place. So we optionally accept the pyscript as the first argument | 123 place. So we optionally accept the pyscript as the first argument |
119 (argv[1]), letting our exe taking the role of the python interpreter. | 124 (argv[1]), letting our exe taking the role of the python interpreter. |
120 */ | 125 */ |
121 if (argc >= 2 && strcmp(argv[1], pyscript) == 0) { | 126 if (argc >= 2 && _tcscmp(argv[1], pyscript) == 0) { |
122 /* | 127 /* |
123 pyscript is already in the args, so there is no need to copy | 128 pyscript is already in the args, so there is no need to copy |
124 the args and we can directly call the python interpreter with | 129 the args and we can directly call the python interpreter with |
125 the original args. | 130 the original args. |
126 */ | 131 */ |
130 /* | 135 /* |
131 Start assembling the args for the Python interpreter call. We put the | 136 Start assembling the args for the Python interpreter call. We put the |
132 name of our exe (argv[0]) in the position where the python.exe | 137 name of our exe (argv[0]) in the position where the python.exe |
133 canonically is, and insert the pyscript next. | 138 canonically is, and insert the pyscript next. |
134 */ | 139 */ |
135 pyargv = malloc((argc + 5) * sizeof(char *)); | 140 pyargv = malloc((argc + 5) * sizeof(TCHAR *)); |
136 if (pyargv == NULL) { | 141 if (pyargv == NULL) { |
137 err = "not enough memory"; | 142 err = "not enough memory"; |
138 goto bail; | 143 goto bail; |
139 } | 144 } |
140 n = 0; | 145 n = 0; |