📄 siplib.c
字号:
*/static int sip_api_export_module(sipExportedModuleDef *client, unsigned api_major,unsigned api_minor, PyObject *mod_dict){ sipExportedModuleDef *em; sipImportedModuleDef *im; sipSubClassConvertorDef *scc; sipWrapperType **mw; sipEnumMemberDef *emd; sipInitExtenderDef *ie; int i; /* Check that we can support it. */ if (api_major != SIP_API_MAJOR_NR || api_minor > SIP_API_MINOR_NR) {#if SIP_API_MINOR_NR > 0 PyErr_Format(PyExc_RuntimeError,"the sip module supports API v%d.0 to v%d.%d but the %s module requires API v%d.%d",SIP_API_MAJOR_NR,SIP_API_MAJOR_NR,SIP_API_MINOR_NR,client -> em_name,api_major,api_minor);#else PyErr_Format(PyExc_RuntimeError,"the sip module supports API v%d.0 but the %s module requires API v%d.%d",SIP_API_MAJOR_NR,client -> em_name,api_major,api_minor);#endif return -1; } /* Convert the module name to an object. */ if ((client->em_nameobj = PyString_FromString(client->em_name)) == NULL) return -1; for (em = clientList; em != NULL; em = em -> em_next) { /* SIP clients must have unique names. */ if (strcmp(em -> em_name,client -> em_name) == 0) { PyErr_Format(PyExc_RuntimeError,"the sip module has already registered a module called %s",client -> em_name); return -1; } /* Only one module can claim to wrap QObject. */ if (em -> em_qt_api != NULL && client -> em_qt_api != NULL) { PyErr_Format(PyExc_RuntimeError,"the %s and %s modules both wrap the QObject class",client -> em_name,em -> em_name); return -1; } } /* Import any required modules. */ if ((im = client -> em_imports) != NULL) { while (im -> im_name != NULL) { PyObject *mod; if ((mod = PyImport_ImportModule(im -> im_name)) == NULL) return -1; for (em = clientList; em != NULL; em = em -> em_next) if (strcmp(em -> em_name,im -> im_name) == 0) break; if (em == NULL) { PyErr_Format(PyExc_RuntimeError,"the %s module failed to register with the sip module",im -> im_name); return -1; } /* Check the versions are compatible. */ if (im -> im_version >= 0 || em -> em_version >= 0) if (im -> im_version != em -> em_version) { PyErr_Format(PyExc_RuntimeError,"the %s module is version %d but the %s module requires version %d",em -> em_name,em -> em_version,client -> em_name,im -> im_version); return -1; } /* Save the imported module. */ im -> im_module = em; ++im; } } /* Create the module's classes. */ if ((mw = client->em_types) != NULL) for (i = 0; i < client->em_nrtypes; ++i, ++mw) { sipTypeDef *td = (sipTypeDef *)*mw; /* Skip external classes. */ if (td == NULL) continue; /* See if this is a namespace extender. */ if (td->td_name == NULL) { sipTypeDef **last; sipWrapperType *wt = getClassType(&td->td_scope, client); /* Append this type to the real one. */ last = &wt->type->td_nsextender; while (*last != NULL) last = &(*last)->td_nsextender; *last = td; /* * Set this so that the extender's original * module can be found. */ td->td_module = client; /* * Save the real namespace type so that it is * the correct scope for any enums or classes * defined in this module. */ *mw = wt; } else if ((*mw = createType(client, td, mod_dict)) == NULL) return -1; } /* Set any Qt support API. */ if (client->em_qt_api != NULL) { sipQtSupport = client->em_qt_api; sipQObjectClass = *sipQtSupport->qt_qobject; } /* Append any initialiser extenders to the relevant classes. */ if ((ie = client->em_initextend) != NULL) while (ie->ie_extender != NULL) { sipWrapperType *wt = getClassType(&ie->ie_class, client); ie->ie_next = wt->iextend; wt->iextend = ie; ++ie; } /* Set the base class object for any sub-class convertors. */ if ((scc = client -> em_convertors) != NULL) while (scc -> scc_convertor != NULL) { scc->scc_basetype = getClassType(&scc->scc_base, client); ++scc; } /* Create the module's enums. */ if (client -> em_nrenums != 0) { if ((client -> em_enums = sip_api_malloc(client -> em_nrenums * sizeof (PyTypeObject *))) == NULL) return -1; for (i = 0; i < client -> em_nrenums; ++i) if ((client->em_enums[i] = createEnum(client, &client->em_enumdefs[i], mod_dict)) == NULL) return -1; } for (emd = client -> em_enummembers, i = 0; i < client -> em_nrenummembers; ++i, ++emd) { PyObject *mo; if ((mo = sip_api_convert_from_named_enum(emd -> em_val, client -> em_enums[emd -> em_enum])) == NULL) return -1; if (PyDict_SetItemString(mod_dict, emd -> em_name, mo) < 0) return -1; Py_DECREF(mo); } /* * Add any class static instances. We need to do this once all types * are fully formed because of potential interdependencies. */ if ((mw = client -> em_types) != NULL) for (i = 0; i < client->em_nrtypes; ++i) { sipWrapperType *wt; if ((wt = *mw++) != NULL && addInstances(wt->super.type.tp_dict, &wt->type->td_instances) < 0) return -1; } /* Add any global static instances. */ if (addInstances(mod_dict,&client -> em_instances) < 0) return -1; /* Add any license. */ if (client -> em_license != NULL && addLicense(mod_dict,client -> em_license) < 0) return -1; /* See if the new module satisfies any outstanding external types. */ for (em = clientList; em != NULL; em = em->em_next) { sipExternalTypeDef *etd; if (em->em_external == NULL) continue; for (etd = em->em_external; etd->et_nr >= 0; ++etd) { if (etd->et_name == NULL) continue; mw = client->em_types; for (i = 0; i < client->em_nrtypes; ++i) { sipWrapperType *wt; const char *tname; if ((wt = *mw++) == NULL) continue; tname = strchr(wt->type->td_name, '.') + 1; if (strcmp(etd->et_name, tname) == 0) { em->em_types[etd->et_nr] = wt; etd->et_name = NULL; break; } } } } /* Add to the list of client modules. */ client -> em_next = clientList; clientList = client; return 0;}/* * Called by the interpreter to do any final clearing up, just in case the * interpreter will re-start. */static void finalise(void){ sipExportedModuleDef *em; /* Handle any delayed dtors. */ for (em = clientList; em != NULL; em = em->em_next) if (em->em_ddlist != NULL) { em->em_delayeddtors(em->em_ddlist); /* Free the list. */ do { sipDelayedDtor *dd = em->em_ddlist; em->em_ddlist = dd->dd_next; sip_api_free(dd); } while (em->em_ddlist != NULL); } Py_XDECREF(licenseName); licenseName = NULL; Py_XDECREF(licenseeName); licenseeName = NULL; Py_XDECREF(typeName); typeName = NULL; Py_XDECREF(timestampName); timestampName = NULL; Py_XDECREF(signatureName); signatureName = NULL; /* Release all memory we've allocated directly. */ sipOMFinalise(&cppPyMap); /* Re-initialise those globals that (might) need it. */ clientList = NULL; sipInterpreter = NULL;}/* * Add a wrapped C/C++ pointer to the list of delayed dtors. */static void sip_api_add_delayed_dtor(sipWrapper *w){ void *ptr; sipTypeDef *td; sipExportedModuleDef *em; if ((ptr = getPtrTypeDef(w, &td)) == NULL) return; /* Find the defining module. */ for (em = clientList; em != NULL; em = em->em_next) { int i; for (i = 0; i < em->em_nrtypes; ++i) if (em->em_types[i] != NULL && em->em_types[i]->type == td) { sipDelayedDtor *dd; if ((dd = sip_api_malloc(sizeof (sipDelayedDtor))) == NULL) return; /* Add to the list. */ dd->dd_ptr = ptr; dd->dd_name = getBaseName(td->td_name); dd->dd_isderived = sipIsDerived(w); dd->dd_next = em->em_ddlist; em->em_ddlist = dd; return; } }}/* * A wrapper around the Python memory allocater that will raise an exception if * if the allocation fails. */void *sip_api_malloc(size_t nbytes){ void *mem; if ((mem = PyMem_Malloc(nbytes)) == NULL) PyErr_NoMemory(); return mem;}/* * A wrapper around the Python memory de-allocater. */void sip_api_free(void *mem){ PyMem_Free(mem);}/* * Extend a Python slot by looking in other modules to see if there is an * extender function that can handle the arguments. */static PyObject *sip_api_pyslot_extend(sipExportedModuleDef *mod, sipPySlotType st, sipWrapperType *type, PyObject *arg0, PyObject *arg1){ sipExportedModuleDef *em; /* Go through each module. */ for (em = clientList; em != NULL; em = em->em_next) { sipPySlotExtenderDef *ex; /* Skip the module that couldn't handle the arguments. */ if (em == mod) continue; /* Skip if the module doesn't have any extenders. */ if (em->em_slotextend == NULL) continue; /* Go through each extender. */ for (ex = em->em_slotextend; ex->pse_func != NULL; ++ex) { PyObject *res; /* Skip if not the right slot type. */ if (ex->pse_type != st) continue; /* Check against the type if one was given. */ if (type != NULL && type != getClassType(&ex->pse_class, NULL)) continue; PyErr_Clear(); res = ((binaryfunc)ex->pse_func)(arg0, arg1); if (res != Py_NotImplemented) return res; } } /* The arguments couldn't handled anywhere. */ PyErr_Clear(); Py_INCREF(Py_NotImplemented); return Py_NotImplemented;}/* * Call the Python re-implementation of a C++ virtual. */static PyObject *sip_api_call_method(int *isErr,PyObject *method,char *fmt,...){ PyObject *args, *res; va_list va; va_start(va,fmt); if ((args = PyTuple_New(strlen(fmt))) != NULL && buildObject(args,fmt,va) != NULL) res = PyEval_CallObject(method,args); else { res = NULL; if (isErr != NULL) *isErr = TRUE; } Py_XDECREF(args); va_end(va); return res;}/* * Build a result object based on a format string. */static PyObject *sip_api_build_result(int *isErr,char *fmt,...){ PyObject *res = NULL; int badfmt, tupsz; va_list va; va_start(va,fmt); /* Basic validation of the format string. */ badfmt = FALSE; if (*fmt == '(') { char *ep; if ((ep = strchr(fmt,')')) == NULL || ep[1] != '\0') badfmt = TRUE; else tupsz = ep - fmt - 1; } else if (strlen(fmt) == 1) tupsz = -1; else badfmt = TRUE; if (badfmt) PyErr_Format(PyExc_SystemError,"sipBuildResult(): invalid format string \"%s\"",fmt); else if (tupsz < 0 || (res = PyTuple_New(tupsz)) != NULL) res = buildObject(res,fmt,va); va_end(va); if (res == NULL && isErr != NULL) *isErr = TRUE; return res;}/* * Get the values off the stack and put them into an object. */static PyObject *buildObject(PyObject *obj,char *fmt,va_list va){ char ch, termch; int i; /* * The format string has already been checked that it is properly * formed if it is enclosed in parenthesis. */ if (*fmt == '(') { termch = ')'; ++fmt; } else termch = '\0'; i = 0; while ((ch = *fmt++) != termch) { PyObject *el; switch (ch) { case 'a': { char *s; int l; s = va_arg(va,char *); l = va_arg(va,int); if (s != NULL) el = PyString_FromStringAndSize(s,l); else { Py_INCREF(Py_None); el = Py_None; } } break; case 'b': el = PyBool_FromLong(va_arg(va,int)); break; case 'c': { char c = va_arg(va, int); el = PyString_FromStringAndSize(&c,1); } break; case 'e': el = PyInt_FromLong(va_arg(va,int)); break; case 'E': { int ev = va_arg(va, int); PyTypeObject *et = va_arg(va, PyTypeObject *); el = sip_api_convert_from_named_enum(ev, et); } break; case 'd': case 'f': el = PyFloat_FromDouble(va_arg(va,double)); break; case 'h': case 'i': el = PyInt_FromLong(va_arg(va,int)); break; case 'l': el = PyLong_FromLong(va_arg(va,long)); break; case 'm': el = PyLong_FromUnsignedLong(va_arg(va, unsigned long)); break; case 'n':#if defined(HAVE_LONG_LONG) el = PyLong_FromLongLong(va_arg(va, long long));#else el = PyLong_FromLong(va_arg(va, long));#endif break; case 'o':#if defined(HAVE_LONG_LONG) el = PyLong_FromUnsignedLongLong(va_arg(va, unsigned long long));#else el = PyLong_FromUnsignedLong(va_arg(va, unsigned long));#endif break; case 's': { char *s = va_arg(va,char *); if (s != NULL) el = PyString_FromString(s); else { Py_INCREF(Py_None); el = Py_None; } } break; case 't': case 'u': el = PyLong_FromUnsignedLong(va_arg(va, unsigned)); break; case 'B': { void *p = va_arg(va,void *); sipWrapperType *wt = va_arg(va, sipWrapperType *); PyObject *xfer = va_arg(va, PyObject *); el = sip_api_convert_from_new_instance(p, wt, xfer); } break; case 'C': { void *p = va_arg(va,void *); sipWrapperType *wt = va_arg(va, sipWrapperType *);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -