3
3
# include <windows.h>
4
4
#endif
5
5
6
+ #ifdef __APPLE__
7
+ extern wchar_t * _Py_DecodeUTF8_surrogateescape (const char * s , Py_ssize_t size );
8
+ #endif
9
+
6
10
#ifdef HAVE_STAT
7
11
8
12
/* Decode a byte string from the locale encoding with the
23
27
wchar_t *
24
28
_Py_char2wchar (const char * arg , size_t * size )
25
29
{
30
+ #ifdef __APPLE__
31
+ wchar_t * wstr ;
32
+ wstr = _Py_DecodeUTF8_surrogateescape (arg , strlen (arg ));
33
+ if (size != NULL ) {
34
+ if (wstr != NULL )
35
+ * size = wcslen (wstr );
36
+ else
37
+ * size = (size_t )-1 ;
38
+ }
39
+ return wstr ;
40
+ #else
26
41
wchar_t * res ;
27
42
#ifdef HAVE_BROKEN_MBSTOWCS
28
43
/* Some platforms have a broken implementation of
@@ -107,7 +122,7 @@ _Py_char2wchar(const char* arg, size_t *size)
107
122
argsize -= converted ;
108
123
out ++ ;
109
124
}
110
- #else
125
+ #else /* HAVE_MBRTOWC */
111
126
/* Cannot use C locale for escaping; manually escape as if charset
112
127
is ASCII (i.e. escape all bytes > 128. This will still roundtrip
113
128
correctly in the locale's charset, which must be an ASCII superset. */
@@ -121,13 +136,14 @@ _Py_char2wchar(const char* arg, size_t *size)
121
136
else
122
137
* out ++ = 0xdc00 + * in ++ ;
123
138
* out = 0 ;
124
- #endif
139
+ #endif /* HAVE_MBRTOWC */
125
140
if (size != NULL )
126
141
* size = out - res ;
127
142
return res ;
128
143
oom :
129
144
fprintf (stderr , "out of memory\n" );
130
145
return NULL ;
146
+ #endif /* __APPLE__ */
131
147
}
132
148
133
149
/* Encode a (wide) character string to the locale encoding with the
@@ -144,14 +160,42 @@ _Py_char2wchar(const char* arg, size_t *size)
144
160
char *
145
161
_Py_wchar2char (const wchar_t * text , size_t * error_pos )
146
162
{
163
+ #ifdef __APPLE__
164
+ Py_ssize_t len ;
165
+ PyObject * unicode , * bytes = NULL ;
166
+ char * cpath ;
167
+
168
+ unicode = PyUnicode_FromWideChar (text , wcslen (text ));
169
+ if (unicode == NULL )
170
+ return NULL ;
171
+
172
+ bytes = _PyUnicode_AsUTF8String (unicode , "surrogateescape" );
173
+ Py_DECREF (unicode );
174
+ if (bytes == NULL ) {
175
+ PyErr_Clear ();
176
+ if (error_pos != NULL )
177
+ * error_pos = (size_t )-1 ;
178
+ return NULL ;
179
+ }
180
+
181
+ len = PyBytes_GET_SIZE (bytes );
182
+ cpath = PyMem_Malloc (len + 1 );
183
+ if (cpath == NULL ) {
184
+ PyErr_Clear ();
185
+ Py_DECREF (bytes );
186
+ if (error_pos != NULL )
187
+ * error_pos = (size_t )-1 ;
188
+ return NULL ;
189
+ }
190
+ memcpy (cpath , PyBytes_AsString (bytes ), len + 1 );
191
+ Py_DECREF (bytes );
192
+ return cpath ;
193
+ #else /* __APPLE__ */
147
194
const size_t len = wcslen (text );
148
195
char * result = NULL , * bytes = NULL ;
149
196
size_t i , size , converted ;
150
197
wchar_t c , buf [2 ];
151
198
152
- if (error_pos != NULL )
153
- * error_pos = (size_t )-1 ;
154
-
155
199
/* The function works in two steps:
156
200
1. compute the length of the output buffer in bytes (size)
157
201
2. outputs the bytes */
@@ -198,11 +242,15 @@ _Py_wchar2char(const wchar_t *text, size_t *error_pos)
198
242
199
243
size += 1 ; /* nul byte at the end */
200
244
result = PyMem_Malloc (size );
201
- if (result == NULL )
245
+ if (result == NULL ) {
246
+ if (error_pos != NULL )
247
+ * error_pos = (size_t )-1 ;
202
248
return NULL ;
249
+ }
203
250
bytes = result ;
204
251
}
205
252
return result ;
253
+ #endif /* __APPLE__ */
206
254
}
207
255
208
256
/* In principle, this should use HAVE__WSTAT, and _wstat
0 commit comments