mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	 6ea4186de3
			
		
	
	
		6ea4186de3
		
	
	
	
	
		
			
			- new PYTHONCOERCECLOCALE config setting - coerces legacy C locale to C.UTF-8, C.utf8 or UTF-8 by default - always uses C.UTF-8 on Android - uses `surrogateescape` on stdin and stdout in the coercion target locales - configure option to disable locale coercion at build time - configure option to disable C locale warning at build time
		
			
				
	
	
		
			119 lines
		
	
	
	
		
			3.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			119 lines
		
	
	
	
		
			3.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* Minimal main program -- everything is loaded from the library */
 | |
| 
 | |
| #include "Python.h"
 | |
| #include <locale.h>
 | |
| 
 | |
| #ifdef __FreeBSD__
 | |
| #include <fenv.h>
 | |
| #endif
 | |
| 
 | |
| #ifdef MS_WINDOWS
 | |
| int
 | |
| wmain(int argc, wchar_t **argv)
 | |
| {
 | |
|     return Py_Main(argc, argv);
 | |
| }
 | |
| #else
 | |
| 
 | |
| /* Access private pylifecycle helper API to better handle the legacy C locale
 | |
|  *
 | |
|  * The legacy C locale assumes ASCII as the default text encoding, which
 | |
|  * causes problems not only for the CPython runtime, but also other
 | |
|  * components like GNU readline.
 | |
|  *
 | |
|  * Accordingly, when the CLI detects it, it attempts to coerce it to a
 | |
|  * more capable UTF-8 based alternative.
 | |
|  *
 | |
|  * See the documentation of the PYTHONCOERCECLOCALE setting for more details.
 | |
|  *
 | |
|  */
 | |
| extern int _Py_LegacyLocaleDetected(void);
 | |
| extern void _Py_CoerceLegacyLocale(void);
 | |
| 
 | |
| int
 | |
| main(int argc, char **argv)
 | |
| {
 | |
|     wchar_t **argv_copy;
 | |
|     /* We need a second copy, as Python might modify the first one. */
 | |
|     wchar_t **argv_copy2;
 | |
|     int i, res;
 | |
|     char *oldloc;
 | |
| 
 | |
|     /* Force malloc() allocator to bootstrap Python */
 | |
| #ifdef Py_DEBUG
 | |
|     (void)_PyMem_SetupAllocators("malloc_debug");
 | |
| #  else
 | |
|     (void)_PyMem_SetupAllocators("malloc");
 | |
| #  endif
 | |
| 
 | |
|     argv_copy = (wchar_t **)PyMem_RawMalloc(sizeof(wchar_t*) * (argc+1));
 | |
|     argv_copy2 = (wchar_t **)PyMem_RawMalloc(sizeof(wchar_t*) * (argc+1));
 | |
|     if (!argv_copy || !argv_copy2) {
 | |
|         fprintf(stderr, "out of memory\n");
 | |
|         return 1;
 | |
|     }
 | |
| 
 | |
|     /* 754 requires that FP exceptions run in "no stop" mode by default,
 | |
|      * and until C vendors implement C99's ways to control FP exceptions,
 | |
|      * Python requires non-stop mode.  Alas, some platforms enable FP
 | |
|      * exceptions by default.  Here we disable them.
 | |
|      */
 | |
| #ifdef __FreeBSD__
 | |
|     fedisableexcept(FE_OVERFLOW);
 | |
| #endif
 | |
| 
 | |
|     oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL));
 | |
|     if (!oldloc) {
 | |
|         fprintf(stderr, "out of memory\n");
 | |
|         return 1;
 | |
|     }
 | |
| 
 | |
| #ifdef __ANDROID__
 | |
|     /* Passing "" to setlocale() on Android requests the C locale rather
 | |
|      * than checking environment variables, so request C.UTF-8 explicitly
 | |
|      */
 | |
|     setlocale(LC_ALL, "C.UTF-8");
 | |
| #else
 | |
|     /* Reconfigure the locale to the default for this process */
 | |
|     setlocale(LC_ALL, "");
 | |
| #endif
 | |
| 
 | |
|     if (_Py_LegacyLocaleDetected()) {
 | |
|         _Py_CoerceLegacyLocale();
 | |
|     }
 | |
| 
 | |
|     /* Convert from char to wchar_t based on the locale settings */
 | |
|     for (i = 0; i < argc; i++) {
 | |
|         argv_copy[i] = Py_DecodeLocale(argv[i], NULL);
 | |
|         if (!argv_copy[i]) {
 | |
|             PyMem_RawFree(oldloc);
 | |
|             fprintf(stderr, "Fatal Python error: "
 | |
|                             "unable to decode the command line argument #%i\n",
 | |
|                             i + 1);
 | |
|             return 1;
 | |
|         }
 | |
|         argv_copy2[i] = argv_copy[i];
 | |
|     }
 | |
|     argv_copy2[argc] = argv_copy[argc] = NULL;
 | |
| 
 | |
|     setlocale(LC_ALL, oldloc);
 | |
|     PyMem_RawFree(oldloc);
 | |
| 
 | |
|     res = Py_Main(argc, argv_copy);
 | |
| 
 | |
|     /* Force again malloc() allocator to release memory blocks allocated
 | |
|        before Py_Main() */
 | |
| #ifdef Py_DEBUG
 | |
|     (void)_PyMem_SetupAllocators("malloc_debug");
 | |
| #  else
 | |
|     (void)_PyMem_SetupAllocators("malloc");
 | |
| #  endif
 | |
| 
 | |
|     for (i = 0; i < argc; i++) {
 | |
|         PyMem_RawFree(argv_copy2[i]);
 | |
|     }
 | |
|     PyMem_RawFree(argv_copy);
 | |
|     PyMem_RawFree(argv_copy2);
 | |
|     return res;
 | |
| }
 | |
| #endif
 |