Panda3D
 All Classes Functions Variables Enumerations
ppython.cxx
1 ///////////////////////////////////////////////////////////////////////
2 //
3 // This is a little wrapper to make it easy to run a python
4 // program from the command line. Basically, it just interfaces
5 // to the Python API and imports the module that was specified
6 // by the IMPORT_MODULE preprocessor definition when it was compiled.
7 //
8 ///////////////////////////////////////////////////////////////////////
9 
10 #include "dtoolbase.h"
11 
12 #include <Python.h>
13 #if PY_MAJOR_VERSION >= 3
14 #include <wchar.h>
15 #endif
16 
17 #ifndef IMPORT_MODULE
18 #error IMPORT_MODULE must be defined when compiling ppython.cxx !
19 #endif
20 
21 #define _STRINGIFY(s) #s
22 #define STRINGIFY(s) _STRINGIFY(s)
23 #define IMPORT_MODULE_STR STRINGIFY(IMPORT_MODULE)
24 
25 #if defined(_WIN32) && PY_MAJOR_VERSION >= 3
26 // As Py_SetProgramName expects a wchar_t*,
27 // it's easiest to just use the wmain entry point.
28 int wmain(int argc, wchar_t *argv[]) {
29  Py_SetProgramName(argv[0]);
30 
31 #elif PY_MAJOR_VERSION >= 3
32 // Convert from UTF-8 to wchar_t*.
33 int main(int argc, char *mb_argv[]) {
34  wchar_t **argv = new wchar_t*[argc + 1];
35  for (int i = 0; i < argc; ++i) {
36  size_t len = mbstowcs(NULL, mb_argv[i], 0);
37  argv[i] = new wchar_t[len + 1];
38  mbstowcs(argv[i], mb_argv[i], len);
39  argv[i][len] = NULL;
40  }
41  // Just for good measure
42  argv[argc] = NULL;
43 
44  Py_SetProgramName(argv[0]);
45 
46 #else
47 // Python 2.
48 int main(int argc, char *argv[]) {
49  Py_SetProgramName(argv[0]);
50 #endif
51 
52  // On Windows, we need to set pythonhome correctly. We'll try to
53  // find ppython.exe on the path and set pythonhome to its location.
54 #ifdef _WIN32
55 #if PY_MAJOR_VERSION >= 3
56  // Py_SetPythonHome expects a wchar_t in Python 3.
57  wchar_t *path = _wgetenv(L"PATH");
58  wchar_t *result = wcstok(path, L";");
59  while (result != NULL) {
60  struct _stat st;
61  wchar_t *ppython = (wchar_t*) malloc(wcslen(result) * 2 + 26);
62  wcscpy(ppython, result);
63  wcscat(ppython, L"\\python.exe");
64  if (_wstat(ppython, &st) == 0) {
65  Py_SetPythonHome(result);
66  free(ppython);
67  break;
68  }
69  result = wcstok(NULL, L";");
70  free(ppython);
71  }
72 #else
73  char *path = getenv("PATH");
74  char *result = strtok(path, ";");
75  while (result != NULL) {
76  struct stat st;
77  char *ppython = (char*) malloc(strlen(result) + 13);
78  strcpy(ppython, result);
79  strcat(ppython, "\\ppython.exe");
80  if (stat(ppython, &st) == 0) {
81  Py_SetPythonHome(result);
82  free(ppython);
83  break;
84  }
85  result = strtok(NULL, ";");
86  free(ppython);
87  }
88 #endif
89 #endif
90 
91  Py_Initialize();
92 
93  if (Py_VerboseFlag) {
94  fprintf(stderr, "Python %s\\n%s\\n", Py_GetVersion(), Py_GetCopyright());
95  }
96 
97  PySys_SetArgv(argc, argv);
98 
99  int sts = 0;
100  PyObject* m = PyImport_ImportModule(IMPORT_MODULE_STR);
101  if (m <= 0) {
102  PyErr_Print();
103  sts = 1;
104  }
105 
106  Py_Finalize();
107  return sts;
108 }