| 
									
										
										
										
											1996-07-30 16:45:48 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  | Written by Jim Hugunin and Chris Chase. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-10-11 16:25:41 +00:00
										 |  |  | This includes both the singular ellipsis object and slice objects. | 
					
						
							| 
									
										
										
										
											1996-07-30 16:45:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | Guido, feel free to do whatever you want in the way of copyrights | 
					
						
							|  |  |  | for this file. | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* 
 | 
					
						
							| 
									
										
										
										
											1996-10-11 16:25:41 +00:00
										 |  |  | Py_Ellipsis encodes the '...' rubber index token. It is similar to | 
					
						
							| 
									
										
										
										
											1996-07-30 16:45:48 +00:00
										 |  |  | the Py_NoneStruct in that there is no way to create other objects of | 
					
						
							|  |  |  | this type and there is exactly one in existence. | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "Python.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											1996-10-11 16:25:41 +00:00
										 |  |  | ellipsis_repr(op) | 
					
						
							| 
									
										
										
										
											1996-07-30 16:45:48 +00:00
										 |  |  | 	PyObject *op; | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											1996-10-11 16:25:41 +00:00
										 |  |  | 	return PyString_FromString("Ellipsis"); | 
					
						
							| 
									
										
										
										
											1996-07-30 16:45:48 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-10-11 16:25:41 +00:00
										 |  |  | static PyTypeObject PyEllipsis_Type = { | 
					
						
							| 
									
										
										
										
											1996-07-30 16:45:48 +00:00
										 |  |  | 	PyObject_HEAD_INIT(&PyType_Type) | 
					
						
							|  |  |  | 	0, | 
					
						
							| 
									
										
										
										
											1996-10-11 16:25:41 +00:00
										 |  |  | 	"ellipsis", | 
					
						
							| 
									
										
										
										
											1996-07-30 16:45:48 +00:00
										 |  |  | 	0, | 
					
						
							|  |  |  | 	0, | 
					
						
							|  |  |  | 	0,		/*tp_dealloc*/ /*never called*/ | 
					
						
							|  |  |  | 	0,		/*tp_print*/ | 
					
						
							|  |  |  | 	0,		/*tp_getattr*/ | 
					
						
							|  |  |  | 	0,		/*tp_setattr*/ | 
					
						
							|  |  |  | 	0,		/*tp_compare*/ | 
					
						
							| 
									
										
										
										
											1996-10-11 16:25:41 +00:00
										 |  |  | 	(reprfunc)ellipsis_repr, /*tp_repr*/ | 
					
						
							| 
									
										
										
										
											1996-07-30 16:45:48 +00:00
										 |  |  | 	0,		/*tp_as_number*/ | 
					
						
							|  |  |  | 	0,		/*tp_as_sequence*/ | 
					
						
							|  |  |  | 	0,		/*tp_as_mapping*/ | 
					
						
							|  |  |  | 	0,		/*tp_hash */ | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-10-11 16:25:41 +00:00
										 |  |  | PyObject _Py_EllipsisObject = { | 
					
						
							|  |  |  | 	PyObject_HEAD_INIT(&PyEllipsis_Type) | 
					
						
							| 
									
										
										
										
											1996-07-30 16:45:48 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Slice object implementation
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    start, stop, and step are python objects with None indicating no | 
					
						
							|  |  |  |    index is present. | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject * | 
					
						
							|  |  |  | PySlice_New(start, stop, step) | 
					
						
							|  |  |  | 	PyObject *start; | 
					
						
							|  |  |  | 	PyObject *stop; | 
					
						
							|  |  |  | 	PyObject *step; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PySliceObject *obj = | 
					
						
							|  |  |  | 		(PySliceObject *) PyObject_NEW(PySliceObject, &PySlice_Type); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (step == NULL) step = Py_None; | 
					
						
							|  |  |  | 	Py_INCREF(step); | 
					
						
							|  |  |  | 	if (start == NULL) start = Py_None; | 
					
						
							|  |  |  | 	Py_INCREF(start); | 
					
						
							|  |  |  | 	if (stop == NULL) stop = Py_None; | 
					
						
							|  |  |  | 	Py_INCREF(stop); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	obj->step = step; | 
					
						
							|  |  |  | 	obj->start = start; | 
					
						
							|  |  |  | 	obj->stop = stop; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return (PyObject *) obj; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | PySlice_GetIndices(r, length, start, stop, step) | 
					
						
							|  |  |  | 	PySliceObject *r; | 
					
						
							|  |  |  | 	int length; | 
					
						
							|  |  |  | 	int *start; | 
					
						
							|  |  |  | 	int *stop; | 
					
						
							|  |  |  | 	int *step; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (r->step == Py_None) { | 
					
						
							|  |  |  | 		*step = 1; | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		if (!PyInt_Check(r->step)) return -1; | 
					
						
							|  |  |  | 		*step = PyInt_AsLong(r->step); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (r->start == Py_None) { | 
					
						
							|  |  |  | 		*start = *step < 0 ? length-1 : 0; | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		if (!PyInt_Check(r->start)) return -1; | 
					
						
							|  |  |  | 		*start = PyInt_AsLong(r->start); | 
					
						
							|  |  |  | 		if (*start < 0) *start += length; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (r->stop == Py_None) { | 
					
						
							|  |  |  | 		*stop = *step < 0 ? -1 : length; | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		if (!PyInt_Check(r->stop)) return -1; | 
					
						
							|  |  |  | 		*stop = PyInt_AsLong(r->stop); | 
					
						
							|  |  |  | 		if (*stop < 0) *stop += length; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (*stop > length) return -1; | 
					
						
							|  |  |  | 	if (*start >= length) return -1; | 
					
						
							|  |  |  | 	if (*step == 0) return -1; | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | slice_dealloc(r) | 
					
						
							|  |  |  | 	PySliceObject *r; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Py_DECREF(r->step); | 
					
						
							|  |  |  | 	Py_DECREF(r->start); | 
					
						
							|  |  |  | 	Py_DECREF(r->stop); | 
					
						
							|  |  |  | 	PyMem_DEL(r); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | slice_repr(r) | 
					
						
							|  |  |  | 	PySliceObject *r; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *s, *comma; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	s = PyString_FromString("slice("); | 
					
						
							|  |  |  | 	comma = PyString_FromString(", "); | 
					
						
							|  |  |  | 	PyString_ConcatAndDel(&s, PyObject_Repr(r->start)); | 
					
						
							|  |  |  | 	PyString_Concat(&s, comma); | 
					
						
							|  |  |  | 	PyString_ConcatAndDel(&s, PyObject_Repr(r->stop)); | 
					
						
							|  |  |  | 	PyString_Concat(&s, comma); | 
					
						
							|  |  |  | 	PyString_ConcatAndDel(&s, PyObject_Repr(r->step)); | 
					
						
							|  |  |  | 	PyString_ConcatAndDel(&s, PyString_FromString(")")); | 
					
						
							|  |  |  | 	Py_DECREF(comma); | 
					
						
							|  |  |  | 	return s; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject *slice_getattr(self, name) | 
					
						
							|  |  |  | 	PySliceObject *self; | 
					
						
							|  |  |  | 	char *name; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *ret; | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  | 	ret = NULL; | 
					
						
							|  |  |  | 	if (strcmp(name, "start") == 0) { | 
					
						
							|  |  |  | 		ret = self->start; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (strcmp(name, "stop") == 0) { | 
					
						
							|  |  |  | 		ret = self->stop; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (strcmp(name, "step") == 0) { | 
					
						
							|  |  |  | 		ret = self->step; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (strcmp(name, "__members__") == 0) { | 
					
						
							|  |  |  | 		return Py_BuildValue("[sss]", | 
					
						
							|  |  |  | 				     "start", "stop", "step"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		PyErr_SetString(PyExc_AttributeError, name); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	Py_INCREF(ret); | 
					
						
							|  |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyTypeObject PySlice_Type = { | 
					
						
							|  |  |  | 	PyObject_HEAD_INIT(&PyType_Type) | 
					
						
							|  |  |  | 	0,			/* Number of items for varobject */ | 
					
						
							|  |  |  | 	"slice",		/* Name of this type */ | 
					
						
							|  |  |  | 	sizeof(PySliceObject),	/* Basic object size */ | 
					
						
							|  |  |  | 	0,			/* Item size for varobject */ | 
					
						
							|  |  |  | 	(destructor)slice_dealloc, /*tp_dealloc*/ | 
					
						
							|  |  |  | 	0,			/*tp_print*/ | 
					
						
							|  |  |  | 	(getattrfunc)slice_getattr, /*tp_getattr*/ | 
					
						
							|  |  |  | 	0,			/*tp_setattr*/ | 
					
						
							|  |  |  | 	0,		    /*tp_compare*/ | 
					
						
							|  |  |  | 	(reprfunc)slice_repr, /*tp_repr*/ | 
					
						
							|  |  |  | 	0,			/*tp_as_number*/ | 
					
						
							|  |  |  | 	0,	    	/*tp_as_sequence*/ | 
					
						
							|  |  |  | 	0,			/*tp_as_mapping*/ | 
					
						
							|  |  |  | }; |