📄 parser.y
字号:
setInputFile(fp,name,&pc,optional);}/* * Find an interface file, or create a new one. */ifaceFileDef *findIfaceFile(sipSpec *pt, moduleDef *mod, scopedNameDef *fqname, ifaceFileType iftype, argDef *ad){ ifaceFileDef *iff; /* See if the name is already used. */ for (iff = pt -> ifacefiles; iff != NULL; iff = iff -> next) { if (!sameScopedName(iff -> fqcname,fqname)) continue; /* * They must be the same type except that we allow a class if * if we want an exception. This is because we allow classes * to be used before they are defined. */ if (iff -> type != iftype) if (iftype != exception_iface || iff -> type != class_iface) yyerror("A class, exception, namespace or mapped type has already been defined with the same name"); /* Ignore an external class declared in another module. */ if (iftype == class_iface && iff->module != mod) { classDef *cd; for (cd = pt->classes; cd != NULL; cd = cd->next) if (cd->iff == iff) break; if (cd != NULL && iff->module != NULL && isExternal(cd)) continue; } /* * If this is a mapped type with the same name defined in a * different module, then check that this type isn't the same * as any of the mapped types defined in that module. */ if (iftype == mappedtype_iface && iff -> module != mod) { mappedTypeDef *mtd; for (mtd = pt -> mappedtypes; mtd != NULL; mtd = mtd -> next) { if (mtd -> iff != iff) continue; if (ad -> atype != template_type || mtd -> type.atype != template_type || sameBaseType(ad,&mtd -> type)) yyerror("Mapped type has already been defined in another module"); } /* * If we got here then we have a mapped type based on * an existing template, but with unique parameters. * We don't want to use interface files from other * modules, so skip this one. */ continue; } /* Ignore a namespace defined in another module. */ if (iftype == namespace_iface && iff->module != mod) continue; return iff; } iff = sipMalloc(sizeof (ifaceFileDef)); iff -> name = cacheName(pt,scopedNameTail(fqname)); iff -> type = iftype; iff -> fqcname = fqname; iff -> module = NULL; iff -> used = NULL; iff -> next = pt -> ifacefiles; pt -> ifacefiles = iff; return iff;}/* * Find a class definition in a parse tree. */static classDef *findClass(sipSpec *pt,ifaceFileType iftype, scopedNameDef *fqname){ return findClassWithInterface(pt, findIfaceFile(pt, currentModule, fqname, iftype, NULL));}/* * Find a class definition given an existing interface file. */static classDef *findClassWithInterface(sipSpec *pt, ifaceFileDef *iff){ classDef *cd; for (cd = pt -> classes; cd != NULL; cd = cd -> next) if (cd -> iff == iff) return cd; /* Create a new one. */ cd = sipMalloc(sizeof (classDef)); cd -> iff = iff; cd -> pyname = classBaseName(cd); cd -> classnr = -1; cd -> classflags = 0; cd -> ecd = NULL; cd -> dtorexceptions = NULL; cd -> real = NULL; cd -> node = NULL; cd -> supers = NULL; cd -> mro = NULL; cd -> td = NULL; cd -> ctors = NULL; cd -> defctor = NULL; cd -> dealloccode = NULL; cd -> dtorcode = NULL; cd -> members = NULL; cd -> overs = NULL; cd -> casts = NULL; cd -> vmembers = NULL; cd -> visible = NULL; cd -> cppcode = NULL; cd -> hdrcode = NULL; cd -> convtosubcode = NULL; cd -> subbase = NULL; cd -> convtocode = NULL; cd -> travcode = NULL; cd -> clearcode = NULL; cd -> readbufcode = NULL; cd -> writebufcode = NULL; cd -> segcountcode = NULL; cd -> charbufcode = NULL; cd -> next = pt -> classes; pt -> classes = cd; return cd;}/* * Add an interface file to an interface file list if it isn't already there. */ifaceFileList *addToUsedList(ifaceFileList **ifflp, ifaceFileDef *iff){ ifaceFileList *iffl; while ((iffl = *ifflp) != NULL) { /* Don't bother if it is already there. */ if (iffl -> iff == iff) return iffl; ifflp = &iffl -> next; } iffl = sipMalloc(sizeof (ifaceFileList)); iffl->iff = iff; iffl->header = FALSE; iffl->next = NULL; *ifflp = iffl; return iffl;}/* * Find an undefined (or create a new) exception definition in a parse tree. */static exceptionDef *findException(sipSpec *pt, scopedNameDef *fqname, int new){ exceptionDef *xd, **tail; ifaceFileDef *iff; classDef *cd; iff = findIfaceFile(pt, currentModule, fqname, exception_iface, NULL); /* See if it is an existing one. */ for (xd = pt->exceptions; xd != NULL; xd = xd->next) if (xd->iff == iff) return xd; /* * If it is an exception interface file then we have never seen this * name before. We require that exceptions are defined before being * used, but don't make the same requirement of classes (for reasons of * backwards compatibility). Therefore the name must be reinterpreted * as a (as yet undefined) class. */ if (new) if (iff->type == exception_iface) cd = NULL; else yyerror("There is already a class with the same name or the exception has been used before being defined"); else { if (iff->type == exception_iface) iff->type = class_iface; cd = findClassWithInterface(pt, iff); } /* Create a new one. */ xd = sipMalloc(sizeof (exceptionDef)); xd->exceptionnr = -1; xd->iff = iff; xd->pyname = NULL; xd->cd = cd; xd->bibase = NULL; xd->base = NULL; xd->hdrcode = NULL; xd->raisecode = NULL; xd->next = NULL; /* Append it to the list. */ for (tail = &pt->exceptions; *tail != NULL; tail = &(*tail)->next) ; *tail = xd; return xd;}/* * Find an undefined (or create a new) class definition in a parse tree. */static classDef *newClass(sipSpec *pt,ifaceFileType iftype, scopedNameDef *fqname){ int flags; classDef *cd, *scope; codeBlock *hdrcode; if (sectionFlags & SECT_IS_PRIVATE) yyerror("Classes, structs and namespaces must be in the public or or protected sections"); flags = 0; if ((scope = currentScope()) != NULL) { if (sectionFlags & SECT_IS_PROT) flags = CLASS_IS_PROTECTED; hdrcode = scope -> hdrcode; } else hdrcode = NULL; if (pt -> genc) { /* C structs are always global types. */ while (fqname -> next != NULL) fqname = fqname -> next; scope = NULL; } cd = findClass(pt,iftype,fqname); /* Check it hasn't already been defined. */ if (iftype != namespace_iface && cd->iff->module != NULL) yyerror("The struct/class has already been defined"); /* Complete the initialisation. */ cd -> classflags |= flags; cd -> ecd = scope; cd -> hdrcode = hdrcode; cd -> iff -> module = currentModule; /* See if it is a namespace extender. */ if (iftype == namespace_iface) { classDef *ns; for (ns = pt->classes; ns != NULL; ns = ns->next) { if (ns == cd) continue; if (ns->iff->type != namespace_iface) continue; if (!sameScopedName(ns->iff->fqcname, fqname)) continue; cd->real = ns; break; } } return cd;}/* * Tidy up after finishing a class definition. */static void finishClass(sipSpec *pt, moduleDef *mod, classDef *cd, optFlags *of){ char *pyname; /* Get the Python name and see if it is different to the C++ name. */ pyname = getPythonName(of, classBaseName(cd)); cd -> pyname = NULL; checkAttributes(pt, cd->ecd, pyname, FALSE); cd->pyname = pyname; if (cd->pyname != classBaseName(cd)) setIsRenamedClass(cd); if (isOpaque(cd)) { if (findOptFlag(of, "External", bool_flag) != NULL) setIsExternal(cd); } else { int seq_might, seq_not; memberDef *md; if (cd -> ctors == NULL) { /* Provide a default ctor. */ cd -> ctors = sipMalloc(sizeof (ctorDef)); cd -> ctors -> ctorflags = SECT_IS_PUBLIC; cd -> ctors -> pysig.nrArgs = 0; cd -> ctors -> cppsig = &cd -> ctors -> pysig; cd -> ctors -> exceptions = NULL; cd -> ctors -> methodcode = NULL; cd -> ctors -> prehook = NULL; cd -> ctors -> posthook = NULL; cd -> ctors -> next = NULL; cd -> defctor = cd -> ctors; setCanCreate(cd); } else if (cd -> defctor == NULL) { ctorDef *ct, *last = NULL; for (ct = cd -> ctors; ct != NULL; ct = ct -> next) { if (!isPublicCtor(ct)) continue; if (ct -> pysig.nrArgs == 0 || ct -> pysig.args[0].defval != NULL) { cd -> defctor = ct; break; } if (last == NULL) last = ct; } /* The last resort is the first public ctor. */ if (cd->defctor == NULL) cd->defctor = last; } if (findOptFlag(of,"Abstract",bool_flag) != NULL) { setIsAbstractClass(cd); setIsIncomplete(cd); resetCanCreate(cd); } /* We assume a public dtor if nothing specific was provided. */ if (!isDtor(cd)) setIsPublicDtor(cd); if (findOptFlag(of, "DelayDtor", bool_flag) != NULL) { setIsDelayedDtor(cd); setHasDelayedDtors(mod); } /* * There are subtle differences between the add and concat * methods and the multiply and repeat methods. The number * versions can have their operands swapped and may return * NotImplemented. If the user has used the /Numeric/ * annotation or there are other numeric operators then we use * add/multiply. Otherwise, if there are indexing operators * then we use concat/repeat. */ seq_might = seq_not = FALSE; for (md = cd -> members; md != NULL; md = md -> next) switch (md -> slot) { case getitem_slot: case setitem_slot: case delitem_slot: /* This might be a sequence. */ seq_might = TRUE; break; case sub_slot: case isub_slot: case div_slot: case idiv_slot: case mod_slot: case imod_slot: case pos_slot: case neg_slot: /* This is definately not a sequence. */ seq_not = TRUE; break; } if (!seq_not && seq_might) for (md = cd -> members; md != NULL; md = md -> next) { /* Ignore if the user has been explicit. */ if (isNumeric(md)) continue; switch (md -> slot) { case add_slot: md -> slot = concat_slot; break; case iadd_slot: md -> slot = iconcat_slot; break; case mul_slot: md -> slot = repeat_slot; break; case imul_slot: md -> slot = irepeat_slot; break; } } } if (inMainModule()) { setIsUsedName(cd->iff->name); setIsClassName(cd->iff->name); }}/* * Create a new mapped type. */static mappedTypeDef *newMappedType(sipSpec *pt,argDef *ad){ mappedTypeDef *mtd; scopedNameDef *snd; ifaceFileDef *iff; /* Check that the type is one we want to map. */ switch (ad -> atype) { case defined_type: snd = ad -> u.snd; break; case template_type: snd = ad -> u.td -> fqname; break; case struct_type: snd = ad -> u.sname; break; default: yyerror("Invalid type for %MappedType"); } iff = findIfaceFile(pt, currentModule, snd, mappedtype_iface, ad); if (inMainModule()) setIsUsedName(iff -> name); /* Check it hasn't already been defined. */ for (mtd = pt -> mappedtypes; mtd != NULL; mtd = mtd -> next) if (mtd -> iff == iff) { /* * We allow types based on the same template but with * different arguments. */ if (ad -> atype != template_type || sameBaseType(ad,&mtd -> type)) yyerror("Mapped type has already been defined in this module"); } /* The module may not have been set yet. */ iff -> module = currentModule; /* Create a new mapped type. */ mtd = allocMappedType(ad); mtd -> iff = iff; mtd -> next = pt -> mappedtypes; pt -> mappedtypes = mtd; return mtd;}/* * Allocate, intialise and return a mapped type structure. */mappedTypeDef *allocMappedType(argDef *type){ mappedTypeDef *mtd; mtd = sipMalloc(sizeof (mappedTypeDef)); mtd->type = *type; mtd->type.argflags = 0; mtd->type.nrderefs = 0; mtd->mappednr = -1; mtd->iff = NULL; mtd->hdrcode = NULL; mtd->convfromcode = NULL; mtd->convtocode = NULL; mtd->next = NULL; return mtd;}/* * Create a new enum. */static enumDef *newEnum(sipSpec *pt,moduleDef *mod,char *name,optFlags *of, int flags){ enumDef *ed; classDef *escope = currentScope(); ed = sipMalloc(sizeof (enumDef)); if (name != NULL) { ed -> fqcname = text2scopedName(name); ed -> pyname = cacheName(pt, getPythonName(of, name)); checkAttributes(pt, escope, ed->pyname->text, FALSE); } else { ed -> fqcname = NULL; ed -> pyname = NULL; } ed -> enumflags = flags; ed -> enumnr = -1; ed -> ecd = escope; ed -> pcd = (flags & SECT_IS_PROT) ? escope : NULL; ed -> module = mod; ed -> members = NULL; ed -> slots = NULL; ed -> overs = NULL; ed -> next = pt -> enums; if (name != NULL && strcmp(ed->pyname->text, name) != 0) setIsRenamedEnum(ed); pt -> enums = ed; if (escope != NULL) setHasEnums(escope); return ed;}/* * Get the type values and (optionally) the type names for substitution in * handwritten code. */void appendTypeStrings(scopedNameDef *ename, signatureDef *patt, signatureDef *src, signatureDef *known, scopedNameDef **names, scopedNameDef **values){ int a; for (a = 0; a < patt->nrArgs; ++a) { argDef *pad = &patt->args[a]; char *ts; if (pad->atype == defined_type) { char *nam = NULL; /* * If the type names are already known then check that * this is one of them.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -