##// END OF EJS Templates
exewrapper: use generic term script...
Adrian Buehlmann -
r17063:3fbc6e3a default
parent child Browse files
Show More
@@ -1,101 +1,101 b''
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 <Python.h>
10 #include <Python.h>
11 #include <windows.h>
11 #include <windows.h>
12
12
13
13
14 #ifdef __GNUC__
14 #ifdef __GNUC__
15 int strcat_s(char *d, size_t n, const char *s)
15 int strcat_s(char *d, size_t n, const char *s)
16 {
16 {
17 return !strncat(d, s, n);
17 return !strncat(d, s, n);
18 }
18 }
19 #endif
19 #endif
20
20
21
21
22 static char pyscript[MAX_PATH + 10];
22 static char pyscript[MAX_PATH + 10];
23
23
24 int main(int argc, char *argv[])
24 int main(int argc, char *argv[])
25 {
25 {
26 char *dot;
26 char *dot;
27 int ret;
27 int ret;
28 int i;
28 int i;
29 int n;
29 int n;
30 char **pyargv;
30 char **pyargv;
31 WIN32_FIND_DATA fdata;
31 WIN32_FIND_DATA fdata;
32 HANDLE hfind;
32 HANDLE hfind;
33 const char *err;
33 const char *err;
34
34
35 if (GetModuleFileName(NULL, pyscript, sizeof(pyscript)) == 0)
35 if (GetModuleFileName(NULL, pyscript, sizeof(pyscript)) == 0)
36 {
36 {
37 err = "GetModuleFileName failed";
37 err = "GetModuleFileName failed";
38 goto bail;
38 goto bail;
39 }
39 }
40
40
41 dot = strrchr(pyscript, '.');
41 dot = strrchr(pyscript, '.');
42 if (dot == NULL) {
42 if (dot == NULL) {
43 err = "malformed module filename";
43 err = "malformed module filename";
44 goto bail;
44 goto bail;
45 }
45 }
46 *dot = 0; /* cut trailing ".exe" */
46 *dot = 0; /* cut trailing ".exe" */
47
47
48 hfind = FindFirstFile(pyscript, &fdata);
48 hfind = FindFirstFile(pyscript, &fdata);
49 if (hfind != INVALID_HANDLE_VALUE) {
49 if (hfind != INVALID_HANDLE_VALUE) {
50 /* pyscript exists, close handle */
50 /* pyscript exists, close handle */
51 FindClose(hfind);
51 FindClose(hfind);
52 } else {
52 } else {
53 /* file pyscript isn't there, take <pyscript>exe.py */
53 /* file pyscript isn't there, take <pyscript>exe.py */
54 strcat_s(pyscript, sizeof(pyscript), "exe.py");
54 strcat_s(pyscript, sizeof(pyscript), "exe.py");
55 }
55 }
56
56
57 /*
57 /*
58 Only add the pyscript to the args, if it's not already there. It may
58 Only add the pyscript to the args, if it's not already there. It may
59 already be there, if Mercurial spawned a child process of itself, in
59 already be there, if the script spawned a child process of itself, in
60 the same way as it got called, that is, with the pyscript already in
60 the same way as it got called, that is, with the pyscript already in
61 place. So we optionally accept the pyscript as the first argument
61 place. So we optionally accept the pyscript as the first argument
62 (argv[1]), letting our exe taking the role of the python interpreter.
62 (argv[1]), letting our exe taking the role of the python interpreter.
63 */
63 */
64 if (argc >= 2 && strcmp(argv[1], pyscript) == 0) {
64 if (argc >= 2 && strcmp(argv[1], pyscript) == 0) {
65 /*
65 /*
66 pyscript is already in the args, so there is no need to copy
66 pyscript is already in the args, so there is no need to copy
67 the args and we can directly call the python interpreter with
67 the args and we can directly call the python interpreter with
68 the original args.
68 the original args.
69 */
69 */
70 return Py_Main(argc, argv);
70 return Py_Main(argc, argv);
71 }
71 }
72
72
73 /*
73 /*
74 Start assembling the args for the Python interpreter call. We put the
74 Start assembling the args for the Python interpreter call. We put the
75 name of our exe (argv[0]) in the position where the python.exe
75 name of our exe (argv[0]) in the position where the python.exe
76 canonically is, and insert the pyscript next.
76 canonically is, and insert the pyscript next.
77 */
77 */
78 pyargv = malloc((argc + 5) * sizeof(char*));
78 pyargv = malloc((argc + 5) * sizeof(char*));
79 if (pyargv == NULL) {
79 if (pyargv == NULL) {
80 err = "not enough memory";
80 err = "not enough memory";
81 goto bail;
81 goto bail;
82 }
82 }
83 n = 0;
83 n = 0;
84 pyargv[n++] = argv[0];
84 pyargv[n++] = argv[0];
85 pyargv[n++] = pyscript;
85 pyargv[n++] = pyscript;
86
86
87 /* copy remaining args from the command line */
87 /* copy remaining args from the command line */
88 for (i = 1; i < argc; i++)
88 for (i = 1; i < argc; i++)
89 pyargv[n++] = argv[i];
89 pyargv[n++] = argv[i];
90 /* argv[argc] is guaranteed to be NULL, so we forward that guarantee */
90 /* argv[argc] is guaranteed to be NULL, so we forward that guarantee */
91 pyargv[n] = NULL;
91 pyargv[n] = NULL;
92
92
93 ret = Py_Main(n, pyargv); /* The Python interpreter call */
93 ret = Py_Main(n, pyargv); /* The Python interpreter call */
94
94
95 free(pyargv);
95 free(pyargv);
96 return ret;
96 return ret;
97
97
98 bail:
98 bail:
99 fprintf(stderr, "abort: %s\n", err);
99 fprintf(stderr, "abort: %s\n", err);
100 return 255;
100 return 255;
101 }
101 }
General Comments 0
You need to be logged in to leave comments. Login now