Mercurial > cpython-lru_cache-weakref
comparison Modules/arraymodule.c @ 14499:7f23ec5cd9ca legacy-trunk
General cleanup in preparation for a bugfix: removed unused code, useless
declarations, added some comments where I had to think too hard to
understand what was happening, and changed the primary internal get/set
functions to assert they're passed objects of the correct type instead of
doing runtime tests for that (it's an internal error that "should never
happen", so it's good enough to check it only in the debug build).
| author | Tim Peters <tim.peters@gmail.com> |
|---|---|
| date | Sun, 10 Sep 2000 05:22:54 +0000 |
| parents | 6f6f965c5e2d |
| children | 1ec6c63347ea |
comparison
equal
deleted
inserted
replaced
| 14498:371e88af645f | 14499:7f23ec5cd9ca |
|---|---|
| 1 | |
| 2 /* Array object implementation */ | 1 /* Array object implementation */ |
| 3 | 2 |
| 4 /* An array is a uniform list -- all items have the same type. | 3 /* An array is a uniform list -- all items have the same type. |
| 5 The item type is restricted to simple C types like int or float */ | 4 The item type is restricted to simple C types like int or float */ |
| 6 | 5 |
| 17 #include <limits.h> | 16 #include <limits.h> |
| 18 #endif /* HAVE_LIMITS_H */ | 17 #endif /* HAVE_LIMITS_H */ |
| 19 | 18 |
| 20 struct arrayobject; /* Forward */ | 19 struct arrayobject; /* Forward */ |
| 21 | 20 |
| 21 /* All possible arraydescr values are defined in the vector "descriptors" | |
| 22 * below. That's defined later because the appropriate get and set | |
| 23 * functions aren't visible yet. | |
| 24 */ | |
| 22 struct arraydescr { | 25 struct arraydescr { |
| 23 int typecode; | 26 int typecode; |
| 24 int itemsize; | 27 int itemsize; |
| 25 PyObject * (*getitem)(struct arrayobject *, int); | 28 PyObject * (*getitem)(struct arrayobject *, int); |
| 26 int (*setitem)(struct arrayobject *, int, PyObject *); | 29 int (*setitem)(struct arrayobject *, int, PyObject *); |
| 34 | 37 |
| 35 staticforward PyTypeObject Arraytype; | 38 staticforward PyTypeObject Arraytype; |
| 36 | 39 |
| 37 #define is_arrayobject(op) ((op)->ob_type == &Arraytype) | 40 #define is_arrayobject(op) ((op)->ob_type == &Arraytype) |
| 38 | 41 |
| 39 /* Forward */ | 42 /**************************************************************************** |
| 40 static PyObject *newarrayobject(int, struct arraydescr *); | 43 Get and Set functions for each type. |
| 41 #if 0 | 44 A Get function takes an arrayobject* and an integer index, returning the |
| 42 static int getarraysize(PyObject *); | 45 array value at that index wrapped in an appropriate PyObject*. |
| 43 #endif | 46 A Set function takes an arrayobject, integer index, and PyObject*; sets |
| 44 static PyObject *getarrayitem(PyObject *, int); | 47 the array value at that index to the raw C data extracted from the PyObject*, |
| 45 static int setarrayitem(PyObject *, int, PyObject *); | 48 and returns 0 if successful, else nonzero on failure (PyObject* not of an |
| 46 #if 0 | 49 appropriate type or value). |
| 47 static int insarrayitem(PyObject *, int, PyObject *); | 50 Note that the basic Get and Set functions do NOT check that the index is |
| 48 static int addarrayitem(PyObject *, PyObject *); | 51 in bounds; that's the responsibility of the caller. |
| 49 #endif | 52 ****************************************************************************/ |
| 50 | 53 |
| 51 static PyObject * | 54 static PyObject * |
| 52 c_getitem(arrayobject *ap, int i) | 55 c_getitem(arrayobject *ap, int i) |
| 53 { | 56 { |
| 54 return PyString_FromStringAndSize(&((char *)ap->ob_item)[i], 1); | 57 return PyString_FromStringAndSize(&((char *)ap->ob_item)[i], 1); |
| 206 PyErr_SetString(PyExc_OverflowError, | 209 PyErr_SetString(PyExc_OverflowError, |
| 207 "unsigned int is less than minimum"); | 210 "unsigned int is less than minimum"); |
| 208 return -1; | 211 return -1; |
| 209 } | 212 } |
| 210 x = (unsigned long)y; | 213 x = (unsigned long)y; |
| 211 | 214 |
| 212 } | 215 } |
| 213 if (x > UINT_MAX) { | 216 if (x > UINT_MAX) { |
| 214 PyErr_SetString(PyExc_OverflowError, | 217 PyErr_SetString(PyExc_OverflowError, |
| 215 "unsigned int is greater than maximum"); | 218 "unsigned int is greater than maximum"); |
| 216 return -1; | 219 return -1; |
| 261 PyErr_SetString(PyExc_OverflowError, | 264 PyErr_SetString(PyExc_OverflowError, |
| 262 "unsigned long is less than minimum"); | 265 "unsigned long is less than minimum"); |
| 263 return -1; | 266 return -1; |
| 264 } | 267 } |
| 265 x = (unsigned long)y; | 268 x = (unsigned long)y; |
| 266 | 269 |
| 267 } | 270 } |
| 268 if (x > ULONG_MAX) { | 271 if (x > ULONG_MAX) { |
| 269 PyErr_SetString(PyExc_OverflowError, | 272 PyErr_SetString(PyExc_OverflowError, |
| 270 "unsigned long is greater than maximum"); | 273 "unsigned long is greater than maximum"); |
| 271 return -1; | 274 return -1; |
| 272 } | 275 } |
| 273 | 276 |
| 274 if (i >= 0) | 277 if (i >= 0) |
| 275 ((unsigned long *)ap->ob_item)[i] = x; | 278 ((unsigned long *)ap->ob_item)[i] = x; |
| 276 return 0; | 279 return 0; |
| 277 } | 280 } |
| 278 | 281 |
| 324 {'f', sizeof(float), f_getitem, f_setitem}, | 327 {'f', sizeof(float), f_getitem, f_setitem}, |
| 325 {'d', sizeof(double), d_getitem, d_setitem}, | 328 {'d', sizeof(double), d_getitem, d_setitem}, |
| 326 {'\0', 0, 0, 0} /* Sentinel */ | 329 {'\0', 0, 0, 0} /* Sentinel */ |
| 327 }; | 330 }; |
| 328 /* If we ever allow items larger than double, we must change reverse()! */ | 331 /* If we ever allow items larger than double, we must change reverse()! */ |
| 329 | 332 |
| 333 /**************************************************************************** | |
| 334 Implementations of array object methods. | |
| 335 ****************************************************************************/ | |
| 330 | 336 |
| 331 static PyObject * | 337 static PyObject * |
| 332 newarrayobject(int size, struct arraydescr *descr) | 338 newarrayobject(int size, struct arraydescr *descr) |
| 333 { | 339 { |
| 334 arrayobject *op; | 340 arrayobject *op; |
| 358 } | 364 } |
| 359 op->ob_descr = descr; | 365 op->ob_descr = descr; |
| 360 return (PyObject *) op; | 366 return (PyObject *) op; |
| 361 } | 367 } |
| 362 | 368 |
| 363 #if 0 | |
| 364 static int | |
| 365 getarraysize(PyObject *op) | |
| 366 { | |
| 367 if (!is_arrayobject(op)) { | |
| 368 PyErr_BadInternalCall(); | |
| 369 return -1; | |
| 370 } | |
| 371 return ((arrayobject *)op) -> ob_size; | |
| 372 } | |
| 373 #endif | |
| 374 | |
| 375 static PyObject * | 369 static PyObject * |
| 376 getarrayitem(PyObject *op, int i) | 370 getarrayitem(PyObject *op, int i) |
| 377 { | 371 { |
| 378 register arrayobject *ap; | 372 register arrayobject *ap; |
| 379 if (!is_arrayobject(op)) { | 373 assert(is_arrayobject(op)); |
| 380 PyErr_BadInternalCall(); | |
| 381 return NULL; | |
| 382 } | |
| 383 ap = (arrayobject *)op; | 374 ap = (arrayobject *)op; |
| 384 if (i < 0 || i >= ap->ob_size) { | 375 if (i < 0 || i >= ap->ob_size) { |
| 385 PyErr_SetString(PyExc_IndexError, "array index out of range"); | 376 PyErr_SetString(PyExc_IndexError, "array index out of range"); |
| 386 return NULL; | 377 return NULL; |
| 387 } | 378 } |
| 414 (self->ob_size-where)*self->ob_descr->itemsize); | 405 (self->ob_size-where)*self->ob_descr->itemsize); |
| 415 self->ob_item = items; | 406 self->ob_item = items; |
| 416 self->ob_size++; | 407 self->ob_size++; |
| 417 return (*self->ob_descr->setitem)(self, where, v); | 408 return (*self->ob_descr->setitem)(self, where, v); |
| 418 } | 409 } |
| 419 | |
| 420 #if 0 | |
| 421 static int | |
| 422 insarrayitem(PyObject *op, int where, PyObject *newitem) | |
| 423 { | |
| 424 if (!is_arrayobject(op)) { | |
| 425 PyErr_BadInternalCall(); | |
| 426 return -1; | |
| 427 } | |
| 428 return ins1((arrayobject *)op, where, newitem); | |
| 429 } | |
| 430 | |
| 431 static int | |
| 432 addarrayitem(PyObject *op, PyObject *newitem) | |
| 433 { | |
| 434 if (!is_arrayobject(op)) { | |
| 435 PyErr_BadInternalCall(); | |
| 436 return -1; | |
| 437 } | |
| 438 return ins1((arrayobject *)op, | |
| 439 (int) ((arrayobject *)op)->ob_size, newitem); | |
| 440 } | |
| 441 #endif | |
| 442 | 410 |
| 443 /* Methods */ | 411 /* Methods */ |
| 444 | 412 |
| 445 static void | 413 static void |
| 446 array_dealloc(arrayobject *op) | 414 array_dealloc(arrayobject *op) |
| 646 } | 614 } |
| 647 | 615 |
| 648 static int | 616 static int |
| 649 setarrayitem(PyObject *a, int i, PyObject *v) | 617 setarrayitem(PyObject *a, int i, PyObject *v) |
| 650 { | 618 { |
| 651 if (!is_arrayobject(a)) { | 619 assert(is_arrayobject(a)); |
| 652 PyErr_BadInternalCall(); | |
| 653 return -1; | |
| 654 } | |
| 655 return array_ass_item((arrayobject *)a, i, v); | 620 return array_ass_item((arrayobject *)a, i, v); |
| 656 } | 621 } |
| 657 | 622 |
| 658 static PyObject * | 623 static PyObject * |
| 659 ins(arrayobject *self, int where, PyObject *v) | 624 ins(arrayobject *self, int where, PyObject *v) |
| 781 static PyObject * | 746 static PyObject * |
| 782 array_extend(arrayobject *self, PyObject *args) | 747 array_extend(arrayobject *self, PyObject *args) |
| 783 { | 748 { |
| 784 int size; | 749 int size; |
| 785 PyObject *bb; | 750 PyObject *bb; |
| 786 | 751 |
| 787 if (!PyArg_ParseTuple(args, "O:extend", &bb)) | 752 if (!PyArg_ParseTuple(args, "O:extend", &bb)) |
| 788 return NULL; | 753 return NULL; |
| 789 | 754 |
| 790 if (!is_arrayobject(bb)) { | 755 if (!is_arrayobject(bb)) { |
| 791 PyErr_Format(PyExc_TypeError, | 756 PyErr_Format(PyExc_TypeError, |
| 792 "can only extend array with array (not \"%.200s\")", | 757 "can only extend array with array (not \"%.200s\")", |
| 793 bb->ob_type->tp_name); | 758 bb->ob_type->tp_name); |
| 794 return NULL; | 759 return NULL; |
| 949 memmove(tmp, p, itemsize); | 914 memmove(tmp, p, itemsize); |
| 950 memmove(p, q, itemsize); | 915 memmove(p, q, itemsize); |
| 951 memmove(q, tmp, itemsize); | 916 memmove(q, tmp, itemsize); |
| 952 } | 917 } |
| 953 } | 918 } |
| 954 | 919 |
| 955 Py_INCREF(Py_None); | 920 Py_INCREF(Py_None); |
| 956 return Py_None; | 921 return Py_None; |
| 957 } | 922 } |
| 958 | 923 |
| 959 static char reverse_doc [] = | 924 static char reverse_doc [] = |
| 1334 static PyBufferProcs array_as_buffer = { | 1299 static PyBufferProcs array_as_buffer = { |
| 1335 (getreadbufferproc)array_buffer_getreadbuf, | 1300 (getreadbufferproc)array_buffer_getreadbuf, |
| 1336 (getwritebufferproc)array_buffer_getwritebuf, | 1301 (getwritebufferproc)array_buffer_getwritebuf, |
| 1337 (getsegcountproc)array_buffer_getsegcount, | 1302 (getsegcountproc)array_buffer_getsegcount, |
| 1338 }; | 1303 }; |
| 1339 | |
| 1340 | |
| 1341 | |
| 1342 | 1304 |
| 1343 static PyObject * | 1305 static PyObject * |
| 1344 a_array(PyObject *self, PyObject *args) | 1306 a_array(PyObject *self, PyObject *args) |
| 1345 { | 1307 { |
| 1346 char c; | 1308 char c; |
