blob: 50e042afa8569d7116379e5ba00eaeee986839e3 [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
58 if (step == NULL) step = Py_None;
59 Py_INCREF(step);
60 if (start == NULL) start = Py_None;
61 Py_INCREF(start);
62 if (stop == NULL) stop = Py_None;
63 Py_INCREF(stop);
64
65 obj->step = step;
66 obj->start = start;
67 obj->stop = stop;
68
69 return (PyObject *) obj;
70}
71
72int
Fred Drake45cfbcc2000-07-09 06:21:27 +000073PySlice_GetIndices(PySliceObject *r, int length,
74 int *start, int *stop, int *step)
Guido van Rossumf2d125b1996-07-30 16:45:48 +000075{
76 if (r->step == Py_None) {
77 *step = 1;
78 } else {
79 if (!PyInt_Check(r->step)) return -1;
80 *step = PyInt_AsLong(r->step);
81 }
82 if (r->start == Py_None) {
83 *start = *step < 0 ? length-1 : 0;
84 } else {
85 if (!PyInt_Check(r->start)) return -1;
86 *start = PyInt_AsLong(r->start);
87 if (*start < 0) *start += length;
88 }
89 if (r->stop == Py_None) {
90 *stop = *step < 0 ? -1 : length;
91 } else {
92 if (!PyInt_Check(r->stop)) return -1;
93 *stop = PyInt_AsLong(r->stop);
94 if (*stop < 0) *stop += length;
95 }
96 if (*stop > length) return -1;
97 if (*start >= length) return -1;
98 if (*step == 0) return -1;
99 return 0;
100}
101
102static void
Fred Drake45cfbcc2000-07-09 06:21:27 +0000103slice_dealloc(PySliceObject *r)
Guido van Rossumf2d125b1996-07-30 16:45:48 +0000104{
105 Py_DECREF(r->step);
106 Py_DECREF(r->start);
107 Py_DECREF(r->stop);
Guido van Rossumb18618d2000-05-03 23:44:39 +0000108 PyObject_DEL(r);
Guido van Rossumf2d125b1996-07-30 16:45:48 +0000109}
110
111static PyObject *
Fred Drake45cfbcc2000-07-09 06:21:27 +0000112slice_repr(PySliceObject *r)
Guido van Rossumf2d125b1996-07-30 16:45:48 +0000113{
114 PyObject *s, *comma;
115
116 s = PyString_FromString("slice(");
117 comma = PyString_FromString(", ");
118 PyString_ConcatAndDel(&s, PyObject_Repr(r->start));
119 PyString_Concat(&s, comma);
120 PyString_ConcatAndDel(&s, PyObject_Repr(r->stop));
121 PyString_Concat(&s, comma);
122 PyString_ConcatAndDel(&s, PyObject_Repr(r->step));
123 PyString_ConcatAndDel(&s, PyString_FromString(")"));
124 Py_DECREF(comma);
125 return s;
126}
127
128
Fred Drake45cfbcc2000-07-09 06:21:27 +0000129static PyObject *slice_getattr(PySliceObject *self, char *name)
Guido van Rossumf2d125b1996-07-30 16:45:48 +0000130{
131 PyObject *ret;
132
133 ret = NULL;
134 if (strcmp(name, "start") == 0) {
135 ret = self->start;
136 }
137 else if (strcmp(name, "stop") == 0) {
138 ret = self->stop;
139 }
140 else if (strcmp(name, "step") == 0) {
141 ret = self->step;
142 }
143 else if (strcmp(name, "__members__") == 0) {
144 return Py_BuildValue("[sss]",
145 "start", "stop", "step");
146 }
147 else {
148 PyErr_SetString(PyExc_AttributeError, name);
149 return NULL;
150 }
151 Py_INCREF(ret);
152 return ret;
153}
154
155
156PyTypeObject PySlice_Type = {
157 PyObject_HEAD_INIT(&PyType_Type)
158 0, /* Number of items for varobject */
159 "slice", /* Name of this type */
160 sizeof(PySliceObject), /* Basic object size */
161 0, /* Item size for varobject */
162 (destructor)slice_dealloc, /*tp_dealloc*/
163 0, /*tp_print*/
164 (getattrfunc)slice_getattr, /*tp_getattr*/
165 0, /*tp_setattr*/
166 0, /*tp_compare*/
167 (reprfunc)slice_repr, /*tp_repr*/
168 0, /*tp_as_number*/
169 0, /*tp_as_sequence*/
170 0, /*tp_as_mapping*/
171};