⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 abstract.c

📁 python s60 1.4.5版本的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
				slotz = *NB_TERNOP(v->ob_type->tp_as_number,
						   op_slot);
				if (slotz)
					x = slotz(v, w, z);
				else
					c = -1;
			}
			else
				c = -1;
			goto error2;
		}
		v1 = v;
		z1 = z;
		c = PyNumber_Coerce(&v1, &z1);
		if (c != 0)
			goto error2;
		w2 = w;
		z2 = z1;
		c = PyNumber_Coerce(&w2, &z2);
		if (c != 0)
			goto error1;

		if (v1->ob_type->tp_as_number != NULL) {
			slotv = *NB_TERNOP(v1->ob_type->tp_as_number,
					   op_slot);
			if (slotv)
				x = slotv(v1, w2, z2);
			else
				c = -1;
		}
		else
			c = -1;

		Py_DECREF(w2);
		Py_DECREF(z2);
	error1:
		Py_DECREF(v1);
		Py_DECREF(z1);
	error2:
		Py_DECREF(v);
		Py_DECREF(w);
	error3:
		if (c >= 0)
			return x;
	}

	if (z == Py_None)
		PyErr_Format(
			PyExc_TypeError,
			"unsupported operand type(s) for ** or pow(): "
			"'%s' and '%s'",
			v->ob_type->tp_name,
			w->ob_type->tp_name);
	else
		PyErr_Format(
			PyExc_TypeError,
			"unsupported operand type(s) for pow(): "
			"'%s', '%s', '%s'",
			v->ob_type->tp_name,
			w->ob_type->tp_name,
			z->ob_type->tp_name);
	return NULL;
}

#define BINARY_FUNC(func, op, op_name) \
    DL_EXPORT(PyObject *) \
    func(PyObject *v, PyObject *w) { \
	    return binary_op(v, w, NB_SLOT(op), op_name); \
    }

BINARY_FUNC(PyNumber_Or, nb_or, "|")
BINARY_FUNC(PyNumber_Xor, nb_xor, "^")
BINARY_FUNC(PyNumber_And, nb_and, "&")
BINARY_FUNC(PyNumber_Lshift, nb_lshift, "<<")
BINARY_FUNC(PyNumber_Rshift, nb_rshift, ">>")
BINARY_FUNC(PyNumber_Subtract, nb_subtract, "-")
BINARY_FUNC(PyNumber_Multiply, nb_multiply, "*")
BINARY_FUNC(PyNumber_Divide, nb_divide, "/")
BINARY_FUNC(PyNumber_Divmod, nb_divmod, "divmod()")

DL_EXPORT(PyObject *)
PyNumber_Add(PyObject *v, PyObject *w)
{
	PyObject *result = binary_op1(v, w, NB_SLOT(nb_add));
	if (result == Py_NotImplemented) {
	  	// XXX:CW32
		PySequenceMethods *m = (PySequenceMethods *)v->ob_type->tp_as_sequence;
		if (m && m->sq_concat) {
			Py_DECREF(result);
			result = (*m->sq_concat)(v, w);
		}
		if (result == Py_NotImplemented) {
			Py_DECREF(result);
			PyErr_Format(
			    PyExc_TypeError,
			    "unsupported operand types for +: '%s' and '%s'",
			    v->ob_type->tp_name,
			    w->ob_type->tp_name);
			result = NULL;
                }
	}
	return result;
}

DL_EXPORT(PyObject *)
PyNumber_FloorDivide(PyObject *v, PyObject *w)
{
	/* XXX tp_flags test */
	return binary_op(v, w, NB_SLOT(nb_floor_divide), "//");
}

DL_EXPORT(PyObject *)
PyNumber_TrueDivide(PyObject *v, PyObject *w)
{
	/* XXX tp_flags test */
	return binary_op(v, w, NB_SLOT(nb_true_divide), "/");
}

DL_EXPORT(PyObject *)
PyNumber_Remainder(PyObject *v, PyObject *w)
{
	if (PyString_Check(v))
		return PyString_Format(v, w);
#ifdef Py_USING_UNICODE
	else if (PyUnicode_Check(v))
		return PyUnicode_Format(v, w);
#endif
	return binary_op(v, w, NB_SLOT(nb_remainder), "%");
}

DL_EXPORT(PyObject *)
PyNumber_Power(PyObject *v, PyObject *w, PyObject *z)
{
	return ternary_op(v, w, z, NB_SLOT(nb_power), "** or pow()");
}

/* Binary in-place operators */

/* The in-place operators are defined to fall back to the 'normal',
   non in-place operations, if the in-place methods are not in place.

   - If the left hand object has the appropriate struct members, and
     they are filled, call the appropriate function and return the
     result.  No coercion is done on the arguments; the left-hand object
     is the one the operation is performed on, and it's up to the
     function to deal with the right-hand object.
     
   - Otherwise, in-place modification is not supported. Handle it exactly as
     a non in-place operation of the same kind.

   */

#define HASINPLACE(t) PyType_HasFeature((t)->ob_type, Py_TPFLAGS_HAVE_INPLACEOPS)

static PyObject *
binary_iop(PyObject *v, PyObject *w, const int iop_slot, const int op_slot,
		const char *op_name)
{
  	// XXX:CW32
	PyNumberMethods *mv = (PyNumberMethods *)v->ob_type->tp_as_number;
	if (mv != NULL && HASINPLACE(v)) {
		binaryfunc *slot = NB_BINOP(mv, iop_slot);
		if (*slot) {
			PyObject *x = (*slot)(v, w);
			if (x != Py_NotImplemented) {
				return x;
			}
			Py_DECREF(x);
		}
	}
	return binary_op(v, w, op_slot, op_name);
}

#define INPLACE_BINOP(func, iop, op, op_name) \
	DL_EXPORT(PyObject *) \
	func(PyObject *v, PyObject *w) { \
		return binary_iop(v, w, NB_SLOT(iop), NB_SLOT(op), op_name); \
	}

INPLACE_BINOP(PyNumber_InPlaceOr, nb_inplace_or, nb_or, "|=")
INPLACE_BINOP(PyNumber_InPlaceXor, nb_inplace_xor, nb_xor, "^=")
INPLACE_BINOP(PyNumber_InPlaceAnd, nb_inplace_and, nb_and, "&=")
INPLACE_BINOP(PyNumber_InPlaceLshift, nb_inplace_lshift, nb_lshift, "<<=")
INPLACE_BINOP(PyNumber_InPlaceRshift, nb_inplace_rshift, nb_rshift, ">>=")
INPLACE_BINOP(PyNumber_InPlaceSubtract, nb_inplace_subtract, nb_subtract, "-=")
INPLACE_BINOP(PyNumber_InPlaceDivide, nb_inplace_divide, nb_divide, "/=")

DL_EXPORT(PyObject *)
PyNumber_InPlaceFloorDivide(PyObject *v, PyObject *w)
{
	/* XXX tp_flags test */
	return binary_iop(v, w, NB_SLOT(nb_inplace_floor_divide),
			  NB_SLOT(nb_floor_divide), "//=");
}

DL_EXPORT(PyObject *)
PyNumber_InPlaceTrueDivide(PyObject *v, PyObject *w)
{
	/* XXX tp_flags test */
	return binary_iop(v, w, NB_SLOT(nb_inplace_true_divide),
			  NB_SLOT(nb_true_divide), "/=");
}

DL_EXPORT(PyObject *)
PyNumber_InPlaceAdd(PyObject *v, PyObject *w)
{
	binaryfunc f = NULL;

	if (v->ob_type->tp_as_sequence != NULL) {
		if (HASINPLACE(v))
			f = v->ob_type->tp_as_sequence->sq_inplace_concat;
		if (f == NULL)
			f = v->ob_type->tp_as_sequence->sq_concat;
		if (f != NULL)
			return (*f)(v, w);
	}
	return binary_iop(v, w, NB_SLOT(nb_inplace_add), NB_SLOT(nb_add), "+=");
}

