📄 gencode.c
字号:
for (vd = pt -> vars; vd != NULL; vd = vd -> next) { if (vd -> ecd != cd || vd -> module != pt -> module) continue; if (vd -> type.atype != enum_type || vd -> type.u.ed -> fqcname == NULL) continue; if (needsHandler(vd)) continue; /* Skip enums that need inline code. */ if (!generating_c && vd->accessfunc == NULL && vd->type.nrderefs == 0) continue; if (noIntro) { if (cd != NULL) prcode(fp,"\n""\n""/* Define the enum instances to be added to this type dictionary. */\n""static sipEnumInstanceDef enumInstances_%C[] = {\n" ,classFQCName(cd)); else prcode(fp,"\n""\n""/* Define the enum instances to be added to this module dictionary. */\n""static sipEnumInstanceDef enumInstances[] = {\n" ); noIntro = FALSE; } prcode(fp," {%N, (int)%S, &sipEnum_%C},\n" ,vd -> pyname,vd -> fqcname,vd -> type.u.ed -> fqcname); } if (!noIntro) prcode(fp," {0, 0, 0}\n""};\n" ); return !noIntro;}/* * Generate the code to add a set of ints to a dictionary. Return TRUE if * there was at least one. */static int generateInts(sipSpec *pt, classDef *cd, FILE *fp){ int noIntro; varDef *vd; enumDef *ed; noIntro = TRUE; for (vd = pt -> vars; vd != NULL; vd = vd -> next) { argType vtype = vd -> type.atype; if (vd -> ecd != cd || vd -> module != pt -> module) continue; if (!(vtype == enum_type || vtype == ushort_type || vtype == short_type || vtype == uint_type || vtype == cint_type || vtype == int_type || vtype == bool_type || vtype == cbool_type)) continue; if (needsHandler(vd)) continue; /* Named enums are handled elsewhere. */ if (vtype == enum_type && vd -> type.u.ed -> fqcname != NULL) continue; if (noIntro) { ints_intro(cd, fp); noIntro = FALSE; } prcode(fp," {%N, %S},\n" ,vd -> pyname,vd -> fqcname); } /* Now do global anonymous enums. */ if (cd == NULL) for (ed = pt->enums; ed != NULL; ed = ed->next) { enumMemberDef *em; if (ed->ecd != cd || ed->module != pt->module) continue; if (ed->fqcname != NULL) continue; for (em = ed->members; em != NULL; em = em->next) { if (noIntro) { ints_intro(cd, fp); noIntro = FALSE; } prcode(fp," {%N, %s},\n" , em->pyname, em->cname); } } if (!noIntro) prcode(fp," {0, 0}\n""};\n" ); return !noIntro;}/* * Generate the intro for a table of int instances. */static void ints_intro(classDef *cd, FILE *fp){ if (cd != NULL) prcode(fp,"\n""\n""/* Define the ints to be added to this type dictionary. */\n""static sipIntInstanceDef intInstances_%C[] = {\n" ,classFQCName(cd)); else prcode(fp,"\n""\n""/* Define the ints to be added to this module dictionary. */\n""static sipIntInstanceDef intInstances[] = {\n" );}/* * Generate the code to add a set of longs to a dictionary. Return TRUE if * there was at least one. */static int generateLongs(sipSpec *pt, classDef *cd, FILE *fp){ return generateVariableType(pt, cd, long_type, "long", "Long", "long", fp);}/* * Generate the code to add a set of unsigned longs to a dictionary. Return * TRUE if there was at least one. */static int generateUnsignedLongs(sipSpec *pt, classDef *cd, FILE *fp){ return generateVariableType(pt, cd, ulong_type, "unsigned long", "UnsignedLong", "unsignedLong", fp);}/* * Generate the code to add a set of long longs to a dictionary. Return TRUE * if there was at least one. */static int generateLongLongs(sipSpec *pt, classDef *cd, FILE *fp){ return generateVariableType(pt, cd, longlong_type, "long long", "LongLong", "longLong", fp);}/* * Generate the code to add a set of unsigned long longs to a dictionary. * Return TRUE if there was at least one. */static int generateUnsignedLongLongs(sipSpec *pt, classDef *cd, FILE *fp){ return generateVariableType(pt, cd, ulonglong_type, "unsigned long long", "UnsignedLongLong", "unsignedLongLong", fp);}/* * Generate the code to add a set of a particular type to a dictionary. Return * TRUE if there was at least one. */static int generateVariableType(sipSpec *pt, classDef *cd, argType atype, const char *eng, const char *s1, const char *s2, FILE *fp){ int noIntro; varDef *vd; noIntro = TRUE; for (vd = pt -> vars; vd != NULL; vd = vd -> next) { argType vtype = vd -> type.atype; if (vd -> ecd != cd || vd -> module != pt -> module) continue; if (vtype != atype) continue; if (needsHandler(vd)) continue; if (noIntro) { if (cd != NULL) prcode(fp,"\n""\n""/* Define the %ss to be added to this type dictionary. */\n""static sip%sInstanceDef %sInstances_%C[] = {\n" , eng , s1, s2, classFQCName(cd)); else prcode(fp,"\n""\n""/* Define the %ss to be added to this module dictionary. */\n""static sip%sInstanceDef %sInstances[] = {\n" , eng , s1, s2); noIntro = FALSE; } prcode(fp," {%N, %S},\n" ,vd -> pyname,vd -> fqcname); } if (!noIntro) prcode(fp," {0, 0}\n""};\n" ); return !noIntro;}/* * Generate the code to add a set of doubles to a dictionary. Return TRUE if * there was at least one. */static int generateDoubles(sipSpec *pt,classDef *cd,FILE *fp){ int noIntro; varDef *vd; noIntro = TRUE; for (vd = pt -> vars; vd != NULL; vd = vd -> next) { argType vtype = vd -> type.atype; if (vd -> ecd != cd || vd -> module != pt -> module) continue; if (!(vtype == float_type || vtype == cfloat_type || vtype == double_type || vtype == cdouble_type)) continue; if (needsHandler(vd)) continue; if (noIntro) { if (cd != NULL) prcode(fp,"\n""\n""/* Define the doubles to be added to this type dictionary. */\n""static sipDoubleInstanceDef doubleInstances_%C[] = {\n" ,classFQCName(cd)); else prcode(fp,"\n""\n""/* Define the doubles to be added to this module dictionary. */\n""static sipDoubleInstanceDef doubleInstances[] = {\n" ); noIntro = FALSE; } prcode(fp," {%N, %S},\n" ,vd -> pyname,vd -> fqcname); } if (!noIntro) prcode(fp," {0, 0}\n""};\n" ); return !noIntro;}/* * Generate the C/C++ code for an interface. */static void generateIfaceCpp(sipSpec *pt,ifaceFileDef *iff,char *codeDir, char *srcSuffix,FILE *master){ char *cppfile, *cmname = iff -> module -> name; classDef *cd; mappedTypeDef *mtd; FILE *fp; if (master == NULL) { cppfile = createIfaceFileName(codeDir,iff,srcSuffix); fp = createFile(pt,cppfile,"Interface wrapper code."); } else fp = master; prcode(fp,"\n""#include \"sipAPI%s.h\"\n""#include \"sip%s%F.h\"\n" ,cmname ,cmname,iff -> fqcname); generateUsedIncludes(iff->used, FALSE, fp); for (cd = pt -> classes; cd != NULL; cd = cd -> next) if (cd -> iff == iff) { if (isProtectedClass(cd)) prcode(fp,"\n""#include \"sip%s%F.h\"\n" ,cmname,cd -> ecd -> iff -> fqcname); if (!isExternal(cd)) generateClassCpp(cd, pt, fp); } for (mtd = pt -> mappedtypes; mtd != NULL; mtd = mtd -> next) if (mtd -> iff == iff) generateMappedTypeCpp(mtd,fp); if (master == NULL) { closeFile(fp); free(cppfile); }}/* * Return a filename for an interface C++ or header file on the heap. */static char *createIfaceFileName(char *codeDir,ifaceFileDef *iff,char *suffix){ char *fn; scopedNameDef *snd; fn = concat(codeDir,"/sip",iff -> module -> name,NULL); for (snd = iff -> fqcname; snd != NULL; snd = snd -> next) append(&fn,snd -> name); append(&fn,suffix); return fn;}/* * Generate the C++ code for a mapped type version. */static void generateMappedTypeCpp(mappedTypeDef *mtd,FILE *fp){ int need_xfer; prcode(fp,"\n""\n""/* Call the mapped type's destructor. */\n""static void release_%T(void *ptr, int%s)\n""{\n" , &mtd->type, (generating_c ? " status" : "")); if (release_gil) prcode(fp," Py_BEGIN_ALLOW_THREADS\n" ); if (generating_c) prcode(fp," sipFree(ptr);\n" ); else prcode(fp," delete reinterpret_cast<%b *>(ptr);\n" , &mtd->type); if (release_gil) prcode(fp," Py_END_ALLOW_THREADS\n" ); prcode(fp,"}\n""\n" ); generateConvertToDefinitions(mtd,NULL,fp); /* Generate the from type convertor. */ need_xfer = (generating_c || usedInCode(mtd->convfromcode, "sipTransferObj")); prcode(fp,"\n""\n""static PyObject *convertFrom_%T(void *sipCppV,PyObject *%s)\n""{\n"" ", &mtd->type, (need_xfer ? "sipTransferObj" : "")); generateMappedTypeFromVoid(mtd, "sipCpp", "sipCppV", fp); prcode(fp, ";\n""\n" ); generateCppCodeBlock(mtd -> convfromcode,fp); prcode(fp,"}\n""\n""\n""sipMappedType sipMappedTypeDef_%T = {\n"" \"%B\",\n"" release_%T,\n"" forceConvertTo_%T,\n"" convertTo_%T,\n"" convertFrom_%T\n""};\n" ,&mtd -> type ,&mtd -> type ,&mtd -> type ,&mtd -> type ,&mtd -> type ,&mtd -> type ,&mtd -> type);}/* * Generate the C++ code for a class. */static void generateClassCpp(classDef *cd,sipSpec *pt,FILE *fp){ varDef *vd; /* Generate any local class code. */ generateCppCodeBlock(cd -> cppcode,fp); generateClassFunctions(pt,cd,fp); generateAccessFunctions(pt,cd,fp); /* Generate the variable handlers. */ if (hasVarHandlers(cd)) { for (vd = pt -> vars; vd != NULL; vd = vd -> next) if (vd -> ecd == cd && needsHandler(vd)) generateVariableHandler(vd,fp); /* Generate the variable table. */ prcode(fp,"\n""PyMethodDef variables_%C[] = {\n" ,classFQCName(cd)); for (vd = pt -> vars; vd != NULL; vd = vd -> next) if (vd -> ecd == cd && needsHandler(vd)) prcode(fp," {%N, var_%C, %s, NULL},\n" ,vd -> pyname,vd -> fqcname,(isStaticVar(vd) ? "METH_STATIC" : "0")); prcode(fp," {0, 0, 0, 0}\n""};\n" ); } if (cd -> iff -> type != namespace_iface) generateConvertToDefinitions(NULL,cd,fp); /* The type definition structure. */ generateTypeDefinition(pt, cd, fp);}/* * Return a sorted array of relevant functions for a namespace. */static sortedMethTab *createFunctionTable(classDef *cd,int *nrp){ int nr; sortedMethTab *mtab, *mt; memberDef *md; /* First we need to count the number of applicable functions. */ nr = 0; for (md = cd -> members; md != NULL; md = md -> next) ++nr; if ((*nrp = nr) == 0) return NULL; /* Create the table of methods. */ mtab = sipMalloc(sizeof (sortedMethTab) * nr); /* Initialise the table. */ mt = mtab; for (md = cd -> members; md != NULL; md = md -> next) { mt -> md = md; mt -> is_static = TRUE; ++mt; } /* Finally sort the table. */ qsort(mtab,nr,sizeof (sortedMethTab),compareMethTab); return mtab;}/* * Return a sorted array of relevant methods (either lazy or non-lazy) for a * class. */static sortedMethTab *createMethodTable(classDef *cd,int *nrp){ int nr; visibleList *vl; sortedMethTab *mtab, *mt; /* * First we need to count the number of applicable methods. Only * provide an entry point if there is at least one overload that is * defined in this class and is a non-abstract function or slot. We * allow private (even though we don't actually generate code) because * we need to intercept the name before it reaches a more public * version further up the class hierarchy. We add the ctor and any * variable handlers as special entries. */ nr = 0; for (vl = cd -> visible; vl != NULL; vl = vl -> next) { overDef *od; fo
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -