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