open_toontown_panda3d/direct/src/directbase/ppython.cxx

107 lines
2.6 KiB
C++

// This is a little wrapper to make it easy to run a python program from the
// command line. Basically, it just interfaces to the Python API and imports
// the module that was specified by the IMPORT_MODULE preprocessor definition
// when it was compiled.
#include "dtoolbase.h"
#undef _POSIX_C_SOURCE
#undef _XOPEN_SOURCE
#include <Python.h>
#if PY_MAJOR_VERSION >= 3
#include <wchar.h>
#endif
#ifndef IMPORT_MODULE
#error IMPORT_MODULE must be defined when compiling ppython.cxx !
#endif
#define _STRINGIFY(s) #s
#define STRINGIFY(s) _STRINGIFY(s)
#define IMPORT_MODULE_STR STRINGIFY(IMPORT_MODULE)
#if defined(_WIN32) && PY_MAJOR_VERSION >= 3
// As Py_SetProgramName expects a wchar_t*, it's easiest to just use the wmain
// entry point.
int wmain(int argc, wchar_t *argv[]) {
Py_SetProgramName(argv[0]);
#elif PY_MAJOR_VERSION >= 3
// Convert from UTF-8 to wchar_t*.
int main(int argc, char *mb_argv[]) {
wchar_t **argv = new wchar_t*[argc + 1];
for (int i = 0; i < argc; ++i) {
size_t len = mbstowcs(NULL, mb_argv[i], 0);
argv[i] = new wchar_t[len + 1];
mbstowcs(argv[i], mb_argv[i], len);
argv[i][len] = 0;
}
// Just for good measure
argv[argc] = NULL;
Py_SetProgramName(argv[0]);
#else
// Python 2.
int main(int argc, char *argv[]) {
Py_SetProgramName(argv[0]);
#endif
// On Windows, we need to set pythonhome correctly. We'll try to find
// ppython.exe on the path and set pythonhome to its location.
#ifdef _WIN32
#if PY_MAJOR_VERSION >= 3
// Py_SetPythonHome expects a wchar_t in Python 3.
wchar_t *path = _wgetenv(L"PATH");
wchar_t *result = wcstok(path, L";");
while (result != NULL) {
struct _stat st;
wchar_t *ppython = (wchar_t*) malloc(wcslen(result) * 2 + 26);
wcscpy(ppython, result);
wcscat(ppython, L"\\python.exe");
if (_wstat(ppython, &st) == 0) {
Py_SetPythonHome(result);
free(ppython);
break;
}
result = wcstok(NULL, L";");
free(ppython);
}
#else
char *path = getenv("PATH");
char *result = strtok(path, ";");
while (result != NULL) {
struct stat st;
char *ppython = (char*) malloc(strlen(result) + 13);
strcpy(ppython, result);
strcat(ppython, "\\ppython.exe");
if (stat(ppython, &st) == 0) {
Py_SetPythonHome(result);
free(ppython);
break;
}
result = strtok(NULL, ";");
free(ppython);
}
#endif
#endif
Py_Initialize();
if (Py_VerboseFlag) {
fprintf(stderr, "Python %s\\n%s\\n", Py_GetVersion(), Py_GetCopyright());
}
PySys_SetArgv(argc, argv);
int sts = 0;
PyObject* m = PyImport_ImportModule(IMPORT_MODULE_STR);
if (m <= 0) {
PyErr_Print();
sts = 1;
}
Py_Finalize();
return sts;
}