149 Py_RETURN_FALSE; |
149 Py_RETURN_FALSE; |
150 } |
150 } |
151 Py_RETURN_TRUE; |
151 Py_RETURN_TRUE; |
152 } |
152 } |
153 |
153 |
154 static inline PyObject *_asciitransform(PyObject *str_obj, |
154 static inline PyObject * |
155 const char table[128], |
155 _asciitransform(PyObject *str_obj, const char table[128], PyObject *fallback_fn) |
156 PyObject *fallback_fn) |
|
157 { |
156 { |
158 char *str, *newstr; |
157 char *str, *newstr; |
159 Py_ssize_t i, len; |
158 Py_ssize_t i, len; |
160 PyObject *newobj = NULL; |
159 PyObject *newobj = NULL; |
161 PyObject *ret = NULL; |
160 PyObject *ret = NULL; |
171 |
170 |
172 for (i = 0; i < len; i++) { |
171 for (i = 0; i < len; i++) { |
173 char c = str[i]; |
172 char c = str[i]; |
174 if (c & 0x80) { |
173 if (c & 0x80) { |
175 if (fallback_fn != NULL) { |
174 if (fallback_fn != NULL) { |
176 ret = PyObject_CallFunctionObjArgs(fallback_fn, |
175 ret = PyObject_CallFunctionObjArgs( |
177 str_obj, NULL); |
176 fallback_fn, str_obj, NULL); |
178 } else { |
177 } else { |
179 PyObject *err = PyUnicodeDecodeError_Create( |
178 PyObject *err = PyUnicodeDecodeError_Create( |
180 "ascii", str, len, i, (i + 1), |
179 "ascii", str, len, i, (i + 1), |
181 "unexpected code byte"); |
180 "unexpected code byte"); |
182 PyErr_SetObject(PyExc_UnicodeDecodeError, err); |
181 PyErr_SetObject(PyExc_UnicodeDecodeError, err); |
183 Py_XDECREF(err); |
182 Py_XDECREF(err); |
184 } |
183 } |
185 goto quit; |
184 goto quit; |
186 } |
185 } |
218 PyObject *k, *v; |
217 PyObject *k, *v; |
219 dirstateTupleObject *tuple; |
218 dirstateTupleObject *tuple; |
220 Py_ssize_t pos = 0; |
219 Py_ssize_t pos = 0; |
221 const char *table; |
220 const char *table; |
222 |
221 |
223 if (!PyArg_ParseTuple(args, "O!O!O!:make_file_foldmap", |
222 if (!PyArg_ParseTuple(args, "O!O!O!:make_file_foldmap", &PyDict_Type, |
224 &PyDict_Type, &dmap, |
223 &dmap, &PyInt_Type, &spec_obj, &PyFunction_Type, |
225 &PyInt_Type, &spec_obj, |
224 &normcase_fallback)) |
226 &PyFunction_Type, &normcase_fallback)) |
|
227 goto quit; |
225 goto quit; |
228 |
226 |
229 spec = (int)PyInt_AS_LONG(spec_obj); |
227 spec = (int)PyInt_AS_LONG(spec_obj); |
230 switch (spec) { |
228 switch (spec) { |
231 case NORMCASE_LOWER: |
229 case NORMCASE_LOWER: |
249 goto quit; |
247 goto quit; |
250 |
248 |
251 while (PyDict_Next(dmap, &pos, &k, &v)) { |
249 while (PyDict_Next(dmap, &pos, &k, &v)) { |
252 if (!dirstate_tuple_check(v)) { |
250 if (!dirstate_tuple_check(v)) { |
253 PyErr_SetString(PyExc_TypeError, |
251 PyErr_SetString(PyExc_TypeError, |
254 "expected a dirstate tuple"); |
252 "expected a dirstate tuple"); |
255 goto quit; |
253 goto quit; |
256 } |
254 } |
257 |
255 |
258 tuple = (dirstateTupleObject *)v; |
256 tuple = (dirstateTupleObject *)v; |
259 if (tuple->state != 'r') { |
257 if (tuple->state != 'r') { |
260 PyObject *normed; |
258 PyObject *normed; |
261 if (table != NULL) { |
259 if (table != NULL) { |
262 normed = _asciitransform(k, table, |
260 normed = _asciitransform(k, table, |
263 normcase_fallback); |
261 normcase_fallback); |
264 } else { |
262 } else { |
265 normed = PyObject_CallFunctionObjArgs( |
263 normed = PyObject_CallFunctionObjArgs( |
266 normcase_fallback, k, NULL); |
264 normcase_fallback, k, NULL); |
267 } |
265 } |
268 |
266 |
269 if (normed == NULL) |
267 if (normed == NULL) |
270 goto quit; |
268 goto quit; |
271 if (PyDict_SetItem(file_foldmap, normed, k) == -1) { |
269 if (PyDict_SetItem(file_foldmap, normed, k) == -1) { |
290 /* don't want to process multi-byte escapes in C */ |
288 /* don't want to process multi-byte escapes in C */ |
291 for (i = 0; i < len; i++) { |
289 for (i = 0; i < len; i++) { |
292 char c = buf[i]; |
290 char c = buf[i]; |
293 if (c & 0x80) { |
291 if (c & 0x80) { |
294 PyErr_SetString(PyExc_ValueError, |
292 PyErr_SetString(PyExc_ValueError, |
295 "cannot process non-ascii str"); |
293 "cannot process non-ascii str"); |
296 return -1; |
294 return -1; |
297 } |
295 } |
298 esclen += jsonparanoidlentable[(unsigned char)c]; |
296 esclen += jsonparanoidlentable[(unsigned char)c]; |
299 if (esclen < 0) { |
297 if (esclen < 0) { |
300 PyErr_SetString(PyExc_MemoryError, |
298 PyErr_SetString(PyExc_MemoryError, |
301 "overflow in jsonescapelen"); |
299 "overflow in jsonescapelen"); |
302 return -1; |
300 return -1; |
303 } |
301 } |
304 } |
302 } |
305 } else { |
303 } else { |
306 for (i = 0; i < len; i++) { |
304 for (i = 0; i < len; i++) { |
307 char c = buf[i]; |
305 char c = buf[i]; |
308 esclen += jsonlentable[(unsigned char)c]; |
306 esclen += jsonlentable[(unsigned char)c]; |
309 if (esclen < 0) { |
307 if (esclen < 0) { |
310 PyErr_SetString(PyExc_MemoryError, |
308 PyErr_SetString(PyExc_MemoryError, |
311 "overflow in jsonescapelen"); |
309 "overflow in jsonescapelen"); |
312 return -1; |
310 return -1; |
313 } |
311 } |
314 } |
312 } |
315 } |
313 } |
316 |
314 |
334 case '"': |
332 case '"': |
335 return '"'; |
333 return '"'; |
336 case '\\': |
334 case '\\': |
337 return '\\'; |
335 return '\\'; |
338 } |
336 } |
339 return '\0'; /* should not happen */ |
337 return '\0'; /* should not happen */ |
340 } |
338 } |
341 |
339 |
342 /* convert 'origbuf' to JSON-escaped form 'escbuf'; 'origbuf' should only |
340 /* convert 'origbuf' to JSON-escaped form 'escbuf'; 'origbuf' should only |
343 include characters mappable by json(paranoid)lentable */ |
341 include characters mappable by json(paranoid)lentable */ |
344 static void encodejsonescape(char *escbuf, Py_ssize_t esclen, |
342 static void encodejsonescape(char *escbuf, Py_ssize_t esclen, |
345 const char *origbuf, Py_ssize_t origlen, |
343 const char *origbuf, Py_ssize_t origlen, |
346 bool paranoid) |
344 bool paranoid) |
347 { |
345 { |
348 const uint8_t *lentable = |
346 const uint8_t *lentable = |
349 (paranoid) ? jsonparanoidlentable : jsonlentable; |
347 (paranoid) ? jsonparanoidlentable : jsonlentable; |
350 Py_ssize_t i, j; |
348 Py_ssize_t i, j; |
351 |
349 |
352 for (i = 0, j = 0; i < origlen; i++) { |
350 for (i = 0, j = 0; i < origlen; i++) { |
353 char c = origbuf[i]; |
351 char c = origbuf[i]; |
354 uint8_t l = lentable[(unsigned char)c]; |
352 uint8_t l = lentable[(unsigned char)c]; |
375 { |
373 { |
376 PyObject *origstr, *escstr; |
374 PyObject *origstr, *escstr; |
377 const char *origbuf; |
375 const char *origbuf; |
378 Py_ssize_t origlen, esclen; |
376 Py_ssize_t origlen, esclen; |
379 int paranoid; |
377 int paranoid; |
380 if (!PyArg_ParseTuple(args, "O!i:jsonescapeu8fast", |
378 if (!PyArg_ParseTuple(args, "O!i:jsonescapeu8fast", &PyBytes_Type, |
381 &PyBytes_Type, &origstr, ¶noid)) |
379 &origstr, ¶noid)) |
382 return NULL; |
380 return NULL; |
383 |
381 |
384 origbuf = PyBytes_AS_STRING(origstr); |
382 origbuf = PyBytes_AS_STRING(origstr); |
385 origlen = PyBytes_GET_SIZE(origstr); |
383 origlen = PyBytes_GET_SIZE(origstr); |
386 esclen = jsonescapelen(origbuf, origlen, paranoid); |
384 esclen = jsonescapelen(origbuf, origlen, paranoid); |
387 if (esclen < 0) |
385 if (esclen < 0) |
388 return NULL; /* unsupported char found or overflow */ |
386 return NULL; /* unsupported char found or overflow */ |
389 if (origlen == esclen) { |
387 if (origlen == esclen) { |
390 Py_INCREF(origstr); |
388 Py_INCREF(origstr); |
391 return origstr; |
389 return origstr; |
392 } |
390 } |
393 |
391 |
394 escstr = PyBytes_FromStringAndSize(NULL, esclen); |
392 escstr = PyBytes_FromStringAndSize(NULL, esclen); |
395 if (!escstr) |
393 if (!escstr) |
396 return NULL; |
394 return NULL; |
397 encodejsonescape(PyBytes_AS_STRING(escstr), esclen, origbuf, origlen, |
395 encodejsonescape(PyBytes_AS_STRING(escstr), esclen, origbuf, origlen, |
398 paranoid); |
396 paranoid); |
399 |
397 |
400 return escstr; |
398 return escstr; |
401 } |
399 } |