📄 siplib.c
字号:
break; } case 'm': { /* Unsigned long integer. */ unsigned long v = sip_api_long_as_unsigned_long(arg); if (PyErr_Occurred()) valid = PARSE_TYPE; else *va_arg(va, unsigned long *) = v; break; } case 'n': { /* Long long integer. */#if defined(HAVE_LONG_LONG) long long v = PyLong_AsLongLong(arg);#else long v = PyLong_AsLong(arg);#endif if (PyErr_Occurred()) valid = PARSE_TYPE; else#if defined(HAVE_LONG_LONG) *va_arg(va, long long *) = v;#else *va_arg(va, long *) = v;#endif break; } case 'o': { /* Unsigned long long integer. */#if defined(HAVE_LONG_LONG) unsigned long long v = PyLong_AsUnsignedLongLong(arg);#else unsigned long v = PyLong_AsUnsignedLong(arg);#endif if (PyErr_Occurred()) valid = PARSE_TYPE; else#if defined(HAVE_LONG_LONG) *va_arg(va, unsigned long long *) = v;#else *va_arg(va, unsigned long *) = v;#endif break; } case 'f': { /* Float. */ double v = PyFloat_AsDouble(arg); if (PyErr_Occurred()) valid = PARSE_TYPE; else *va_arg(va,float *) = (float)v; break; } case 'X': { /* Constrained (ie. exact) types. */ switch (*fmt++) { case 'b': { /* Boolean. */ if (PyBool_Check(arg)) sipSetBool(va_arg(va,void *),(arg == Py_True)); else valid = PARSE_TYPE; break; } case 'd': { /* Double float. */ if (PyFloat_Check(arg)) *va_arg(va,double *) = PyFloat_AS_DOUBLE(arg); else valid = PARSE_TYPE; break; } case 'f': { /* Float. */ if (PyFloat_Check(arg)) *va_arg(va,float *) = (float)PyFloat_AS_DOUBLE(arg); else valid = PARSE_TYPE; break; } case 'i': { /* Integer. */ if (PyInt_Check(arg)) *va_arg(va,int *) = PyInt_AS_LONG(arg); else valid = PARSE_TYPE; break; } default: valid = PARSE_FORMAT; } break; } case 'd': { /* Double float. */ double v = PyFloat_AsDouble(arg); if (PyErr_Occurred()) valid = PARSE_TYPE; else *va_arg(va,double *) = v; break; } case 'v': { /* Void pointer. */ void *v = sip_api_convert_to_void_ptr(arg); if (PyErr_Occurred()) valid = PARSE_TYPE; else *va_arg(va,void **) = v; break; } default: valid = PARSE_FORMAT; } if (valid == PARSE_OK) { if (ch == 'W') { /* * An ellipsis matches everything and ends the * parse. */ nrparsed = nrargs; break; } ++nrparsed; } } *argsParsedp = nrparsed; return valid;}/* * Second pass of the argument parse, converting the remaining ones that might * have side effects. Return PARSE_OK if there was no error. */static int parsePass2(sipWrapper *self,int selfarg,int nrargs, PyObject *sipArgs,char *fmt,va_list va){ int a, valid; valid = PARSE_OK; /* Handle the converions of "self" first. */ switch (*fmt++) { case 'B': { /* * The address of a C++ instance when calling one of * its public methods. */ sipWrapperType *type; void **p; *va_arg(va,PyObject **) = (PyObject *)self; type = va_arg(va,sipWrapperType *); p = va_arg(va,void **); if ((*p = sip_api_get_cpp_ptr(self,type)) == NULL) valid = PARSE_RAISED; break; } case 'p': { /* * The address of a C++ instance when calling one of * its protected methods. */ void **p; *va_arg(va,PyObject **) = (PyObject *)self; va_arg(va,sipWrapperType *); p = va_arg(va,void **); if ((*p = sip_api_get_complex_cpp_ptr(self)) == NULL) valid = PARSE_RAISED; break; } case 'C': va_arg(va,PyObject *); break; default: --fmt; } for (a = (selfarg ? 1 : 0); a < nrargs && *fmt != 'W' && valid == PARSE_OK; ++a) { char ch; PyObject *arg = PyTuple_GET_ITEM(sipArgs,a); /* Skip the optional character. */ if ((ch = *fmt++) == '|') ch = *fmt++; /* * Do the outstanding conversions. For most types it has * already been done, so we are just skipping the parameters. */ switch (ch) { case 'q': { /* Qt receiver to connect. */ char *sig = va_arg(va,char *); void **rx = va_arg(va,void **); const char **slot = va_arg(va,const char **); if ((*rx = sip_api_convert_rx(self,sig,arg,*slot,slot)) == NULL) valid = PARSE_RAISED; break; } case 'Q': { /* Qt receiver to disconnect. */ char *sig = va_arg(va,char *); void **rx = va_arg(va,void **); const char **slot = va_arg(va,const char **); *rx = sipGetRx(self,sig,arg,*slot,slot); break; } case 'y': { /* Python slot to connect. */ char *sig = va_arg(va,char *); void **rx = va_arg(va,void **); const char **slot = va_arg(va,const char **); if ((*rx = sip_api_convert_rx(self,sig,arg,NULL,slot)) == NULL) valid = PARSE_RAISED; break; } case 'Y': { /* Python slot to disconnect. */ char *sig = va_arg(va,char *); void **rx = va_arg(va,void **); const char **slot = va_arg(va,const char **); *rx = sipGetRx(self,sig,arg,NULL,slot); break; } case 'J': { /* Class instance. */ int flags = *fmt++ - '0'; sipWrapperType *type; void **p; int iflgs = 0; int iserr = FALSE; int *state; PyObject *xfer, **wrapper; type = va_arg(va,sipWrapperType *); p = va_arg(va,void **); if (flags & FORMAT_TRANSFER) xfer = (self ? (PyObject *)self : arg); else if (flags & FORMAT_TRANSFER_BACK) xfer = Py_None; else xfer = NULL; if (flags & FORMAT_DEREF) iflgs |= SIP_NOT_NONE; if (flags & FORMAT_GET_WRAPPER) wrapper = va_arg(va, PyObject **); else wrapper = NULL; if (flags & FORMAT_NO_CONVERTORS) { iflgs |= SIP_NO_CONVERTORS; state = NULL; } else state = va_arg(va, int *); *p = sip_api_convert_to_instance(arg, type, xfer, iflgs, state, &iserr); if (iserr) valid = PARSE_RAISED; if (wrapper != NULL) *wrapper = (*p != NULL ? arg : NULL); break; } case 'M': { /* Mapped type instance. */ int flags = *fmt++ - '0'; sipMappedType *mt; void **p; int iflgs = 0; int iserr = FALSE; int *state; PyObject *xfer; mt = va_arg(va, sipMappedType *); p = va_arg(va, void **); state = va_arg(va, int *); if (flags & FORMAT_TRANSFER) xfer = (self ? (PyObject *)self : arg); else if (flags & FORMAT_TRANSFER_BACK) xfer = Py_None; else xfer = NULL; if (flags & FORMAT_DEREF) iflgs |= SIP_NOT_NONE; *p = sip_api_convert_to_mapped_type(arg, mt, xfer, iflgs, state, &iserr); if (iserr) valid = PARSE_RAISED; break; } case 'P': { /* * Python object of any type with a * sub-format. */ PyObject **p = va_arg(va,PyObject **); int flags = *fmt++ - '0'; if (flags & FORMAT_TRANSFER) { Py_XINCREF(*p); } else if (flags & FORMAT_TRANSFER_BACK) { Py_XDECREF(*p); } break; } case 'X': { /* Constrained (ie. exact) type. */ ++fmt; va_arg(va,void *); break; } case 'E': { /* Named enum. */ int *p; va_arg(va, PyTypeObject *); p = va_arg(va, int *); *p = PyInt_AsLong(arg); break; } /* * Every other argument is a pointer and only differ in how * many there are. */ case 'N': case 'T': case 'a': va_arg(va,void *); /* Drop through. */ default: va_arg(va,void *); } } /* Handle any ellipsis argument. */ if (*fmt == 'W' && valid == PARSE_OK) { PyObject *al; /* Create a tuple for any remaining arguments. */ if ((al = PyTuple_New(nrargs - a)) != NULL) { int da = 0; while (a < nrargs) { PyObject *arg = PyTuple_GET_ITEM(sipArgs,a); /* Add the remaining argument to the tuple. */ Py_INCREF(arg); PyTuple_SET_ITEM(al, da, arg); ++a; ++da; } /* Return the tuple. */ *va_arg(va, PyObject **) = al; } else valid = PARSE_RAISED; } return valid;}/* * Carry out actions common to all ctors. */static void sip_api_common_ctor(sipMethodCache *cache,int nrmeths){ /* This is thread safe. */ while (nrmeths-- > 0) cache++ -> mcflags = 0;}/* * Carry out actions common to all dtors. */static void sip_api_common_dtor(sipWrapper *sipSelf){ if (sipSelf != NULL && sipInterpreter != NULL) { SIP_BLOCK_THREADS if (!sipNotInMap(sipSelf)) sipOMRemoveObject(&cppPyMap,sipSelf); /* This no longer points to anything useful. */ sipSelf -> u.cppPtr = NULL; /* Remove it from any parent. */ removeFromParent(sipSelf); SIP_UNBLOCK_THREADS }}/* * Add a wrapper to it's parent owner if it has one. The wrapper must not * currently have a parent and, therefore, no siblings. */static void addToParent(sipWrapper *self, sipWrapper *owner){ if (owner != NULL) { if (owner->first_child != NULL) { self->sibling_next = owner->first_child; owner->first_child->sibling_prev = self; } owner->first_child = self; self->parent = owner; /* * The owner holds a real reference so that the cyclic garbage * collector works properly. */ Py_INCREF(self); }}/* * Remove a wrapper from it's parent if it has one. */static void removeFromParent(sipWrapper *self){ if (self->parent != NULL) { if (self->parent->first_child == self) self->parent->first_child = self->sibling_next; if (self->sibling_next != NULL) self->sibling_next->sibling_prev = self->sibling_prev; if (self->sibling_prev != NULL) self->sibling_prev->sibling_next = self->sibling_next; self->parent = NULL; self->sibling_next = NULL; self->sibling_prev = NULL; /* * We must do this last, after all the pointers are correct, * because this is used by the clear slot. */ Py_DECREF(self); }}/* * Convert a sequence index. Return the index or a negative value if there was * an error. */static int sip_api_convert_from_sequence_index(int idx,int len){ /* Negative indices start from the other end. */ if (idx < 0) idx = len + idx; if (idx < 0 || idx >= len) { PyErr_Format(PyExc_IndexError,"sequence index out of range"); return -1; } return idx;}/* * Create and return a single type object. */static sipWrapperType *createType(sipExportedModuleDef *client, sipTypeDef *type, PyObject *mod_dict){ PyObject *name, *bases, *typedict, *args, *dict; sipEncodedClassDef *sup; sipWrapperType *wt; /* Create an object corresponding to the type name. */ if ((name = getBaseNameObject(type -> td_name)) == NULL) goto reterr; /* Create the tuple of super types. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -