[pypy-commit] cffi cffi-1.0: Arrays
arigo
noreply at buildbot.pypy.org
Tue Apr 14 16:13:04 CEST 2015
Author: Armin Rigo <arigo at tunes.org>
Branch: cffi-1.0
Changeset: r1702:802ad7fc65d4
Date: 2015-04-14 16:13 +0200
http://bitbucket.org/cffi/cffi/changeset/802ad7fc65d4/
Log: Arrays
diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -1902,8 +1902,8 @@
return cd->c_data + i * cd->c_type->ct_itemdescr->ct_size;
}
-static PyObject *
-new_array_type(CTypeDescrObject *ctptr, PyObject *lengthobj); /* forward */
+static CTypeDescrObject *
+new_array_type(CTypeDescrObject *ctptr, Py_ssize_t length); /* forward */
static CTypeDescrObject *
_cdata_getslicearg(CDataObject *cd, PySliceObject *slice, Py_ssize_t bounds[])
@@ -1968,7 +1968,7 @@
return NULL;
if (ct->ct_stuff == NULL) {
- ct->ct_stuff = new_array_type(ct, Py_None);
+ ct->ct_stuff = (PyObject *)new_array_type(ct, -1);
if (ct->ct_stuff == NULL)
return NULL;
}
@@ -3540,41 +3540,15 @@
static PyObject *b_new_array_type(PyObject *self, PyObject *args)
{
PyObject *lengthobj;
+ Py_ssize_t length;
CTypeDescrObject *ctptr;
if (!PyArg_ParseTuple(args, "O!O:new_array_type",
&CTypeDescr_Type, &ctptr, &lengthobj))
return NULL;
- return new_array_type(ctptr, lengthobj);
-}
-
-static PyObject *
-new_array_type(CTypeDescrObject *ctptr, PyObject *lengthobj)
-{
- CTypeDescrObject *td, *ctitem;
- char extra_text[32];
- Py_ssize_t length, arraysize;
- int flags = CT_ARRAY;
-
- if (!(ctptr->ct_flags & CT_POINTER)) {
- PyErr_SetString(PyExc_TypeError, "first arg must be a pointer ctype");
- return NULL;
- }
- ctitem = ctptr->ct_itemdescr;
- if (ctitem->ct_size < 0) {
- PyErr_Format(PyExc_ValueError, "array item of unknown size: '%s'",
- ctitem->ct_name);
- return NULL;
- }
-
if (lengthobj == Py_None) {
- sprintf(extra_text, "[]");
length = -1;
- arraysize = -1;
- if ((ctitem->ct_flags & CT_PRIMITIVE_CHAR) &&
- ctitem->ct_size == sizeof(char))
- flags |= CT_IS_UNSIZED_CHAR_A;
}
else {
length = PyNumber_AsSsize_t(lengthobj, PyExc_OverflowError);
@@ -3583,6 +3557,38 @@
PyErr_SetString(PyExc_ValueError, "negative array length");
return NULL;
}
+ }
+ return (PyObject *)new_array_type(ctptr, length);
+}
+
+static CTypeDescrObject *
+new_array_type(CTypeDescrObject *ctptr, Py_ssize_t length)
+{
+ CTypeDescrObject *td, *ctitem;
+ char extra_text[32];
+ Py_ssize_t arraysize;
+ int flags = CT_ARRAY;
+
+ if (!(ctptr->ct_flags & CT_POINTER)) {
+ PyErr_SetString(PyExc_TypeError, "first arg must be a pointer ctype");
+ return NULL;
+ }
+ ctitem = ctptr->ct_itemdescr;
+ if (ctitem->ct_size < 0) {
+ PyErr_Format(PyExc_ValueError, "array item of unknown size: '%s'",
+ ctitem->ct_name);
+ return NULL;
+ }
+
+ if (length < 0) {
+ sprintf(extra_text, "[]");
+ length = -1;
+ arraysize = -1;
+ if ((ctitem->ct_flags & CT_PRIMITIVE_CHAR) &&
+ ctitem->ct_size == sizeof(char))
+ flags |= CT_IS_UNSIZED_CHAR_A;
+ }
+ else {
sprintf(extra_text, "[%llu]", (unsigned PY_LONG_LONG)length);
arraysize = length * ctitem->ct_size;
if (length > 0 && (arraysize / length) != ctitem->ct_size) {
@@ -3600,7 +3606,7 @@
td->ct_size = arraysize;
td->ct_length = length;
td->ct_flags = flags;
- return (PyObject *)td;
+ return td;
}
static CTypeDescrObject *new_void_type(void)
diff --git a/new/parse_c_type.c b/new/parse_c_type.c
--- a/new/parse_c_type.c
+++ b/new/parse_c_type.c
@@ -330,7 +330,7 @@
length = strtoull(tok->p, NULL, 10);
else
length = strtoul(tok->p, NULL, 10);
- if (errno == ERANGE)
+ if (errno == ERANGE || ((ssize_t)length) < 0)
return parse_error(tok, "number too large");
next_token(tok);
diff --git a/new/realize_c_type.c b/new/realize_c_type.c
--- a/new/realize_c_type.c
+++ b/new/realize_c_type.c
@@ -34,8 +34,9 @@
_cffi_opcode_t opcodes[], int index)
{
CTypeDescrObject *ct;
- CTypeDescrObject *x, *y;
+ CTypeDescrObject *x, *y, *z;
_cffi_opcode_t op = opcodes[index];
+ Py_ssize_t length = -1;
if ((((uintptr_t)op) & 1) == 0) {
ct = (CTypeDescrObject *)op;
@@ -60,6 +61,25 @@
Py_DECREF(y);
break;
+ case _CFFI_OP_ARRAY:
+ length = (Py_ssize_t)opcodes[_CFFI_GETARG(op) + 1];
+ /* fall-through */
+ case _CFFI_OP_OPEN_ARRAY:
+ y = realize_c_type(ctx, opcodes, _CFFI_GETARG(op));
+ if (y == NULL)
+ return NULL;
+ z = new_pointer_type(y);
+ Py_DECREF(y);
+ if (z == NULL)
+ return NULL;
+ x = new_array_type(z, length);
+ Py_DECREF(z);
+ break;
+
+ case _CFFI_OP_NOOP:
+ x = realize_c_type(ctx, opcodes, _CFFI_GETARG(op));
+ break;
+
default:
PyErr_Format(PyExc_NotImplementedError, "op=%d", (int)_CFFI_GETOP(op));
return NULL;
diff --git a/new/test_realize_c_type.py b/new/test_realize_c_type.py
--- a/new/test_realize_c_type.py
+++ b/new/test_realize_c_type.py
@@ -14,3 +14,10 @@
def test_int_star():
check("int")
check("int *")
+ check("int*", "int *")
+
+def test_noop():
+ check("int(*)", "int *")
+
+def test_array():
+ check("int[5]")
More information about the pypy-commit
mailing list