RFC: Alternative for exemaker

Andrei Polushin polushin at gmail.com
Sat Jun 23 06:24:06 CDT 2012


23.06.2012 16:13, Adrian Buehlmann wrote:
> 	Py_Initialize();
> 	ret = Py_Main(n, pyargv);
> 	Py_Finalize();
> 	return ret;

In Python 2.7, main is implemented this way[1]:

    int main(int argc, char **argv)
    {
        return Py_Main(argc, argv);
    }

So, Py_Initialize() is not required.

[1] http://hg.python.org/cpython/file/70274d53c1dd/Modules/python.c


As for me, I don't use hackable Mercurial, but I have had the related
problem when I install Mercurial with using setup.py into a shared
Python installation.

Notice that I'm on Windows, and the installation creates `hg.bat' in
PYTHON_HOME/Scripts directory. A few months ago, I've noticed that this
configuration prevents the Mercurial to work in command server mode,
because the command server mode clients expect the existence of `hg.exe'.

So my guess that not only the Hackable-Mercurial, but also the default
installation should install a little .exe instead of .bat on Windows!

Well, that was slightly off-topic, but the above motivated me to create
short hg.exe similar to yours.

My version has the following properties:

 1) It doesn't link to shlwapi.dll
 2) It assumes the script name is the same as .exe name, but
    without the .exe extension (.py extension is not appended)
 3) It allocates a copy of argv on stack, so the number of arguments
    is not limited by a constant.

The code is as follows:

    #define _CRT_SECURE_NO_DEPRECATE
    #include <malloc.h>
    #include <stdlib.h>
    #include <string.h>
    #include <windows.h>

    #include <Python.h>

    int main(int argc, char* argv[])
    {
        char script[_MAX_PATH];
        GetModuleFileName(NULL, script, _MAX_PATH);

        char* dot = strrchr(script, '.');
        if (!dot) {
            return -1;
        } else {
            *dot = 0; // cut ".exe"
        }

        char** args = (char**)_alloca((argc + 2) * sizeof(char*));
        if (!args) {
            return -2;
        } else {
            args[0] = argv[0];
            args[1] = script;
            for (int i = 1; i <= argc; ++i) {
                args[i + 1] = argv[i];
            }
        }

        return Py_Main(argc + 1, args);
    }

It's worth noting that I link hg.exe to the same runtime as used by the
corresponding Python version. For Python 2.7, it is MSVCR90.DLL

--
Andrei Polushin


More information about the Mercurial-devel mailing list