You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

116 lines
3.1 KiB

bpo-32030: Split Py_Main() into subfunctions (#4399) * Don't use "Python runtime" anymore to parse command line options or to get environment variables: pymain_init() is now a strict separation. * Use an error message rather than "crashing" directly with Py_FatalError(). Limit the number of calls to Py_FatalError(). It prepares the code to handle errors more nicely later. * Warnings options (-W, PYTHONWARNINGS) and "XOptions" (-X) are now only added to the sys module once Python core is properly initialized. * _PyMain is now the well identified owner of some important strings like: warnings options, XOptions, and the "program name". The program name string is now properly freed at exit. pymain_free() is now responsible to free the "command" string. * Rename most methods in Modules/main.c to use a "pymain_" prefix to avoid conflits and ease debug. * Replace _Py_CommandLineDetails_INIT with memset(0) * Reorder a lot of code to fix the initialization ordering. For example, initializing standard streams now comes before parsing PYTHONWARNINGS. * Py_Main() now handles errors when adding warnings options and XOptions. * Add _PyMem_GetDefaultRawAllocator() private function. * Cleanup _PyMem_Initialize(): remove useless global constants: move them into _PyMem_Initialize(). * Call _PyRuntime_Initialize() as soon as possible: _PyRuntime_Initialize() now returns an error message on failure. * Add _PyInitError structure and following macros: * _Py_INIT_OK() * _Py_INIT_ERR(msg) * _Py_INIT_USER_ERR(msg): "user" error, don't abort() in that case * _Py_INIT_FAILED(err)
8 years ago
bpo-32030: Split Py_Main() into subfunctions (#4399) * Don't use "Python runtime" anymore to parse command line options or to get environment variables: pymain_init() is now a strict separation. * Use an error message rather than "crashing" directly with Py_FatalError(). Limit the number of calls to Py_FatalError(). It prepares the code to handle errors more nicely later. * Warnings options (-W, PYTHONWARNINGS) and "XOptions" (-X) are now only added to the sys module once Python core is properly initialized. * _PyMain is now the well identified owner of some important strings like: warnings options, XOptions, and the "program name". The program name string is now properly freed at exit. pymain_free() is now responsible to free the "command" string. * Rename most methods in Modules/main.c to use a "pymain_" prefix to avoid conflits and ease debug. * Replace _Py_CommandLineDetails_INIT with memset(0) * Reorder a lot of code to fix the initialization ordering. For example, initializing standard streams now comes before parsing PYTHONWARNINGS. * Py_Main() now handles errors when adding warnings options and XOptions. * Add _PyMem_GetDefaultRawAllocator() private function. * Cleanup _PyMem_Initialize(): remove useless global constants: move them into _PyMem_Initialize(). * Call _PyRuntime_Initialize() as soon as possible: _PyRuntime_Initialize() now returns an error message on failure. * Add _PyInitError structure and following macros: * _Py_INIT_OK() * _Py_INIT_ERR(msg) * _Py_INIT_USER_ERR(msg): "user" error, don't abort() in that case * _Py_INIT_FAILED(err)
8 years ago
bpo-32030: Split Py_Main() into subfunctions (#4399) * Don't use "Python runtime" anymore to parse command line options or to get environment variables: pymain_init() is now a strict separation. * Use an error message rather than "crashing" directly with Py_FatalError(). Limit the number of calls to Py_FatalError(). It prepares the code to handle errors more nicely later. * Warnings options (-W, PYTHONWARNINGS) and "XOptions" (-X) are now only added to the sys module once Python core is properly initialized. * _PyMain is now the well identified owner of some important strings like: warnings options, XOptions, and the "program name". The program name string is now properly freed at exit. pymain_free() is now responsible to free the "command" string. * Rename most methods in Modules/main.c to use a "pymain_" prefix to avoid conflits and ease debug. * Replace _Py_CommandLineDetails_INIT with memset(0) * Reorder a lot of code to fix the initialization ordering. For example, initializing standard streams now comes before parsing PYTHONWARNINGS. * Py_Main() now handles errors when adding warnings options and XOptions. * Add _PyMem_GetDefaultRawAllocator() private function. * Cleanup _PyMem_Initialize(): remove useless global constants: move them into _PyMem_Initialize(). * Call _PyRuntime_Initialize() as soon as possible: _PyRuntime_Initialize() now returns an error message on failure. * Add _PyInitError structure and following macros: * _Py_INIT_OK() * _Py_INIT_ERR(msg) * _Py_INIT_USER_ERR(msg): "user" error, don't abort() in that case * _Py_INIT_FAILED(err)
8 years ago
bpo-32030: Split Py_Main() into subfunctions (#4399) * Don't use "Python runtime" anymore to parse command line options or to get environment variables: pymain_init() is now a strict separation. * Use an error message rather than "crashing" directly with Py_FatalError(). Limit the number of calls to Py_FatalError(). It prepares the code to handle errors more nicely later. * Warnings options (-W, PYTHONWARNINGS) and "XOptions" (-X) are now only added to the sys module once Python core is properly initialized. * _PyMain is now the well identified owner of some important strings like: warnings options, XOptions, and the "program name". The program name string is now properly freed at exit. pymain_free() is now responsible to free the "command" string. * Rename most methods in Modules/main.c to use a "pymain_" prefix to avoid conflits and ease debug. * Replace _Py_CommandLineDetails_INIT with memset(0) * Reorder a lot of code to fix the initialization ordering. For example, initializing standard streams now comes before parsing PYTHONWARNINGS. * Py_Main() now handles errors when adding warnings options and XOptions. * Add _PyMem_GetDefaultRawAllocator() private function. * Cleanup _PyMem_Initialize(): remove useless global constants: move them into _PyMem_Initialize(). * Call _PyRuntime_Initialize() as soon as possible: _PyRuntime_Initialize() now returns an error message on failure. * Add _PyInitError structure and following macros: * _Py_INIT_OK() * _Py_INIT_ERR(msg) * _Py_INIT_USER_ERR(msg): "user" error, don't abort() in that case * _Py_INIT_FAILED(err)
8 years ago
bpo-32030: Split Py_Main() into subfunctions (#4399) * Don't use "Python runtime" anymore to parse command line options or to get environment variables: pymain_init() is now a strict separation. * Use an error message rather than "crashing" directly with Py_FatalError(). Limit the number of calls to Py_FatalError(). It prepares the code to handle errors more nicely later. * Warnings options (-W, PYTHONWARNINGS) and "XOptions" (-X) are now only added to the sys module once Python core is properly initialized. * _PyMain is now the well identified owner of some important strings like: warnings options, XOptions, and the "program name". The program name string is now properly freed at exit. pymain_free() is now responsible to free the "command" string. * Rename most methods in Modules/main.c to use a "pymain_" prefix to avoid conflits and ease debug. * Replace _Py_CommandLineDetails_INIT with memset(0) * Reorder a lot of code to fix the initialization ordering. For example, initializing standard streams now comes before parsing PYTHONWARNINGS. * Py_Main() now handles errors when adding warnings options and XOptions. * Add _PyMem_GetDefaultRawAllocator() private function. * Cleanup _PyMem_Initialize(): remove useless global constants: move them into _PyMem_Initialize(). * Call _PyRuntime_Initialize() as soon as possible: _PyRuntime_Initialize() now returns an error message on failure. * Add _PyInitError structure and following macros: * _Py_INIT_OK() * _Py_INIT_ERR(msg) * _Py_INIT_USER_ERR(msg): "user" error, don't abort() in that case * _Py_INIT_FAILED(err)
8 years ago
  1. /* Minimal main program -- everything is loaded from the library */
  2. #include "Python.h"
  3. #include "internal/pystate.h"
  4. #include <locale.h>
  5. #ifdef __FreeBSD__
  6. #include <fenv.h>
  7. #endif
  8. #ifdef MS_WINDOWS
  9. int
  10. wmain(int argc, wchar_t **argv)
  11. {
  12. return Py_Main(argc, argv);
  13. }
  14. #else
  15. int
  16. main(int argc, char **argv)
  17. {
  18. wchar_t **argv_copy;
  19. /* We need a second copy, as Python might modify the first one. */
  20. wchar_t **argv_copy2;
  21. int i, status;
  22. char *oldloc;
  23. _PyInitError err = _PyRuntime_Initialize();
  24. if (_Py_INIT_FAILED(err)) {
  25. fprintf(stderr, "Fatal Python error: %s\n", err.msg);
  26. fflush(stderr);
  27. exit(1);
  28. }
  29. /* Force malloc() allocator to bootstrap Python */
  30. #ifdef Py_DEBUG
  31. (void)_PyMem_SetupAllocators("malloc_debug");
  32. # else
  33. (void)_PyMem_SetupAllocators("malloc");
  34. # endif
  35. argv_copy = (wchar_t **)PyMem_RawMalloc(sizeof(wchar_t*) * (argc+1));
  36. argv_copy2 = (wchar_t **)PyMem_RawMalloc(sizeof(wchar_t*) * (argc+1));
  37. if (!argv_copy || !argv_copy2) {
  38. fprintf(stderr, "out of memory\n");
  39. return 1;
  40. }
  41. /* 754 requires that FP exceptions run in "no stop" mode by default,
  42. * and until C vendors implement C99's ways to control FP exceptions,
  43. * Python requires non-stop mode. Alas, some platforms enable FP
  44. * exceptions by default. Here we disable them.
  45. */
  46. #ifdef __FreeBSD__
  47. fedisableexcept(FE_OVERFLOW);
  48. #endif
  49. oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL));
  50. if (!oldloc) {
  51. fprintf(stderr, "out of memory\n");
  52. return 1;
  53. }
  54. /* Reconfigure the locale to the default for this process */
  55. _Py_SetLocaleFromEnv(LC_ALL);
  56. /* The legacy C locale assumes ASCII as the default text encoding, which
  57. * causes problems not only for the CPython runtime, but also other
  58. * components like GNU readline.
  59. *
  60. * Accordingly, when the CLI detects it, it attempts to coerce it to a
  61. * more capable UTF-8 based alternative.
  62. *
  63. * See the documentation of the PYTHONCOERCECLOCALE setting for more
  64. * details.
  65. */
  66. if (_Py_LegacyLocaleDetected()) {
  67. _Py_CoerceLegacyLocale();
  68. }
  69. /* Convert from char to wchar_t based on the locale settings */
  70. for (i = 0; i < argc; i++) {
  71. argv_copy[i] = Py_DecodeLocale(argv[i], NULL);
  72. if (!argv_copy[i]) {
  73. PyMem_RawFree(oldloc);
  74. fprintf(stderr, "Fatal Python error: "
  75. "unable to decode the command line argument #%i\n",
  76. i + 1);
  77. return 1;
  78. }
  79. argv_copy2[i] = argv_copy[i];
  80. }
  81. argv_copy2[argc] = argv_copy[argc] = NULL;
  82. setlocale(LC_ALL, oldloc);
  83. PyMem_RawFree(oldloc);
  84. status = Py_Main(argc, argv_copy);
  85. /* Force again malloc() allocator to release memory blocks allocated
  86. before Py_Main() */
  87. #ifdef Py_DEBUG
  88. (void)_PyMem_SetupAllocators("malloc_debug");
  89. # else
  90. (void)_PyMem_SetupAllocators("malloc");
  91. # endif
  92. for (i = 0; i < argc; i++) {
  93. PyMem_RawFree(argv_copy2[i]);
  94. }
  95. PyMem_RawFree(argv_copy);
  96. PyMem_RawFree(argv_copy2);
  97. return status;
  98. }
  99. #endif