diff options
author | Walter Dörwald <walter@livinglogic.de> | 2002-09-02 13:14:32 (GMT) |
---|---|---|
committer | Walter Dörwald <walter@livinglogic.de> | 2002-09-02 13:14:32 (GMT) |
commit | 3aeb632c3152fa082132ce55b9a880e0d16b04ae (patch) | |
tree | 192bc1543ea77a826d0c940d024dbc8ebba82156 /Python | |
parent | 94fab762de532de551987e1f48a125145f85304b (diff) | |
download | cpython-3aeb632c3152fa082132ce55b9a880e0d16b04ae.zip cpython-3aeb632c3152fa082132ce55b9a880e0d16b04ae.tar.gz cpython-3aeb632c3152fa082132ce55b9a880e0d16b04ae.tar.bz2 |
PEP 293 implemention (from SF patch http://www.python.org/sf/432401)
Diffstat (limited to 'Python')
-rw-r--r-- | Python/codecs.c | 399 | ||||
-rw-r--r-- | Python/exceptions.c | 603 |
2 files changed, 1002 insertions, 0 deletions
diff --git a/Python/codecs.c b/Python/codecs.c index 3e54d8f..09cba75 100644 --- a/Python/codecs.c +++ b/Python/codecs.c @@ -422,12 +422,409 @@ PyObject *PyCodec_Decode(PyObject *object, return NULL; } +static PyObject *_PyCodec_ErrorRegistry; + +/* Register the error handling callback function error under the name + name. This function will be called by the codec when it encounters + an unencodable characters/undecodable bytes and doesn't know the + callback name, when name is specified as the error parameter + in the call to the encode/decode function. + Return 0 on success, -1 on error */ +int PyCodec_RegisterError(const char *name, PyObject *error) +{ + if (!PyCallable_Check(error)) { + PyErr_SetString(PyExc_TypeError, "handler must be callable"); + return -1; + } + return PyDict_SetItemString( _PyCodec_ErrorRegistry, (char *)name, error); +} + +/* Lookup the error handling callback function registered under the + name error. As a special case NULL can be passed, in which case + the error handling callback for strict encoding will be returned. */ +PyObject *PyCodec_LookupError(const char *name) +{ + PyObject *handler = NULL; + + if (name==NULL) + name = "strict"; + handler = PyDict_GetItemString(_PyCodec_ErrorRegistry, (char *)name); + if (!handler) + PyErr_Format(PyExc_LookupError, "unknown error handler name '%.400s'", name); + else + Py_INCREF(handler); + return handler; +} + +static void wrong_exception_type(PyObject *exc) +{ + PyObject *type = PyObject_GetAttrString(exc, "__class__"); + if (type != NULL) { + PyObject *name = PyObject_GetAttrString(type, "__name__"); + Py_DECREF(type); + if (name != NULL) { + PyObject *string = PyObject_Str(name); + Py_DECREF(name); + PyErr_Format(PyExc_TypeError, "don't know how to handle %.400s in error callback", + PyString_AS_STRING(string)); + Py_DECREF(string); + } + } +} + +PyObject *PyCodec_StrictErrors(PyObject *exc) +{ + if (PyInstance_Check(exc)) + PyErr_SetObject((PyObject*)((PyInstanceObject*)exc)->in_class, + exc); + else + PyErr_SetString(PyExc_TypeError, "codec must pass exception instance"); + return NULL; +} + + +PyObject *PyCodec_IgnoreErrors(PyObject *exc) +{ + int end; + if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) { + if (PyUnicodeEncodeError_GetEnd(exc, &end)) + return NULL; + } + else if (PyObject_IsInstance(exc, PyExc_UnicodeDecodeError)) { + if (PyUnicodeDecodeError_GetEnd(exc, &end)) + return NULL; + } + else if (PyObject_IsInstance(exc, PyExc_UnicodeTranslateError)) { + if (PyUnicodeTranslateError_GetEnd(exc, &end)) + return NULL; + } + else { + wrong_exception_type(exc); + return NULL; + } + /* ouch: passing NULL, 0, pos gives None instead of u'' */ + return Py_BuildValue("(u#i)", &end, 0, end); +} + + +PyObject *PyCodec_ReplaceErrors(PyObject *exc) +{ + PyObject *restuple; + int start; + int end; + int i; + + if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) { + PyObject *res; + Py_UNICODE *p; + if (PyUnicodeEncodeError_GetStart(exc, &start)) + return NULL; + if (PyUnicodeEncodeError_GetEnd(exc, &end)) + return NULL; + res = PyUnicode_FromUnicode(NULL, end-start); + if (res == NULL) + return NULL; + for (p = PyUnicode_AS_UNICODE(res), i = start; + i<end; ++p, ++i) + *p = '?'; + restuple = Py_BuildValue("(Oi)", res, end); + Py_DECREF(res); + return restuple; + } + else if (PyObject_IsInstance(exc, PyExc_UnicodeDecodeError)) { + Py_UNICODE res = Py_UNICODE_REPLACEMENT_CHARACTER; + if (PyUnicodeDecodeError_GetEnd(exc, &end)) + return NULL; + return Py_BuildValue("(u#i)", &res, 1, end); + } + else if (PyObject_IsInstance(exc, PyExc_UnicodeTranslateError)) { + PyObject *res; + Py_UNICODE *p; + if (PyUnicodeTranslateError_GetStart(exc, &start)) + return NULL; + if (PyUnicodeTranslateError_GetEnd(exc, &end)) + return NULL; + res = PyUnicode_FromUnicode(NULL, end-start); + if (res == NULL) + return NULL; + for (p = PyUnicode_AS_UNICODE(res), i = start; + i<end; ++p, ++i) + *p = Py_UNICODE_REPLACEMENT_CHARACTER; + restuple = Py_BuildValue("(Oi)", res, end); + Py_DECREF(res); + return restuple; + } + else { + wrong_exception_type(exc); + return NULL; + } +} + +PyObject *PyCodec_XMLCharRefReplaceErrors(PyObject *exc) +{ + if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) { + PyObject *restuple; + PyObject *object; + int start; + int end; + PyObject *res; + Py_UNICODE *p; + Py_UNICODE *startp; + Py_UNICODE *outp; + int ressize; + if (PyUnicodeEncodeError_GetStart(exc, &start)) + return NULL; + if (PyUnicodeEncodeError_GetEnd(exc, &end)) + return NULL; + if (!(object = PyUnicodeEncodeError_GetObject(exc))) + return NULL; + startp = PyUnicode_AS_UNICODE(object); + for (p = startp+start, ressize = 0; p < startp+end; ++p) { + if (*p<10) + ressize += 2+1+1; + else if (*p<100) + ressize += 2+2+1; + else if (*p<1000) + ressize += 2+3+1; + else if (*p<10000) + ressize += 2+4+1; + else if (*p<100000) + ressize += 2+5+1; + else if (*p<1000000) + ressize += 2+6+1; + else + ressize += 2+7+1; + } + /* allocate replacement */ + res = PyUnicode_FromUnicode(NULL, ressize); + if (res == NULL) { + Py_DECREF(object); + return NULL; + } + /* generate replacement */ + for (p = startp+start, outp = PyUnicode_AS_UNICODE(res); + p < startp+end; ++p) { + Py_UNICODE c = *p; + int digits; + int base; + *outp++ = '&'; + *outp++ = '#'; + if (*p<10) { + digits = 1; + base = 1; + } + else if (*p<100) { + digits = 2; + base = 10; + } + else if (*p<1000) { + digits = 3; + base = 100; + } + else if (*p<10000) { + digits = 4; + base = 1000; + } + else if (*p<100000) { + digits = 5; + base = 10000; + } + else if (*p<1000000) { + digits = 6; + base = 100000; + } + else { + digits = 7; + base = 1000000; + } + while (digits-->0) { + *outp++ = '0' + c/base; + c %= base; + base /= 10; + } + *outp++ = ';'; + } + restuple = Py_BuildValue("(Oi)", res, end); + Py_DECREF(res); + Py_DECREF(object); + return restuple; + } + else { + wrong_exception_type(exc); + return NULL; + } +} + +static Py_UNICODE hexdigits[] = { + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' +}; + +PyObject *PyCodec_BackslashReplaceErrors(PyObject *exc) +{ + if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) { + PyObject *restuple; + PyObject *object; + int start; + int end; + PyObject *res; + Py_UNICODE *p; + Py_UNICODE *startp; + Py_UNICODE *outp; + int ressize; + if (PyUnicodeEncodeError_GetStart(exc, &start)) + return NULL; + if (PyUnicodeEncodeError_GetEnd(exc, &end)) + return NULL; + if (!(object = PyUnicodeEncodeError_GetObject(exc))) + return NULL; + startp = PyUnicode_AS_UNICODE(object); + for (p = startp+start, ressize = 0; p < startp+end; ++p) { + if (*p >= 0x00010000) + ressize += 1+1+8; + else if (*p >= 0x100) { + ressize += 1+1+4; + } + else + ressize += 1+1+2; + } + res = PyUnicode_FromUnicode(NULL, ressize); + if (res==NULL) + return NULL; + for (p = startp+start, outp = PyUnicode_AS_UNICODE(res); + p < startp+end; ++p) { + Py_UNICODE c = *p; + *outp++ = '\\'; + if (c >= 0x00010000) { + *outp++ = 'U'; + *outp++ = hexdigits[(c>>28)&0xf]; + *outp++ = hexdigits[(c>>24)&0xf]; + *outp++ = hexdigits[(c>>20)&0xf]; + *outp++ = hexdigits[(c>>16)&0xf]; + *outp++ = hexdigits[(c>>12)&0xf]; + *outp++ = hexdigits[(c>>8)&0xf]; + } + else if (c >= 0x100) { + *outp++ = 'u'; + *outp++ = hexdigits[(c>>12)&0xf]; + *outp++ = hexdigits[(c>>8)&0xf]; + } + else + *outp++ = 'x'; + *outp++ = hexdigits[(c>>4)&0xf]; + *outp++ = hexdigits[c&0xf]; + } + + restuple = Py_BuildValue("(Oi)", res, end); + Py_DECREF(res); + Py_DECREF(object); + return restuple; + } + else { + wrong_exception_type(exc); + return NULL; + } +} + +static PyObject *strict_errors(PyObject *self, PyObject *exc) +{ + return PyCodec_StrictErrors(exc); +} + + +static PyObject *ignore_errors(PyObject *self, PyObject *exc) +{ + return PyCodec_IgnoreErrors(exc); +} + + +static PyObject *replace_errors(PyObject *self, PyObject *exc) +{ + return PyCodec_ReplaceErrors(exc); +} + + +static PyObject *xmlcharrefreplace_errors(PyObject *self, PyObject *exc) +{ + return PyCodec_XMLCharRefReplaceErrors(exc); +} + + +static PyObject *backslashreplace_errors(PyObject *self, PyObject *exc) +{ + return PyCodec_BackslashReplaceErrors(exc); +} + + void _PyCodecRegistry_Init(void) { + static struct { + char *name; + PyMethodDef def; + } methods[] = + { + { + "strict", + { + "strict_errors", + strict_errors, + METH_O + } + }, + { + "ignore", + { + "ignore_errors", + ignore_errors, + METH_O + } + }, + { + "replace", + { + "replace_errors", + replace_errors, + METH_O + } + }, + { + "xmlcharrefreplace", + { + "xmlcharrefreplace_errors", + xmlcharrefreplace_errors, + METH_O + } + }, + { + "backslashreplace", + { + "backslashreplace_errors", + backslashreplace_errors, + METH_O + } + } + }; if (_PyCodec_SearchPath == NULL) _PyCodec_SearchPath = PyList_New(0); if (_PyCodec_SearchCache == NULL) _PyCodec_SearchCache = PyDict_New(); + if (_PyCodec_ErrorRegistry == NULL) { + int i; + _PyCodec_ErrorRegistry = PyDict_New(); + + if (_PyCodec_ErrorRegistry) { + for (i = 0; i < 5; ++i) { + PyObject *func = PyCFunction_New(&methods[i].def, NULL); + int res; + if (!func) + Py_FatalError("can't initialize codec error registry"); + res = PyCodec_RegisterError(methods[i].name, func); + Py_DECREF(func); + if (res) + Py_FatalError("can't initialize codec error registry"); + } + } + } if (_PyCodec_SearchPath == NULL || _PyCodec_SearchCache == NULL) Py_FatalError("can't initialize codec registry"); @@ -439,4 +836,6 @@ void _PyCodecRegistry_Fini(void) _PyCodec_SearchPath = NULL; Py_XDECREF(_PyCodec_SearchCache); _PyCodec_SearchCache = NULL; + Py_XDECREF(_PyCodec_ErrorRegistry); + _PyCodec_ErrorRegistry = NULL; } diff --git a/Python/exceptions.c b/Python/exceptions.c index c4bd626..1667cd9 100644 --- a/Python/exceptions.c +++ b/Python/exceptions.c @@ -100,6 +100,10 @@ Exception\n\ | +-- ValueError\n\ | | |\n\ | | +-- UnicodeError\n\ + | | |\n\ + | | +-- UnicodeEncodeError\n\ + | | +-- UnicodeDecodeError\n\ + | | +-- UnicodeTranslateError\n\ | |\n\ | +-- ReferenceError\n\ | +-- SystemError\n\ @@ -840,6 +844,590 @@ static PyMethodDef SyntaxError_methods[] = { }; +static +int get_int(PyObject *exc, const char *name, int *value) +{ + PyObject *attr = PyObject_GetAttrString(exc, (char *)name); + + if (!attr) + return -1; + if (!PyInt_Check(attr)) { + PyErr_Format(PyExc_TypeError, "%s attribute must be int", name); + Py_DECREF(attr); + return -1; + } + *value = PyInt_AS_LONG(attr); + Py_DECREF(attr); + return 0; +} + + +static +int set_int(PyObject *exc, const char *name, int value) +{ + PyObject *obj = PyInt_FromLong(value); + int result; + + if (!obj) + return -1; + result = PyObject_SetAttrString(exc, (char *)name, obj); + Py_DECREF(obj); + return result; +} + + +static +PyObject *get_string(PyObject *exc, const char *name) +{ + PyObject *attr = PyObject_GetAttrString(exc, (char *)name); + + if (!attr) + return NULL; + if (!PyString_Check(attr)) { + PyErr_Format(PyExc_TypeError, "%s attribute must be str", name); + Py_DECREF(attr); + return NULL; + } + return attr; +} + + +static +int set_string(PyObject *exc, const char *name, const char *value) +{ + PyObject *obj = PyString_FromString(value); + int result; + + if (!obj) + return -1; + result = PyObject_SetAttrString(exc, (char *)name, obj); + Py_DECREF(obj); + return result; +} + + +static +PyObject *get_unicode(PyObject *exc, const char *name) +{ + PyObject *attr = PyObject_GetAttrString(exc, (char *)name); + + if (!attr) + return NULL; + if (!PyUnicode_Check(attr)) { + PyErr_Format(PyExc_TypeError, "%s attribute must be unicode", name); + Py_DECREF(attr); + return NULL; + } + return attr; +} + +PyObject * PyUnicodeEncodeError_GetEncoding(PyObject *exc) +{ + return get_string(exc, "encoding"); +} + +PyObject * PyUnicodeDecodeError_GetEncoding(PyObject *exc) +{ + return get_string(exc, "encoding"); +} + +PyObject * PyUnicodeTranslateError_GetEncoding(PyObject *exc) +{ + return get_string(exc, "encoding"); +} + +PyObject *PyUnicodeEncodeError_GetObject(PyObject *exc) +{ + return get_unicode(exc, "object"); +} + +PyObject *PyUnicodeDecodeError_GetObject(PyObject *exc) +{ + return get_string(exc, "object"); +} + +PyObject *PyUnicodeTranslateError_GetObject(PyObject *exc) +{ + return get_unicode(exc, "object"); +} + +int PyUnicodeEncodeError_GetStart(PyObject *exc, int *start) +{ + if (!get_int(exc, "start", start)) { + PyObject *object = PyUnicodeEncodeError_GetObject(exc); + int size; + if (!object) + return -1; + size = PyUnicode_GET_SIZE(object); + if (*start<0) + *start = 0; + if (*start>=size) + *start = size-1; + Py_DECREF(object); + return 0; + } + return -1; +} + + +int PyUnicodeDecodeError_GetStart(PyObject *exc, int *start) +{ + if (!get_int(exc, "start", start)) { + PyObject *object = PyUnicodeDecodeError_GetObject(exc); + int size; + if (!object) + return -1; + size = PyString_GET_SIZE(object); + if (*start<0) + *start = 0; + if (*start>=size) + *start = size-1; + Py_DECREF(object); + return 0; + } + return -1; +} + + +int PyUnicodeTranslateError_GetStart(PyObject *exc, int *start) +{ + return PyUnicodeEncodeError_GetStart(exc, start); +} + + +int PyUnicodeEncodeError_SetStart(PyObject *exc, int start) +{ + return set_int(exc, "start", start); +} + + +int PyUnicodeDecodeError_SetStart(PyObject *exc, int start) +{ + return set_int(exc, "start", start); +} + + +int PyUnicodeTranslateError_SetStart(PyObject *exc, int start) +{ + return set_int(exc, "start", start); +} + + +int PyUnicodeEncodeError_GetEnd(PyObject *exc, int *end) +{ + if (!get_int(exc, "end", end)) { + PyObject *object = PyUnicodeEncodeError_GetObject(exc); + int size; + if (!object) + return -1; + size = PyUnicode_GET_SIZE(object); + if (*end<1) + *end = 1; + if (*end>size) + *end = size; + Py_DECREF(object); + return 0; + } + return -1; +} + + +int PyUnicodeDecodeError_GetEnd(PyObject *exc, int *end) +{ + if (!get_int(exc, "end", end)) { + PyObject *object = PyUnicodeDecodeError_GetObject(exc); + int size; + if (!object) + return -1; + size = PyString_GET_SIZE(object); + if (*end<1) + *end = 1; + if (*end>size) + *end = size; + Py_DECREF(object); + return 0; + } + return -1; +} + + +int PyUnicodeTranslateError_GetEnd(PyObject *exc, int *start) +{ + return PyUnicodeEncodeError_GetEnd(exc, start); +} + + +int PyUnicodeEncodeError_SetEnd(PyObject *exc, int end) +{ + return set_int(exc, "end", end); +} + + +int PyUnicodeDecodeError_SetEnd(PyObject *exc, int end) +{ + return set_int(exc, "end", end); +} + + +int PyUnicodeTranslateError_SetEnd(PyObject *exc, int end) +{ + return set_int(exc, "end", end); +} + + +PyObject *PyUnicodeEncodeError_GetReason(PyObject *exc) +{ + return get_string(exc, "reason"); +} + + +PyObject *PyUnicodeDecodeError_GetReason(PyObject *exc) +{ + return get_string(exc, "reason"); +} + + +PyObject *PyUnicodeTranslateError_GetReason(PyObject *exc) +{ + return get_string(exc, "reason"); +} + + +int PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason) +{ + return set_string(exc, "reason", reason); +} + + +int PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason) +{ + return set_string(exc, "reason", reason); +} + + +int PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason) +{ + return set_string(exc, "reason", reason); +} + + +static PyObject * +UnicodeError__init__(PyObject *self, PyObject *args, PyTypeObject *objecttype) +{ + PyObject *rtnval = NULL; + PyObject *encoding; + PyObject *object; + PyObject *start; + PyObject *end; + PyObject *reason; + + if (!(self = get_self(args))) + return NULL; + + if (!(args = PySequence_GetSlice(args, 1, PySequence_Size(args)))) + return NULL; + + if (!PyArg_ParseTuple(args, "O!O!O!O!O!", + &PyString_Type, &encoding, + objecttype, &object, + &PyInt_Type, &start, + &PyInt_Type, &end, + &PyString_Type, &reason)) + return NULL; + + if (PyObject_SetAttrString(self, "args", args)) + goto finally; + + if (PyObject_SetAttrString(self, "encoding", encoding)) + goto finally; + if (PyObject_SetAttrString(self, "object", object)) + goto finally; + if (PyObject_SetAttrString(self, "start", start)) + goto finally; + if (PyObject_SetAttrString(self, "end", end)) + goto finally; + if (PyObject_SetAttrString(self, "reason", reason)) + goto finally; + + Py_INCREF(Py_None); + rtnval = Py_None; + + finally: + Py_DECREF(args); + return rtnval; +} + + +static PyObject * +UnicodeEncodeError__init__(PyObject *self, PyObject *args) +{ + return UnicodeError__init__(self, args, &PyUnicode_Type); +} + +static PyObject * +UnicodeEncodeError__str__(PyObject *self, PyObject *arg) +{ + PyObject *encodingObj = NULL; + PyObject *objectObj = NULL; + int length; + int start; + int end; + PyObject *reasonObj = NULL; + char buffer[1000]; + PyObject *result = NULL; + + self = arg; + + if (!(encodingObj = PyUnicodeEncodeError_GetEncoding(self))) + goto error; + + if (!(objectObj = PyUnicodeEncodeError_GetObject(self))) + goto error; + + length = PyUnicode_GET_SIZE(objectObj); + + if (PyUnicodeEncodeError_GetStart(self, &start)) + goto error; + + if (PyUnicodeEncodeError_GetEnd(self, &end)) + goto error; + + if (!(reasonObj = PyUnicodeEncodeError_GetReason(self))) + goto error; + + if (end==start+1) { + PyOS_snprintf(buffer, sizeof(buffer), + "'%.400s' codec can't encode character '\\u%x' in position %d: %.400s", + PyString_AS_STRING(encodingObj), + (int)PyUnicode_AS_UNICODE(objectObj)[start], + start, + PyString_AS_STRING(reasonObj) + ); + } + else { + PyOS_snprintf(buffer, sizeof(buffer), + "'%.400s' codec can't encode characters in position %d-%d: %.400s", + PyString_AS_STRING(encodingObj), + start, + end-1, + PyString_AS_STRING(reasonObj) + ); + } + result = PyString_FromString(buffer); + +error: + Py_XDECREF(reasonObj); + Py_XDECREF(objectObj); + Py_XDECREF(encodingObj); + return result; +} + +static PyMethodDef UnicodeEncodeError_methods[] = { + {"__init__", UnicodeEncodeError__init__, METH_VARARGS}, + {"__str__", UnicodeEncodeError__str__, METH_O}, + {NULL, NULL} +}; + + +PyObject * PyUnicodeEncodeError_Create( + const char *encoding, const Py_UNICODE *object, int length, + int start, int end, const char *reason) +{ + return PyObject_CallFunction(PyExc_UnicodeEncodeError, "su#iis", + encoding, object, length, start, end, reason); +} + + +static PyObject * +UnicodeDecodeError__init__(PyObject *self, PyObject *args) +{ + return UnicodeError__init__(self, args, &PyString_Type); +} + +static PyObject * +UnicodeDecodeError__str__(PyObject *self, PyObject *arg) +{ + PyObject *encodingObj = NULL; + PyObject *objectObj = NULL; + int length; + int start; + int end; + PyObject *reasonObj = NULL; + char buffer[1000]; + PyObject *result = NULL; + + self = arg; + + if (!(encodingObj = PyUnicodeDecodeError_GetEncoding(self))) + goto error; + + if (!(objectObj = PyUnicodeDecodeError_GetObject(self))) + goto error; + + length = PyString_GET_SIZE(objectObj); + + if (PyUnicodeDecodeError_GetStart(self, &start)) + goto error; + + if (PyUnicodeDecodeError_GetEnd(self, &end)) + goto error; + + if (!(reasonObj = PyUnicodeDecodeError_GetReason(self))) + goto error; + + if (end==start+1) { + PyOS_snprintf(buffer, sizeof(buffer), + "'%.400s' codec can't decode byte 0x%x in position %d: %.400s", + PyString_AS_STRING(encodingObj), + ((int)PyString_AS_STRING(objectObj)[start])&0xff, + start, + PyString_AS_STRING(reasonObj) + ); + } + else { + PyOS_snprintf(buffer, sizeof(buffer), + "'%.400s' codec can't decode bytes in position %d-%d: %.400s", + PyString_AS_STRING(encodingObj), + start, + end-1, + PyString_AS_STRING(reasonObj) + ); + } + result = PyString_FromString(buffer); + +error: + Py_XDECREF(reasonObj); + Py_XDECREF(objectObj); + Py_XDECREF(encodingObj); + return result; +} + +static PyMethodDef UnicodeDecodeError_methods[] = { + {"__init__", UnicodeDecodeError__init__, METH_VARARGS}, + {"__str__", UnicodeDecodeError__str__, METH_O}, + {NULL, NULL} +}; + + +PyObject * PyUnicodeDecodeError_Create( + const char *encoding, const char *object, int length, + int start, int end, const char *reason) +{ + return PyObject_CallFunction(PyExc_UnicodeDecodeError, "ss#iis", + encoding, object, length, start, end, reason); +} + + +static PyObject * +UnicodeTranslateError__init__(PyObject *self, PyObject *args) +{ + PyObject *rtnval = NULL; + PyObject *object; + PyObject *start; + PyObject *end; + PyObject *reason; + + if (!(self = get_self(args))) + return NULL; + + if (!(args = PySequence_GetSlice(args, 1, PySequence_Size(args)))) + return NULL; + + if (!PyArg_ParseTuple(args, "O!O!O!O!", + &PyUnicode_Type, &object, + &PyInt_Type, &start, + &PyInt_Type, &end, + &PyString_Type, &reason)) + goto finally; + + if (PyObject_SetAttrString(self, "args", args)) + goto finally; + + if (PyObject_SetAttrString(self, "object", object)) + goto finally; + if (PyObject_SetAttrString(self, "start", start)) + goto finally; + if (PyObject_SetAttrString(self, "end", end)) + goto finally; + if (PyObject_SetAttrString(self, "reason", reason)) + goto finally; + + Py_INCREF(Py_None); + rtnval = Py_None; + + finally: + Py_DECREF(args); + return rtnval; +} + + +static PyObject * +UnicodeTranslateError__str__(PyObject *self, PyObject *arg) +{ + PyObject *objectObj = NULL; + int length; + int start; + int end; + PyObject *reasonObj = NULL; + char buffer[1000]; + PyObject *result = NULL; + + self = arg; + + if (!(objectObj = PyUnicodeTranslateError_GetObject(self))) + goto error; + + length = PyUnicode_GET_SIZE(objectObj); + + if (PyUnicodeTranslateError_GetStart(self, &start)) + goto error; + + if (PyUnicodeTranslateError_GetEnd(self, &end)) + goto error; + + if (!(reasonObj = PyUnicodeTranslateError_GetReason(self))) + goto error; + + if (end==start+1) { + PyOS_snprintf(buffer, sizeof(buffer), + "can't translate character '\\u%x' in position %d: %.400s", + (int)PyUnicode_AS_UNICODE(objectObj)[start], + start, + PyString_AS_STRING(reasonObj) + ); + } + else { + PyOS_snprintf(buffer, sizeof(buffer), + "can't translate characters in position %d-%d: %.400s", + start, + end-1, + PyString_AS_STRING(reasonObj) + ); + } + result = PyString_FromString(buffer); + +error: + Py_XDECREF(reasonObj); + Py_XDECREF(objectObj); + return result; +} + +static PyMethodDef UnicodeTranslateError_methods[] = { + {"__init__", UnicodeTranslateError__init__, METH_VARARGS}, + {"__str__", UnicodeTranslateError__str__, METH_O}, + {NULL, NULL} +}; + + +PyObject * PyUnicodeTranslateError_Create( + const Py_UNICODE *object, int length, + int start, int end, const char *reason) +{ + return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#iis", + object, length, start, end, reason); +} + + /* Exception doc strings */ @@ -865,6 +1453,12 @@ PyDoc_STRVAR(ValueError__doc__, PyDoc_STRVAR(UnicodeError__doc__, "Unicode related error."); +PyDoc_STRVAR(UnicodeEncodeError__doc__, "Unicode encoding error."); + +PyDoc_STRVAR(UnicodeDecodeError__doc__, "Unicode decoding error."); + +PyDoc_STRVAR(UnicodeTranslateError__doc__, "Unicode translation error."); + PyDoc_STRVAR(SystemError__doc__, "Internal error in the Python interpreter.\n\ \n\ @@ -949,6 +1543,9 @@ PyObject *PyExc_SystemError; PyObject *PyExc_SystemExit; PyObject *PyExc_UnboundLocalError; PyObject *PyExc_UnicodeError; +PyObject *PyExc_UnicodeEncodeError; +PyObject *PyExc_UnicodeDecodeError; +PyObject *PyExc_UnicodeTranslateError; PyObject *PyExc_TypeError; PyObject *PyExc_ValueError; PyObject *PyExc_ZeroDivisionError; @@ -1035,6 +1632,12 @@ static struct { FloatingPointError__doc__}, {"ValueError", &PyExc_ValueError, 0, ValueError__doc__}, {"UnicodeError", &PyExc_UnicodeError, &PyExc_ValueError, UnicodeError__doc__}, + {"UnicodeEncodeError", &PyExc_UnicodeEncodeError, &PyExc_UnicodeError, + UnicodeEncodeError__doc__, UnicodeEncodeError_methods}, + {"UnicodeDecodeError", &PyExc_UnicodeDecodeError, &PyExc_UnicodeError, + UnicodeDecodeError__doc__, UnicodeDecodeError_methods}, + {"UnicodeTranslateError", &PyExc_UnicodeTranslateError, &PyExc_UnicodeError, + UnicodeTranslateError__doc__, UnicodeTranslateError_methods}, {"ReferenceError", &PyExc_ReferenceError, 0, ReferenceError__doc__}, {"SystemError", &PyExc_SystemError, 0, SystemError__doc__}, {"MemoryError", &PyExc_MemoryError, 0, MemoryError__doc__}, |