DL_EXPORT(PyObject *)
PyNumber_InPlaceMultiply(PyObject *v, PyObject *w)
{
	PyObject * (*g)(PyObject *, int) = NULL;
	if (HASINPLACE(v) &&
	    v->ob_type->tp_as_sequence &&
	    (g = v->ob_type->tp_as_sequence->sq_inplace_repeat) &&
	    !(v->ob_type->tp_as_number &&
	      v->ob_type->tp_as_number->nb_inplace_multiply))
	{
		long n;
		if (PyInt_Check(w)) {
			n  = PyInt_AsLong(w);
		}
		else if (PyLong_Check(w)) {
			n = PyLong_AsLong(w);
			if (n == -1 && PyErr_Occurred())
				return NULL;
		}
		else {
			return type_error("can't multiply sequence to non-int");
		}
		return (*g)(v, (int)n);
	}
	return binary_iop(v, w, NB_SLOT(nb_inplace_multiply),
				NB_SLOT(nb_multiply), "*=");
}



DL_EXPORT(PyObject *)
PyNumber_InPlaceRemainder(PyObject *v, PyObject *w)
{
	if (PyString_Check(v))
		return PyString_Format(v, w);
#ifdef Py_USING_UNICODE
	else if (PyUnicode_Check(v))
		return PyUnicode_Format(v, w);
#endif
	else
		return binary_iop(v, w, NB_SLOT(nb_inplace_remainder),
					NB_SLOT(nb_remainder), "%=");
}


DL_EXPORT(PyObject *)
PyNumber_InPlacePower(PyObject *v, PyObject *w, PyObject *z)
{
	if (HASINPLACE(v) && v->ob_type->tp_as_number &&
	    v->ob_type->tp_as_number->nb_inplace_power != NULL) {
		return ternary_op(v, w, z, NB_SLOT(nb_inplace_power), "**=");
	}
	else {
		return ternary_op(v, w, z, NB_SLOT(nb_power), "**=");
	}
}


/* Unary operators and functions */

DL_EXPORT(PyObject *)
PyNumber_Negative(PyObject *o)
{
	PyNumberMethods *m;

	if (o == NULL)
		return null_error();
	// XXX:CW32
	m = (PyNumberMethods *)o->ob_type->tp_as_number;
	if (m && m->nb_negative)
		return (*m->nb_negative)(o);

	return type_error("bad operand type for unary -");
}

DL_EXPORT(PyObject *)
PyNumber_Positive(PyObject *o)
{
	PyNumberMethods *m;

	if (o == NULL)
		return null_error();
	// XXX:CW32
	m = (PyNumberMethods *)o->ob_type->tp_as_number;
	if (m && m->nb_positive)
		return (*m->nb_positive)(o);

	return type_error("bad operand type for unary +");
}

DL_EXPORT(PyObject *)
PyNumber_Invert(PyObject *o)
{
	PyNumberMethods *m;

	if (o == NULL)
		return null_error();
	// XXX:CW32
	m = (PyNumberMethods *)o->ob_type->tp_as_number;
	if (m && m->nb_invert)
		return (*m->nb_invert)(o);

	return type_error("bad operand type for unary ~");
}

DL_EXPORT(PyObject *)
PyNumber_Absolute(PyObject *o)
{
	PyNumberMethods *m;

	if (o == NULL)
		return null_error();
	// XXX:CW32
	m = (PyNumberMethods *)o->ob_type->tp_as_number;
	if (m && m->nb_absolute)
		return m->nb_absolute(o);

	return type_error("bad operand type for abs()");
}

/* Add a check for embedded NULL-bytes in the argument. */
static PyObject *
int_from_string(const char *s, int len)
{
	char *end;
	PyObject *x;

	x = PyInt_FromString((char*)s, &end, 10);
	if (x == NULL)
		return NULL;
	if (end != s + len) {
		PyErr_SetString(PyExc_ValueError,
				"null byte in argument for int()");
		Py_DECREF(x);
		return NULL;
	}
	return x;
}

DL_EXPORT(PyObject *)
PyNumber_Int(PyObject *o)
{
	PyNumberMethods *m;
	const char *buffer;
	int buffer_len;

	if (o == NULL)
		return null_error();
	if (PyInt_CheckExact(o)) {
		Py_INCREF(o);
		return o;
	}
	if (PyInt_Check(o)) {
		PyIntObject *io = (PyIntObject*)o;
		return PyInt_FromLong(io->ob_ival);
	}
	if (PyString_Check(o))
		return int_from_string(PyString_AS_STRING(o), 
				       PyString_GET_SIZE(o));
#ifdef Py_USING_UNICODE
	if (PyUnicode_Check(o))
		return PyInt_FromUnicode(PyUnicode_AS_UNICODE(o),
					 PyUnicode_GET_SIZE(o),
					 10);
#endif
  	// XXX:CW32
	m = (PyNumberMethods *)o->ob_type->tp_as_number;
	if (m && m->nb_int)
		return m->nb_int(o);
	if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len))
		return int_from_string((char*)buffer, buffer_len);

	return type_error("int() argument must be a string or a number");
}

