blob: 6f7a6d818ba8c79712fd280a2ab2f35970538fad [file] [log] [blame]
Guido van Rossumf2d125b1996-07-30 16:45:48 +00001/*
2Written by Jim Hugunin and Chris Chase.
3
Guido van Rossume449af71996-10-11 16:25:41 +00004This includes both the singular ellipsis object and slice objects.
Guido van Rossumf2d125b1996-07-30 16:45:48 +00005
6Guido, feel free to do whatever you want in the way of copyrights
7for this file.
8*/
9
10/*
Guido van Rossume449af71996-10-11 16:25:41 +000011Py_Ellipsis encodes the '...' rubber index token. It is similar to
Guido van Rossumf2d125b1996-07-30 16:45:48 +000012the Py_NoneStruct in that there is no way to create other objects of
13this type and there is exactly one in existence.
14*/
15
16#include "Python.h"
17
18static PyObject *
Fred Drake45cfbcc2000-07-09 06:21:27 +000019ellipsis_repr(PyObject *op)
Guido van Rossumf2d125b1996-07-30 16:45:48 +000020{
Guido van Rossume449af71996-10-11 16:25:41 +000021 return PyString_FromString("Ellipsis");
Guido van Rossumf2d125b1996-07-30 16:45:48 +000022}
23
Guido van Rossume449af71996-10-11 16:25:41 +000024static PyTypeObject PyEllipsis_Type = {
Guido van Rossumf2d125b1996-07-30 16:45:48 +000025 PyObject_HEAD_INIT(&PyType_Type)
26 0,
Guido van Rossume449af71996-10-11 16:25:41 +000027 "ellipsis",
Guido van Rossumf2d125b1996-07-30 16:45:48 +000028 0,
29 0,
30 0, /*tp_dealloc*/ /*never called*/
31 0, /*tp_print*/
32 0, /*tp_getattr*/
33 0, /*tp_setattr*/
34 0, /*tp_compare*/
Guido van Rossume449af71996-10-11 16:25:41 +000035 (reprfunc)ellipsis_repr, /*tp_repr*/
Guido van Rossumf2d125b1996-07-30 16:45:48 +000036 0, /*tp_as_number*/
37 0, /*tp_as_sequence*/
38 0, /*tp_as_mapping*/
39 0, /*tp_hash */
40};
41
Guido van Rossume449af71996-10-11 16:25:41 +000042PyObject _Py_EllipsisObject = {
43 PyObject_HEAD_INIT(&PyEllipsis_Type)
Guido van Rossumf2d125b1996-07-30 16:45:48 +000044};
45
46
47/* Slice object implementation
48
49 start, stop, and step are python objects with None indicating no
50 index is present.
51*/
52
53PyObject *
Fred Drake45cfbcc2000-07-09 06:21:27 +000054PySlice_New(PyObject *start, PyObject *stop, PyObject *step)
Guido van Rossumf2d125b1996-07-30 16:45:48 +000055{
Guido van Rossumb18618d2000-05-03 23:44:39 +000056 PySliceObject *obj = PyObject_NEW(PySliceObject, &PySlice_Type);
Guido van Rossumf2d125b1996-07-30 16:45:48 +000057
Guido van Rossumadf54102000-12-14 15:09:46 +000058 if (obj == NULL)
59 return NULL;
60
Guido van Rossumf2d125b1996-07-30 16:45:48 +000061 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);
67
68 obj->step = step;
69 obj->start = start;
70 obj->stop = stop;
71
72 return (PyObject *) obj;
73}
74
75int
Fred Drake45cfbcc2000-07-09 06:21:27 +000076PySlice_GetIndices(PySliceObject *r, int length,
77 int *start, int *stop, int *step)
Guido van Rossumf2d125b1996-07-30 16:45:48 +000078{
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);
84 }
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;
91 }
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;
98 }
99 if (*stop > length) return -1;
100 if (*start >= length) return -1;
101 if (*step == 0) return -1;
102 return 0;
103}
104
105static void
Fred Drake45cfbcc2000-07-09 06:21:27 +0000106slice_dealloc(PySliceObject *r)
Guido van Rossumf2d125b1996-07-30 16:45:48 +0000107{
108 Py_DECREF(r->step);
109 Py_DECREF(r->start);
110 Py_DECREF(r->stop);
Guido van Rossumb18618d2000-05-03 23:44:39 +0000111 PyObject_DEL(r);
Guido van Rossumf2d125b1996-07-30 16:45:48 +0000112}
113
114static PyObject *
Fred Drake45cfbcc2000-07-09 06:21:27 +0000115slice_repr(PySliceObject *r)
Guido van Rossumf2d125b1996-07-30 16:45:48 +0000116{
117 PyObject *s, *comma;
118
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;
129}
130
131
Fred Drake45cfbcc2000-07-09 06:21:27 +0000132static PyObject *slice_getattr(PySliceObject *self, char *name)
Guido van Rossumf2d125b1996-07-30 16:45:48 +0000133{
134 PyObject *ret;
135
136 ret = NULL;
137 if (strcmp(name, "start") == 0) {
138 ret = self->start;
139 }
140 else if (strcmp(name, "stop") == 0) {
141 ret = self->stop;
142 }
143 else if (strcmp(name, "step") == 0) {
144 ret = self->step;
145 }
146 else if (strcmp(name, "__members__") == 0) {
147 return Py_BuildValue("[sss]",
148 "start", "stop", "step");
149 }
150 else {
151 PyErr_SetString(PyExc_AttributeError, name);
152 return NULL;
153 }
154 Py_INCREF(ret);
155 return ret;
156}
157
Guido van Rossuma1351fb2001-03-20 12:41:34 +0000158static int
159slice_compare(PySliceObject *v, PySliceObject *w)
160{
161 int result = 0;
162
163 if (v == w)
164 return 0;
165
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;
177}
Guido van Rossumf2d125b1996-07-30 16:45:48 +0000178
179PyTypeObject 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*/
Guido van Rossuma1351fb2001-03-20 12:41:34 +0000189 (cmpfunc)slice_compare, /*tp_compare*/
190 (reprfunc)slice_repr, /*tp_repr*/
Guido van Rossumf2d125b1996-07-30 16:45:48 +0000191 0, /*tp_as_number*/
Guido van Rossuma1351fb2001-03-20 12:41:34 +0000192 0, /*tp_as_sequence*/
Guido van Rossumf2d125b1996-07-30 16:45:48 +0000193 0, /*tp_as_mapping*/
194};