diff options
Diffstat (limited to 'Modules/arraymodule.c')
-rw-r--r-- | Modules/arraymodule.c | 136 |
1 files changed, 50 insertions, 86 deletions
diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index a4966b4bdd..2caa8ee5a8 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -31,7 +31,7 @@ struct arraydescr { int itemsize; PyObject * (*getitem)(struct arrayobject *, Py_ssize_t); int (*setitem)(struct arrayobject *, Py_ssize_t, PyObject *); - char *formats; + const char *formats; int is_integer_type; int is_signed; }; @@ -40,7 +40,7 @@ typedef struct arrayobject { PyObject_VAR_HEAD char *ob_item; Py_ssize_t allocated; - struct arraydescr *ob_descr; + const struct arraydescr *ob_descr; PyObject *weakreflist; /* List of weak references */ int ob_exports; /* Number of exported buffers */ } arrayobject; @@ -418,22 +418,20 @@ LL_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) return 0; } -#ifdef HAVE_LONG_LONG - static PyObject * q_getitem(arrayobject *ap, Py_ssize_t i) { - return PyLong_FromLongLong(((PY_LONG_LONG *)ap->ob_item)[i]); + return PyLong_FromLongLong(((long long *)ap->ob_item)[i]); } static int q_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) { - PY_LONG_LONG x; + long long x; if (!PyArg_Parse(v, "L;array item must be integer", &x)) return -1; if (i >= 0) - ((PY_LONG_LONG *)ap->ob_item)[i] = x; + ((long long *)ap->ob_item)[i] = x; return 0; } @@ -441,20 +439,20 @@ static PyObject * QQ_getitem(arrayobject *ap, Py_ssize_t i) { return PyLong_FromUnsignedLongLong( - ((unsigned PY_LONG_LONG *)ap->ob_item)[i]); + ((unsigned long long *)ap->ob_item)[i]); } static int QQ_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) { - unsigned PY_LONG_LONG x; + unsigned long long x; if (PyLong_Check(v)) { x = PyLong_AsUnsignedLongLong(v); - if (x == (unsigned PY_LONG_LONG) -1 && PyErr_Occurred()) + if (x == (unsigned long long) -1 && PyErr_Occurred()) return -1; } else { - PY_LONG_LONG y; + long long y; if (!PyArg_Parse(v, "L;array item must be integer", &y)) return -1; if (y < 0) { @@ -462,14 +460,13 @@ QQ_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) "unsigned long long is less than minimum"); return -1; } - x = (unsigned PY_LONG_LONG)y; + x = (unsigned long long)y; } if (i >= 0) - ((unsigned PY_LONG_LONG *)ap->ob_item)[i] = x; + ((unsigned long long *)ap->ob_item)[i] = x; return 0; } -#endif static PyObject * f_getitem(arrayobject *ap, Py_ssize_t i) @@ -511,7 +508,7 @@ d_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) * Don't forget to update typecode_to_mformat_code() if you add a new * typecode. */ -static struct arraydescr descriptors[] = { +static const struct arraydescr descriptors[] = { {'b', 1, b_getitem, b_setitem, "b", 1, 1}, {'B', 1, BB_getitem, BB_setitem, "B", 1, 0}, {'u', sizeof(Py_UNICODE), u_getitem, u_setitem, "u", 0, 0}, @@ -521,10 +518,8 @@ static struct arraydescr descriptors[] = { {'I', sizeof(int), II_getitem, II_setitem, "I", 1, 0}, {'l', sizeof(long), l_getitem, l_setitem, "l", 1, 1}, {'L', sizeof(long), LL_getitem, LL_setitem, "L", 1, 0}, -#ifdef HAVE_LONG_LONG - {'q', sizeof(PY_LONG_LONG), q_getitem, q_setitem, "q", 1, 1}, - {'Q', sizeof(PY_LONG_LONG), QQ_getitem, QQ_setitem, "Q", 1, 0}, -#endif + {'q', sizeof(long long), q_getitem, q_setitem, "q", 1, 1}, + {'Q', sizeof(long long), QQ_getitem, QQ_setitem, "Q", 1, 0}, {'f', sizeof(float), f_getitem, f_setitem, "f", 0, 0}, {'d', sizeof(double), d_getitem, d_setitem, "d", 0, 0}, {'\0', 0, 0, 0, 0, 0, 0} /* Sentinel */ @@ -539,7 +534,7 @@ class array.array "arrayobject *" "&Arraytype" /*[clinic end generated code: output=da39a3ee5e6b4b0d input=ad43d37e942a8854]*/ static PyObject * -newarrayobject(PyTypeObject *type, Py_ssize_t size, struct arraydescr *descr) +newarrayobject(PyTypeObject *type, Py_ssize_t size, const struct arraydescr *descr) { arrayobject *op; size_t nbytes; @@ -841,10 +836,10 @@ array_repeat(arrayobject *a, Py_ssize_t n) memset(np->ob_item, a->ob_item[0], newbytes); } else { Py_ssize_t done = oldbytes; - Py_MEMCPY(np->ob_item, a->ob_item, oldbytes); + memcpy(np->ob_item, a->ob_item, oldbytes); while (done < newbytes) { Py_ssize_t ncopy = (done <= newbytes-done) ? done : newbytes-done; - Py_MEMCPY(np->ob_item+done, np->ob_item, ncopy); + memcpy(np->ob_item+done, np->ob_item, ncopy); done += ncopy; } } @@ -852,37 +847,10 @@ array_repeat(arrayobject *a, Py_ssize_t n) } static int -array_ass_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v) +array_del_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh) { char *item; - Py_ssize_t n; /* Size of replacement array */ Py_ssize_t d; /* Change in size */ -#define b ((arrayobject *)v) - if (v == NULL) - n = 0; - else if (array_Check(v)) { - n = Py_SIZE(b); - if (a == b) { - /* Special case "a[i:j] = a" -- copy b first */ - int ret; - v = array_slice(b, 0, n); - if (!v) - return -1; - ret = array_ass_slice(a, ilow, ihigh, v); - Py_DECREF(v); - return ret; - } - if (b->ob_descr != a->ob_descr) { - PyErr_BadArgument(); - return -1; - } - } - else { - PyErr_Format(PyExc_TypeError, - "can only assign array (not \"%.200s\") to array slice", - Py_TYPE(v)->tp_name); - return -1; - } if (ilow < 0) ilow = 0; else if (ilow > Py_SIZE(a)) @@ -894,7 +862,7 @@ array_ass_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v) else if (ihigh > Py_SIZE(a)) ihigh = Py_SIZE(a); item = a->ob_item; - d = n - (ihigh-ilow); + d = ihigh-ilow; /* Issue #4509: If the array has exported buffers and the slice assignment would change the size of the array, fail early to make sure we don't modify it. */ @@ -903,25 +871,14 @@ array_ass_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v) "cannot resize an array that is exporting buffers"); return -1; } - if (d < 0) { /* Delete -d items */ - memmove(item + (ihigh+d)*a->ob_descr->itemsize, + if (d > 0) { /* Delete d items */ + memmove(item + (ihigh-d)*a->ob_descr->itemsize, item + ihigh*a->ob_descr->itemsize, (Py_SIZE(a)-ihigh)*a->ob_descr->itemsize); - if (array_resize(a, Py_SIZE(a) + d) == -1) - return -1; - } - else if (d > 0) { /* Insert d items */ - if (array_resize(a, Py_SIZE(a) + d)) + if (array_resize(a, Py_SIZE(a) - d) == -1) return -1; - memmove(item + (ihigh+d)*a->ob_descr->itemsize, - item + ihigh*a->ob_descr->itemsize, - (Py_SIZE(a)-ihigh)*a->ob_descr->itemsize); } - if (n > 0) - memcpy(item + ilow*a->ob_descr->itemsize, b->ob_item, - n*b->ob_descr->itemsize); return 0; -#undef b } static int @@ -933,7 +890,7 @@ array_ass_item(arrayobject *a, Py_ssize_t i, PyObject *v) return -1; } if (v == NULL) - return array_ass_slice(a, i, i+1, v); + return array_del_slice(a, i, i+1); return (*a->ob_descr->setitem)(a, i, v); } @@ -1163,8 +1120,7 @@ array_array_remove(arrayobject *self, PyObject *v) cmp = PyObject_RichCompareBool(selfi, v, Py_EQ); Py_DECREF(selfi); if (cmp > 0) { - if (array_ass_slice(self, i, i+1, - (PyObject *)NULL) != 0) + if (array_del_slice(self, i, i+1) != 0) return NULL; Py_INCREF(Py_None); return Py_None; @@ -1207,7 +1163,7 @@ array_array_pop_impl(arrayobject *self, Py_ssize_t i) v = getarrayitem((PyObject *)self, i); if (v == NULL) return NULL; - if (array_ass_slice(self, i, i+1, (PyObject *)NULL) != 0) { + if (array_del_slice(self, i, i+1) != 0) { Py_DECREF(v); return NULL; } @@ -1861,16 +1817,14 @@ typecode_to_mformat_code(char typecode) intsize = sizeof(long); is_signed = 0; break; -#if HAVE_LONG_LONG case 'q': - intsize = sizeof(PY_LONG_LONG); + intsize = sizeof(long long); is_signed = 1; break; case 'Q': - intsize = sizeof(PY_LONG_LONG); + intsize = sizeof(long long); is_signed = 0; break; -#endif default: return UNKNOWN_FORMAT; } @@ -1954,7 +1908,7 @@ array__array_reconstructor_impl(PyObject *module, PyTypeObject *arraytype, { PyObject *converted_items; PyObject *result; - struct arraydescr *descr; + const struct arraydescr *descr; if (!PyType_Check(arraytype)) { PyErr_Format(PyExc_TypeError, @@ -2092,7 +2046,7 @@ array__array_reconstructor_impl(PyObject *module, PyTypeObject *arraytype, Py_ssize_t itemcount = Py_SIZE(items) / mf_descr.size; const unsigned char *memstr = (unsigned char *)PyBytes_AS_STRING(items); - struct arraydescr *descr; + const struct arraydescr *descr; /* If possible, try to pack array's items using a data type * that fits better. This may result in an array with narrower @@ -2562,7 +2516,7 @@ array_buffer_getbuf(arrayobject *self, Py_buffer *view, int flags) view->format = NULL; view->internal = NULL; if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) { - view->format = self->ob_descr->formats; + view->format = (char *)self->ob_descr->formats; #ifdef Py_UNICODE_WIDE if (self->ob_descr->typecode == 'u') { view->format = "w"; @@ -2603,7 +2557,7 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { int c; PyObject *initial = NULL, *it = NULL; - struct arraydescr *descr; + const struct arraydescr *descr; if (type == &Arraytype && !_PyArg_NoKeywords("array.array()", kwds)) return NULL; @@ -2732,11 +2686,7 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } } PyErr_SetString(PyExc_ValueError, -#ifdef HAVE_LONG_LONG "bad typecode (must be b, B, u, h, H, i, I, l, L, q, Q, f or d)"); -#else - "bad typecode (must be b, B, u, h, H, i, I, l, L, f or d)"); -#endif return NULL; } @@ -2883,9 +2833,20 @@ array_iter(arrayobject *ao) static PyObject * arrayiter_next(arrayiterobject *it) { + arrayobject *ao; + + assert(it != NULL); assert(PyArrayIter_Check(it)); - if (it->index < Py_SIZE(it->ao)) - return (*it->getitem)(it->ao, it->index++); + ao = it->ao; + if (ao == NULL) { + return NULL; + } + assert(array_Check(ao)); + if (it->index < Py_SIZE(ao)) { + return (*it->getitem)(ao, it->index++); + } + it->ao = NULL; + Py_DECREF(ao); return NULL; } @@ -2914,8 +2875,11 @@ static PyObject * array_arrayiterator___reduce___impl(arrayiterobject *self) /*[clinic end generated code: output=7898a52e8e66e016 input=a062ea1e9951417a]*/ { - return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"), - self->ao, self->index); + PyObject *func = _PyObject_GetBuiltin("iter"); + if (self->ao == NULL) { + return Py_BuildValue("N(())", func); + } + return Py_BuildValue("N(O)n", func, self->ao, self->index); } /*[clinic input] @@ -2995,7 +2959,7 @@ array_modexec(PyObject *m) char buffer[Py_ARRAY_LENGTH(descriptors)], *p; PyObject *typecodes; Py_ssize_t size = 0; - struct arraydescr *descr; + const struct arraydescr *descr; if (PyType_Ready(&Arraytype) < 0) return -1; |