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; | 
