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