/* Add a check for embedded NULL-bytes in the argument. */
static PyObject *
long_from_string(const char *s, int len)
{
	char *end;
	PyObject *x;

	x = PyLong_FromString((char*)s, &end, 10);
	if (x == NULL)
		return NULL;
	if (end != s + len) {
		PyErr_SetString(PyExc_ValueError,
				"null byte in argument for long()");
		Py_DECREF(x);
		return NULL;
	}
	return x;
}

DL_EXPORT(PyObject *)
PyNumber_Long(PyObject *o)
{
	PyNumberMethods *m;
	const char *buffer;
	int buffer_len;

	if (o == NULL)
		return null_error();
	if (PyLong_CheckExact(o)) {
		Py_INCREF(o);
		return o;
	}
	if (PyLong_Check(o))
		return _PyLong_Copy((PyLongObject *)o);
	if (PyString_Check(o))
		/* need to do extra error checking that PyLong_FromString() 
		 * doesn't do.  In particular long('9.5') must raise an
		 * exception, not truncate the float.
		 */
		return long_from_string(PyString_AS_STRING(o),
					PyString_GET_SIZE(o));
#ifdef Py_USING_UNICODE
	if (PyUnicode_Check(o))
		/* The above check is done in PyLong_FromUnicode(). */
		return PyLong_FromUnicode(PyUnicode_AS_UNICODE(o),
					  PyUnicode_GET_SIZE(o),
					  10);
#endif
  	// XXX:CW32
	m = (PyNumberMethods *)o->ob_type->tp_as_number;
	if (m && m->nb_long)
		return m->nb_long(o);
	if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len))
		return long_from_string(buffer, buffer_len);

	return type_error("long() argument must be a string or a number");
}

DL_EXPORT(PyObject *)
PyNumber_Float(PyObject *o)
{
	PyNumberMethods *m;

	if (o == NULL)
		return null_error();
	if (PyFloat_CheckExact(o)) {
		Py_INCREF(o);
		return o;
	}
	if (PyFloat_Check(o)) {
		PyFloatObject *po = (PyFloatObject *)o;
		return PyFloat_FromDouble(po->ob_fval);
	}
	if (!PyString_Check(o)) {
	  	// XXX:CW32
		m = (PyNumberMethods *)o->ob_type->tp_as_number;
		if (m && m->nb_float)
			return m->nb_float(o);
	}
	return PyFloat_FromString(o, NULL);
}

/* Operations on sequences */

DL_EXPORT(int)
PySequence_Check(PyObject *s)
{
	return s != NULL && s->ob_type->tp_as_sequence &&
		s->ob_type->tp_as_sequence->sq_item != NULL;
}

DL_EXPORT(int)
PySequence_Size(PyObject *s)
{
	PySequenceMethods *m;

	if (s == NULL) {
		null_error();
		return -1;
	}

  	// XXX:CW32
	m = (PySequenceMethods *)s->ob_type->tp_as_sequence;
	if (m && m->sq_length)
		return m->sq_length(s);

	type_error("len() of unsized object");
	return -1;
}

#undef PySequence_Length
DL_EXPORT(int)
PySequence_Length(PyObject *s)
{
	return PySequence_Size(s);
}
#define PySequence_Length PySequence_Size

DL_EXPORT(PyObject *)
PySequence_Concat(PyObject *s, PyObject *o)
{
	PySequenceMethods *m;

	if (s == NULL || o == NULL)
		return null_error();
	
  	// XXX:CW32
	m = (PySequenceMethods *)s->ob_type->tp_as_sequence;
	if (m && m->sq_concat)
		return m->sq_concat(s, o);

	return type_error("object can't be concatenated");
}

DL_EXPORT(PyObject *)
PySequence_Repeat(PyObject *o, int count)
{
	PySequenceMethods *m;

	if (o == NULL)
		return null_error();
	
  	// XXX:CW32
	m = (PySequenceMethods *)o->ob_type->tp_as_sequence;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -