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.

109 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 default allocator, to be able to release memory above
  30. with a known allocator. */
  31. _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, NULL);
  32. argv_copy = (wchar_t **)PyMem_RawMalloc(sizeof(wchar_t*) * (argc+1));
  33. argv_copy2 = (wchar_t **)PyMem_RawMalloc(sizeof(wchar_t*) * (argc+1));
  34. if (!argv_copy || !argv_copy2) {
  35. fprintf(stderr, "out of memory\n");
  36. return 1;
  37. }
  38. /* 754 requires that FP exceptions run in "no stop" mode by default,
  39. * and until C vendors implement C99's ways to control FP exceptions,
  40. * Python requires non-stop mode. Alas, some platforms enable FP
  41. * exceptions by default. Here we disable them.
  42. */
  43. #ifdef __FreeBSD__
  44. fedisableexcept(FE_OVERFLOW);
  45. #endif
  46. oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL));
  47. if (!oldloc) {
  48. fprintf(stderr, "out of memory\n");
  49. return 1;
  50. }
  51. /* Reconfigure the locale to the default for this process */
  52. _Py_SetLocaleFromEnv(LC_ALL);
  53. /* The legacy C locale assumes ASCII as the default text encoding, which
  54. * causes problems not only for the CPython runtime, but also other
  55. * components like GNU readline.
  56. *
  57. * Accordingly, when the CLI detects it, it attempts to coerce it to a
  58. * more capable UTF-8 based alternative.
  59. *
  60. * See the documentation of the PYTHONCOERCECLOCALE setting for more
  61. * details.
  62. */
  63. if (_Py_LegacyLocaleDetected()) {
  64. _Py_CoerceLegacyLocale();
  65. }
  66. /* Convert from char to wchar_t based on the locale settings */
  67. for (i = 0; i < argc; i++) {
  68. argv_copy[i] = Py_DecodeLocale(argv[i], NULL);
  69. if (!argv_copy[i]) {
  70. PyMem_RawFree(oldloc);
  71. fprintf(stderr, "Fatal Python error: "
  72. "unable to decode the command line argument #%i\n",
  73. i + 1);
  74. return 1;
  75. }
  76. argv_copy2[i] = argv_copy[i];
  77. }
  78. argv_copy2[argc] = argv_copy[argc] = NULL;
  79. setlocale(LC_ALL, oldloc);
  80. PyMem_RawFree(oldloc);
  81. status = Py_Main(argc, argv_copy);
  82. /* Py_Main() can change PyMem_RawMalloc() allocator, so restore the default
  83. to release memory blocks allocated before Py_Main() */
  84. _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, NULL);
  85. for (i = 0; i < argc; i++) {
  86. PyMem_RawFree(argv_copy2[i]);
  87. }
  88. PyMem_RawFree(argv_copy);
  89. PyMem_RawFree(argv_copy2);
  90. return status;
  91. }
  92. #endif