| /*********************************************************** |
| Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam, |
| The Netherlands. |
| |
| All Rights Reserved |
| |
| Permission to use, copy, modify, and distribute this software and its |
| documentation for any purpose and without fee is hereby granted, |
| provided that the above copyright notice appear in all copies and that |
| both that copyright notice and this permission notice appear in |
| supporting documentation, and that the names of Stichting Mathematisch |
| 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. |
| |
| 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. |
| |
| ******************************************************************/ |
| |
| /* Abstract Object Interface (many thanks to Jim Fulton) */ |
| |
| #include "Python.h" |
| |
| #define Py_TRY(E) if(!(E)) return NULL |
| #define Py_ASSERT(EXP,E,V) if(!(EXP)) return PyErr_SetString(E,V), (void*)NULL |
| #define SPAM printf("line %d\n",__LINE__) |
| |
| static PyObject * |
| Py_ReturnMethodError(name) |
| char *name; |
| { |
| if(! name) name = "Unknown Error"; |
| PyErr_SetString(PyExc_AttributeError,name); |
| return 0; |
| } |
| |
| static PyObject * |
| Py_ReturnNullError() |
| { |
| if(! PyErr_Occurred()) |
| PyErr_SetString(PyExc_SystemError, |
| "null argument to internal routine"); |
| return 0; |
| } |
| |
| int |
| PyObject_Cmp(o1, o2, result) |
| PyObject *o1; |
| PyObject *o2; |
| int *result; |
| { |
| int r; |
| |
| if(! o1 || ! o2) return Py_ReturnNullError(),-1; |
| r=PyObject_Compare(o1,o2); |
| if(PyErr_Occurred()) return -1; |
| *result=r; |
| return 0; |
| } |
| |
| #if 0 /* Already in object.c */ |
| int |
| PyCallable_Check(x) |
| PyObject *x; |
| { |
| if (x == NULL) |
| return 0; |
| if (x->ob_type->tp_call != NULL || |
| PyFunction_Check(x) || |
| PyMethod_Check(x) || |
| PyCFunction_Check(x) || |
| PyClass_Check(x)) |
| return 1; |
| if (PyInstance_Check(x)) { |
| PyObject *call = PyObject_GetAttrString(x, "__call__"); |
| if (call == NULL) { |
| PyErr_Clear(); |
| return 0; |
| } |
| /* Could test recursively but don't, for fear of endless |
| recursion if some joker sets self.__call__ = self */ |
| Py_DECREF(call); |
| return 1; |
| } |
| return 0; |
| } |
| #endif |
| |
| PyObject * |
| PyObject_Type(o) |
| PyObject *o; |
| { |
| PyObject *v; |
| |
| if(! o) return Py_ReturnNullError(); |
| v = (PyObject *)o->ob_type; |
| Py_INCREF(v); |
| return v; |
| } |
| |
| int |
| PyObject_Length(o) |
| PyObject *o; |
| { |
| PySequenceMethods *m; |
| |
| if(! o) return Py_ReturnNullError(),-1; |
| |
| if((m=o->ob_type->tp_as_sequence) && m->sq_length) |
| return m->sq_length(o); |
| |
| return PyMapping_Length(o); |
| } |
| |
| PyObject * |
| PyObject_GetItem(o, key) |
| PyObject *o; |
| PyObject *key; |
| { |
| PyMappingMethods *m; |
| |
| if(! o || ! key) return Py_ReturnNullError(); |
| |
| if((m=o->ob_type->tp_as_mapping) && m->mp_subscript) |
| return m->mp_subscript(o,key); |
| |
| if(PyInt_Check(key)) |
| return PySequence_GetItem(o,PyInt_AsLong(key)); |
| |
| PyErr_SetString(PyExc_TypeError,"expected integer index"); |
| return NULL; |
| } |
| |
| int |
| PyObject_SetItem(o, key, value) |
| PyObject *o; |
| PyObject *key; |
| PyObject *value; |
| { |
| PyMappingMethods *m; |
| |
| if(! o || ! key || ! value) return Py_ReturnNullError(),-1; |
| if((m=o->ob_type->tp_as_mapping) && m->mp_ass_subscript) |
| return m->mp_ass_subscript(o,key,value); |
| |
| if(PyInt_Check(key)) |
| return PySequence_SetItem(o,PyInt_AsLong(key),value); |
| |
| PyErr_SetString(PyExc_TypeError,"expected integer index"); |
| return -1; |
| } |
| |
| int |
| PyObject_DelItem(o, key) |
| PyObject *o; |
| PyObject *key; |
| { |
| PyMappingMethods *m; |
| |
| if(! o || ! key) return Py_ReturnNullError(),-1; |
| if((m=o->ob_type->tp_as_mapping) && m->mp_ass_subscript) |
| return m->mp_ass_subscript(o,key,(PyObject*)NULL); |
| |
| if(PyInt_Check(key)) |
| return PySequence_SetItem(o,PyInt_AsLong(key),(PyObject*)NULL); |
| |
| PyErr_SetString(PyExc_TypeError,"expected integer index"); |
| return -1; |
| } |
| |
| int |
| PyNumber_Check(o) |
| PyObject *o; |
| { |
| return o && o->ob_type->tp_as_number; |
| } |
| |
| |
| #define BINOP(opname, ropname, thisfunc) \ |
| if (!PyInstance_Check(v) && !PyInstance_Check(w)) \ |
| ; \ |
| else \ |
| return PyInstance_DoBinOp(v, w, opname, ropname, thisfunc) |
| |
| PyObject * |
| PyNumber_Or(v, w) |
| PyObject *v, *w; |
| { |
| extern int PyNumber_Coerce(); |
| |
| BINOP("__or__", "__ror__", PyNumber_Or); |
| if (v->ob_type->tp_as_number != NULL) { |
| PyObject *x = NULL; |
| PyObject * (*f) Py_FPROTO((PyObject *, PyObject *)); |
| if (PyNumber_Coerce(&v, &w) != 0) |
| return NULL; |
| if ((f = v->ob_type->tp_as_number->nb_or) != NULL) |
| x = (*f)(v, w); |
| Py_DECREF(v); |
| Py_DECREF(w); |
| if (f != NULL) |
| return x; |
| } |
| PyErr_SetString(PyExc_TypeError, "bad operand type(s) for |"); |
| return NULL; |
| } |
| |
| PyObject * |
| PyNumber_Xor(v, w) |
| PyObject *v, *w; |
| { |
| extern int PyNumber_Coerce(); |
| |
| BINOP("__xor__", "__rxor__", PyNumber_Xor); |
| if (v->ob_type->tp_as_number != NULL) { |
| PyObject *x = NULL; |
| PyObject * (*f) Py_FPROTO((PyObject *, PyObject *)); |
| if (PyNumber_Coerce(&v, &w) != 0) |
| return NULL; |
| if ((f = v->ob_type->tp_as_number->nb_xor) != NULL) |
| x = (*f)(v, w); |
| Py_DECREF(v); |
| Py_DECREF(w); |
| if (f != NULL) |
| return x; |
| } |
| PyErr_SetString(PyExc_TypeError, "bad operand type(s) for ^"); |
| return NULL; |
| } |
| |
| PyObject * |
| PyNumber_And(v, w) |
| PyObject *v, *w; |
| { |
| BINOP("__and__", "__rand__", PyNumber_And); |
| if (v->ob_type->tp_as_number != NULL) { |
| PyObject *x = NULL; |
| PyObject * (*f) Py_FPROTO((PyObject *, PyObject *)); |
| if (PyNumber_Coerce(&v, &w) != 0) |
| return NULL; |
| if ((f = v->ob_type->tp_as_number->nb_and) != NULL) |
| x = (*f)(v, w); |
| Py_DECREF(v); |
| Py_DECREF(w); |
| if (f != NULL) |
| return x; |
| } |
| PyErr_SetString(PyExc_TypeError, "bad operand type(s) for &"); |
| return NULL; |
| } |
| |
| PyObject * |
| PyNumber_Lshift(v, w) |
| PyObject *v, *w; |
| { |
| BINOP("__lshift__", "__rlshift__", PyNumber_Lshift); |
| if (v->ob_type->tp_as_number != NULL) { |
| PyObject *x = NULL; |
| PyObject * (*f) Py_FPROTO((PyObject *, PyObject *)); |
| if (PyNumber_Coerce(&v, &w) != 0) |
| return NULL; |
| if ((f = v->ob_type->tp_as_number->nb_lshift) != NULL) |
| x = (*f)(v, w); |
| Py_DECREF(v); |
| Py_DECREF(w); |
| if (f != NULL) |
| return x; |
| } |
| PyErr_SetString(PyExc_TypeError, "bad operand type(s) for <<"); |
| return NULL; |
| } |
| |
| PyObject * |
| PyNumber_Rshift(v, w) |
| PyObject *v, *w; |
| { |
| BINOP("__rshift__", "__rrshift__", PyNumber_Rshift); |
| if (v->ob_type->tp_as_number != NULL) { |
| PyObject *x = NULL; |
| PyObject * (*f) Py_FPROTO((PyObject *, PyObject *)); |
| if (PyNumber_Coerce(&v, &w) != 0) |
| return NULL; |
| if ((f = v->ob_type->tp_as_number->nb_rshift) != NULL) |
| x = (*f)(v, w); |
| Py_DECREF(v); |
| Py_DECREF(w); |
| if (f != NULL) |
| return x; |
| } |
| PyErr_SetString(PyExc_TypeError, "bad operand type(s) for >>"); |
| return NULL; |
| } |
| |
| PyObject * |
| PyNumber_Add(v, w) |
| PyObject *v, *w; |
| { |
| BINOP("__add__", "__radd__", PyNumber_Add); |
| if (v->ob_type->tp_as_sequence != NULL) |
| return (*v->ob_type->tp_as_sequence->sq_concat)(v, w); |
| else if (v->ob_type->tp_as_number != NULL) { |
| PyObject *x; |
| if (PyNumber_Coerce(&v, &w) != 0) |
| return NULL; |
| x = (*v->ob_type->tp_as_number->nb_add)(v, w); |
| Py_DECREF(v); |
| Py_DECREF(w); |
| return x; |
| } |
| PyErr_SetString(PyExc_TypeError, "bad operand type(s) for +"); |
| return NULL; |
| } |
| |
| PyObject * |
| PyNumber_Subtract(v, w) |
| PyObject *v, *w; |
| { |
| BINOP("__sub__", "__rsub__", PyNumber_Subtract); |
| if (v->ob_type->tp_as_number != NULL) { |
| PyObject *x; |
| if (PyNumber_Coerce(&v, &w) != 0) |
| return NULL; |
| x = (*v->ob_type->tp_as_number->nb_subtract)(v, w); |
| Py_DECREF(v); |
| Py_DECREF(w); |
| return x; |
| } |
| PyErr_SetString(PyExc_TypeError, "bad operand type(s) for -"); |
| return NULL; |
| } |
| |
| PyObject * |
| PyNumber_Multiply(v, w) |
| PyObject *v, *w; |
| { |
| PyTypeObject *tp; |
| tp = v->ob_type; |
| BINOP("__mul__", "__rmul__", PyNumber_Multiply); |
| if (tp->tp_as_number != NULL && |
| w->ob_type->tp_as_sequence != NULL && |
| !PyInstance_Check(v)) { |
| /* number*sequence -- swap v and w */ |
| PyObject *tmp = v; |
| v = w; |
| w = tmp; |
| tp = v->ob_type; |
| } |
| if (tp->tp_as_number != NULL) { |
| PyObject *x; |
| if (PyInstance_Check(v)) { |
| /* Instances of user-defined classes get their |
| other argument uncoerced, so they may |
| implement sequence*number as well as |
| number*number. */ |
| Py_INCREF(v); |
| Py_INCREF(w); |
| } |
| else if (PyNumber_Coerce(&v, &w) != 0) |
| return NULL; |
| x = (*v->ob_type->tp_as_number->nb_multiply)(v, w); |
| Py_DECREF(v); |
| Py_DECREF(w); |
| return x; |
| } |
| if (tp->tp_as_sequence != NULL) { |
| if (!PyInt_Check(w)) { |
| PyErr_SetString(PyExc_TypeError, |
| "can't multiply sequence with non-int"); |
| return NULL; |
| } |
| return (*tp->tp_as_sequence->sq_repeat) |
| (v, (int)PyInt_AsLong(w)); |
| } |
| PyErr_SetString(PyExc_TypeError, "bad operand type(s) for *"); |
| return NULL; |
| } |
| |
| PyObject * |
| PyNumber_Divide(v, w) |
| PyObject *v, *w; |
| { |
| BINOP("__div__", "__rdiv__", PyNumber_Divide); |
| if (v->ob_type->tp_as_number != NULL) { |
| PyObject *x; |
| if (PyNumber_Coerce(&v, &w) != 0) |
| return NULL; |
| x = (*v->ob_type->tp_as_number->nb_divide)(v, w); |
| Py_DECREF(v); |
| Py_DECREF(w); |
| return x; |
| } |
| PyErr_SetString(PyExc_TypeError, "bad operand type(s) for /"); |
| return NULL; |
| } |
| |
| PyObject * |
| PyNumber_Remainder(v, w) |
| PyObject *v, *w; |
| { |
| if (PyString_Check(v)) { |
| return PyString_Format(v, w); |
| } |
| BINOP("__mod__", "__rmod__", PyNumber_Remainder); |
| if (v->ob_type->tp_as_number != NULL) { |
| PyObject *x; |
| if (PyNumber_Coerce(&v, &w) != 0) |
| return NULL; |
| x = (*v->ob_type->tp_as_number->nb_remainder)(v, w); |
| Py_DECREF(v); |
| Py_DECREF(w); |
| return x; |
| } |
| PyErr_SetString(PyExc_TypeError, "bad operand type(s) for %"); |
| return NULL; |
| } |
| |
| PyObject * |
| PyNumber_Divmod(v, w) |
| PyObject *v, *w; |
| { |
| PyObject *res; |
| |
| if (PyInstance_Check(v) || PyInstance_Check(w)) |
| return PyInstance_DoBinOp(v, w, "__divmod__", "__rdivmod__", |
| PyNumber_Divmod); |
| if (v->ob_type->tp_as_number == NULL || |
| w->ob_type->tp_as_number == NULL) { |
| PyErr_SetString(PyExc_TypeError, |
| "divmod() requires numeric or class instance arguments"); |
| return NULL; |
| } |
| if (PyNumber_Coerce(&v, &w) != 0) |
| return NULL; |
| res = (*v->ob_type->tp_as_number->nb_divmod)(v, w); |
| Py_DECREF(v); |
| Py_DECREF(w); |
| return res; |
| } |
| |
| |
| static PyObject * |
| do_pow(v, w) |
| PyObject *v, *w; |
| { |
| PyObject *res; |
| if (PyInstance_Check(v) || PyInstance_Check(w)) |
| return PyInstance_DoBinOp(v, w, "__pow__", "__rpow__", do_pow); |
| if (v->ob_type->tp_as_number == NULL || |
| w->ob_type->tp_as_number == NULL) { |
| PyErr_SetString(PyExc_TypeError, |
| "pow() requires numeric arguments"); |
| return NULL; |
| } |
| if (PyFloat_Check(v) && PyFloat_Check(w) && |
| PyFloat_AsDouble(v) < 0.0) { |
| if (!PyErr_Occurred()) |
| PyErr_SetString(PyExc_ValueError, |
| "negative number to float power"); |
| return NULL; |
| } |
| if (PyNumber_Coerce(&v, &w) != 0) |
| return NULL; |
| res = (*v->ob_type->tp_as_number->nb_power)(v, w, Py_None); |
| Py_DECREF(v); |
| Py_DECREF(w); |
| return res; |
| } |
| |
| PyObject * |
| PyNumber_Power(v,w,z) |
| PyObject *v, *w, *z; |
| { |
| PyObject *res; |
| PyObject *v1, *z1, *w2, *z2; |
| |
| if (z == Py_None) |
| return do_pow(v, w); |
| /* XXX The ternary version doesn't do class instance coercions */ |
| if (PyInstance_Check(v)) |
| return v->ob_type->tp_as_number->nb_power(v, w, z); |
| if (v->ob_type->tp_as_number == NULL || |
| z->ob_type->tp_as_number == NULL || |
| w->ob_type->tp_as_number == NULL) { |
| PyErr_SetString(PyExc_TypeError, "pow() requires numeric arguments"); |
| return NULL; |
| } |
| if (PyNumber_Coerce(&v, &w) != 0) |
| return NULL; |
| res = NULL; |
| v1 = v; |
| z1 = z; |
| if (PyNumber_Coerce(&v1, &z1) != 0) |
| goto error2; |
| w2 = w; |
| z2 = z1; |
| if (PyNumber_Coerce(&w2, &z2) != 0) |
| goto error1; |
| res = (*v1->ob_type->tp_as_number->nb_power)(v1, w2, z2); |
| Py_DECREF(w2); |
| Py_DECREF(z2); |
| error1: |
| Py_DECREF(v1); |
| Py_DECREF(z1); |
| error2: |
| Py_DECREF(v); |
| Py_DECREF(w); |
| return res; |
| } |
| |
| |
| PyObject * |
| PyNumber_Negative(v) |
| PyObject *v; |
| { |
| if (v->ob_type->tp_as_number != NULL) |
| return (*v->ob_type->tp_as_number->nb_negative)(v); |
| PyErr_SetString(PyExc_TypeError, "bad operand type(s) for unary -"); |
| return NULL; |
| } |
| |
| PyObject * |
| PyNumber_Positive(v) |
| PyObject *v; |
| { |
| if (v->ob_type->tp_as_number != NULL) |
| return (*v->ob_type->tp_as_number->nb_positive)(v); |
| PyErr_SetString(PyExc_TypeError, "bad operand type(s) for unary +"); |
| return NULL; |
| } |
| |
| PyObject * |
| PyNumber_Invert(v) |
| PyObject *v; |
| { |
| PyObject * (*f) Py_FPROTO((PyObject *)); |
| if (v->ob_type->tp_as_number != NULL && |
| (f = v->ob_type->tp_as_number->nb_invert) != NULL) |
| return (*f)(v); |
| PyErr_SetString(PyExc_TypeError, "bad operand type(s) for unary ~"); |
| return NULL; |
| } |
| |
| PyObject * |
| PyNumber_Absolute(o) |
| PyObject *o; |
| { |
| PyNumberMethods *m; |
| |
| if(! o) return Py_ReturnNullError(); |
| if((m=o->ob_type->tp_as_number) && m->nb_absolute) |
| return m->nb_absolute(o); |
| |
| return Py_ReturnMethodError("__abs__"); |
| } |
| |
| PyObject * |
| PyNumber_Int(o) |
| PyObject *o; |
| { |
| PyNumberMethods *m; |
| |
| if(! o) return Py_ReturnNullError(); |
| if((m=o->ob_type->tp_as_number) && m->nb_int) |
| return m->nb_int(o); |
| |
| return Py_ReturnMethodError("__int__"); |
| } |
| |
| PyObject * |
| PyNumber_Long(o) |
| PyObject *o; |
| { |
| PyNumberMethods *m; |
| |
| if(! o) return Py_ReturnNullError(); |
| if((m=o->ob_type->tp_as_number) && m->nb_long) |
| return m->nb_long(o); |
| |
| return Py_ReturnMethodError("__long__"); |
| } |
| |
| PyObject * |
| PyNumber_Float(o) |
| PyObject *o; |
| { |
| PyNumberMethods *m; |
| |
| if(! o) return Py_ReturnNullError(); |
| if((m=o->ob_type->tp_as_number) && m->nb_float) |
| return m->nb_float(o); |
| |
| return Py_ReturnMethodError("__float__"); |
| } |
| |
| |
| int |
| PySequence_Check(o) |
| PyObject *o; |
| { |
| return o && o->ob_type->tp_as_sequence; |
| } |
| |
| int |
| PySequence_Length(s) |
| PyObject *s; |
| { |
| PySequenceMethods *m; |
| |
| if(! s) return Py_ReturnNullError(),-1; |
| |
| if((m=s->ob_type->tp_as_sequence) && m->sq_length) |
| return m->sq_length(s); |
| |
| Py_ReturnMethodError("__len__"); |
| return -1; |
| } |
| |
| PyObject * |
| PySequence_Concat(s, o) |
| PyObject *s; |
| PyObject *o; |
| { |
| PySequenceMethods *m; |
| |
| if(! s || ! o) return Py_ReturnNullError(); |
| |
| if((m=s->ob_type->tp_as_sequence) && m->sq_concat) |
| return m->sq_concat(s,o); |
| |
| return Py_ReturnMethodError("__concat__"); |
| } |
| |
| PyObject * |
| PySequence_Repeat(o, count) |
| PyObject *o; |
| int count; |
| { |
| PySequenceMethods *m; |
| |
| if(! o) return Py_ReturnNullError(); |
| |
| if((m=o->ob_type->tp_as_sequence) && m->sq_repeat) |
| return m->sq_repeat(o,count); |
| |
| return Py_ReturnMethodError("__repeat__"); |
| } |
| |
| PyObject * |
| PySequence_GetItem(s, i) |
| PyObject *s; |
| int i; |
| { |
| PySequenceMethods *m; |
| int l; |
| |
| if(! s) return Py_ReturnNullError(); |
| |
| if(! ((m=s->ob_type->tp_as_sequence) && m->sq_item)) |
| return Py_ReturnMethodError("__getitem__"); |
| |
| if(i < 0) |
| { |
| if(! m->sq_length || 0 > (l=m->sq_length(s))) return NULL; |
| i += l; |
| } |
| |
| return m->sq_item(s,i); |
| } |
| |
| PyObject * |
| PySequence_GetSlice(s, i1, i2) |
| PyObject *s; |
| int i1; |
| int i2; |
| { |
| PySequenceMethods *m; |
| int l; |
| |
| if(! s) return Py_ReturnNullError(); |
| |
| if(! ((m=s->ob_type->tp_as_sequence) && m->sq_slice)) |
| return Py_ReturnMethodError("__getslice__"); |
| |
| if(i1 < 0 || i2 < 0) |
| { |
| |
| if(! m->sq_length || 0 > (l=m->sq_length(s))) return NULL; |
| |
| if(i1 < 0) i1 += l; |
| if(i2 < 0) i2 += l; |
| } |
| |
| return m->sq_slice(s,i1,i2); |
| } |
| |
| int |
| PySequence_SetItem(s, i, o) |
| PyObject *s; |
| int i; |
| PyObject *o; |
| { |
| PySequenceMethods *m; |
| int l; |
| if(! s) return Py_ReturnNullError(),-1; |
| |
| if(! ((m=s->ob_type->tp_as_sequence) && m->sq_length && m->sq_ass_item)) |
| return Py_ReturnMethodError("__setitem__"),-1; |
| |
| if(i < 0) |
| { |
| if(0 > (l=m->sq_length(s))) return -1; |
| i += l; |
| } |
| |
| return m->sq_ass_item(s,i,o); |
| } |
| |
| int |
| PySequence_DelItem(s, i) |
| PyObject *s; |
| int i; |
| { |
| PySequenceMethods *m; |
| int l; |
| if(! s) return Py_ReturnNullError(),-1; |
| |
| if(! ((m=s->ob_type->tp_as_sequence) && m->sq_length && m->sq_ass_item)) |
| return Py_ReturnMethodError("__delitem__"),-1; |
| |
| if(i < 0) |
| { |
| if(0 > (l=m->sq_length(s))) return -1; |
| i += l; |
| } |
| |
| return m->sq_ass_item(s,i,(PyObject*)NULL); |
| } |
| |
| int |
| PySequence_SetSlice(s, i1, i2, o) |
| PyObject *s; |
| int i1; |
| int i2; |
| PyObject *o; |
| { |
| PySequenceMethods *m; |
| int l; |
| |
| if(! s) return Py_ReturnNullError(),-1; |
| |
| if(! ((m=s->ob_type->tp_as_sequence) && m->sq_length && m->sq_ass_slice)) |
| return Py_ReturnMethodError("__setslice__"),-1; |
| |
| if(0 > (l=m->sq_length(s))) return -1; |
| |
| if(i1 < 0) i1 += l; |
| if(i2 < 0) i2 += l; |
| |
| return m->sq_ass_slice(s,i1,i2,o); |
| } |
| |
| int |
| PySequence_DelSlice(s, i1, i2) |
| PyObject *s; |
| int i1; |
| int i2; |
| { |
| PySequenceMethods *m; |
| int l; |
| |
| if(! s) return Py_ReturnNullError(),-1; |
| |
| if(! ((m=s->ob_type->tp_as_sequence) && m->sq_length && m->sq_ass_slice)) |
| return Py_ReturnMethodError("__delslice__"),-1; |
| |
| if(0 > (l=m->sq_length(s))) return -1; |
| |
| if(i1 < 0) i1 += l; |
| if(i2 < 0) i2 += l; |
| |
| return m->sq_ass_slice(s,i1,i2,(PyObject*)NULL); |
| } |
| |
| PyObject * |
| PySequence_Tuple(s) |
| PyObject *s; |
| { |
| int l, i; |
| PyObject *t, *item; |
| |
| if(! s) return Py_ReturnNullError(); |
| |
| Py_TRY((l=PySequence_Length(s)) != -1); |
| Py_TRY(t=PyTuple_New(l)); |
| |
| for(i=0; i < l; i++) |
| { |
| if(!(item=PySequence_GetItem(s,i)) || |
| PyTuple_SetItem(t,i,item) == -1) |
| { |
| Py_DECREF(t); |
| return NULL; |
| } |
| } |
| return t; |
| } |
| |
| PyObject * |
| PySequence_List(s) |
| PyObject *s; |
| { |
| int l, i; |
| PyObject *t, *item; |
| |
| if(! s) return Py_ReturnNullError(); |
| |
| Py_TRY((l=PySequence_Length(s)) != -1); |
| Py_TRY(t=PyList_New(l)); |
| |
| for(i=0; i < l; i++) |
| { |
| if(!(item=PySequence_GetItem(s,i)) || |
| PyList_SetItem(t,i,item) == -1) |
| { |
| Py_DECREF(t); |
| return NULL; |
| } |
| } |
| return t; |
| } |
| |
| int |
| PySequence_Count(s, o) |
| PyObject *s; |
| PyObject *o; |
| { |
| int l, i, n=0, not_equal, err; |
| PyObject *item; |
| |
| if(! s || ! o) return Py_ReturnNullError(), -1; |
| if((l=PySequence_Length(s)) == -1) return -1; |
| |
| for(i=0; i < l; i++) |
| { |
| if((item=PySequence_GetItem(s,i)) == NULL) return -1; |
| err=PyObject_Cmp(item,o,¬_equal) == -1; |
| Py_DECREF(item); |
| if(err) return -1; |
| n += ! not_equal; |
| } |
| return n; |
| } |
| |
| int |
| PySequence_In(s, o) |
| PyObject *s; |
| PyObject *o; |
| { |
| int l, i, not_equal, err; |
| PyObject *item; |
| |
| if(! o || ! s) return Py_ReturnNullError(), -1; |
| if((l=PySequence_Length(s)) == -1) return -1; |
| |
| for(i=0; i < l; i++) |
| { |
| if((item=PySequence_GetItem(s,i)) == NULL) return -1; |
| err=PyObject_Cmp(item,o,¬_equal) == -1; |
| Py_DECREF(item); |
| if(err) return -1; |
| if(! not_equal) return 1; |
| } |
| return 0; |
| } |
| |
| int |
| PySequence_Index(s, o) |
| PyObject *s; |
| PyObject *o; |
| { |
| int l, i, not_equal, err; |
| PyObject *item; |
| |
| if(! s || ! o) return Py_ReturnNullError(), -1; |
| if((l=PySequence_Length(s)) == -1) return -1; |
| |
| for(i=0; i < l; i++) |
| { |
| if((item=PySequence_GetItem(s,i)) == NULL) return -1; |
| err=PyObject_Cmp(item,o,¬_equal) == -1; |
| Py_DECREF(item); |
| if(err) return -1; |
| if(! not_equal) return i; |
| } |
| PyErr_SetString(PyExc_ValueError, "list.index(x): x not in list"); |
| return -1; |
| } |
| |
| int |
| PyMapping_Check(o) |
| PyObject *o; |
| { |
| return o && o->ob_type->tp_as_mapping; |
| } |
| |
| int |
| PyMapping_Length(s) |
| PyObject *s; |
| { |
| PyMappingMethods *m; |
| |
| if(! s) return Py_ReturnNullError(),-1; |
| |
| if((m=s->ob_type->tp_as_mapping) && m->mp_length) |
| return m->mp_length(s); |
| |
| Py_ReturnMethodError("__len__"); |
| return -1; |
| } |
| |
| int |
| PyMapping_HasKeyString(o, key) |
| PyObject *o; |
| char *key; |
| { |
| PyObject *v; |
| |
| v=PyMapping_GetItemString(o,key); |
| if(v) { |
| Py_DECREF(v); |
| return 1; |
| } |
| PyErr_Clear(); |
| return 0; |
| } |
| |
| int |
| PyMapping_HasKey(o, key) |
| PyObject *o; |
| PyObject *key; |
| { |
| PyObject *v; |
| |
| v=PyObject_GetItem(o,key); |
| if(v) { |
| Py_DECREF(v); |
| return 1; |
| } |
| PyErr_Clear(); |
| return 0; |
| } |
| |
| PyObject * |
| PyObject_CallObject(o, a) |
| PyObject *o, *a; |
| { |
| PyObject *r; |
| |
| if(a) return PyEval_CallObject(o,a); |
| |
| if(! (a=PyTuple_New(0))) |
| return NULL; |
| r=PyEval_CallObject(o,a); |
| Py_DECREF(a); |
| return r; |
| } |
| |
| PyObject * |
| #ifdef HAVE_STDARG_PROTOTYPES |
| /* VARARGS 2 */ |
| PyObject_CallFunction(PyObject *PyCallable_Check, char *format, ...) |
| #else |
| /* VARARGS */ |
| PyObject_CallFunction(va_alist) va_dcl |
| #endif |
| { |
| va_list va; |
| PyObject *args, *retval; |
| #ifdef HAVE_STDARG_PROTOTYPES |
| va_start(va, format); |
| #else |
| PyObject *PyCallable_Check; |
| char *format; |
| va_start(va); |
| PyCallable_Check = va_arg(va, PyObject *); |
| format = va_arg(va, char *); |
| #endif |
| |
| if( ! PyCallable_Check) |
| { |
| va_end(va); |
| return Py_ReturnNullError(); |
| } |
| |
| if(format) |
| args = Py_VaBuildValue(format, va); |
| else |
| args = PyTuple_New(0); |
| |
| va_end(va); |
| if(! args) return NULL; |
| |
| if(! PyTuple_Check(args)) |
| { |
| PyObject *a; |
| |
| Py_TRY(a=PyTuple_New(1)); |
| Py_TRY(PyTuple_SetItem(a,0,args) != -1); |
| args=a; |
| } |
| retval = PyObject_CallObject(PyCallable_Check,args); |
| Py_DECREF(args); |
| return retval; |
| } |
| |
| PyObject * |
| #ifdef HAVE_STDARG_PROTOTYPES |
| /* VARARGS 2 */ |
| PyObject_CallMethod(PyObject *o, char *name, char *format, ...) |
| #else |
| /* VARARGS */ |
| PyObject_CallMethod(va_alist) va_dcl |
| #endif |
| { |
| va_list va; |
| PyObject *args, *func=0, *retval; |
| #ifdef HAVE_STDARG_PROTOTYPES |
| va_start(va, format); |
| #else |
| PyObject *o; |
| char *name; |
| char *format; |
| va_start(va); |
| o = va_arg(va, PyObject *); |
| name = va_arg(va, char *); |
| format = va_arg(va, char *); |
| #endif |
| |
| if( ! o || ! name) |
| { |
| va_end(va); |
| return Py_ReturnNullError(); |
| } |
| |
| func=PyObject_GetAttrString(o,name); |
| if(! func) |
| { |
| va_end(va); |
| PyErr_SetString(PyExc_AttributeError,name); |
| return 0; |
| } |
| |
| if(! (PyCallable_Check(func))) |
| { |
| va_end(va); |
| PyErr_SetString(PyExc_TypeError,"call of non-callable attribute"); |
| return 0; |
| } |
| |
| if(format && *format) |
| args = Py_VaBuildValue(format, va); |
| else |
| args = PyTuple_New(0); |
| |
| va_end(va); |
| |
| if(! args) return NULL; |
| |
| if(! PyTuple_Check(args)) |
| { |
| PyObject *a; |
| |
| Py_TRY(a=PyTuple_New(1)); |
| Py_TRY(PyTuple_SetItem(a,0,args) != -1); |
| args=a; |
| } |
| |
| retval = PyObject_CallObject(func,args); |
| Py_DECREF(args); |
| Py_DECREF(func); |
| return retval; |
| } |
| |
| PyObject * |
| PyMapping_GetItemString(o, key) |
| PyObject *o; |
| char *key; |
| { |
| PyObject *okey, *r; |
| |
| if( ! key) return Py_ReturnNullError(); |
| Py_TRY(okey=PyString_FromString(key)); |
| r = PyObject_GetItem(o,okey); |
| Py_DECREF(okey); |
| return r; |
| } |
| |
| int |
| PyMapping_SetItemString(o, key, value) |
| PyObject *o; |
| char *key; |
| PyObject *value; |
| { |
| PyObject *okey; |
| int r; |
| |
| if( ! key) return Py_ReturnNullError(),-1; |
| if (!(okey=PyString_FromString(key))) return -1; |
| r = PyObject_SetItem(o,okey,value); |
| Py_DECREF(okey); |
| return r; |
| } |