ppython.cxx 2.6 KB

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