##// END OF EJS Templates
exewrapper: apply clang-format to silence test-check-clang-format.t
Yuya Nishihara -
r40452:36ba91e0 stable
parent child Browse files
Show More
@@ -1,163 +1,164
1 1 /*
2 2 exewrapper.c - wrapper for calling a python script on Windows
3 3
4 4 Copyright 2012 Adrian Buehlmann <adrian@cadifra.com> and others
5 5
6 6 This software may be used and distributed according to the terms of the
7 7 GNU General Public License version 2 or any later version.
8 8 */
9 9
10 10 #include <stdio.h>
11 11 #include <tchar.h>
12 12 #include <windows.h>
13 13
14 14 #include "hgpythonlib.h"
15 15
16 16 #ifdef __GNUC__
17 17 int strcat_s(char *d, size_t n, const char *s)
18 18 {
19 19 return !strncat(d, s, n);
20 20 }
21 21 int strcpy_s(char *d, size_t n, const char *s)
22 22 {
23 23 return !strncpy(d, s, n);
24 24 }
25 25
26 26 #define _tcscpy_s strcpy_s
27 27 #define _tcscat_s strcat_s
28 #define _countof(array) (sizeof(array)/sizeof(array[0]))
28 #define _countof(array) (sizeof(array) / sizeof(array[0]))
29 29 #endif
30 30
31 31 static TCHAR pyscript[MAX_PATH + 10];
32 32 static TCHAR pyhome[MAX_PATH + 10];
33 33 static TCHAR pydllfile[MAX_PATH + 10];
34 34
35 35 int _tmain(int argc, TCHAR *argv[])
36 36 {
37 37 TCHAR *p;
38 38 int ret;
39 39 int i;
40 40 int n;
41 41 TCHAR **pyargv;
42 42 WIN32_FIND_DATA fdata;
43 43 HANDLE hfind;
44 44 const char *err;
45 45 HMODULE pydll;
46 void(__cdecl * Py_SetPythonHome)(TCHAR *home);
46 void(__cdecl * Py_SetPythonHome)(TCHAR * home);
47 47 int(__cdecl * Py_Main)(int argc, TCHAR *argv[]);
48 48
49 49 if (GetModuleFileName(NULL, pyscript, _countof(pyscript)) == 0) {
50 50 err = "GetModuleFileName failed";
51 51 goto bail;
52 52 }
53 53
54 54 p = _tcsrchr(pyscript, '.');
55 55 if (p == NULL) {
56 56 err = "malformed module filename";
57 57 goto bail;
58 58 }
59 59 *p = 0; /* cut trailing ".exe" */
60 60 _tcscpy_s(pyhome, _countof(pyhome), pyscript);
61 61
62 62 hfind = FindFirstFile(pyscript, &fdata);
63 63 if (hfind != INVALID_HANDLE_VALUE) {
64 64 /* pyscript exists, close handle */
65 65 FindClose(hfind);
66 66 } else {
67 67 /* file pyscript isn't there, take <pyscript>exe.py */
68 68 _tcscat_s(pyscript, _countof(pyscript), _T("exe.py"));
69 69 }
70 70
71 71 pydll = NULL;
72 72
73 73 p = _tcsrchr(pyhome, _T('\\'));
74 74 if (p == NULL) {
75 75 err = "can't find backslash in module filename";
76 76 goto bail;
77 77 }
78 78 *p = 0; /* cut at directory */
79 79
80 80 /* check for private Python of HackableMercurial */
81 81 _tcscat_s(pyhome, _countof(pyhome), _T("\\hg-python"));
82 82
83 83 hfind = FindFirstFile(pyhome, &fdata);
84 84 if (hfind != INVALID_HANDLE_VALUE) {
85 85 /* Path .\hg-python exists. We are probably in HackableMercurial
86 86 scenario, so let's load python dll from this dir. */
87 87 FindClose(hfind);
88 88 _tcscpy_s(pydllfile, _countof(pydllfile), pyhome);
89 _tcscat_s(pydllfile, _countof(pydllfile), _T("\\") _T(HGPYTHONLIB)
90 _T(".dll"));
89 _tcscat_s(pydllfile, _countof(pydllfile),
90 _T("\\") _T(HGPYTHONLIB) _T(".dll"));
91 91 pydll = LoadLibrary(pydllfile);
92 92 if (pydll == NULL) {
93 err = "failed to load private Python DLL " HGPYTHONLIB ".dll";
93 err = "failed to load private Python DLL " HGPYTHONLIB
94 ".dll";
94 95 goto bail;
95 96 }
96 97 Py_SetPythonHome =
97 98 (void *)GetProcAddress(pydll, "Py_SetPythonHome");
98 99 if (Py_SetPythonHome == NULL) {
99 100 err = "failed to get Py_SetPythonHome";
100 101 goto bail;
101 102 }
102 103 Py_SetPythonHome(pyhome);
103 104 }
104 105
105 106 if (pydll == NULL) {
106 107 pydll = LoadLibrary(_T(HGPYTHONLIB) _T(".dll"));
107 108 if (pydll == NULL) {
108 109 err = "failed to load Python DLL " HGPYTHONLIB ".dll";
109 110 goto bail;
110 111 }
111 112 }
112 113
113 114 Py_Main = (void *)GetProcAddress(pydll, "Py_Main");
114 115 if (Py_Main == NULL) {
115 116 err = "failed to get Py_Main";
116 117 goto bail;
117 118 }
118 119
119 120 /*
120 121 Only add the pyscript to the args, if it's not already there. It may
121 122 already be there, if the script spawned a child process of itself, in
122 123 the same way as it got called, that is, with the pyscript already in
123 124 place. So we optionally accept the pyscript as the first argument
124 125 (argv[1]), letting our exe taking the role of the python interpreter.
125 126 */
126 127 if (argc >= 2 && _tcscmp(argv[1], pyscript) == 0) {
127 128 /*
128 129 pyscript is already in the args, so there is no need to copy
129 130 the args and we can directly call the python interpreter with
130 131 the original args.
131 132 */
132 133 return Py_Main(argc, argv);
133 134 }
134 135
135 136 /*
136 137 Start assembling the args for the Python interpreter call. We put the
137 138 name of our exe (argv[0]) in the position where the python.exe
138 139 canonically is, and insert the pyscript next.
139 140 */
140 141 pyargv = malloc((argc + 5) * sizeof(TCHAR *));
141 142 if (pyargv == NULL) {
142 143 err = "not enough memory";
143 144 goto bail;
144 145 }
145 146 n = 0;
146 147 pyargv[n++] = argv[0];
147 148 pyargv[n++] = pyscript;
148 149
149 150 /* copy remaining args from the command line */
150 151 for (i = 1; i < argc; i++)
151 152 pyargv[n++] = argv[i];
152 153 /* argv[argc] is guaranteed to be NULL, so we forward that guarantee */
153 154 pyargv[n] = NULL;
154 155
155 156 ret = Py_Main(n, pyargv); /* The Python interpreter call */
156 157
157 158 free(pyargv);
158 159 return ret;
159 160
160 161 bail:
161 162 fprintf(stderr, "abort: %s\n", err);
162 163 return 255;
163 164 }
General Comments 0
You need to be logged in to leave comments. Login now