blob: eb4972b49125eb567a8bfe4061d497e6dc49c61b [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 *
Guido van Rossume449af71996-10-11 16:25:41 +000019ellipsis_repr(op)
Guido van Rossumf2d125b1996-07-30 16:45:48 +000020 PyObject *op;
21{
Guido van Rossume449af71996-10-11 16:25:41 +000022 return PyString_FromString("Ellipsis");
Guido van Rossumf2d125b1996-07-30 16:45:48 +000023}
24
Guido van Rossume449af71996-10-11 16:25:41 +000025static PyTypeObject PyEllipsis_Type = {
Guido van Rossumf2d125b1996-07-30 16:45:48 +000026 PyObject_HEAD_INIT(&PyType_Type)
27 0,
Guido van Rossume449af71996-10-11 16:25:41 +000028 "ellipsis",
Guido van Rossumf2d125b1996-07-30 16:45:48 +000029 0,
30 0,
31 0, /*tp_dealloc*/ /*never called*/
32 0, /*tp_print*/
33 0, /*tp_getattr*/
34 0, /*tp_setattr*/
35 0, /*tp_compare*/
Guido van Rossume449af71996-10-11 16:25:41 +000036 (reprfunc)ellipsis_repr, /*tp_repr*/
Guido van Rossumf2d125b1996-07-30 16:45:48 +000037 0, /*tp_as_number*/
38 0, /*tp_as_sequence*/
39 0, /*tp_as_mapping*/
40 0, /*tp_hash */
41};
42
Guido van Rossume449af71996-10-11 16:25:41 +000043PyObject _Py_EllipsisObject = {
44 PyObject_HEAD_INIT(&PyEllipsis_Type)
Guido van Rossumf2d125b1996-07-30 16:45:48 +000045};
46
47
48/* Slice object implementation
49
50 start, stop, and step are python objects with None indicating no
51 index is present.
52*/
53
54PyObject *
55PySlice_New(start, stop, step)
56 PyObject *start;
57 PyObject *stop;
58 PyObject *step;
59{
Guido van Rossumb18618d2000-05-03 23:44:39 +000060 PySliceObject *obj = PyObject_NEW(PySliceObject, &PySlice_Type);
Guido van Rossumf2d125b1996-07-30 16:45:48 +000061
62 if (step == NULL) step = Py_None;
63 Py_INCREF(step);
64 if (start == NULL) start = Py_None;
65 Py_INCREF(start);
66 if (stop == NULL) stop = Py_None;
67 Py_INCREF(stop);
68
69 obj->step = step;
70 obj->start = start;
71 obj->stop = stop;
72
73 return (PyObject *) obj;
74}
75
76int
77PySlice_GetIndices(r, length, start, stop, step)
78 PySliceObject *r;
79 int length;
80 int *start;
81 int *stop;
82 int *step;
83{
84 if (r->step == Py_None) {
85 *step = 1;
86 } else {
87 if (!PyInt_Check(r->step)) return -1;
88 *step = PyInt_AsLong(r->step);
89 }
90 if (r->start == Py_None) {
91 *start = *step < 0 ? length-1 : 0;
92 } else {
93 if (!PyInt_Check(r->start)) return -1;
94 *start = PyInt_AsLong(r->start);
95 if (*start < 0) *start += length;
96 }
97 if (r->stop == Py_None) {
98 *stop = *step < 0 ? -1 : length;
99 } else {
100 if (!PyInt_Check(r->stop)) return -1;
101 *stop = PyInt_AsLong(r->stop);
102 if (*stop < 0) *stop += length;
103 }
104 if (*stop > length) return -1;
105 if (*start >= length) return -1;
106 if (*step == 0) return -1;
107 return 0;
108}
109
110static void
111slice_dealloc(r)
112 PySliceObject *r;
113{
114 Py_DECREF(r->step);
115 Py_DECREF(r->start);
116 Py_DECREF(r->stop);
Guido van Rossumb18618d2000-05-03 23:44:39 +0000117 PyObject_DEL(r);
Guido van Rossumf2d125b1996-07-30 16:45:48 +0000118}
119
120static PyObject *
121slice_repr(r)
122 PySliceObject *r;
123{
124 PyObject *s, *comma;
125
126 s = PyString_FromString("slice(");
127 comma = PyString_FromString(", ");
128 PyString_ConcatAndDel(&s, PyObject_Repr(r->start));
129 PyString_Concat(&s, comma);
130 PyString_ConcatAndDel(&s, PyObject_Repr(r->stop));
131 PyString_Concat(&s, comma);
132 PyString_ConcatAndDel(&s, PyObject_Repr(r->step));
133 PyString_ConcatAndDel(&s, PyString_FromString(")"));
134 Py_DECREF(comma);
135 return s;
136}
137
138
139static PyObject *slice_getattr(self, name)
140 PySliceObject *self;
141 char *name;
142{
143 PyObject *ret;
144
145 ret = NULL;
146 if (strcmp(name, "start") == 0) {
147 ret = self->start;
148 }
149 else if (strcmp(name, "stop") == 0) {
150 ret = self->stop;
151 }
152 else if (strcmp(name, "step") == 0) {
153 ret = self->step;
154 }
155 else if (strcmp(name, "__members__") == 0) {
156 return Py_BuildValue("[sss]",
157 "start", "stop", "step");
158 }
159 else {
160 PyErr_SetString(PyExc_AttributeError, name);
161 return NULL;
162 }
163 Py_INCREF(ret);
164 return ret;
165}
166
167
168PyTypeObject PySlice_Type = {
169 PyObject_HEAD_INIT(&PyType_Type)
170 0, /* Number of items for varobject */
171 "slice", /* Name of this type */
172 sizeof(PySliceObject), /* Basic object size */
173 0, /* Item size for varobject */
174 (destructor)slice_dealloc, /*tp_dealloc*/
175 0, /*tp_print*/
176 (getattrfunc)slice_getattr, /*tp_getattr*/
177 0, /*tp_setattr*/
178 0, /*tp_compare*/
179 (reprfunc)slice_repr, /*tp_repr*/
180 0, /*tp_as_number*/
181 0, /*tp_as_sequence*/
182 0, /*tp_as_mapping*/
183};