summaryrefslogtreecommitdiffstats
path: root/Objects/stringobject.c
diff options
context:
space:
mode:
authorMarc-André Lemburg <mal@egenix.com>2000-09-19 21:04:18 (GMT)
committerMarc-André Lemburg <mal@egenix.com>2000-09-19 21:04:18 (GMT)
commitd1ba443206b535f41154f10b9d56d4fc76a1a9d8 (patch)
treeae56be2777275ca19f347e1154f756ddde4d4b22 /Objects/stringobject.c
parentf8d071332a485ede280675a55e3319e136826dd0 (diff)
downloadcpython-d1ba443206b535f41154f10b9d56d4fc76a1a9d8.zip
cpython-d1ba443206b535f41154f10b9d56d4fc76a1a9d8.tar.gz
cpython-d1ba443206b535f41154f10b9d56d4fc76a1a9d8.tar.bz2
This patch adds a new Python C API called PyString_AsStringAndSize()
which implements the automatic conversion from Unicode to a string object using the default encoding. The new API is then put to use to have eval() and exec accept Unicode objects as code parameter. This closes bugs #110924 and #113890. As side-effect, the traditional C APIs PyString_Size() and PyString_AsString() will also accept Unicode objects as parameters.
Diffstat (limited to 'Objects/stringobject.c')
-rw-r--r--Objects/stringobject.c70
1 files changed, 63 insertions, 7 deletions
diff --git a/Objects/stringobject.c b/Objects/stringobject.c
index eee3551..cadca16 100644
--- a/Objects/stringobject.c
+++ b/Objects/stringobject.c
@@ -239,24 +239,80 @@ string_dealloc(PyObject *op)
PyObject_DEL(op);
}
+static int
+string_getsize(register PyObject *op)
+{
+ char *s;
+ int len;
+ if (PyString_AsStringAndSize(op, &s, &len))
+ return -1;
+ return len;
+}
+
+static /*const*/ char *
+string_getbuffer(register PyObject *op)
+{
+ char *s;
+ int len;
+ if (PyString_AsStringAndSize(op, &s, &len))
+ return NULL;
+ return s;
+}
+
int
PyString_Size(register PyObject *op)
{
- if (!PyString_Check(op)) {
- PyErr_BadInternalCall();
- return -1;
- }
+ if (!PyString_Check(op))
+ return string_getsize(op);
return ((PyStringObject *)op) -> ob_size;
}
/*const*/ char *
PyString_AsString(register PyObject *op)
{
- if (!PyString_Check(op)) {
+ if (!PyString_Check(op))
+ return string_getbuffer(op);
+ return ((PyStringObject *)op) -> ob_sval;
+}
+
+/* Internal API needed by PyString_AsStringAndSize(): */
+extern
+PyObject *_PyUnicode_AsDefaultEncodedString(PyObject *unicode,
+ const char *errors);
+
+int
+PyString_AsStringAndSize(register PyObject *obj,
+ register char **s,
+ register int *len)
+{
+ if (s == NULL) {
PyErr_BadInternalCall();
- return NULL;
+ return -1;
}
- return ((PyStringObject *)op) -> ob_sval;
+
+ if (!PyString_Check(obj)) {
+ if (PyUnicode_Check(obj)) {
+ obj = _PyUnicode_AsDefaultEncodedString(obj, NULL);
+ if (obj == NULL)
+ return -1;
+ }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "expected string or Unicode object, "
+ "%.200s found", obj->ob_type->tp_name);
+ return -1;
+ }
+ }
+
+ *s = PyString_AS_STRING(obj);
+ if (len != NULL)
+ *len = PyString_GET_SIZE(obj);
+ else if ((int)strlen(*s) != PyString_GET_SIZE(obj)) {
+ PyErr_SetString(PyExc_TypeError,
+ "expected string without null bytes");
+ return -1;
+ }
+ return 0;
}
/* Methods */