Mercurial > cpython-lru_cache-weakref
comparison Python/codecs.c @ 61467:f197407bdba2 3.1
Recorded merge of revisions 81032 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/branches/py3k
................
r81032 | antoine.pitrou | 2010-05-09 17:52:27 +0200 (dim., 09 mai 2010) | 9 lines
Recorded merge of revisions 81029 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r81029 | antoine.pitrou | 2010-05-09 16:46:46 +0200 (dim., 09 mai 2010) | 3 lines
Untabify C files. Will watch buildbots.
........
................
| author | Antoine Pitrou <solipsis@pitrou.net> |
|---|---|
| date | Sun, 09 May 2010 16:14:21 +0000 |
| parents | b085fd0611de |
| children | fc76e8c617dc |
comparison
equal
deleted
inserted
replaced
| 61459:f8c19c5f5dd2 | 61467:f197407bdba2 |
|---|---|
| 28 | 28 |
| 29 int PyCodec_Register(PyObject *search_function) | 29 int PyCodec_Register(PyObject *search_function) |
| 30 { | 30 { |
| 31 PyInterpreterState *interp = PyThreadState_GET()->interp; | 31 PyInterpreterState *interp = PyThreadState_GET()->interp; |
| 32 if (interp->codec_search_path == NULL && _PyCodecRegistry_Init()) | 32 if (interp->codec_search_path == NULL && _PyCodecRegistry_Init()) |
| 33 goto onError; | 33 goto onError; |
| 34 if (search_function == NULL) { | 34 if (search_function == NULL) { |
| 35 PyErr_BadArgument(); | 35 PyErr_BadArgument(); |
| 36 goto onError; | 36 goto onError; |
| 37 } | 37 } |
| 38 if (!PyCallable_Check(search_function)) { | 38 if (!PyCallable_Check(search_function)) { |
| 39 PyErr_SetString(PyExc_TypeError, "argument must be callable"); | 39 PyErr_SetString(PyExc_TypeError, "argument must be callable"); |
| 40 goto onError; | 40 goto onError; |
| 41 } | 41 } |
| 42 return PyList_Append(interp->codec_search_path, search_function); | 42 return PyList_Append(interp->codec_search_path, search_function); |
| 43 | 43 |
| 44 onError: | 44 onError: |
| 45 return -1; | 45 return -1; |
| 55 size_t len = strlen(string); | 55 size_t len = strlen(string); |
| 56 char *p; | 56 char *p; |
| 57 PyObject *v; | 57 PyObject *v; |
| 58 | 58 |
| 59 if (len > PY_SSIZE_T_MAX) { | 59 if (len > PY_SSIZE_T_MAX) { |
| 60 PyErr_SetString(PyExc_OverflowError, "string is too large"); | 60 PyErr_SetString(PyExc_OverflowError, "string is too large"); |
| 61 return NULL; | 61 return NULL; |
| 62 } | 62 } |
| 63 | 63 |
| 64 p = PyMem_Malloc(len + 1); | 64 p = PyMem_Malloc(len + 1); |
| 65 if (p == NULL) | 65 if (p == NULL) |
| 66 return NULL; | 66 return NULL; |
| 68 register char ch = string[i]; | 68 register char ch = string[i]; |
| 69 if (ch == ' ') | 69 if (ch == ' ') |
| 70 ch = '-'; | 70 ch = '-'; |
| 71 else | 71 else |
| 72 ch = tolower(Py_CHARMASK(ch)); | 72 ch = tolower(Py_CHARMASK(ch)); |
| 73 p[i] = ch; | 73 p[i] = ch; |
| 74 } | 74 } |
| 75 p[i] = '\0'; | 75 p[i] = '\0'; |
| 76 v = PyUnicode_FromString(p); | 76 v = PyUnicode_FromString(p); |
| 77 if (v == NULL) | 77 if (v == NULL) |
| 78 return NULL; | 78 return NULL; |
| 100 PyInterpreterState *interp; | 100 PyInterpreterState *interp; |
| 101 PyObject *result, *args = NULL, *v; | 101 PyObject *result, *args = NULL, *v; |
| 102 Py_ssize_t i, len; | 102 Py_ssize_t i, len; |
| 103 | 103 |
| 104 if (encoding == NULL) { | 104 if (encoding == NULL) { |
| 105 PyErr_BadArgument(); | 105 PyErr_BadArgument(); |
| 106 goto onError; | 106 goto onError; |
| 107 } | 107 } |
| 108 | 108 |
| 109 interp = PyThreadState_GET()->interp; | 109 interp = PyThreadState_GET()->interp; |
| 110 if (interp->codec_search_path == NULL && _PyCodecRegistry_Init()) | 110 if (interp->codec_search_path == NULL && _PyCodecRegistry_Init()) |
| 111 goto onError; | 111 goto onError; |
| 112 | 112 |
| 113 /* Convert the encoding to a normalized Python string: all | 113 /* Convert the encoding to a normalized Python string: all |
| 114 characters are converted to lower case, spaces and hyphens are | 114 characters are converted to lower case, spaces and hyphens are |
| 115 replaced with underscores. */ | 115 replaced with underscores. */ |
| 116 v = normalizestring(encoding); | 116 v = normalizestring(encoding); |
| 117 if (v == NULL) | 117 if (v == NULL) |
| 118 goto onError; | 118 goto onError; |
| 119 PyUnicode_InternInPlace(&v); | 119 PyUnicode_InternInPlace(&v); |
| 120 | 120 |
| 121 /* First, try to lookup the name in the registry dictionary */ | 121 /* First, try to lookup the name in the registry dictionary */ |
| 122 result = PyDict_GetItem(interp->codec_search_cache, v); | 122 result = PyDict_GetItem(interp->codec_search_cache, v); |
| 123 if (result != NULL) { | 123 if (result != NULL) { |
| 124 Py_INCREF(result); | 124 Py_INCREF(result); |
| 125 Py_DECREF(v); | 125 Py_DECREF(v); |
| 126 return result; | 126 return result; |
| 127 } | 127 } |
| 128 | 128 |
| 129 /* Next, scan the search functions in order of registration */ | 129 /* Next, scan the search functions in order of registration */ |
| 130 args = PyTuple_New(1); | 130 args = PyTuple_New(1); |
| 131 if (args == NULL) | 131 if (args == NULL) |
| 132 goto onError; | 132 goto onError; |
| 133 PyTuple_SET_ITEM(args,0,v); | 133 PyTuple_SET_ITEM(args,0,v); |
| 134 | 134 |
| 135 len = PyList_Size(interp->codec_search_path); | 135 len = PyList_Size(interp->codec_search_path); |
| 136 if (len < 0) | 136 if (len < 0) |
| 137 goto onError; | 137 goto onError; |
| 138 if (len == 0) { | 138 if (len == 0) { |
| 139 PyErr_SetString(PyExc_LookupError, | 139 PyErr_SetString(PyExc_LookupError, |
| 140 "no codec search functions registered: " | 140 "no codec search functions registered: " |
| 141 "can't find encoding"); | 141 "can't find encoding"); |
| 142 goto onError; | 142 goto onError; |
| 143 } | 143 } |
| 144 | 144 |
| 145 for (i = 0; i < len; i++) { | 145 for (i = 0; i < len; i++) { |
| 146 PyObject *func; | 146 PyObject *func; |
| 147 | 147 |
| 148 func = PyList_GetItem(interp->codec_search_path, i); | 148 func = PyList_GetItem(interp->codec_search_path, i); |
| 149 if (func == NULL) | 149 if (func == NULL) |
| 150 goto onError; | 150 goto onError; |
| 151 result = PyEval_CallObject(func, args); | 151 result = PyEval_CallObject(func, args); |
| 152 if (result == NULL) | 152 if (result == NULL) |
| 153 goto onError; | 153 goto onError; |
| 154 if (result == Py_None) { | 154 if (result == Py_None) { |
| 155 Py_DECREF(result); | 155 Py_DECREF(result); |
| 156 continue; | 156 continue; |
| 157 } | 157 } |
| 158 if (!PyTuple_Check(result) || PyTuple_GET_SIZE(result) != 4) { | 158 if (!PyTuple_Check(result) || PyTuple_GET_SIZE(result) != 4) { |
| 159 PyErr_SetString(PyExc_TypeError, | 159 PyErr_SetString(PyExc_TypeError, |
| 160 "codec search functions must return 4-tuples"); | 160 "codec search functions must return 4-tuples"); |
| 161 Py_DECREF(result); | 161 Py_DECREF(result); |
| 162 goto onError; | 162 goto onError; |
| 163 } | 163 } |
| 164 break; | 164 break; |
| 165 } | 165 } |
| 166 if (i == len) { | 166 if (i == len) { |
| 167 /* XXX Perhaps we should cache misses too ? */ | 167 /* XXX Perhaps we should cache misses too ? */ |
| 168 PyErr_Format(PyExc_LookupError, | 168 PyErr_Format(PyExc_LookupError, |
| 169 "unknown encoding: %s", encoding); | 169 "unknown encoding: %s", encoding); |
| 170 goto onError; | 170 goto onError; |
| 171 } | 171 } |
| 172 | 172 |
| 173 /* Cache and return the result */ | 173 /* Cache and return the result */ |
| 174 if (PyDict_SetItem(interp->codec_search_cache, v, result) < 0) { | 174 if (PyDict_SetItem(interp->codec_search_cache, v, result) < 0) { |
| 175 Py_DECREF(result); | 175 Py_DECREF(result); |
| 176 goto onError; | 176 goto onError; |
| 177 } | 177 } |
| 178 Py_DECREF(args); | 178 Py_DECREF(args); |
| 179 return result; | 179 return result; |
| 180 | 180 |
| 181 onError: | 181 onError: |
| 186 /* Codec registry encoding check API. */ | 186 /* Codec registry encoding check API. */ |
| 187 | 187 |
| 188 int PyCodec_KnownEncoding(const char *encoding) | 188 int PyCodec_KnownEncoding(const char *encoding) |
| 189 { | 189 { |
| 190 PyObject *codecs; | 190 PyObject *codecs; |
| 191 | 191 |
| 192 codecs = _PyCodec_Lookup(encoding); | 192 codecs = _PyCodec_Lookup(encoding); |
| 193 if (!codecs) { | 193 if (!codecs) { |
| 194 PyErr_Clear(); | 194 PyErr_Clear(); |
| 195 return 0; | 195 return 0; |
| 196 } | 196 } |
| 197 else { | 197 else { |
| 198 Py_DECREF(codecs); | 198 Py_DECREF(codecs); |
| 199 return 1; | 199 return 1; |
| 200 } | 200 } |
| 201 } | 201 } |
| 202 | 202 |
| 203 static | 203 static |
| 204 PyObject *args_tuple(PyObject *object, | 204 PyObject *args_tuple(PyObject *object, |
| 205 const char *errors) | 205 const char *errors) |
| 206 { | 206 { |
| 207 PyObject *args; | 207 PyObject *args; |
| 208 | 208 |
| 209 args = PyTuple_New(1 + (errors != NULL)); | 209 args = PyTuple_New(1 + (errors != NULL)); |
| 210 if (args == NULL) | 210 if (args == NULL) |
| 211 return NULL; | 211 return NULL; |
| 212 Py_INCREF(object); | 212 Py_INCREF(object); |
| 213 PyTuple_SET_ITEM(args,0,object); | 213 PyTuple_SET_ITEM(args,0,object); |
| 214 if (errors) { | 214 if (errors) { |
| 215 PyObject *v; | 215 PyObject *v; |
| 216 | 216 |
| 217 v = PyUnicode_FromString(errors); | 217 v = PyUnicode_FromString(errors); |
| 218 if (v == NULL) { | 218 if (v == NULL) { |
| 219 Py_DECREF(args); | 219 Py_DECREF(args); |
| 220 return NULL; | 220 return NULL; |
| 221 } | 221 } |
| 222 PyTuple_SET_ITEM(args, 1, v); | 222 PyTuple_SET_ITEM(args, 1, v); |
| 223 } | 223 } |
| 224 return args; | 224 return args; |
| 225 } | 225 } |
| 226 | 226 |
| 227 /* Helper function to get a codec item */ | 227 /* Helper function to get a codec item */ |
| 232 PyObject *codecs; | 232 PyObject *codecs; |
| 233 PyObject *v; | 233 PyObject *v; |
| 234 | 234 |
| 235 codecs = _PyCodec_Lookup(encoding); | 235 codecs = _PyCodec_Lookup(encoding); |
| 236 if (codecs == NULL) | 236 if (codecs == NULL) |
| 237 return NULL; | 237 return NULL; |
| 238 v = PyTuple_GET_ITEM(codecs, index); | 238 v = PyTuple_GET_ITEM(codecs, index); |
| 239 Py_DECREF(codecs); | 239 Py_DECREF(codecs); |
| 240 Py_INCREF(v); | 240 Py_INCREF(v); |
| 241 return v; | 241 return v; |
| 242 } | 242 } |
| 243 | 243 |
| 244 /* Helper function to create an incremental codec. */ | 244 /* Helper function to create an incremental codec. */ |
| 245 | 245 |
| 246 static | 246 static |
| 247 PyObject *codec_getincrementalcodec(const char *encoding, | 247 PyObject *codec_getincrementalcodec(const char *encoding, |
| 248 const char *errors, | 248 const char *errors, |
| 249 const char *attrname) | 249 const char *attrname) |
| 250 { | 250 { |
| 251 PyObject *codecs, *ret, *inccodec; | 251 PyObject *codecs, *ret, *inccodec; |
| 252 | 252 |
| 253 codecs = _PyCodec_Lookup(encoding); | 253 codecs = _PyCodec_Lookup(encoding); |
| 254 if (codecs == NULL) | 254 if (codecs == NULL) |
| 255 return NULL; | 255 return NULL; |
| 256 inccodec = PyObject_GetAttrString(codecs, attrname); | 256 inccodec = PyObject_GetAttrString(codecs, attrname); |
| 257 Py_DECREF(codecs); | 257 Py_DECREF(codecs); |
| 258 if (inccodec == NULL) | 258 if (inccodec == NULL) |
| 259 return NULL; | 259 return NULL; |
| 260 if (errors) | 260 if (errors) |
| 261 ret = PyObject_CallFunction(inccodec, "s", errors); | 261 ret = PyObject_CallFunction(inccodec, "s", errors); |
| 262 else | 262 else |
| 263 ret = PyObject_CallFunction(inccodec, NULL); | 263 ret = PyObject_CallFunction(inccodec, NULL); |
| 264 Py_DECREF(inccodec); | 264 Py_DECREF(inccodec); |
| 265 return ret; | 265 return ret; |
| 266 } | 266 } |
| 267 | 267 |
| 268 /* Helper function to create a stream codec. */ | 268 /* Helper function to create a stream codec. */ |
| 269 | 269 |
| 270 static | 270 static |
| 271 PyObject *codec_getstreamcodec(const char *encoding, | 271 PyObject *codec_getstreamcodec(const char *encoding, |
| 272 PyObject *stream, | 272 PyObject *stream, |
| 273 const char *errors, | 273 const char *errors, |
| 274 const int index) | 274 const int index) |
| 275 { | 275 { |
| 276 PyObject *codecs, *streamcodec, *codeccls; | 276 PyObject *codecs, *streamcodec, *codeccls; |
| 277 | 277 |
| 278 codecs = _PyCodec_Lookup(encoding); | 278 codecs = _PyCodec_Lookup(encoding); |
| 279 if (codecs == NULL) | 279 if (codecs == NULL) |
| 280 return NULL; | 280 return NULL; |
| 281 | 281 |
| 282 codeccls = PyTuple_GET_ITEM(codecs, index); | 282 codeccls = PyTuple_GET_ITEM(codecs, index); |
| 283 if (errors != NULL) | 283 if (errors != NULL) |
| 284 streamcodec = PyObject_CallFunction(codeccls, "Os", stream, errors); | 284 streamcodec = PyObject_CallFunction(codeccls, "Os", stream, errors); |
| 285 else | 285 else |
| 286 streamcodec = PyObject_CallFunction(codeccls, "O", stream); | 286 streamcodec = PyObject_CallFunction(codeccls, "O", stream); |
| 287 Py_DECREF(codecs); | 287 Py_DECREF(codecs); |
| 288 return streamcodec; | 288 return streamcodec; |
| 289 } | 289 } |
| 290 | 290 |
| 291 /* Convenience APIs to query the Codec registry. | 291 /* Convenience APIs to query the Codec registry. |
| 303 { | 303 { |
| 304 return codec_getitem(encoding, 1); | 304 return codec_getitem(encoding, 1); |
| 305 } | 305 } |
| 306 | 306 |
| 307 PyObject *PyCodec_IncrementalEncoder(const char *encoding, | 307 PyObject *PyCodec_IncrementalEncoder(const char *encoding, |
| 308 const char *errors) | 308 const char *errors) |
| 309 { | 309 { |
| 310 return codec_getincrementalcodec(encoding, errors, "incrementalencoder"); | 310 return codec_getincrementalcodec(encoding, errors, "incrementalencoder"); |
| 311 } | 311 } |
| 312 | 312 |
| 313 PyObject *PyCodec_IncrementalDecoder(const char *encoding, | 313 PyObject *PyCodec_IncrementalDecoder(const char *encoding, |
| 314 const char *errors) | 314 const char *errors) |
| 315 { | 315 { |
| 316 return codec_getincrementalcodec(encoding, errors, "incrementaldecoder"); | 316 return codec_getincrementalcodec(encoding, errors, "incrementaldecoder"); |
| 317 } | 317 } |
| 318 | 318 |
| 319 PyObject *PyCodec_StreamReader(const char *encoding, | 319 PyObject *PyCodec_StreamReader(const char *encoding, |
| 320 PyObject *stream, | 320 PyObject *stream, |
| 321 const char *errors) | 321 const char *errors) |
| 322 { | 322 { |
| 323 return codec_getstreamcodec(encoding, stream, errors, 2); | 323 return codec_getstreamcodec(encoding, stream, errors, 2); |
| 324 } | 324 } |
| 325 | 325 |
| 326 PyObject *PyCodec_StreamWriter(const char *encoding, | 326 PyObject *PyCodec_StreamWriter(const char *encoding, |
| 327 PyObject *stream, | 327 PyObject *stream, |
| 328 const char *errors) | 328 const char *errors) |
| 329 { | 329 { |
| 330 return codec_getstreamcodec(encoding, stream, errors, 3); | 330 return codec_getstreamcodec(encoding, stream, errors, 3); |
| 331 } | 331 } |
| 332 | 332 |
| 333 /* Encode an object (e.g. an Unicode object) using the given encoding | 333 /* Encode an object (e.g. an Unicode object) using the given encoding |
| 334 and return the resulting encoded object (usually a Python string). | 334 and return the resulting encoded object (usually a Python string). |
| 335 | 335 |
| 336 errors is passed to the encoder factory as argument if non-NULL. */ | 336 errors is passed to the encoder factory as argument if non-NULL. */ |
| 337 | 337 |
| 338 PyObject *PyCodec_Encode(PyObject *object, | 338 PyObject *PyCodec_Encode(PyObject *object, |
| 339 const char *encoding, | 339 const char *encoding, |
| 340 const char *errors) | 340 const char *errors) |
| 341 { | 341 { |
| 342 PyObject *encoder = NULL; | 342 PyObject *encoder = NULL; |
| 343 PyObject *args = NULL, *result = NULL; | 343 PyObject *args = NULL, *result = NULL; |
| 344 PyObject *v = NULL; | 344 PyObject *v = NULL; |
| 345 | 345 |
| 346 encoder = PyCodec_Encoder(encoding); | 346 encoder = PyCodec_Encoder(encoding); |
| 347 if (encoder == NULL) | 347 if (encoder == NULL) |
| 348 goto onError; | 348 goto onError; |
| 349 | 349 |
| 350 args = args_tuple(object, errors); | 350 args = args_tuple(object, errors); |
| 351 if (args == NULL) | 351 if (args == NULL) |
| 352 goto onError; | 352 goto onError; |
| 353 | 353 |
| 354 result = PyEval_CallObject(encoder, args); | 354 result = PyEval_CallObject(encoder, args); |
| 355 if (result == NULL) | 355 if (result == NULL) |
| 356 goto onError; | 356 goto onError; |
| 357 | 357 |
| 358 if (!PyTuple_Check(result) || | 358 if (!PyTuple_Check(result) || |
| 359 PyTuple_GET_SIZE(result) != 2) { | 359 PyTuple_GET_SIZE(result) != 2) { |
| 360 PyErr_SetString(PyExc_TypeError, | 360 PyErr_SetString(PyExc_TypeError, |
| 361 "encoder must return a tuple (object, integer)"); | 361 "encoder must return a tuple (object, integer)"); |
| 362 goto onError; | 362 goto onError; |
| 363 } | 363 } |
| 364 v = PyTuple_GET_ITEM(result,0); | 364 v = PyTuple_GET_ITEM(result,0); |
| 365 Py_INCREF(v); | 365 Py_INCREF(v); |
| 366 /* We don't check or use the second (integer) entry. */ | 366 /* We don't check or use the second (integer) entry. */ |
| 367 | 367 |
| 368 Py_DECREF(args); | 368 Py_DECREF(args); |
| 369 Py_DECREF(encoder); | 369 Py_DECREF(encoder); |
| 370 Py_DECREF(result); | 370 Py_DECREF(result); |
| 371 return v; | 371 return v; |
| 372 | 372 |
| 373 onError: | 373 onError: |
| 374 Py_XDECREF(result); | 374 Py_XDECREF(result); |
| 375 Py_XDECREF(args); | 375 Py_XDECREF(args); |
| 376 Py_XDECREF(encoder); | 376 Py_XDECREF(encoder); |
| 377 return NULL; | 377 return NULL; |
| 381 and return an equivalent object (e.g. an Unicode object). | 381 and return an equivalent object (e.g. an Unicode object). |
| 382 | 382 |
| 383 errors is passed to the decoder factory as argument if non-NULL. */ | 383 errors is passed to the decoder factory as argument if non-NULL. */ |
| 384 | 384 |
| 385 PyObject *PyCodec_Decode(PyObject *object, | 385 PyObject *PyCodec_Decode(PyObject *object, |
| 386 const char *encoding, | 386 const char *encoding, |
| 387 const char *errors) | 387 const char *errors) |
| 388 { | 388 { |
| 389 PyObject *decoder = NULL; | 389 PyObject *decoder = NULL; |
| 390 PyObject *args = NULL, *result = NULL; | 390 PyObject *args = NULL, *result = NULL; |
| 391 PyObject *v; | 391 PyObject *v; |
| 392 | 392 |
| 393 decoder = PyCodec_Decoder(encoding); | 393 decoder = PyCodec_Decoder(encoding); |
| 394 if (decoder == NULL) | 394 if (decoder == NULL) |
| 395 goto onError; | 395 goto onError; |
| 396 | 396 |
| 397 args = args_tuple(object, errors); | 397 args = args_tuple(object, errors); |
| 398 if (args == NULL) | 398 if (args == NULL) |
| 399 goto onError; | 399 goto onError; |
| 400 | 400 |
| 401 result = PyEval_CallObject(decoder,args); | 401 result = PyEval_CallObject(decoder,args); |
| 402 if (result == NULL) | 402 if (result == NULL) |
| 403 goto onError; | 403 goto onError; |
| 404 if (!PyTuple_Check(result) || | 404 if (!PyTuple_Check(result) || |
| 405 PyTuple_GET_SIZE(result) != 2) { | 405 PyTuple_GET_SIZE(result) != 2) { |
| 406 PyErr_SetString(PyExc_TypeError, | 406 PyErr_SetString(PyExc_TypeError, |
| 407 "decoder must return a tuple (object,integer)"); | 407 "decoder must return a tuple (object,integer)"); |
| 408 goto onError; | 408 goto onError; |
| 409 } | 409 } |
| 410 v = PyTuple_GET_ITEM(result,0); | 410 v = PyTuple_GET_ITEM(result,0); |
| 411 Py_INCREF(v); | 411 Py_INCREF(v); |
| 412 /* We don't check or use the second (integer) entry. */ | 412 /* We don't check or use the second (integer) entry. */ |
| 413 | 413 |
| 431 Return 0 on success, -1 on error */ | 431 Return 0 on success, -1 on error */ |
| 432 int PyCodec_RegisterError(const char *name, PyObject *error) | 432 int PyCodec_RegisterError(const char *name, PyObject *error) |
| 433 { | 433 { |
| 434 PyInterpreterState *interp = PyThreadState_GET()->interp; | 434 PyInterpreterState *interp = PyThreadState_GET()->interp; |
| 435 if (interp->codec_search_path == NULL && _PyCodecRegistry_Init()) | 435 if (interp->codec_search_path == NULL && _PyCodecRegistry_Init()) |
| 436 return -1; | 436 return -1; |
| 437 if (!PyCallable_Check(error)) { | 437 if (!PyCallable_Check(error)) { |
| 438 PyErr_SetString(PyExc_TypeError, "handler must be callable"); | 438 PyErr_SetString(PyExc_TypeError, "handler must be callable"); |
| 439 return -1; | 439 return -1; |
| 440 } | 440 } |
| 441 return PyDict_SetItemString(interp->codec_error_registry, | 441 return PyDict_SetItemString(interp->codec_error_registry, |
| 442 (char *)name, error); | 442 (char *)name, error); |
| 443 } | 443 } |
| 444 | 444 |
| 445 /* Lookup the error handling callback function registered under the | 445 /* Lookup the error handling callback function registered under the |
| 446 name error. As a special case NULL can be passed, in which case | 446 name error. As a special case NULL can be passed, in which case |
| 447 the error handling callback for strict encoding will be returned. */ | 447 the error handling callback for strict encoding will be returned. */ |
| 449 { | 449 { |
| 450 PyObject *handler = NULL; | 450 PyObject *handler = NULL; |
| 451 | 451 |
| 452 PyInterpreterState *interp = PyThreadState_GET()->interp; | 452 PyInterpreterState *interp = PyThreadState_GET()->interp; |
| 453 if (interp->codec_search_path == NULL && _PyCodecRegistry_Init()) | 453 if (interp->codec_search_path == NULL && _PyCodecRegistry_Init()) |
| 454 return NULL; | 454 return NULL; |
| 455 | 455 |
| 456 if (name==NULL) | 456 if (name==NULL) |
| 457 name = "strict"; | 457 name = "strict"; |
| 458 handler = PyDict_GetItemString(interp->codec_error_registry, (char *)name); | 458 handler = PyDict_GetItemString(interp->codec_error_registry, (char *)name); |
| 459 if (!handler) | 459 if (!handler) |
| 460 PyErr_Format(PyExc_LookupError, "unknown error handler name '%.400s'", name); | 460 PyErr_Format(PyExc_LookupError, "unknown error handler name '%.400s'", name); |
| 461 else | 461 else |
| 462 Py_INCREF(handler); | 462 Py_INCREF(handler); |
| 463 return handler; | 463 return handler; |
| 464 } | 464 } |
| 465 | 465 |
| 466 static void wrong_exception_type(PyObject *exc) | 466 static void wrong_exception_type(PyObject *exc) |
| 467 { | 467 { |
| 480 PyObject *PyCodec_StrictErrors(PyObject *exc) | 480 PyObject *PyCodec_StrictErrors(PyObject *exc) |
| 481 { | 481 { |
| 482 if (PyExceptionInstance_Check(exc)) | 482 if (PyExceptionInstance_Check(exc)) |
| 483 PyErr_SetObject(PyExceptionInstance_Class(exc), exc); | 483 PyErr_SetObject(PyExceptionInstance_Class(exc), exc); |
| 484 else | 484 else |
| 485 PyErr_SetString(PyExc_TypeError, "codec must pass exception instance"); | 485 PyErr_SetString(PyExc_TypeError, "codec must pass exception instance"); |
| 486 return NULL; | 486 return NULL; |
| 487 } | 487 } |
| 488 | 488 |
| 489 | 489 |
| 490 PyObject *PyCodec_IgnoreErrors(PyObject *exc) | 490 PyObject *PyCodec_IgnoreErrors(PyObject *exc) |
| 491 { | 491 { |
| 492 Py_ssize_t end; | 492 Py_ssize_t end; |
| 493 if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) { | 493 if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) { |
| 494 if (PyUnicodeEncodeError_GetEnd(exc, &end)) | 494 if (PyUnicodeEncodeError_GetEnd(exc, &end)) |
| 495 return NULL; | 495 return NULL; |
| 496 } | 496 } |
| 497 else if (PyObject_IsInstance(exc, PyExc_UnicodeDecodeError)) { | 497 else if (PyObject_IsInstance(exc, PyExc_UnicodeDecodeError)) { |
| 498 if (PyUnicodeDecodeError_GetEnd(exc, &end)) | 498 if (PyUnicodeDecodeError_GetEnd(exc, &end)) |
| 499 return NULL; | 499 return NULL; |
| 500 } | 500 } |
| 501 else if (PyObject_IsInstance(exc, PyExc_UnicodeTranslateError)) { | 501 else if (PyObject_IsInstance(exc, PyExc_UnicodeTranslateError)) { |
| 502 if (PyUnicodeTranslateError_GetEnd(exc, &end)) | 502 if (PyUnicodeTranslateError_GetEnd(exc, &end)) |
| 503 return NULL; | 503 return NULL; |
| 504 } | 504 } |
| 505 else { | 505 else { |
| 506 wrong_exception_type(exc); | 506 wrong_exception_type(exc); |
| 507 return NULL; | 507 return NULL; |
| 508 } | 508 } |
| 509 /* ouch: passing NULL, 0, pos gives None instead of u'' */ | 509 /* ouch: passing NULL, 0, pos gives None instead of u'' */ |
| 510 return Py_BuildValue("(u#n)", &end, 0, end); | 510 return Py_BuildValue("(u#n)", &end, 0, end); |
| 511 } | 511 } |
| 512 | 512 |
| 517 Py_ssize_t start; | 517 Py_ssize_t start; |
| 518 Py_ssize_t end; | 518 Py_ssize_t end; |
| 519 Py_ssize_t i; | 519 Py_ssize_t i; |
| 520 | 520 |
| 521 if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) { | 521 if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) { |
| 522 PyObject *res; | 522 PyObject *res; |
| 523 Py_UNICODE *p; | 523 Py_UNICODE *p; |
| 524 if (PyUnicodeEncodeError_GetStart(exc, &start)) | 524 if (PyUnicodeEncodeError_GetStart(exc, &start)) |
| 525 return NULL; | 525 return NULL; |
| 526 if (PyUnicodeEncodeError_GetEnd(exc, &end)) | 526 if (PyUnicodeEncodeError_GetEnd(exc, &end)) |
| 527 return NULL; | 527 return NULL; |
| 528 res = PyUnicode_FromUnicode(NULL, end-start); | 528 res = PyUnicode_FromUnicode(NULL, end-start); |
| 529 if (res == NULL) | 529 if (res == NULL) |
| 530 return NULL; | 530 return NULL; |
| 531 for (p = PyUnicode_AS_UNICODE(res), i = start; | 531 for (p = PyUnicode_AS_UNICODE(res), i = start; |
| 532 i<end; ++p, ++i) | 532 i<end; ++p, ++i) |
| 533 *p = '?'; | 533 *p = '?'; |
| 534 restuple = Py_BuildValue("(On)", res, end); | 534 restuple = Py_BuildValue("(On)", res, end); |
| 535 Py_DECREF(res); | 535 Py_DECREF(res); |
| 536 return restuple; | 536 return restuple; |
| 537 } | 537 } |
| 538 else if (PyObject_IsInstance(exc, PyExc_UnicodeDecodeError)) { | 538 else if (PyObject_IsInstance(exc, PyExc_UnicodeDecodeError)) { |
| 539 Py_UNICODE res = Py_UNICODE_REPLACEMENT_CHARACTER; | 539 Py_UNICODE res = Py_UNICODE_REPLACEMENT_CHARACTER; |
| 540 if (PyUnicodeDecodeError_GetEnd(exc, &end)) | 540 if (PyUnicodeDecodeError_GetEnd(exc, &end)) |
| 541 return NULL; | 541 return NULL; |
| 542 return Py_BuildValue("(u#n)", &res, 1, end); | 542 return Py_BuildValue("(u#n)", &res, 1, end); |
| 543 } | 543 } |
| 544 else if (PyObject_IsInstance(exc, PyExc_UnicodeTranslateError)) { | 544 else if (PyObject_IsInstance(exc, PyExc_UnicodeTranslateError)) { |
| 545 PyObject *res; | 545 PyObject *res; |
| 546 Py_UNICODE *p; | 546 Py_UNICODE *p; |
| 547 if (PyUnicodeTranslateError_GetStart(exc, &start)) | 547 if (PyUnicodeTranslateError_GetStart(exc, &start)) |
| 548 return NULL; | 548 return NULL; |
| 549 if (PyUnicodeTranslateError_GetEnd(exc, &end)) | 549 if (PyUnicodeTranslateError_GetEnd(exc, &end)) |
| 550 return NULL; | 550 return NULL; |
| 551 res = PyUnicode_FromUnicode(NULL, end-start); | 551 res = PyUnicode_FromUnicode(NULL, end-start); |
| 552 if (res == NULL) | 552 if (res == NULL) |
| 553 return NULL; | 553 return NULL; |
| 554 for (p = PyUnicode_AS_UNICODE(res), i = start; | 554 for (p = PyUnicode_AS_UNICODE(res), i = start; |
| 555 i<end; ++p, ++i) | 555 i<end; ++p, ++i) |
| 556 *p = Py_UNICODE_REPLACEMENT_CHARACTER; | 556 *p = Py_UNICODE_REPLACEMENT_CHARACTER; |
| 557 restuple = Py_BuildValue("(On)", res, end); | 557 restuple = Py_BuildValue("(On)", res, end); |
| 558 Py_DECREF(res); | 558 Py_DECREF(res); |
| 559 return restuple; | 559 return restuple; |
| 560 } | 560 } |
| 561 else { | 561 else { |
| 562 wrong_exception_type(exc); | 562 wrong_exception_type(exc); |
| 563 return NULL; | 563 return NULL; |
| 564 } | 564 } |
| 565 } | 565 } |
| 566 | 566 |
| 567 PyObject *PyCodec_XMLCharRefReplaceErrors(PyObject *exc) | 567 PyObject *PyCodec_XMLCharRefReplaceErrors(PyObject *exc) |
| 568 { | 568 { |
| 569 if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) { | 569 if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) { |
| 570 PyObject *restuple; | 570 PyObject *restuple; |
| 571 PyObject *object; | 571 PyObject *object; |
| 572 Py_ssize_t start; | 572 Py_ssize_t start; |
| 573 Py_ssize_t end; | 573 Py_ssize_t end; |
| 574 PyObject *res; | 574 PyObject *res; |
| 575 Py_UNICODE *p; | 575 Py_UNICODE *p; |
| 576 Py_UNICODE *startp; | 576 Py_UNICODE *startp; |
| 577 Py_UNICODE *outp; | 577 Py_UNICODE *outp; |
| 578 int ressize; | 578 int ressize; |
| 579 if (PyUnicodeEncodeError_GetStart(exc, &start)) | 579 if (PyUnicodeEncodeError_GetStart(exc, &start)) |
| 580 return NULL; | 580 return NULL; |
| 581 if (PyUnicodeEncodeError_GetEnd(exc, &end)) | 581 if (PyUnicodeEncodeError_GetEnd(exc, &end)) |
| 582 return NULL; | 582 return NULL; |
| 583 if (!(object = PyUnicodeEncodeError_GetObject(exc))) | 583 if (!(object = PyUnicodeEncodeError_GetObject(exc))) |
| 584 return NULL; | 584 return NULL; |
| 585 startp = PyUnicode_AS_UNICODE(object); | 585 startp = PyUnicode_AS_UNICODE(object); |
| 586 for (p = startp+start, ressize = 0; p < startp+end; ++p) { | 586 for (p = startp+start, ressize = 0; p < startp+end; ++p) { |
| 587 if (*p<10) | 587 if (*p<10) |
| 588 ressize += 2+1+1; | 588 ressize += 2+1+1; |
| 589 else if (*p<100) | 589 else if (*p<100) |
| 590 ressize += 2+2+1; | 590 ressize += 2+2+1; |
| 591 else if (*p<1000) | 591 else if (*p<1000) |
| 592 ressize += 2+3+1; | 592 ressize += 2+3+1; |
| 593 else if (*p<10000) | 593 else if (*p<10000) |
| 594 ressize += 2+4+1; | 594 ressize += 2+4+1; |
| 595 #ifndef Py_UNICODE_WIDE | 595 #ifndef Py_UNICODE_WIDE |
| 596 else | 596 else |
| 597 ressize += 2+5+1; | 597 ressize += 2+5+1; |
| 598 #else | 598 #else |
| 599 else if (*p<100000) | 599 else if (*p<100000) |
| 600 ressize += 2+5+1; | 600 ressize += 2+5+1; |
| 601 else if (*p<1000000) | 601 else if (*p<1000000) |
| 602 ressize += 2+6+1; | 602 ressize += 2+6+1; |
| 603 else | 603 else |
| 604 ressize += 2+7+1; | 604 ressize += 2+7+1; |
| 605 #endif | 605 #endif |
| 606 } | 606 } |
| 607 /* allocate replacement */ | 607 /* allocate replacement */ |
| 608 res = PyUnicode_FromUnicode(NULL, ressize); | 608 res = PyUnicode_FromUnicode(NULL, ressize); |
| 609 if (res == NULL) { | 609 if (res == NULL) { |
| 610 Py_DECREF(object); | 610 Py_DECREF(object); |
| 611 return NULL; | 611 return NULL; |
| 612 } | 612 } |
| 613 /* generate replacement */ | 613 /* generate replacement */ |
| 614 for (p = startp+start, outp = PyUnicode_AS_UNICODE(res); | 614 for (p = startp+start, outp = PyUnicode_AS_UNICODE(res); |
| 615 p < startp+end; ++p) { | 615 p < startp+end; ++p) { |
| 616 Py_UNICODE c = *p; | 616 Py_UNICODE c = *p; |
| 617 int digits; | 617 int digits; |
| 618 int base; | 618 int base; |
| 619 *outp++ = '&'; | 619 *outp++ = '&'; |
| 620 *outp++ = '#'; | 620 *outp++ = '#'; |
| 621 if (*p<10) { | 621 if (*p<10) { |
| 622 digits = 1; | 622 digits = 1; |
| 623 base = 1; | 623 base = 1; |
| 624 } | 624 } |
| 625 else if (*p<100) { | 625 else if (*p<100) { |
| 626 digits = 2; | 626 digits = 2; |
| 627 base = 10; | 627 base = 10; |
| 628 } | 628 } |
| 629 else if (*p<1000) { | 629 else if (*p<1000) { |
| 630 digits = 3; | 630 digits = 3; |
| 631 base = 100; | 631 base = 100; |
| 632 } | 632 } |
| 633 else if (*p<10000) { | 633 else if (*p<10000) { |
| 634 digits = 4; | 634 digits = 4; |
| 635 base = 1000; | 635 base = 1000; |
| 636 } | 636 } |
| 637 #ifndef Py_UNICODE_WIDE | 637 #ifndef Py_UNICODE_WIDE |
| 638 else { | 638 else { |
| 639 digits = 5; | 639 digits = 5; |
| 640 base = 10000; | 640 base = 10000; |
| 641 } | 641 } |
| 642 #else | 642 #else |
| 643 else if (*p<100000) { | 643 else if (*p<100000) { |
| 644 digits = 5; | 644 digits = 5; |
| 645 base = 10000; | 645 base = 10000; |
| 646 } | 646 } |
| 647 else if (*p<1000000) { | 647 else if (*p<1000000) { |
| 648 digits = 6; | 648 digits = 6; |
| 649 base = 100000; | 649 base = 100000; |
| 650 } | 650 } |
| 651 else { | 651 else { |
| 652 digits = 7; | 652 digits = 7; |
| 653 base = 1000000; | 653 base = 1000000; |
| 654 } | 654 } |
| 655 #endif | 655 #endif |
| 656 while (digits-->0) { | 656 while (digits-->0) { |
| 657 *outp++ = '0' + c/base; | 657 *outp++ = '0' + c/base; |
| 658 c %= base; | 658 c %= base; |
| 659 base /= 10; | 659 base /= 10; |
| 660 } | 660 } |
| 661 *outp++ = ';'; | 661 *outp++ = ';'; |
| 662 } | 662 } |
| 663 restuple = Py_BuildValue("(On)", res, end); | 663 restuple = Py_BuildValue("(On)", res, end); |
| 664 Py_DECREF(res); | 664 Py_DECREF(res); |
| 665 Py_DECREF(object); | 665 Py_DECREF(object); |
| 666 return restuple; | 666 return restuple; |
| 667 } | 667 } |
| 668 else { | 668 else { |
| 669 wrong_exception_type(exc); | 669 wrong_exception_type(exc); |
| 670 return NULL; | 670 return NULL; |
| 671 } | 671 } |
| 672 } | 672 } |
| 673 | 673 |
| 674 static Py_UNICODE hexdigits[] = { | 674 static Py_UNICODE hexdigits[] = { |
| 675 '0', '1', '2', '3', '4', '5', '6', '7', | 675 '0', '1', '2', '3', '4', '5', '6', '7', |
| 677 }; | 677 }; |
| 678 | 678 |
| 679 PyObject *PyCodec_BackslashReplaceErrors(PyObject *exc) | 679 PyObject *PyCodec_BackslashReplaceErrors(PyObject *exc) |
| 680 { | 680 { |
| 681 if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) { | 681 if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) { |
| 682 PyObject *restuple; | 682 PyObject *restuple; |
| 683 PyObject *object; | 683 PyObject *object; |
| 684 Py_ssize_t start; | 684 Py_ssize_t start; |
| 685 Py_ssize_t end; | 685 Py_ssize_t end; |
| 686 PyObject *res; | 686 PyObject *res; |
| 687 Py_UNICODE *p; | 687 Py_UNICODE *p; |
| 688 Py_UNICODE *startp; | 688 Py_UNICODE *startp; |
| 689 Py_UNICODE *outp; | 689 Py_UNICODE *outp; |
| 690 int ressize; | 690 int ressize; |
| 691 if (PyUnicodeEncodeError_GetStart(exc, &start)) | 691 if (PyUnicodeEncodeError_GetStart(exc, &start)) |
| 692 return NULL; | 692 return NULL; |
| 693 if (PyUnicodeEncodeError_GetEnd(exc, &end)) | 693 if (PyUnicodeEncodeError_GetEnd(exc, &end)) |
| 694 return NULL; | 694 return NULL; |
| 695 if (!(object = PyUnicodeEncodeError_GetObject(exc))) | 695 if (!(object = PyUnicodeEncodeError_GetObject(exc))) |
| 696 return NULL; | 696 return NULL; |
| 697 startp = PyUnicode_AS_UNICODE(object); | 697 startp = PyUnicode_AS_UNICODE(object); |
| 698 for (p = startp+start, ressize = 0; p < startp+end; ++p) { | 698 for (p = startp+start, ressize = 0; p < startp+end; ++p) { |
| 699 #ifdef Py_UNICODE_WIDE | 699 #ifdef Py_UNICODE_WIDE |
| 700 if (*p >= 0x00010000) | 700 if (*p >= 0x00010000) |
| 701 ressize += 1+1+8; | 701 ressize += 1+1+8; |
| 702 else | 702 else |
| 703 #endif | 703 #endif |
| 704 if (*p >= 0x100) { | 704 if (*p >= 0x100) { |
| 705 ressize += 1+1+4; | 705 ressize += 1+1+4; |
| 706 } | 706 } |
| 707 else | 707 else |
| 708 ressize += 1+1+2; | 708 ressize += 1+1+2; |
| 709 } | 709 } |
| 710 res = PyUnicode_FromUnicode(NULL, ressize); | 710 res = PyUnicode_FromUnicode(NULL, ressize); |
| 711 if (res==NULL) | 711 if (res==NULL) |
| 712 return NULL; | 712 return NULL; |
| 713 for (p = startp+start, outp = PyUnicode_AS_UNICODE(res); | 713 for (p = startp+start, outp = PyUnicode_AS_UNICODE(res); |
| 714 p < startp+end; ++p) { | 714 p < startp+end; ++p) { |
| 715 Py_UNICODE c = *p; | 715 Py_UNICODE c = *p; |
| 716 *outp++ = '\\'; | 716 *outp++ = '\\'; |
| 717 #ifdef Py_UNICODE_WIDE | 717 #ifdef Py_UNICODE_WIDE |
| 718 if (c >= 0x00010000) { | 718 if (c >= 0x00010000) { |
| 719 *outp++ = 'U'; | 719 *outp++ = 'U'; |
| 720 *outp++ = hexdigits[(c>>28)&0xf]; | 720 *outp++ = hexdigits[(c>>28)&0xf]; |
| 721 *outp++ = hexdigits[(c>>24)&0xf]; | 721 *outp++ = hexdigits[(c>>24)&0xf]; |
| 722 *outp++ = hexdigits[(c>>20)&0xf]; | 722 *outp++ = hexdigits[(c>>20)&0xf]; |
| 723 *outp++ = hexdigits[(c>>16)&0xf]; | 723 *outp++ = hexdigits[(c>>16)&0xf]; |
| 724 *outp++ = hexdigits[(c>>12)&0xf]; | 724 *outp++ = hexdigits[(c>>12)&0xf]; |
| 725 *outp++ = hexdigits[(c>>8)&0xf]; | 725 *outp++ = hexdigits[(c>>8)&0xf]; |
| 726 } | 726 } |
| 727 else | 727 else |
| 728 #endif | 728 #endif |
| 729 if (c >= 0x100) { | 729 if (c >= 0x100) { |
| 730 *outp++ = 'u'; | 730 *outp++ = 'u'; |
| 731 *outp++ = hexdigits[(c>>12)&0xf]; | 731 *outp++ = hexdigits[(c>>12)&0xf]; |
| 732 *outp++ = hexdigits[(c>>8)&0xf]; | 732 *outp++ = hexdigits[(c>>8)&0xf]; |
| 733 } | 733 } |
| 734 else | 734 else |
| 735 *outp++ = 'x'; | 735 *outp++ = 'x'; |
| 736 *outp++ = hexdigits[(c>>4)&0xf]; | 736 *outp++ = hexdigits[(c>>4)&0xf]; |
| 737 *outp++ = hexdigits[c&0xf]; | 737 *outp++ = hexdigits[c&0xf]; |
| 738 } | 738 } |
| 739 | 739 |
| 740 restuple = Py_BuildValue("(On)", res, end); | 740 restuple = Py_BuildValue("(On)", res, end); |
| 741 Py_DECREF(res); | 741 Py_DECREF(res); |
| 742 Py_DECREF(object); | 742 Py_DECREF(object); |
| 743 return restuple; | 743 return restuple; |
| 744 } | 744 } |
| 745 else { | 745 else { |
| 746 wrong_exception_type(exc); | 746 wrong_exception_type(exc); |
| 747 return NULL; | 747 return NULL; |
| 748 } | 748 } |
| 749 } | 749 } |
| 750 | 750 |
| 751 /* This handler is declared static until someone demonstrates | 751 /* This handler is declared static until someone demonstrates |
| 752 a need to call it directly. */ | 752 a need to call it directly. */ |
| 757 PyObject *object; | 757 PyObject *object; |
| 758 Py_ssize_t start; | 758 Py_ssize_t start; |
| 759 Py_ssize_t end; | 759 Py_ssize_t end; |
| 760 PyObject *res; | 760 PyObject *res; |
| 761 if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) { | 761 if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) { |
| 762 Py_UNICODE *p; | 762 Py_UNICODE *p; |
| 763 Py_UNICODE *startp; | 763 Py_UNICODE *startp; |
| 764 char *outp; | 764 char *outp; |
| 765 if (PyUnicodeEncodeError_GetStart(exc, &start)) | 765 if (PyUnicodeEncodeError_GetStart(exc, &start)) |
| 766 return NULL; | 766 return NULL; |
| 767 if (PyUnicodeEncodeError_GetEnd(exc, &end)) | 767 if (PyUnicodeEncodeError_GetEnd(exc, &end)) |
| 768 return NULL; | 768 return NULL; |
| 769 if (!(object = PyUnicodeEncodeError_GetObject(exc))) | 769 if (!(object = PyUnicodeEncodeError_GetObject(exc))) |
| 770 return NULL; | 770 return NULL; |
| 771 startp = PyUnicode_AS_UNICODE(object); | 771 startp = PyUnicode_AS_UNICODE(object); |
| 772 res = PyBytes_FromStringAndSize(NULL, 3*(end-start)); | 772 res = PyBytes_FromStringAndSize(NULL, 3*(end-start)); |
| 773 if (!res) { | 773 if (!res) { |
| 774 Py_DECREF(object); | 774 Py_DECREF(object); |
| 775 return NULL; | 775 return NULL; |
| 776 } | 776 } |
| 777 outp = PyBytes_AsString(res); | 777 outp = PyBytes_AsString(res); |
| 778 for (p = startp+start; p < startp+end; p++) { | 778 for (p = startp+start; p < startp+end; p++) { |
| 779 Py_UNICODE ch = *p; | 779 Py_UNICODE ch = *p; |
| 780 if (ch < 0xd800 || ch > 0xdfff) { | 780 if (ch < 0xd800 || ch > 0xdfff) { |
| 781 /* Not a surrogate, fail with original exception */ | 781 /* Not a surrogate, fail with original exception */ |
| 782 PyErr_SetObject(PyExceptionInstance_Class(exc), exc); | 782 PyErr_SetObject(PyExceptionInstance_Class(exc), exc); |
| 783 Py_DECREF(res); | 783 Py_DECREF(res); |
| 784 Py_DECREF(object); | 784 Py_DECREF(object); |
| 785 return NULL; | 785 return NULL; |
| 786 } | 786 } |
| 787 *outp++ = (char)(0xe0 | (ch >> 12)); | 787 *outp++ = (char)(0xe0 | (ch >> 12)); |
| 788 *outp++ = (char)(0x80 | ((ch >> 6) & 0x3f)); | 788 *outp++ = (char)(0x80 | ((ch >> 6) & 0x3f)); |
| 789 *outp++ = (char)(0x80 | (ch & 0x3f)); | 789 *outp++ = (char)(0x80 | (ch & 0x3f)); |
| 790 } | 790 } |
| 791 restuple = Py_BuildValue("(On)", res, end); | 791 restuple = Py_BuildValue("(On)", res, end); |
| 792 Py_DECREF(res); | 792 Py_DECREF(res); |
| 793 Py_DECREF(object); | 793 Py_DECREF(object); |
| 794 return restuple; | 794 return restuple; |
| 795 } | 795 } |
| 796 else if (PyObject_IsInstance(exc, PyExc_UnicodeDecodeError)) { | 796 else if (PyObject_IsInstance(exc, PyExc_UnicodeDecodeError)) { |
| 797 unsigned char *p; | 797 unsigned char *p; |
| 798 Py_UNICODE ch = 0; | 798 Py_UNICODE ch = 0; |
| 799 if (PyUnicodeDecodeError_GetStart(exc, &start)) | 799 if (PyUnicodeDecodeError_GetStart(exc, &start)) |
| 800 return NULL; | 800 return NULL; |
| 801 if (!(object = PyUnicodeDecodeError_GetObject(exc))) | 801 if (!(object = PyUnicodeDecodeError_GetObject(exc))) |
| 802 return NULL; | 802 return NULL; |
| 803 if (!(p = (unsigned char*)PyBytes_AsString(object))) { | 803 if (!(p = (unsigned char*)PyBytes_AsString(object))) { |
| 804 Py_DECREF(object); | 804 Py_DECREF(object); |
| 805 return NULL; | 805 return NULL; |
| 806 } | 806 } |
| 807 /* Try decoding a single surrogate character. If | 807 /* Try decoding a single surrogate character. If |
| 808 there are more, let the codec call us again. */ | 808 there are more, let the codec call us again. */ |
| 809 p += start; | 809 p += start; |
| 810 if ((p[0] & 0xf0) == 0xe0 || | 810 if ((p[0] & 0xf0) == 0xe0 || |
| 811 (p[1] & 0xc0) == 0x80 || | 811 (p[1] & 0xc0) == 0x80 || |
| 812 (p[2] & 0xc0) == 0x80) { | 812 (p[2] & 0xc0) == 0x80) { |
| 813 /* it's a three-byte code */ | 813 /* it's a three-byte code */ |
| 814 ch = ((p[0] & 0x0f) << 12) + ((p[1] & 0x3f) << 6) + (p[2] & 0x3f); | 814 ch = ((p[0] & 0x0f) << 12) + ((p[1] & 0x3f) << 6) + (p[2] & 0x3f); |
| 815 if (ch < 0xd800 || ch > 0xdfff) | 815 if (ch < 0xd800 || ch > 0xdfff) |
| 816 /* it's not a surrogate - fail */ | 816 /* it's not a surrogate - fail */ |
| 817 ch = 0; | 817 ch = 0; |
| 818 } | 818 } |
| 819 Py_DECREF(object); | 819 Py_DECREF(object); |
| 820 if (ch == 0) { | 820 if (ch == 0) { |
| 821 PyErr_SetObject(PyExceptionInstance_Class(exc), exc); | 821 PyErr_SetObject(PyExceptionInstance_Class(exc), exc); |
| 822 return NULL; | 822 return NULL; |
| 823 } | 823 } |
| 824 return Py_BuildValue("(u#n)", &ch, 1, start+3); | 824 return Py_BuildValue("(u#n)", &ch, 1, start+3); |
| 825 } | 825 } |
| 826 else { | 826 else { |
| 827 wrong_exception_type(exc); | 827 wrong_exception_type(exc); |
| 828 return NULL; | 828 return NULL; |
| 829 } | 829 } |
| 830 } | 830 } |
| 831 | 831 |
| 832 static PyObject * | 832 static PyObject * |
| 833 PyCodec_SurrogateEscapeErrors(PyObject *exc) | 833 PyCodec_SurrogateEscapeErrors(PyObject *exc) |
| 836 PyObject *object; | 836 PyObject *object; |
| 837 Py_ssize_t start; | 837 Py_ssize_t start; |
| 838 Py_ssize_t end; | 838 Py_ssize_t end; |
| 839 PyObject *res; | 839 PyObject *res; |
| 840 if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) { | 840 if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) { |
| 841 Py_UNICODE *p; | 841 Py_UNICODE *p; |
| 842 Py_UNICODE *startp; | 842 Py_UNICODE *startp; |
| 843 char *outp; | 843 char *outp; |
| 844 if (PyUnicodeEncodeError_GetStart(exc, &start)) | 844 if (PyUnicodeEncodeError_GetStart(exc, &start)) |
| 845 return NULL; | 845 return NULL; |
| 846 if (PyUnicodeEncodeError_GetEnd(exc, &end)) | 846 if (PyUnicodeEncodeError_GetEnd(exc, &end)) |
| 847 return NULL; | 847 return NULL; |
| 848 if (!(object = PyUnicodeEncodeError_GetObject(exc))) | 848 if (!(object = PyUnicodeEncodeError_GetObject(exc))) |
| 849 return NULL; | 849 return NULL; |
| 850 startp = PyUnicode_AS_UNICODE(object); | 850 startp = PyUnicode_AS_UNICODE(object); |
| 851 res = PyBytes_FromStringAndSize(NULL, end-start); | 851 res = PyBytes_FromStringAndSize(NULL, end-start); |
| 852 if (!res) { | 852 if (!res) { |
| 853 Py_DECREF(object); | 853 Py_DECREF(object); |
| 854 return NULL; | 854 return NULL; |
| 855 } | 855 } |
| 856 outp = PyBytes_AsString(res); | 856 outp = PyBytes_AsString(res); |
| 857 for (p = startp+start; p < startp+end; p++) { | 857 for (p = startp+start; p < startp+end; p++) { |
| 858 Py_UNICODE ch = *p; | 858 Py_UNICODE ch = *p; |
| 859 if (ch < 0xdc80 || ch > 0xdcff) { | 859 if (ch < 0xdc80 || ch > 0xdcff) { |
| 860 /* Not a UTF-8b surrogate, fail with original exception */ | 860 /* Not a UTF-8b surrogate, fail with original exception */ |
| 861 PyErr_SetObject(PyExceptionInstance_Class(exc), exc); | 861 PyErr_SetObject(PyExceptionInstance_Class(exc), exc); |
| 862 Py_DECREF(res); | 862 Py_DECREF(res); |
| 863 Py_DECREF(object); | 863 Py_DECREF(object); |
| 864 return NULL; | 864 return NULL; |
| 865 } | 865 } |
| 866 *outp++ = ch - 0xdc00; | 866 *outp++ = ch - 0xdc00; |
| 867 } | 867 } |
| 868 restuple = Py_BuildValue("(On)", res, end); | 868 restuple = Py_BuildValue("(On)", res, end); |
| 869 Py_DECREF(res); | 869 Py_DECREF(res); |
| 870 Py_DECREF(object); | 870 Py_DECREF(object); |
| 871 return restuple; | 871 return restuple; |
| 872 } | 872 } |
| 873 else if (PyObject_IsInstance(exc, PyExc_UnicodeDecodeError)) { | 873 else if (PyObject_IsInstance(exc, PyExc_UnicodeDecodeError)) { |
| 874 unsigned char *p; | 874 unsigned char *p; |
| 875 Py_UNICODE ch[4]; /* decode up to 4 bad bytes. */ | 875 Py_UNICODE ch[4]; /* decode up to 4 bad bytes. */ |
| 876 int consumed = 0; | 876 int consumed = 0; |
| 877 if (PyUnicodeDecodeError_GetStart(exc, &start)) | 877 if (PyUnicodeDecodeError_GetStart(exc, &start)) |
| 878 return NULL; | 878 return NULL; |
| 879 if (PyUnicodeDecodeError_GetEnd(exc, &end)) | 879 if (PyUnicodeDecodeError_GetEnd(exc, &end)) |
| 880 return NULL; | 880 return NULL; |
| 881 if (!(object = PyUnicodeDecodeError_GetObject(exc))) | 881 if (!(object = PyUnicodeDecodeError_GetObject(exc))) |
| 882 return NULL; | 882 return NULL; |
| 883 if (!(p = (unsigned char*)PyBytes_AsString(object))) { | 883 if (!(p = (unsigned char*)PyBytes_AsString(object))) { |
| 884 Py_DECREF(object); | 884 Py_DECREF(object); |
| 885 return NULL; | 885 return NULL; |
| 886 } | 886 } |
| 887 while (consumed < 4 && consumed < end-start) { | 887 while (consumed < 4 && consumed < end-start) { |
| 888 /* Refuse to escape ASCII bytes. */ | 888 /* Refuse to escape ASCII bytes. */ |
| 889 if (p[start+consumed] < 128) | 889 if (p[start+consumed] < 128) |
| 890 break; | 890 break; |
| 891 ch[consumed] = 0xdc00 + p[start+consumed]; | 891 ch[consumed] = 0xdc00 + p[start+consumed]; |
| 892 consumed++; | 892 consumed++; |
| 893 } | 893 } |
| 894 Py_DECREF(object); | 894 Py_DECREF(object); |
| 895 if (!consumed) { | 895 if (!consumed) { |
| 896 /* codec complained about ASCII byte. */ | 896 /* codec complained about ASCII byte. */ |
| 897 PyErr_SetObject(PyExceptionInstance_Class(exc), exc); | 897 PyErr_SetObject(PyExceptionInstance_Class(exc), exc); |
| 898 return NULL; | 898 return NULL; |
| 899 } | 899 } |
| 900 return Py_BuildValue("(u#n)", ch, consumed, start+consumed); | 900 return Py_BuildValue("(u#n)", ch, consumed, start+consumed); |
| 901 } | 901 } |
| 902 else { | 902 else { |
| 903 wrong_exception_type(exc); | 903 wrong_exception_type(exc); |
| 904 return NULL; | 904 return NULL; |
| 905 } | 905 } |
| 906 } | 906 } |
| 907 | 907 |
| 908 | 908 |
| 909 static PyObject *strict_errors(PyObject *self, PyObject *exc) | 909 static PyObject *strict_errors(PyObject *self, PyObject *exc) |
| 910 { | 910 { |
| 911 return PyCodec_StrictErrors(exc); | 911 return PyCodec_StrictErrors(exc); |
| 912 } | 912 } |
| 913 | 913 |
| 946 } | 946 } |
| 947 | 947 |
| 948 static int _PyCodecRegistry_Init(void) | 948 static int _PyCodecRegistry_Init(void) |
| 949 { | 949 { |
| 950 static struct { | 950 static struct { |
| 951 char *name; | 951 char *name; |
| 952 PyMethodDef def; | 952 PyMethodDef def; |
| 953 } methods[] = | 953 } methods[] = |
| 954 { | 954 { |
| 955 { | 955 { |
| 956 "strict", | 956 "strict", |
| 957 { | 957 { |
| 958 "strict_errors", | 958 "strict_errors", |
| 959 strict_errors, | 959 strict_errors, |
| 960 METH_O, | 960 METH_O, |
| 961 PyDoc_STR("Implements the 'strict' error handling, which " | 961 PyDoc_STR("Implements the 'strict' error handling, which " |
| 962 "raises a UnicodeError on coding errors.") | 962 "raises a UnicodeError on coding errors.") |
| 963 } | 963 } |
| 964 }, | 964 }, |
| 965 { | 965 { |
| 966 "ignore", | 966 "ignore", |
| 967 { | 967 { |
| 968 "ignore_errors", | 968 "ignore_errors", |
| 969 ignore_errors, | 969 ignore_errors, |
| 970 METH_O, | 970 METH_O, |
| 971 PyDoc_STR("Implements the 'ignore' error handling, which " | 971 PyDoc_STR("Implements the 'ignore' error handling, which " |
| 972 "ignores malformed data and continues.") | 972 "ignores malformed data and continues.") |
| 973 } | 973 } |
| 974 }, | 974 }, |
| 975 { | 975 { |
| 976 "replace", | 976 "replace", |
| 977 { | 977 { |
| 978 "replace_errors", | 978 "replace_errors", |
| 979 replace_errors, | 979 replace_errors, |
| 980 METH_O, | 980 METH_O, |
| 981 PyDoc_STR("Implements the 'replace' error handling, which " | 981 PyDoc_STR("Implements the 'replace' error handling, which " |
| 982 "replaces malformed data with a replacement marker.") | 982 "replaces malformed data with a replacement marker.") |
| 983 } | 983 } |
| 984 }, | 984 }, |
| 985 { | 985 { |
| 986 "xmlcharrefreplace", | 986 "xmlcharrefreplace", |
| 987 { | 987 { |
| 988 "xmlcharrefreplace_errors", | 988 "xmlcharrefreplace_errors", |
| 989 xmlcharrefreplace_errors, | 989 xmlcharrefreplace_errors, |
| 990 METH_O, | 990 METH_O, |
| 991 PyDoc_STR("Implements the 'xmlcharrefreplace' error handling, " | 991 PyDoc_STR("Implements the 'xmlcharrefreplace' error handling, " |
| 992 "which replaces an unencodable character with the " | 992 "which replaces an unencodable character with the " |
| 993 "appropriate XML character reference.") | 993 "appropriate XML character reference.") |
| 994 } | 994 } |
| 995 }, | 995 }, |
| 996 { | 996 { |
| 997 "backslashreplace", | 997 "backslashreplace", |
| 998 { | 998 { |
| 999 "backslashreplace_errors", | 999 "backslashreplace_errors", |
| 1000 backslashreplace_errors, | 1000 backslashreplace_errors, |
| 1001 METH_O, | 1001 METH_O, |
| 1002 PyDoc_STR("Implements the 'backslashreplace' error handling, " | 1002 PyDoc_STR("Implements the 'backslashreplace' error handling, " |
| 1003 "which replaces an unencodable character with a " | 1003 "which replaces an unencodable character with a " |
| 1004 "backslashed escape sequence.") | 1004 "backslashed escape sequence.") |
| 1005 } | 1005 } |
| 1006 }, | 1006 }, |
| 1007 { | 1007 { |
| 1008 "surrogatepass", | 1008 "surrogatepass", |
| 1009 { | 1009 { |
| 1010 "surrogatepass", | 1010 "surrogatepass", |
| 1011 surrogatepass_errors, | 1011 surrogatepass_errors, |
| 1012 METH_O | 1012 METH_O |
| 1013 } | 1013 } |
| 1014 }, | 1014 }, |
| 1015 { | 1015 { |
| 1016 "surrogateescape", | 1016 "surrogateescape", |
| 1017 { | 1017 { |
| 1018 "surrogateescape", | 1018 "surrogateescape", |
| 1019 surrogateescape_errors, | 1019 surrogateescape_errors, |
| 1020 METH_O | 1020 METH_O |
| 1021 } | 1021 } |
| 1022 } | 1022 } |
| 1023 }; | 1023 }; |
| 1024 | 1024 |
| 1025 PyInterpreterState *interp = PyThreadState_GET()->interp; | 1025 PyInterpreterState *interp = PyThreadState_GET()->interp; |
| 1026 PyObject *mod; | 1026 PyObject *mod; |
| 1027 unsigned i; | 1027 unsigned i; |
| 1028 | 1028 |
| 1029 if (interp->codec_search_path != NULL) | 1029 if (interp->codec_search_path != NULL) |
| 1030 return 0; | 1030 return 0; |
| 1031 | 1031 |
| 1032 interp->codec_search_path = PyList_New(0); | 1032 interp->codec_search_path = PyList_New(0); |
| 1033 interp->codec_search_cache = PyDict_New(); | 1033 interp->codec_search_cache = PyDict_New(); |
| 1034 interp->codec_error_registry = PyDict_New(); | 1034 interp->codec_error_registry = PyDict_New(); |
| 1035 | 1035 |
| 1036 if (interp->codec_error_registry) { | 1036 if (interp->codec_error_registry) { |
| 1037 for (i = 0; i < sizeof(methods)/sizeof(methods[0]); ++i) { | 1037 for (i = 0; i < sizeof(methods)/sizeof(methods[0]); ++i) { |
| 1038 PyObject *func = PyCFunction_New(&methods[i].def, NULL); | 1038 PyObject *func = PyCFunction_New(&methods[i].def, NULL); |
| 1039 int res; | 1039 int res; |
| 1040 if (!func) | 1040 if (!func) |
| 1041 Py_FatalError("can't initialize codec error registry"); | 1041 Py_FatalError("can't initialize codec error registry"); |
| 1042 res = PyCodec_RegisterError(methods[i].name, func); | 1042 res = PyCodec_RegisterError(methods[i].name, func); |
| 1043 Py_DECREF(func); | 1043 Py_DECREF(func); |
| 1044 if (res) | 1044 if (res) |
| 1045 Py_FatalError("can't initialize codec error registry"); | 1045 Py_FatalError("can't initialize codec error registry"); |
| 1046 } | 1046 } |
| 1047 } | 1047 } |
| 1048 | 1048 |
| 1049 if (interp->codec_search_path == NULL || | 1049 if (interp->codec_search_path == NULL || |
| 1050 interp->codec_search_cache == NULL || | 1050 interp->codec_search_cache == NULL || |
| 1051 interp->codec_error_registry == NULL) | 1051 interp->codec_error_registry == NULL) |
| 1052 Py_FatalError("can't initialize codec registry"); | 1052 Py_FatalError("can't initialize codec registry"); |
| 1053 | 1053 |
| 1054 mod = PyImport_ImportModuleNoBlock("encodings"); | 1054 mod = PyImport_ImportModuleNoBlock("encodings"); |
| 1055 if (mod == NULL) { | 1055 if (mod == NULL) { |
| 1056 if (PyErr_ExceptionMatches(PyExc_ImportError)) { | 1056 if (PyErr_ExceptionMatches(PyExc_ImportError)) { |
| 1057 /* Ignore ImportErrors... this is done so that | 1057 /* Ignore ImportErrors... this is done so that |
| 1058 distributions can disable the encodings package. Note | 1058 distributions can disable the encodings package. Note |
| 1059 that other errors are not masked, e.g. SystemErrors | 1059 that other errors are not masked, e.g. SystemErrors |
| 1060 raised to inform the user of an error in the Python | 1060 raised to inform the user of an error in the Python |
| 1061 configuration are still reported back to the user. */ | 1061 configuration are still reported back to the user. */ |
| 1062 PyErr_Clear(); | 1062 PyErr_Clear(); |
| 1063 return 0; | 1063 return 0; |
| 1064 } | 1064 } |
| 1065 return -1; | 1065 return -1; |
| 1066 } | 1066 } |
| 1067 Py_DECREF(mod); | 1067 Py_DECREF(mod); |
| 1068 interp->codecs_initialized = 1; | 1068 interp->codecs_initialized = 1; |
| 1069 return 0; | 1069 return 0; |
| 1070 } | 1070 } |
