diff options
Diffstat (limited to 'Python/bltinmodule.c')
| -rw-r--r-- | Python/bltinmodule.c | 299 | 
1 files changed, 1 insertions, 298 deletions
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 093bb8114f..46fbf777f4 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -1593,302 +1593,6 @@ sep:  string inserted between values, default a space.\n\  end:  string appended after the last value, default a newline."); -/* Return number of items in range (lo, hi, step), when arguments are - * PyInt or PyLong objects.  step > 0 required.  Return a value < 0 if - * & only if the true value is too large to fit in a signed long. - * Arguments MUST return 1 with either PyInt_Check() or - * PyLong_Check().  Return -1 when there is an error. - */ -static long -get_len_of_range_longs(PyObject *lo, PyObject *hi, PyObject *step) -{ -	/* ------------------------------------------------------------- -	Algorithm is equal to that of get_len_of_range(), but it operates -	on PyObjects (which are assumed to be PyLong or PyInt objects). -	---------------------------------------------------------------*/ -	long n; -	PyObject *diff = NULL; -	PyObject *one = NULL; -	PyObject *tmp1 = NULL, *tmp2 = NULL, *tmp3 = NULL; -		/* holds sub-expression evaluations */ - -	/* If (lo >= hi), return length of 0 (or error). */ -	n = PyObject_RichCompareBool(lo, hi, Py_LT); -	if (n <= 0) -		return n; - -	if ((one = PyLong_FromLong(1L)) == NULL) -		goto Fail; - -	if ((tmp1 = PyNumber_Subtract(hi, lo)) == NULL) -		goto Fail; - -	if ((diff = PyNumber_Subtract(tmp1, one)) == NULL) -		goto Fail; - -	if ((tmp2 = PyNumber_FloorDivide(diff, step)) == NULL) -		goto Fail; - -	if ((tmp3 = PyNumber_Add(tmp2, one)) == NULL) -		goto Fail; - -	n = PyLong_AsLong(tmp3); -	if (PyErr_Occurred()) {  /* Check for Overflow */ -		PyErr_Clear(); -		goto Fail; -	} - -	Py_DECREF(tmp3); -	Py_DECREF(tmp2); -	Py_DECREF(diff); -	Py_DECREF(tmp1); -	Py_DECREF(one); -	return n; - -  Fail: -	Py_XDECREF(tmp3); -	Py_XDECREF(tmp2); -	Py_XDECREF(diff); -	Py_XDECREF(tmp1); -	Py_XDECREF(one); -	return -1; -} - -/* An extension of builtin_range() that handles the case when PyLong - * arguments are given. */ -static PyObject * -handle_range_longs(PyObject *self, PyObject *args) -{ -	PyObject *ilow; -	PyObject *ihigh = NULL; -	PyObject *istep = NULL; - -	PyObject *curnum = NULL; -	PyObject *v = NULL; -	long bign; -	int i, n; -	int step_pos; - -	PyObject *zero = PyLong_FromLong(0); - -	if (zero == NULL) -		return NULL; - -	if (!PyArg_UnpackTuple(args, "range", 1, 3, &ilow, &ihigh, &istep)) { -		Py_DECREF(zero); -		return NULL; -	} - -	/* Figure out which way we were called, supply defaults, and be -	 * sure to incref everything so that the decrefs at the end -	 * are correct. -	 */ -	assert(ilow != NULL); -	if (ihigh == NULL) { -		/* only 1 arg -- it's the upper limit */ -		ihigh = ilow; -		ilow = NULL; -	} -	assert(ihigh != NULL); -	Py_INCREF(ihigh); - -	/* ihigh correct now; do ilow */ -	if (ilow == NULL) -		ilow = zero; -	Py_INCREF(ilow); - -	/* ilow and ihigh correct now; do istep */ -	if (istep == NULL) { -		istep = PyLong_FromLong(1L); -		if (istep == NULL) -			goto Fail; -	} -	else { -		Py_INCREF(istep); -	} - -	if (!PyInt_Check(ilow) && !PyLong_Check(ilow)) { -		PyErr_Format(PyExc_TypeError, -			     "range() integer start argument expected, got %s.", -			     ilow->ob_type->tp_name); -		goto Fail; -	} - -	if (!PyInt_Check(ihigh) && !PyLong_Check(ihigh)) { -		PyErr_Format(PyExc_TypeError, -			     "range() integer end argument expected, got %s.", -			     ihigh->ob_type->tp_name); -		goto Fail; -	} - -	if (!PyInt_Check(istep) && !PyLong_Check(istep)) { -		PyErr_Format(PyExc_TypeError, -			     "range() integer step argument expected, got %s.", -			     istep->ob_type->tp_name); -		goto Fail; -	} - -	step_pos = PyObject_RichCompareBool(istep, zero, Py_GT); -	if (step_pos < 0) -		goto Fail; -	if (step_pos) -		bign = get_len_of_range_longs(ilow, ihigh, istep); -	else { -		int step_zero = PyObject_RichCompareBool(istep, zero, Py_EQ); -		PyObject *neg_istep; -		if (step_zero < 0) -			goto Fail; -		if (step_zero) { -			PyErr_SetString(PyExc_ValueError, -				"range() step argument must not be zero"); -			goto Fail; -		} -		neg_istep = PyNumber_Negative(istep); -		if (neg_istep == NULL) -			goto Fail; -		bign = get_len_of_range_longs(ihigh, ilow, neg_istep); -		Py_DECREF(neg_istep); -	} - -	n = (int)bign; -	if (bign < 0 || (long)n != bign) { -		PyErr_SetString(PyExc_OverflowError, -				"range() result has too many items"); -		goto Fail; -	} - -	v = PyList_New(n); -	if (v == NULL) -		goto Fail; - -	curnum = ilow; -	Py_INCREF(curnum); - -	for (i = 0; i < n; i++) { -		PyObject *w = PyNumber_Long(curnum); -		PyObject *tmp_num; -		if (w == NULL) -			goto Fail; - -		PyList_SET_ITEM(v, i, w); - -		tmp_num = PyNumber_Add(curnum, istep); -		if (tmp_num == NULL) -			goto Fail; - -		Py_DECREF(curnum); -		curnum = tmp_num; -	} -	Py_DECREF(ilow); -	Py_DECREF(ihigh); -	Py_DECREF(istep); -	Py_DECREF(zero); -	Py_DECREF(curnum); -	return v; - -  Fail: -	Py_DECREF(ilow); -	Py_DECREF(ihigh); -	Py_XDECREF(istep); -	Py_DECREF(zero); -	Py_XDECREF(curnum); -	Py_XDECREF(v); -	return NULL; -} - -/* Return number of items in range/xrange (lo, hi, step).  step > 0 - * required.  Return a value < 0 if & only if the true value is too - * large to fit in a signed long. - */ -static long -get_len_of_range(long lo, long hi, long step) -{ -	/* ------------------------------------------------------------- -	If lo >= hi, the range is empty. -	Else if n values are in the range, the last one is -	lo + (n-1)*step, which must be <= hi-1.  Rearranging, -	n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives -	the proper value.  Since lo < hi in this case, hi-lo-1 >= 0, so -	the RHS is non-negative and so truncation is the same as the -	floor.  Letting M be the largest positive long, the worst case -	for the RHS numerator is hi=M, lo=-M-1, and then -	hi-lo-1 = M-(-M-1)-1 = 2*M.  Therefore unsigned long has enough -	precision to compute the RHS exactly. -	---------------------------------------------------------------*/ -	long n = 0; -	if (lo < hi) { -		unsigned long uhi = (unsigned long)hi; -		unsigned long ulo = (unsigned long)lo; -		unsigned long diff = uhi - ulo - 1; -		n = (long)(diff / (unsigned long)step + 1); -	} -	return n; -} - -static PyObject * -builtin_range(PyObject *self, PyObject *args) -{ -	long ilow = 0, ihigh = 0, istep = 1; -	long bign; -	int i, n; - -	PyObject *v; - -	if (PyTuple_Size(args) <= 1) { -		if (!PyArg_ParseTuple(args, -				"l;range() requires 1-3 int arguments", -				&ihigh)) { -			PyErr_Clear(); -			return handle_range_longs(self, args); -		} -	} -	else { -		if (!PyArg_ParseTuple(args, -				"ll|l;range() requires 1-3 int arguments", -				&ilow, &ihigh, &istep)) { -			PyErr_Clear(); -			return handle_range_longs(self, args); -		} -	} -	if (istep == 0) { -		PyErr_SetString(PyExc_ValueError, -				"range() step argument must not be zero"); -		return NULL; -	} -	if (istep > 0) -		bign = get_len_of_range(ilow, ihigh, istep); -	else -		bign = get_len_of_range(ihigh, ilow, -istep); -	n = (int)bign; -	if (bign < 0 || (long)n != bign) { -		PyErr_SetString(PyExc_OverflowError, -				"range() result has too many items"); -		return NULL; -	} -	v = PyList_New(n); -	if (v == NULL) -		return NULL; -	for (i = 0; i < n; i++) { -		PyObject *w = PyInt_FromLong(ilow); -		if (w == NULL) { -			Py_DECREF(v); -			return NULL; -		} -		PyList_SET_ITEM(v, i, w); -		ilow += istep; -	} -	return v; -} - -PyDoc_STRVAR(range_doc, -"range([start,] stop[, step]) -> list of integers\n\ -\n\ -Return a list containing an arithmetic progression of integers.\n\ -range(i, j) returns [i, i+1, i+2, ..., j-1]; start (!) defaults to 0.\n\ -When step is given, it specifies the increment (or decrement).\n\ -For example, range(4) returns [0, 1, 2, 3].  The end point is omitted!\n\ -These are exactly the valid indices for a list of 4 elements."); -  static PyObject *  builtin_input(PyObject *self, PyObject *args)  { @@ -2277,7 +1981,6 @@ static PyMethodDef builtin_methods[] = {   	{"ord",		builtin_ord,        METH_O, ord_doc},   	{"pow",		builtin_pow,        METH_VARARGS, pow_doc},   	{"print",	(PyCFunction)builtin_print,      METH_VARARGS | METH_KEYWORDS, print_doc}, - 	{"range",	builtin_range,      METH_VARARGS, range_doc},   	{"reload",	builtin_reload,     METH_O, reload_doc},   	{"repr",	builtin_repr,       METH_O, repr_doc},   	{"round",	(PyCFunction)builtin_round,      METH_VARARGS | METH_KEYWORDS, round_doc}, @@ -2344,6 +2047,7 @@ _PyBuiltin_Init(void)  	SETBUILTIN("int",		&PyLong_Type);  	SETBUILTIN("list",		&PyList_Type);  	SETBUILTIN("object",		&PyBaseObject_Type); +	SETBUILTIN("range",		&PyRange_Type);  	SETBUILTIN("reversed",		&PyReversed_Type);  	SETBUILTIN("set",		&PySet_Type);  	SETBUILTIN("slice",		&PySlice_Type); @@ -2353,7 +2057,6 @@ _PyBuiltin_Init(void)  	SETBUILTIN("super",		&PySuper_Type);  	SETBUILTIN("tuple",		&PyTuple_Type);  	SETBUILTIN("type",		&PyType_Type); -	SETBUILTIN("xrange",		&PyRange_Type);  	SETBUILTIN("unicode",		&PyUnicode_Type);  	debug = PyBool_FromLong(Py_OptimizeFlag == 0);  	if (PyDict_SetItemString(dict, "__debug__", debug) < 0) {  | 
