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.

119 lines
3.2 KiB

  1. /* Minimal main program -- everything is loaded from the library */
  2. #include "Python.h"
  3. #include <locale.h>
  4. #ifdef __FreeBSD__
  5. #include <fenv.h>
  6. #endif
  7. #ifdef MS_WINDOWS
  8. int
  9. wmain(int argc, wchar_t **argv)
  10. {
  11. return Py_Main(argc, argv);
  12. }
  13. #else
  14. /* Access private pylifecycle helper API to better handle the legacy C locale
  15. *
  16. * The legacy C locale assumes ASCII as the default text encoding, which
  17. * causes problems not only for the CPython runtime, but also other
  18. * components like GNU readline.
  19. *
  20. * Accordingly, when the CLI detects it, it attempts to coerce it to a
  21. * more capable UTF-8 based alternative.
  22. *
  23. * See the documentation of the PYTHONCOERCECLOCALE setting for more details.
  24. *
  25. */
  26. extern int _Py_LegacyLocaleDetected(void);
  27. extern void _Py_CoerceLegacyLocale(void);
  28. int
  29. main(int argc, char **argv)
  30. {
  31. wchar_t **argv_copy;
  32. /* We need a second copy, as Python might modify the first one. */
  33. wchar_t **argv_copy2;
  34. int i, res;
  35. char *oldloc;
  36. /* Force malloc() allocator to bootstrap Python */
  37. #ifdef Py_DEBUG
  38. (void)_PyMem_SetupAllocators("malloc_debug");
  39. # else
  40. (void)_PyMem_SetupAllocators("malloc");
  41. # endif
  42. argv_copy = (wchar_t **)PyMem_RawMalloc(sizeof(wchar_t*) * (argc+1));
  43. argv_copy2 = (wchar_t **)PyMem_RawMalloc(sizeof(wchar_t*) * (argc+1));
  44. if (!argv_copy || !argv_copy2) {
  45. fprintf(stderr, "out of memory\n");
  46. return 1;
  47. }
  48. /* 754 requires that FP exceptions run in "no stop" mode by default,
  49. * and until C vendors implement C99's ways to control FP exceptions,
  50. * Python requires non-stop mode. Alas, some platforms enable FP
  51. * exceptions by default. Here we disable them.
  52. */
  53. #ifdef __FreeBSD__
  54. fedisableexcept(FE_OVERFLOW);
  55. #endif
  56. oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL));
  57. if (!oldloc) {
  58. fprintf(stderr, "out of memory\n");
  59. return 1;
  60. }
  61. #ifdef __ANDROID__
  62. /* Passing "" to setlocale() on Android requests the C locale rather
  63. * than checking environment variables, so request C.UTF-8 explicitly
  64. */
  65. setlocale(LC_ALL, "C.UTF-8");
  66. #else
  67. /* Reconfigure the locale to the default for this process */
  68. setlocale(LC_ALL, "");
  69. #endif
  70. if (_Py_LegacyLocaleDetected()) {
  71. _Py_CoerceLegacyLocale();
  72. }
  73. /* Convert from char to wchar_t based on the locale settings */
  74. for (i = 0; i < argc; i++) {
  75. argv_copy[i] = Py_DecodeLocale(argv[i], NULL);
  76. if (!argv_copy[i]) {
  77. PyMem_RawFree(oldloc);
  78. fprintf(stderr, "Fatal Python error: "
  79. "unable to decode the command line argument #%i\n",
  80. i + 1);
  81. return 1;
  82. }
  83. argv_copy2[i] = argv_copy[i];
  84. }
  85. argv_copy2[argc] = argv_copy[argc] = NULL;
  86. setlocale(LC_ALL, oldloc);
  87. PyMem_RawFree(oldloc);
  88. res = Py_Main(argc, argv_copy);
  89. /* Force again malloc() allocator to release memory blocks allocated
  90. before Py_Main() */
  91. #ifdef Py_DEBUG
  92. (void)_PyMem_SetupAllocators("malloc_debug");
  93. # else
  94. (void)_PyMem_SetupAllocators("malloc");
  95. # endif
  96. for (i = 0; i < argc; i++) {
  97. PyMem_RawFree(argv_copy2[i]);
  98. }
  99. PyMem_RawFree(argv_copy);
  100. PyMem_RawFree(argv_copy2);
  101. return res;
  102. }
  103. #endif