py-cvs-rel2_1 (Rev 1.2) merge
[python/dscho.git] / Objects / sliceobject.c
blob6f7a6d818ba8c79712fd280a2ab2f35970538fad
1 /*
2 Written by Jim Hugunin and Chris Chase.
4 This includes both the singular ellipsis object and slice objects.
6 Guido, feel free to do whatever you want in the way of copyrights
7 for this file.
8 */
10 /*
11 Py_Ellipsis encodes the '...' rubber index token. It is similar to
12 the Py_NoneStruct in that there is no way to create other objects of
13 this type and there is exactly one in existence.
16 #include "Python.h"
18 static PyObject *
19 ellipsis_repr(PyObject *op)
21 return PyString_FromString("Ellipsis");
24 static PyTypeObject PyEllipsis_Type = {
25 PyObject_HEAD_INIT(&PyType_Type)
27 "ellipsis",
30 0, /*tp_dealloc*/ /*never called*/
31 0, /*tp_print*/
32 0, /*tp_getattr*/
33 0, /*tp_setattr*/
34 0, /*tp_compare*/
35 (reprfunc)ellipsis_repr, /*tp_repr*/
36 0, /*tp_as_number*/
37 0, /*tp_as_sequence*/
38 0, /*tp_as_mapping*/
39 0, /*tp_hash */
42 PyObject _Py_EllipsisObject = {
43 PyObject_HEAD_INIT(&PyEllipsis_Type)
47 /* Slice object implementation
49 start, stop, and step are python objects with None indicating no
50 index is present.
53 PyObject *
54 PySlice_New(PyObject *start, PyObject *stop, PyObject *step)
56 PySliceObject *obj = PyObject_NEW(PySliceObject, &PySlice_Type);
58 if (obj == NULL)
59 return NULL;
61 if (step == NULL) step = Py_None;
62 Py_INCREF(step);
63 if (start == NULL) start = Py_None;
64 Py_INCREF(start);
65 if (stop == NULL) stop = Py_None;
66 Py_INCREF(stop);
68 obj->step = step;
69 obj->start = start;
70 obj->stop = stop;
72 return (PyObject *) obj;
75 int
76 PySlice_GetIndices(PySliceObject *r, int length,
77 int *start, int *stop, int *step)
79 if (r->step == Py_None) {
80 *step = 1;
81 } else {
82 if (!PyInt_Check(r->step)) return -1;
83 *step = PyInt_AsLong(r->step);
85 if (r->start == Py_None) {
86 *start = *step < 0 ? length-1 : 0;
87 } else {
88 if (!PyInt_Check(r->start)) return -1;
89 *start = PyInt_AsLong(r->start);
90 if (*start < 0) *start += length;
92 if (r->stop == Py_None) {
93 *stop = *step < 0 ? -1 : length;
94 } else {
95 if (!PyInt_Check(r->stop)) return -1;
96 *stop = PyInt_AsLong(r->stop);
97 if (*stop < 0) *stop += length;
99 if (*stop > length) return -1;
100 if (*start >= length) return -1;
101 if (*step == 0) return -1;
102 return 0;
105 static void
106 slice_dealloc(PySliceObject *r)
108 Py_DECREF(r->step);
109 Py_DECREF(r->start);
110 Py_DECREF(r->stop);
111 PyObject_DEL(r);
114 static PyObject *
115 slice_repr(PySliceObject *r)
117 PyObject *s, *comma;
119 s = PyString_FromString("slice(");
120 comma = PyString_FromString(", ");
121 PyString_ConcatAndDel(&s, PyObject_Repr(r->start));
122 PyString_Concat(&s, comma);
123 PyString_ConcatAndDel(&s, PyObject_Repr(r->stop));
124 PyString_Concat(&s, comma);
125 PyString_ConcatAndDel(&s, PyObject_Repr(r->step));
126 PyString_ConcatAndDel(&s, PyString_FromString(")"));
127 Py_DECREF(comma);
128 return s;
132 static PyObject *slice_getattr(PySliceObject *self, char *name)
134 PyObject *ret;
136 ret = NULL;
137 if (strcmp(name, "start") == 0) {
138 ret = self->start;
140 else if (strcmp(name, "stop") == 0) {
141 ret = self->stop;
143 else if (strcmp(name, "step") == 0) {
144 ret = self->step;
146 else if (strcmp(name, "__members__") == 0) {
147 return Py_BuildValue("[sss]",
148 "start", "stop", "step");
150 else {
151 PyErr_SetString(PyExc_AttributeError, name);
152 return NULL;
154 Py_INCREF(ret);
155 return ret;
158 static int
159 slice_compare(PySliceObject *v, PySliceObject *w)
161 int result = 0;
163 if (v == w)
164 return 0;
166 if (PyObject_Cmp(v->start, w->start, &result) < 0)
167 return -2;
168 if (result != 0)
169 return result;
170 if (PyObject_Cmp(v->stop, w->stop, &result) < 0)
171 return -2;
172 if (result != 0)
173 return result;
174 if (PyObject_Cmp(v->step, w->step, &result) < 0)
175 return -2;
176 return result;
179 PyTypeObject PySlice_Type = {
180 PyObject_HEAD_INIT(&PyType_Type)
181 0, /* Number of items for varobject */
182 "slice", /* Name of this type */
183 sizeof(PySliceObject), /* Basic object size */
184 0, /* Item size for varobject */
185 (destructor)slice_dealloc, /*tp_dealloc*/
186 0, /*tp_print*/
187 (getattrfunc)slice_getattr, /*tp_getattr*/
188 0, /*tp_setattr*/
189 (cmpfunc)slice_compare, /*tp_compare*/
190 (reprfunc)slice_repr, /*tp_repr*/
191 0, /*tp_as_number*/
192 0, /*tp_as_sequence*/
193 0, /*tp_as_mapping*/