##// END OF EJS Templates
stream-clone: filter possible missing requirements using all supported one...
stream-clone: filter possible missing requirements using all supported one The `supportedformat` requirements is missing some important requirements and it seems better to filter out with all requirements we know, not just an "arbitrary" subset. The `supportedformat` set is lacking some important requirements (for example `revlog-compression-zstd`). This is getting fixed on default (for Mercurial 6.1) However, fixing that in 6.1 means the stream requirements sent over the wire will contains more items. And if we don't apply this fix on older version, they might end up complaining about lacking support for feature they actually support for years. This patch does not fix the deeper problem (advertised stream requirement lacking some of them), but focus on the trivial part : Lets use the full set of supported requirement for looking for unsupported ones. This patch should be simple to backport to older version of Mercurial and packager should be encouraged to do so. This is a graft of d9017df70135 from default. Differential Revision: https://phab.mercurial-scm.org/D12091

File last commit:

r49125:2ec5fbe2 default
r49522:6d2ddea0 stable
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
Matt Harbison
exewrapper: avoid directly linking against python3X.dll...
r48096 _wputenv(L"PYTHONLEGACYWINDOWSSTDIO=1");
Matt Harbison
py3: enable legacy stdio mode in exewrapper...
r41012 #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;
}