##// END OF EJS Templates
subrepo: demonstrate broken `hg files` with ui.relative-paths=no...
subrepo: demonstrate broken `hg files` with ui.relative-paths=no Differential Revision: https://phab.mercurial-scm.org/D5977

File last commit:

r41012:ef7119cd default
r41897:61cb59d0 default
Show More
exewrapper.c
169 lines | 4.2 KiB | text/x-c | CLexer
Adrian Buehlmann
exewrapper: adding new exewrapper.c
r17058 /*
exewrapper.c - wrapper for calling a python script on Windows
Copyright 2012 Adrian Buehlmann <adrian@cadifra.com> and others
This software may be used and distributed according to the terms of the
GNU General Public License version 2 or any later version.
*/
Matt Harbison
py3: enable legacy stdio mode in exewrapper...
r41012 #include <Python.h>
Adrian Buehlmann
exewrapper: adapt for legacy HackableMercurial...
r17732 #include <stdio.h>
Matt Harbison
exewrapper: convert to _tcsxxx functions for Unicode compatability...
r40432 #include <tchar.h>
Adrian Buehlmann
exewrapper: adding new exewrapper.c
r17058 #include <windows.h>
Adrian Buehlmann
exewrapper: adapt for legacy HackableMercurial...
r17732 #include "hgpythonlib.h"
Adrian Buehlmann
exewrapper: adding new exewrapper.c
r17058
#ifdef __GNUC__
int strcat_s(char *d, size_t n, const char *s)
{
return !strncat(d, s, n);
}
Adrian Buehlmann
exewrapper: adapt for legacy HackableMercurial...
r17732 int strcpy_s(char *d, size_t n, const char *s)
{
return !strncpy(d, s, n);
}
Matt Harbison
exewrapper: convert to _tcsxxx functions for Unicode compatability...
r40432
#define _tcscpy_s strcpy_s
#define _tcscat_s strcat_s
Yuya Nishihara
exewrapper: apply clang-format to silence test-check-clang-format.t
r40452 #define _countof(array) (sizeof(array) / sizeof(array[0]))
Adrian Buehlmann
exewrapper: adding new exewrapper.c
r17058 #endif
Matt Harbison
exewrapper: convert to _tcsxxx functions for Unicode compatability...
r40432 static TCHAR pyscript[MAX_PATH + 10];
static TCHAR pyhome[MAX_PATH + 10];
static TCHAR pydllfile[MAX_PATH + 10];
Adrian Buehlmann
exewrapper: adding new exewrapper.c
r17058
Matt Harbison
exewrapper: convert to _tcsxxx functions for Unicode compatability...
r40432 int _tmain(int argc, TCHAR *argv[])
Adrian Buehlmann
exewrapper: adding new exewrapper.c
r17058 {
Matt Harbison
exewrapper: convert to _tcsxxx functions for Unicode compatability...
r40432 TCHAR *p;
Adrian Buehlmann
exewrapper: adding new exewrapper.c
r17058 int ret;
int i;
int n;
Matt Harbison
exewrapper: convert to _tcsxxx functions for Unicode compatability...
r40432 TCHAR **pyargv;
Adrian Buehlmann
exewrapper: adding new exewrapper.c
r17058 WIN32_FIND_DATA fdata;
HANDLE hfind;
const char *err;
Adrian Buehlmann
exewrapper: adapt for legacy HackableMercurial...
r17732 HMODULE pydll;
Yuya Nishihara
exewrapper: apply clang-format to silence test-check-clang-format.t
r40452 void(__cdecl * Py_SetPythonHome)(TCHAR * home);
Matt Harbison
exewrapper: convert to _tcsxxx functions for Unicode compatability...
r40432 int(__cdecl * Py_Main)(int argc, TCHAR *argv[]);
Adrian Buehlmann
exewrapper: adding new exewrapper.c
r17058
Matt Harbison
py3: enable legacy stdio mode in exewrapper...
r41012 #if PY_MAJOR_VERSION >= 3
Py_LegacyWindowsStdioFlag = 1;
#endif
Matt Harbison
exewrapper: convert to _tcsxxx functions for Unicode compatability...
r40432 if (GetModuleFileName(NULL, pyscript, _countof(pyscript)) == 0) {
Adrian Buehlmann
exewrapper: adding new exewrapper.c
r17058 err = "GetModuleFileName failed";
goto bail;
}
Matt Harbison
exewrapper: convert to _tcsxxx functions for Unicode compatability...
r40432 p = _tcsrchr(pyscript, '.');
Adrian Buehlmann
exewrapper: adapt for legacy HackableMercurial...
r17732 if (p == NULL) {
Adrian Buehlmann
exewrapper: adding new exewrapper.c
r17058 err = "malformed module filename";
goto bail;
}
Adrian Buehlmann
exewrapper: adapt for legacy HackableMercurial...
r17732 *p = 0; /* cut trailing ".exe" */
Matt Harbison
exewrapper: convert to _tcsxxx functions for Unicode compatability...
r40432 _tcscpy_s(pyhome, _countof(pyhome), pyscript);
Adrian Buehlmann
exewrapper: adding new exewrapper.c
r17058
hfind = FindFirstFile(pyscript, &fdata);
if (hfind != INVALID_HANDLE_VALUE) {
/* pyscript exists, close handle */
FindClose(hfind);
} else {
/* file pyscript isn't there, take <pyscript>exe.py */
Matt Harbison
exewrapper: convert to _tcsxxx functions for Unicode compatability...
r40432 _tcscat_s(pyscript, _countof(pyscript), _T("exe.py"));
Adrian Buehlmann
exewrapper: adding new exewrapper.c
r17058 }
Adrian Buehlmann
exewrapper: adapt for legacy HackableMercurial...
r17732 pydll = NULL;
Kostia Balytskyi
exewrapper: prefer HackableMercurial python if availbale...
r31443
Matt Harbison
exewrapper: convert to _tcsxxx functions for Unicode compatability...
r40432 p = _tcsrchr(pyhome, _T('\\'));
Kostia Balytskyi
exewrapper: prefer HackableMercurial python if availbale...
r31443 if (p == NULL) {
err = "can't find backslash in module filename";
goto bail;
}
*p = 0; /* cut at directory */
/* check for private Python of HackableMercurial */
Matt Harbison
exewrapper: convert to _tcsxxx functions for Unicode compatability...
r40432 _tcscat_s(pyhome, _countof(pyhome), _T("\\hg-python"));
Adrian Buehlmann
exewrapper: adapt for legacy HackableMercurial...
r17732
Kostia Balytskyi
exewrapper: prefer HackableMercurial python if availbale...
r31443 hfind = FindFirstFile(pyhome, &fdata);
if (hfind != INVALID_HANDLE_VALUE) {
/* Path .\hg-python exists. We are probably in HackableMercurial
scenario, so let's load python dll from this dir. */
FindClose(hfind);
Matt Harbison
exewrapper: convert to _tcsxxx functions for Unicode compatability...
r40432 _tcscpy_s(pydllfile, _countof(pydllfile), pyhome);
Yuya Nishihara
exewrapper: apply clang-format to silence test-check-clang-format.t
r40452 _tcscat_s(pydllfile, _countof(pydllfile),
_T("\\") _T(HGPYTHONLIB) _T(".dll"));
Kostia Balytskyi
exewrapper: prefer HackableMercurial python if availbale...
r31443 pydll = LoadLibrary(pydllfile);
if (pydll == NULL) {
Yuya Nishihara
exewrapper: apply clang-format to silence test-check-clang-format.t
r40452 err = "failed to load private Python DLL " HGPYTHONLIB
".dll";
Adrian Buehlmann
exewrapper: adapt for legacy HackableMercurial...
r17732 goto bail;
}
Augie Fackler
exewrapper: format with clang-format...
r34637 Py_SetPythonHome =
(void *)GetProcAddress(pydll, "Py_SetPythonHome");
Kostia Balytskyi
exewrapper: prefer HackableMercurial python if availbale...
r31443 if (Py_SetPythonHome == NULL) {
err = "failed to get Py_SetPythonHome";
goto bail;
Adrian Buehlmann
exewrapper: adapt for legacy HackableMercurial...
r17732 }
Kostia Balytskyi
exewrapper: prefer HackableMercurial python if availbale...
r31443 Py_SetPythonHome(pyhome);
Adrian Buehlmann
exewrapper: adapt for legacy HackableMercurial...
r17732 }
if (pydll == NULL) {
Matt Harbison
exewrapper: convert to _tcsxxx functions for Unicode compatability...
r40432 pydll = LoadLibrary(_T(HGPYTHONLIB) _T(".dll"));
Adrian Buehlmann
exewrapper: adapt for legacy HackableMercurial...
r17732 if (pydll == NULL) {
Adrian Buehlmann
exewrapper: report name of failed DLL in error message...
r26662 err = "failed to load Python DLL " HGPYTHONLIB ".dll";
Adrian Buehlmann
exewrapper: adapt for legacy HackableMercurial...
r17732 goto bail;
}
}
Augie Fackler
exewrapper: format with clang-format...
r34637 Py_Main = (void *)GetProcAddress(pydll, "Py_Main");
Adrian Buehlmann
exewrapper: adapt for legacy HackableMercurial...
r17732 if (Py_Main == NULL) {
err = "failed to get Py_Main";
goto bail;
}
Adrian Buehlmann
exewrapper: adding new exewrapper.c
r17058 /*
Only add the pyscript to the args, if it's not already there. It may
Adrian Buehlmann
exewrapper: use generic term script...
r17063 already be there, if the script spawned a child process of itself, in
Adrian Buehlmann
exewrapper: adding new exewrapper.c
r17058 the same way as it got called, that is, with the pyscript already in
place. So we optionally accept the pyscript as the first argument
(argv[1]), letting our exe taking the role of the python interpreter.
*/
Matt Harbison
exewrapper: convert to _tcsxxx functions for Unicode compatability...
r40432 if (argc >= 2 && _tcscmp(argv[1], pyscript) == 0) {
Adrian Buehlmann
exewrapper: adding new exewrapper.c
r17058 /*
pyscript is already in the args, so there is no need to copy
the args and we can directly call the python interpreter with
the original args.
*/
return Py_Main(argc, argv);
}
/*
Start assembling the args for the Python interpreter call. We put the
name of our exe (argv[0]) in the position where the python.exe
canonically is, and insert the pyscript next.
*/
Matt Harbison
exewrapper: convert to _tcsxxx functions for Unicode compatability...
r40432 pyargv = malloc((argc + 5) * sizeof(TCHAR *));
Adrian Buehlmann
exewrapper: adding new exewrapper.c
r17058 if (pyargv == NULL) {
err = "not enough memory";
goto bail;
}
n = 0;
pyargv[n++] = argv[0];
pyargv[n++] = pyscript;
/* copy remaining args from the command line */
for (i = 1; i < argc; i++)
pyargv[n++] = argv[i];
/* argv[argc] is guaranteed to be NULL, so we forward that guarantee */
pyargv[n] = NULL;
ret = Py_Main(n, pyargv); /* The Python interpreter call */
free(pyargv);
return ret;
bail:
fprintf(stderr, "abort: %s\n", err);
return 255;
}