| 
									
										
										
										
											1993-10-26 17:58:25 +00:00
										 |  |  | /***********************************************************
 | 
					
						
							| 
									
										
										
										
											1995-01-04 19:07:38 +00:00
										 |  |  | Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam, | 
					
						
							|  |  |  | The Netherlands. | 
					
						
							| 
									
										
										
										
											1993-10-26 17:58:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |                         All Rights Reserved | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-10-25 14:44:06 +00:00
										 |  |  | Permission to use, copy, modify, and distribute this software and its | 
					
						
							|  |  |  | documentation for any purpose and without fee is hereby granted, | 
					
						
							| 
									
										
										
										
											1993-10-26 17:58:25 +00:00
										 |  |  | provided that the above copyright notice appear in all copies and that | 
					
						
							| 
									
										
										
										
											1996-10-25 14:44:06 +00:00
										 |  |  | both that copyright notice and this permission notice appear in | 
					
						
							| 
									
										
										
										
											1993-10-26 17:58:25 +00:00
										 |  |  | supporting documentation, and that the names of Stichting Mathematisch | 
					
						
							| 
									
										
										
										
											1996-10-25 14:44:06 +00:00
										 |  |  | Centrum or CWI or Corporation for National Research Initiatives or | 
					
						
							|  |  |  | CNRI not be used in advertising or publicity pertaining to | 
					
						
							|  |  |  | distribution of the software without specific, written prior | 
					
						
							|  |  |  | permission. | 
					
						
							| 
									
										
										
										
											1993-10-26 17:58:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-10-25 14:44:06 +00:00
										 |  |  | While CWI is the initial source for this software, a modified version | 
					
						
							|  |  |  | is made available by the Corporation for National Research Initiatives | 
					
						
							|  |  |  | (CNRI) at the Internet address ftp://ftp.python.org.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH | 
					
						
							|  |  |  | REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF | 
					
						
							|  |  |  | MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH | 
					
						
							|  |  |  | CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL | 
					
						
							|  |  |  | DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR | 
					
						
							|  |  |  | PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | 
					
						
							|  |  |  | TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | 
					
						
							|  |  |  | PERFORMANCE OF THIS SOFTWARE. | 
					
						
							| 
									
										
										
										
											1993-10-26 17:58:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ******************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Range object implementation */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | #include "Python.h"
 | 
					
						
							| 
									
										
										
										
											1993-10-26 17:58:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	PyObject_HEAD | 
					
						
							| 
									
										
										
										
											1993-10-26 17:58:25 +00:00
										 |  |  | 	long	start; | 
					
						
							|  |  |  | 	long	step; | 
					
						
							|  |  |  | 	long	len; | 
					
						
							| 
									
										
										
										
											1993-12-21 22:50:31 +00:00
										 |  |  | 	int	reps; | 
					
						
							| 
									
										
										
										
											1993-10-26 17:58:25 +00:00
										 |  |  | } rangeobject; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | PyObject * | 
					
						
							|  |  |  | PyRange_New(start, len, step, reps) | 
					
						
							| 
									
										
										
										
											1993-10-26 17:58:25 +00:00
										 |  |  | 	long start, len, step; | 
					
						
							| 
									
										
										
										
											1993-12-21 22:50:31 +00:00
										 |  |  | 	int reps; | 
					
						
							| 
									
										
										
										
											1993-10-26 17:58:25 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	rangeobject *obj = PyObject_NEW(rangeobject, &PyRange_Type); | 
					
						
							| 
									
										
										
										
											1993-10-26 17:58:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	obj->start = start; | 
					
						
							|  |  |  | 	obj->len   = len; | 
					
						
							|  |  |  | 	obj->step  = step; | 
					
						
							| 
									
										
										
										
											1993-12-21 22:50:31 +00:00
										 |  |  | 	obj->reps  = reps; | 
					
						
							| 
									
										
										
										
											1993-10-26 17:58:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	return (PyObject *) obj; | 
					
						
							| 
									
										
										
										
											1993-10-26 17:58:25 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | range_dealloc(r) | 
					
						
							|  |  |  | 	rangeobject *r; | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	PyMem_DEL(r); | 
					
						
							| 
									
										
										
										
											1993-10-26 17:58:25 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											1993-10-26 17:58:25 +00:00
										 |  |  | range_item(r, i) | 
					
						
							|  |  |  | 	rangeobject *r; | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											1993-12-21 22:50:31 +00:00
										 |  |  | 	if (i < 0 || i >= r->len * r->reps) { | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 		PyErr_SetString(PyExc_IndexError, | 
					
						
							| 
									
										
										
										
											1999-01-09 21:40:35 +00:00
										 |  |  | 				"xrange object index out of range"); | 
					
						
							| 
									
										
										
										
											1993-10-26 17:58:25 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	return PyInt_FromLong(r->start + (i % r->len) * r->step); | 
					
						
							| 
									
										
										
										
											1993-10-26 17:58:25 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | range_length(r) | 
					
						
							|  |  |  | 	rangeobject *r; | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											1993-12-21 22:50:31 +00:00
										 |  |  | 	return r->len * r->reps; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | range_print(r, fp, flags) | 
					
						
							|  |  |  | 	rangeobject *r; | 
					
						
							|  |  |  | 	FILE *fp; | 
					
						
							|  |  |  | 	int flags; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int i, j; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fprintf(fp, "("); | 
					
						
							|  |  |  | 	for (i = 0; i < r->reps; ++i) | 
					
						
							|  |  |  | 		for (j = 0; j < r->len; ++j) { | 
					
						
							|  |  |  | 			if (j > 0 || i > 0) | 
					
						
							|  |  |  | 				fprintf(fp, ", "); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-05 21:58:58 +00:00
										 |  |  | 			fprintf(fp, "%ld", r->start + j * r->step); | 
					
						
							| 
									
										
										
										
											1993-12-21 22:50:31 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (r->len == 1 && r->reps == 1) | 
					
						
							|  |  |  | 		fprintf(fp, ","); | 
					
						
							|  |  |  | 	fprintf(fp, ")"); | 
					
						
							|  |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											1993-10-26 17:58:25 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											1993-10-26 17:58:25 +00:00
										 |  |  | range_repr(r) | 
					
						
							|  |  |  | 	rangeobject *r; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	char buf[80]; | 
					
						
							| 
									
										
										
										
											1994-09-28 15:51:32 +00:00
										 |  |  | 	sprintf(buf, "(xrange(%ld, %ld, %ld) * %d)", | 
					
						
							| 
									
										
										
										
											1993-12-21 22:50:31 +00:00
										 |  |  | 			r->start, | 
					
						
							|  |  |  | 			r->start + r->len * r->step, | 
					
						
							|  |  |  | 			r->step, | 
					
						
							|  |  |  | 			r->reps); | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	return PyString_FromString(buf); | 
					
						
							| 
									
										
										
										
											1993-10-26 17:58:25 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											1993-12-21 22:50:31 +00:00
										 |  |  | range_concat(r, obj) | 
					
						
							|  |  |  | 	rangeobject *r; | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	PyObject *obj; | 
					
						
							| 
									
										
										
										
											1993-12-21 22:50:31 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1999-01-09 21:40:35 +00:00
										 |  |  | 	PyErr_SetString(PyExc_TypeError, "cannot concatenate xrange objects"); | 
					
						
							| 
									
										
										
										
											1993-12-21 22:50:31 +00:00
										 |  |  | 	return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											1993-12-21 22:50:31 +00:00
										 |  |  | range_repeat(r, n) | 
					
						
							|  |  |  | 	rangeobject *r; | 
					
						
							|  |  |  | 	int n; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (n < 0) | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 		return (PyObject *) PyRange_New(0, 0, 1, 1); | 
					
						
							| 
									
										
										
										
											1993-12-21 22:50:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	else if (n == 1) { | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 		Py_INCREF(r); | 
					
						
							|  |  |  | 		return (PyObject *) r; | 
					
						
							| 
									
										
										
										
											1993-12-21 22:50:31 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	else | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 		return (PyObject *) PyRange_New( | 
					
						
							| 
									
										
										
										
											1993-12-21 22:50:31 +00:00
										 |  |  | 						r->start, | 
					
						
							|  |  |  | 						r->len, | 
					
						
							|  |  |  | 						r->step, | 
					
						
							|  |  |  | 						r->reps * n); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1993-10-26 17:58:25 +00:00
										 |  |  | static int | 
					
						
							|  |  |  | range_compare(r1, r2) | 
					
						
							|  |  |  | 	rangeobject *r1, *r2; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (r1->start != r2->start) | 
					
						
							|  |  |  | 		return r1->start - r2->start; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	else if (r1->step != r2->step) | 
					
						
							|  |  |  | 		return r1->step - r2->step; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	else if (r1->len != r2->len) | 
					
						
							|  |  |  | 		return r1->len - r2->len; | 
					
						
							| 
									
										
										
										
											1993-12-21 22:50:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		return r1->reps - r2->reps; | 
					
						
							| 
									
										
										
										
											1993-11-01 16:21:44 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											1993-10-26 17:58:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											1993-12-21 22:50:31 +00:00
										 |  |  | range_slice(r, low, high) | 
					
						
							| 
									
										
										
										
											1993-11-01 16:21:44 +00:00
										 |  |  | 	rangeobject *r; | 
					
						
							| 
									
										
										
										
											1993-12-21 22:50:31 +00:00
										 |  |  | 	int low, high; | 
					
						
							| 
									
										
										
										
											1993-11-01 16:21:44 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1993-12-21 22:50:31 +00:00
										 |  |  | 	if (r->reps != 1) { | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 		PyErr_SetString(PyExc_TypeError, | 
					
						
							| 
									
										
										
										
											1999-01-09 21:40:35 +00:00
										 |  |  | 				"cannot slice a replicated xrange"); | 
					
						
							| 
									
										
										
										
											1993-12-21 22:50:31 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (low < 0) | 
					
						
							|  |  |  | 		low = 0; | 
					
						
							|  |  |  | 	else if (low > r->len) | 
					
						
							|  |  |  | 		low = r->len; | 
					
						
							|  |  |  | 	if (high < 0) | 
					
						
							|  |  |  | 		high = 0; | 
					
						
							|  |  |  | 	if (high < low) | 
					
						
							|  |  |  | 		high = low; | 
					
						
							|  |  |  | 	else if (high > r->len) | 
					
						
							|  |  |  | 		high = r->len; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (low == 0 && high == r->len) { | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 		Py_INCREF(r); | 
					
						
							|  |  |  | 		return (PyObject *) r; | 
					
						
							| 
									
										
										
										
											1993-12-21 22:50:31 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	return (PyObject *) PyRange_New( | 
					
						
							| 
									
										
										
										
											1993-12-21 22:50:31 +00:00
										 |  |  | 				low * r->step + r->start, | 
					
						
							|  |  |  | 				high - low, | 
					
						
							|  |  |  | 				r->step, | 
					
						
							|  |  |  | 				1); | 
					
						
							| 
									
										
										
										
											1993-10-26 17:58:25 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											1993-12-21 22:50:31 +00:00
										 |  |  | range_tolist(self, args) | 
					
						
							|  |  |  | rangeobject *self; | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | PyObject *args; | 
					
						
							| 
									
										
										
										
											1993-10-26 17:58:25 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	PyObject *thelist; | 
					
						
							| 
									
										
										
										
											1993-12-21 22:50:31 +00:00
										 |  |  | 	int j; | 
					
						
							|  |  |  | 	int len = self->len * self->reps; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	if (! PyArg_Parse(args, "")) | 
					
						
							| 
									
										
										
										
											1993-12-21 22:50:31 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	if ((thelist = PyList_New(len)) == NULL) | 
					
						
							| 
									
										
										
										
											1993-12-21 22:50:31 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (j = 0; j < len; ++j) | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 		if ((PyList_SetItem(thelist, j, (PyObject *) PyInt_FromLong( | 
					
						
							|  |  |  | 			self->start + (j % self->len) * self->step))) < 0) | 
					
						
							| 
									
										
										
										
											1993-12-21 22:50:31 +00:00
										 |  |  | 			return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return thelist; | 
					
						
							| 
									
										
										
										
											1993-11-01 16:21:44 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											1993-12-21 22:50:31 +00:00
										 |  |  | range_getattr(r, name) | 
					
						
							| 
									
										
										
										
											1993-11-01 16:21:44 +00:00
										 |  |  | 	rangeobject *r; | 
					
						
							| 
									
										
										
										
											1993-12-21 22:50:31 +00:00
										 |  |  | 	char *name; | 
					
						
							| 
									
										
										
										
											1993-11-01 16:21:44 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	static PyMethodDef range_methods[] = { | 
					
						
							|  |  |  | 		{"tolist",	(PyCFunction)range_tolist}, | 
					
						
							| 
									
										
										
										
											1993-12-21 22:50:31 +00:00
										 |  |  | 		{NULL,		NULL} | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	return Py_FindMethod(range_methods, (PyObject *) r, name); | 
					
						
							| 
									
										
										
										
											1993-10-26 17:58:25 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | static PySequenceMethods range_as_sequence = { | 
					
						
							| 
									
										
										
										
											1994-09-28 15:51:32 +00:00
										 |  |  | 	(inquiry)range_length, /*sq_length*/ | 
					
						
							|  |  |  | 	(binaryfunc)range_concat, /*sq_concat*/ | 
					
						
							|  |  |  | 	(intargfunc)range_repeat, /*sq_repeat*/ | 
					
						
							|  |  |  | 	(intargfunc)range_item, /*sq_item*/ | 
					
						
							|  |  |  | 	(intintargfunc)range_slice, /*sq_slice*/ | 
					
						
							| 
									
										
										
										
											1993-10-26 17:58:25 +00:00
										 |  |  | 	0,		/*sq_ass_item*/ | 
					
						
							|  |  |  | 	0,		/*sq_ass_slice*/ | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | PyTypeObject PyRange_Type = { | 
					
						
							|  |  |  | 	PyObject_HEAD_INIT(&PyType_Type) | 
					
						
							| 
									
										
										
										
											1993-10-26 17:58:25 +00:00
										 |  |  | 	0,			/* Number of items for varobject */ | 
					
						
							| 
									
										
										
										
											1993-11-01 16:21:44 +00:00
										 |  |  | 	"xrange",		/* Name of this type */ | 
					
						
							| 
									
										
										
										
											1993-10-26 17:58:25 +00:00
										 |  |  | 	sizeof(rangeobject),	/* Basic object size */ | 
					
						
							|  |  |  | 	0,			/* Item size for varobject */ | 
					
						
							| 
									
										
										
										
											1994-09-28 15:51:32 +00:00
										 |  |  | 	(destructor)range_dealloc, /*tp_dealloc*/ | 
					
						
							|  |  |  | 	(printfunc)range_print, /*tp_print*/ | 
					
						
							|  |  |  | 	(getattrfunc)range_getattr, /*tp_getattr*/ | 
					
						
							| 
									
										
										
										
											1993-10-26 17:58:25 +00:00
										 |  |  | 	0,			/*tp_setattr*/ | 
					
						
							| 
									
										
										
										
											1994-09-28 15:51:32 +00:00
										 |  |  | 	(cmpfunc)range_compare, /*tp_compare*/ | 
					
						
							|  |  |  | 	(reprfunc)range_repr, /*tp_repr*/ | 
					
						
							| 
									
										
										
										
											1993-10-26 17:58:25 +00:00
										 |  |  | 	0,			/*tp_as_number*/ | 
					
						
							|  |  |  | 	&range_as_sequence,	/*tp_as_sequence*/ | 
					
						
							|  |  |  | 	0,			/*tp_as_mapping*/ | 
					
						
							|  |  |  | }; |