88#include <langinfo.h>
99#endif
1010
11+ #ifdef __APPLE__
12+ extern wchar_t * _Py_DecodeUTF8_surrogateescape (const char * s , Py_ssize_t size );
13+ #endif
14+
1115PyObject *
1216_Py_device_encoding (int fd )
1317{
@@ -60,6 +64,15 @@ _Py_device_encoding(int fd)
6064wchar_t *
6165_Py_char2wchar (const char * arg , size_t * size )
6266{
67+ #ifdef __APPLE__
68+ wchar_t * wstr ;
69+ wstr = _Py_DecodeUTF8_surrogateescape (arg , strlen (arg ));
70+ if (wstr == NULL )
71+ return NULL ;
72+ if (size != NULL )
73+ * size = wcslen (wstr );
74+ return wstr ;
75+ #else
6376 wchar_t * res ;
6477#ifdef HAVE_BROKEN_MBSTOWCS
6578 /* Some platforms have a broken implementation of
@@ -145,7 +158,7 @@ _Py_char2wchar(const char* arg, size_t *size)
145158 argsize -= converted ;
146159 out ++ ;
147160 }
148- #else
161+ #else /* HAVE_MBRTOWC */
149162 /* Cannot use C locale for escaping; manually escape as if charset
150163 is ASCII (i.e. escape all bytes > 128. This will still roundtrip
151164 correctly in the locale's charset, which must be an ASCII superset. */
@@ -160,14 +173,15 @@ _Py_char2wchar(const char* arg, size_t *size)
160173 else
161174 * out ++ = 0xdc00 + * in ++ ;
162175 * out = 0 ;
163- #endif
176+ #endif /* HAVE_MBRTOWC */
164177 if (size != NULL )
165178 * size = out - res ;
166179 return res ;
167180oom :
168181 if (size != NULL )
169182 * size = (size_t )-1 ;
170183 return NULL ;
184+ #endif /* __APPLE__ */
171185}
172186
173187/* Encode a (wide) character string to the locale encoding with the
@@ -184,6 +198,34 @@ _Py_char2wchar(const char* arg, size_t *size)
184198char *
185199_Py_wchar2char (const wchar_t * text , size_t * error_pos )
186200{
201+ #ifdef __APPLE__
202+ Py_ssize_t len ;
203+ PyObject * unicode , * bytes = NULL ;
204+ char * cpath ;
205+
206+ unicode = PyUnicode_FromWideChar (text , wcslen (text ));
207+ if (unicode == NULL ) {
208+ Py_DECREF (unicode );
209+ return NULL ;
210+ }
211+
212+ bytes = _PyUnicode_AsUTF8String (unicode , "surrogateescape" );
213+ Py_DECREF (unicode );
214+ if (bytes == NULL ) {
215+ PyErr_Clear ();
216+ return NULL ;
217+ }
218+
219+ len = PyBytes_GET_SIZE (bytes );
220+ cpath = PyMem_Malloc (len + 1 );
221+ if (cpath == NULL ) {
222+ Py_DECREF (bytes );
223+ return NULL ;
224+ }
225+ memcpy (cpath , PyBytes_AsString (bytes ), len + 1 );
226+ Py_DECREF (bytes );
227+ return cpath ;
228+ #else /* __APPLE__ */
187229 const size_t len = wcslen (text );
188230 char * result = NULL , * bytes = NULL ;
189231 size_t i , size , converted ;
@@ -243,6 +285,7 @@ _Py_wchar2char(const wchar_t *text, size_t *error_pos)
243285 bytes = result ;
244286 }
245287 return result ;
288+ #endif /* __APPLE__ */
246289}
247290
248291/* In principle, this should use HAVE__WSTAT, and _wstat
0 commit comments