blob: a232296705788a41e4e11711e0ac3fb9ff2583f9 [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{
60 PySliceObject *obj =
61 (PySliceObject *) PyObject_NEW(PySliceObject, &PySlice_Type);
62
63 if (step == NULL) step = Py_None;
64 Py_INCREF(step);
65 if (start == NULL) start = Py_None;
66 Py_INCREF(start);
67 if (stop == NULL) stop = Py_None;
68 Py_INCREF(stop);
69
70 obj->step = step;
71 obj->start = start;
72 obj->stop = stop;
73
74 return (PyObject *) obj;
75}
76
77int
78PySlice_GetIndices(r, length, start, stop, step)
79 PySliceObject *r;
80 int length;
81 int *start;
82 int *stop;
83 int *step;
84{
85 if (r->step == Py_None) {
86 *step = 1;
87 } else {
88 if (!PyInt_Check(r->step)) return -1;
89 *step = PyInt_AsLong(r->step);
90 }
91 if (r->start == Py_None) {
92 *start = *step < 0 ? length-1 : 0;
93 } else {
94 if (!PyInt_Check(r->start)) return -1;
95 *start = PyInt_AsLong(r->start);
96 if (*start < 0) *start += length;
97 }
98 if (r->stop == Py_None) {
99 *stop = *step < 0 ? -1 : length;
100 } else {
101 if (!PyInt_Check(r->stop)) return -1;
102 *stop = PyInt_AsLong(r->stop);
103 if (*stop < 0) *stop += length;
104 }
105 if (*stop > length) return -1;
106 if (*start >= length) return -1;
107 if (*step == 0) return -1;
108 return 0;
109}
110
111static void
112slice_dealloc(r)
113 PySliceObject *r;
114{
115 Py_DECREF(r->step);
116 Py_DECREF(r->start);
117 Py_DECREF(r->stop);
118 PyMem_DEL(r);
119}
120
121static PyObject *
122slice_repr(r)
123 PySliceObject *r;
124{
125 PyObject *s, *comma;
126
127 s = PyString_FromString("slice(");
128 comma = PyString_FromString(", ");
129 PyString_ConcatAndDel(&s, PyObject_Repr(r->start));
130 PyString_Concat(&s, comma);
131 PyString_ConcatAndDel(&s, PyObject_Repr(r->stop));
132 PyString_Concat(&s, comma);
133 PyString_ConcatAndDel(&s, PyObject_Repr(r->step));
134 PyString_ConcatAndDel(&s, PyString_FromString(")"));
135 Py_DECREF(comma);
136 return s;
137}
138
139
140static PyObject *slice_getattr(self, name)
141 PySliceObject *self;
142 char *name;
143{
144 PyObject *ret;
145
146 ret = NULL;
147 if (strcmp(name, "start") == 0) {
148 ret = self->start;
149 }
150 else if (strcmp(name, "stop") == 0) {
151 ret = self->stop;
152 }
153 else if (strcmp(name, "step") == 0) {
154 ret = self->step;
155 }
156 else if (strcmp(name, "__members__") == 0) {
157 return Py_BuildValue("[sss]",
158 "start", "stop", "step");
159 }
160 else {
161 PyErr_SetString(PyExc_AttributeError, name);
162 return NULL;
163 }
164 Py_INCREF(ret);
165 return ret;
166}
167
168
169PyTypeObject PySlice_Type = {
170 PyObject_HEAD_INIT(&PyType_Type)
171 0, /* Number of items for varobject */
172 "slice", /* Name of this type */
173 sizeof(PySliceObject), /* Basic object size */
174 0, /* Item size for varobject */
175 (destructor)slice_dealloc, /*tp_dealloc*/
176 0, /*tp_print*/
177 (getattrfunc)slice_getattr, /*tp_getattr*/
178 0, /*tp_setattr*/
179 0, /*tp_compare*/
180 (reprfunc)slice_repr, /*tp_repr*/
181 0, /*tp_as_number*/
182 0, /*tp_as_sequence*/
183 0, /*tp_as_mapping*/
184};