int PySlice_GetIndicesEx(PySliceObject *r, Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, Py_ssize_t *slicelength) { /* this is harder to get right than you might think */ Py_ssize_t defstart, defstop; if (r->step == Py_None) { *step = 1; } else { if (!_PyEval_SliceIndex(r->step, step)) return -1; if (*step == 0) { PyErr_SetString(PyExc_ValueError, "slice step cannot be zero"); return -1; } } defstart = *step < 0 ? length-1 : 0; defstop = *step < 0 ? -1 : length; if (r->start == Py_None) { *start = defstart; } else { if (!_PyEval_SliceIndex(r->start, start)) return -1; if (*start < 0) *start += length; if (*start < 0) *start = (*step < 0) ? -1 : 0; if (*start >= length) *start = (*step < 0) ? length - 1 : length; } if (r->stop == Py_None) { *stop = defstop; } else { if (!_PyEval_SliceIndex(r->stop, stop)) return -1; if (*stop < 0) *stop += length; if (*stop < 0) *stop = (*step < 0) ? -1 : 0; if (*stop >= length) *stop = (*step < 0) ? length - 1 : length; } if ((*step < 0 && *stop >= *start) || (*step > 0 && *start >= *stop)) { *slicelength = 0; } else if (*step < 0) { *slicelength = (*stop-*start+1)/(*step)+1; } else { *slicelength = (*stop-*start-1)/(*step)+1; } return 0; }
static PyObject *bpy_bmlayercollection_subscript(BPy_BMLayerCollection *self, PyObject *key) { /* don't need error check here */ if (PyUnicode_Check(key)) { return bpy_bmlayercollection_subscript_str(self, _PyUnicode_AsString(key)); } else if (PyIndex_Check(key)) { Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError); if (i == -1 && PyErr_Occurred()) return NULL; return bpy_bmlayercollection_subscript_int(self, i); } else if (PySlice_Check(key)) { PySliceObject *key_slice = (PySliceObject *)key; Py_ssize_t step = 1; if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) { return NULL; } else if (step != 1) { PyErr_SetString(PyExc_TypeError, "BMLayerCollection[slice]: slice steps not supported"); return NULL; } else if (key_slice->start == Py_None && key_slice->stop == Py_None) { return bpy_bmlayercollection_subscript_slice(self, 0, PY_SSIZE_T_MAX); } else { Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX; /* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */ if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) return NULL; if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop)) return NULL; if (start < 0 || stop < 0) { /* only get the length for negative values */ Py_ssize_t len = bpy_bmlayercollection_length(self); if (start < 0) start += len; if (stop < 0) stop += len; } if (stop - start <= 0) { return PyTuple_New(0); } else { return bpy_bmlayercollection_subscript_slice(self, start, stop); } } } else { PyErr_SetString(PyExc_AttributeError, "BMLayerCollection[key]: invalid key, key must be an int"); return NULL; } }
static int assign_slice(PyObject *u, PyObject *v, PyObject *w, PyObject *x) /* u[v:w] = x */ { int ilow = 0, ihigh = 1<<31; if (!_PyEval_SliceIndex(v, &ilow)) return -1; if (!_PyEval_SliceIndex(w, &ihigh)) return -1; // if (x == NULL) // return PySequence_DelSlice(u, ilow, ihigh); // else return PySequence_SetSlice(u, ilow, ihigh, x); }
PyObject * string_count(PyStringObject *self, PyObject *sub_obj, PyObject* obj_start, PyObject** args) { const char *str = PyString_AS_STRING(self), *sub; Py_ssize_t sub_len; Py_ssize_t start = 0, end = PY_SSIZE_T_MAX; PyObject* obj_end = args[0]; /* if (!stringlib_parse_args_finds("count", args, &sub_obj, &start, &end)) return NULL; */ if (obj_start && obj_start != Py_None) if (!_PyEval_SliceIndex(obj_start, &start)) return 0; if (obj_end && obj_end != Py_None) if (!_PyEval_SliceIndex(obj_end, &end)) return 0; if (PyString_Check(sub_obj)) { sub = PyString_AS_STRING(sub_obj); sub_len = PyString_GET_SIZE(sub_obj); } #ifdef Py_USING_UNICODE else if (PyUnicode_Check(sub_obj)) { Py_ssize_t count; count = PyUnicode_Count((PyObject *)self, sub_obj, start, end); if (count == -1) return NULL; else return PyInt_FromSsize_t(count); } #endif else if (PyObject_AsCharBuffer(sub_obj, &sub, &sub_len)) return NULL; ADJUST_INDICES(start, end, PyString_GET_SIZE(self)); return PyInt_FromSsize_t( stringlib_count(str + start, end - start, sub, sub_len, PY_SSIZE_T_MAX) ); }
int PySlice_Unpack(PyObject *_r, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step) { PySliceObject *r = (PySliceObject*)_r; /* this is harder to get right than you might think */ Py_BUILD_ASSERT(PY_SSIZE_T_MIN + 1 <= -PY_SSIZE_T_MAX); if (r->step == Py_None) { *step = 1; } else { if (!_PyEval_SliceIndex(r->step, step)) return -1; if (*step == 0) { PyErr_SetString(PyExc_ValueError, "slice step cannot be zero"); return -1; } /* Here *step might be -PY_SSIZE_T_MAX-1; in this case we replace it * with -PY_SSIZE_T_MAX. This doesn't affect the semantics, and it * guards against later undefined behaviour resulting from code that * does "step = -step" as part of a slice reversal. */ if (*step < -PY_SSIZE_T_MAX) *step = -PY_SSIZE_T_MAX; } if (r->start == Py_None) { *start = *step < 0 ? PY_SSIZE_T_MAX : 0; } else { if (!_PyEval_SliceIndex(r->start, start)) return -1; } if (r->stop == Py_None) { *stop = *step < 0 ? PY_SSIZE_T_MIN : PY_SSIZE_T_MAX; } else { if (!_PyEval_SliceIndex(r->stop, stop)) return -1; } return 0; }
Box* tupleIndex(BoxedTuple* self, Box* elt, Box* startBox, Box** args) { Box* endBox = args[0]; Py_ssize_t start, end; _PyEval_SliceIndex(startBox, &start); _PyEval_SliceIndex(endBox, &end); Py_ssize_t size = self->size(); if (start < 0) { start += size; if (start < 0) { start = 0; } } if (end < 0) { end += size; if (end < 0) { end = 0; } } else if (end > size) { end = size; } for (Py_ssize_t i = start; i < end; i++) { Box* e = self->elts[i]; int r = PyObject_RichCompareBool(e, elt, Py_EQ); if (r == -1) throwCAPIException(); if (r) return boxInt(i); } raiseExcHelper(ValueError, "tuple.index(x): x not in tuple"); }
int PySlice_GetIndicesEx(PyObject *_r, Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, Py_ssize_t *slicelength) { PySliceObject *r = (PySliceObject*)_r; /* this is harder to get right than you might think */ Py_ssize_t defstart, defstop; if (r->step == Py_None) { *step = 1; } else { if (!_PyEval_SliceIndex(r->step, step)) return -1; if (*step == 0) { PyErr_SetString(PyExc_ValueError, "slice step cannot be zero"); return -1; } /* Here *step might be -PY_SSIZE_T_MAX-1; in this case we replace it * with -PY_SSIZE_T_MAX. This doesn't affect the semantics, and it * guards against later undefined behaviour resulting from code that * does "step = -step" as part of a slice reversal. */ if (*step < -PY_SSIZE_T_MAX) *step = -PY_SSIZE_T_MAX; } defstart = *step < 0 ? length-1 : 0; defstop = *step < 0 ? -1 : length; if (r->start == Py_None) { *start = defstart; } else { if (!_PyEval_SliceIndex(r->start, start)) return -1; if (*start < 0) *start += length; if (*start < 0) *start = (*step < 0) ? -1 : 0; if (*start >= length) *start = (*step < 0) ? length - 1 : length; } if (r->stop == Py_None) { *stop = defstop; } else { if (!_PyEval_SliceIndex(r->stop, stop)) return -1; if (*stop < 0) *stop += length; if (*stop < 0) *stop = (*step < 0) ? -1 : 0; if (*stop >= length) *stop = (*step < 0) ? length - 1 : length; } if ((*step < 0 && *stop >= *start) || (*step > 0 && *start >= *stop)) { *slicelength = 0; } else if (*step < 0) { *slicelength = (*stop-*start+1)/(*step)+1; } else { *slicelength = (*stop-*start-1)/(*step)+1; } return 0; }