summaryrefslogtreecommitdiffstats
path: root/Objects/unicodeobject.c
diff options
context:
space:
mode:
authorMarc-André Lemburg <mal@egenix.com>2002-08-11 12:23:04 (GMT)
committerMarc-André Lemburg <mal@egenix.com>2002-08-11 12:23:04 (GMT)
commitcc8764ca9dc3fceb9dc283163a89c9bb649b5392 (patch)
tree7f4c069636e05afe04482cc42c38f1937818806d /Objects/unicodeobject.c
parent078151da901bebce6eb232d958fbbb1e5ced4399 (diff)
downloadcpython-cc8764ca9dc3fceb9dc283163a89c9bb649b5392.zip
cpython-cc8764ca9dc3fceb9dc283163a89c9bb649b5392.tar.gz
cpython-cc8764ca9dc3fceb9dc283163a89c9bb649b5392.tar.bz2
Add C API PyUnicode_FromOrdinal() which exposes unichr() at C level.
u'%c' will now raise a ValueError in case the argument is an integer outside the valid range of Unicode code point ordinals. Closes SF bug #593581.
Diffstat (limited to 'Objects/unicodeobject.c')
-rw-r--r--Objects/unicodeobject.c56
1 files changed, 55 insertions, 1 deletions
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 145186e..d0fe24c 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -390,6 +390,45 @@ int PyUnicode_AsWideChar(PyUnicodeObject *unicode,
#endif
+PyObject *PyUnicode_FromOrdinal(int ordinal)
+{
+ Py_UNICODE s[2];
+
+#ifdef Py_UNICODE_WIDE
+ if (ordinal < 0 || ordinal > 0x10ffff) {
+ PyErr_SetString(PyExc_ValueError,
+ "unichr() arg not in range(0x110000) "
+ "(wide Python build)");
+ return NULL;
+ }
+#else
+ if (ordinal < 0 || ordinal > 0xffff) {
+ PyErr_SetString(PyExc_ValueError,
+ "unichr() arg not in range(0x10000) "
+ "(narrow Python build)");
+ return NULL;
+ }
+#endif
+
+ if (ordinal <= 0xffff) {
+ /* UCS-2 character */
+ s[0] = (Py_UNICODE) ordinal;
+ return PyUnicode_FromUnicode(s, 1);
+ }
+ else {
+#ifndef Py_UNICODE_WIDE
+ /* UCS-4 character. store as two surrogate characters */
+ ordinal -= 0x10000L;
+ s[0] = 0xD800 + (Py_UNICODE) (ordinal >> 10);
+ s[1] = 0xDC00 + (Py_UNICODE) (ordinal & 0x03FF);
+ return PyUnicode_FromUnicode(s, 2);
+#else
+ s[0] = (Py_UNICODE)ordinal;
+ return PyUnicode_FromUnicode(s, 1);
+#endif
+ }
+}
+
PyObject *PyUnicode_FromObject(register PyObject *obj)
{
/* XXX Perhaps we should make this API an alias of
@@ -5373,7 +5412,22 @@ formatchar(Py_UNICODE *buf,
x = PyInt_AsLong(v);
if (x == -1 && PyErr_Occurred())
goto onError;
- buf[0] = (char) x;
+#ifdef Py_UNICODE_WIDE
+ if (x < 0 || x > 0x10ffff) {
+ PyErr_SetString(PyExc_ValueError,
+ "%c arg not in range(0x110000) "
+ "(wide Python build)");
+ return -1;
+ }
+#else
+ if (x < 0 || x > 0xffff) {
+ PyErr_SetString(PyExc_ValueError,
+ "%c arg not in range(0x10000) "
+ "(narrow Python build)");
+ return -1;
+ }
+#endif
+ buf[0] = (Py_UNICODE) x;
}
buf[1] = '\0';
return 1;