📄 util.cpp
字号:
} else if (!dstA->name.isEmpty()) { srcA->name = dstA->name.copy(); } else if (!srcA->name.isEmpty()) { dstA->name = srcA->name.copy(); }done: //printf("merge argument result %s:%s <-> %s:%s\n", // srcA->type.data(),srcA->name.data(), // dstA->type.data(),dstA->name.data()); return;}/*! * Matches the arguments list srcAl with the argument list dstAl * Returns TRUE if the argument lists are equal. Two argument list are * considered equal if the number of arguments is equal and the types of all * arguments are equal. Furthermore the const and volatile specifiers * stored in the list should be equal. */bool matchArguments(ArgumentList *srcAl,ArgumentList *dstAl, const char *cl,const char *ns,bool checkCV, NamespaceList *usingNamespaces, ClassList *usingClasses){ QCString className=cl; QCString namespaceName=ns; // strip template specialization from class name if present //int til=className.find('<'),tir=className.find('>'); //if (til!=-1 && tir!=-1 && tir>til) //{ // className=className.left(til)+className.right(className.length()-tir-1); //} //printf("matchArguments(%s,%s) className=%s namespaceName=%s checkCV=%d usingNamespaces=%d usingClasses=%d\n", // srcAl ? argListToString(srcAl).data() : "", // dstAl ? argListToString(dstAl).data() : "", // cl,ns,checkCV, // usingNamespaces?usingNamespaces->count():0, // usingClasses?usingClasses->count():0 // ); if (srcAl==0 || dstAl==0) { bool match = srcAl==dstAl; // at least one of the members is not a function if (match) { MATCH return TRUE; } else { NOMATCH return FALSE; } } // handle special case with void argument if ( srcAl->count()==0 && dstAl->count()==1 && dstAl->getFirst()->type=="void" ) { // special case for finding match between func() and func(void) Argument *a=new Argument; a->type = "void"; srcAl->append(a); MATCH return TRUE; } if ( dstAl->count()==0 && srcAl->count()==1 && srcAl->getFirst()->type=="void" ) { // special case for finding match between func(void) and func() Argument *a=new Argument; a->type = "void"; dstAl->append(a); MATCH return TRUE; } if (srcAl->count() != dstAl->count()) { NOMATCH return FALSE; // different number of arguments -> no match } if (checkCV) { if (srcAl->constSpecifier != dstAl->constSpecifier) { NOMATCH return FALSE; // one member is const, the other not -> no match } if (srcAl->volatileSpecifier != dstAl->volatileSpecifier) { NOMATCH return FALSE; // one member is volatile, the other not -> no match } } // so far the argument list could match, so we need to compare the types of // all arguments. ArgumentListIterator srcAli(*srcAl),dstAli(*dstAl); Argument *srcA,*dstA; for (;(srcA=srcAli.current(),dstA=dstAli.current());++srcAli,++dstAli) { if (!matchArgument(srcA,dstA,className,namespaceName, usingNamespaces,usingClasses)) { NOMATCH return FALSE; } } // merge/correct argument type/names for (srcAli.toFirst(),dstAli.toFirst(); (srcA=srcAli.current(),dstA=dstAli.current()); ++srcAli,++dstAli ) { mergeArgument(srcA,dstA,className,namespaceName, usingNamespaces,usingClasses); } MATCH return TRUE; // all arguments match }// merges the initializer of two argument lists// pre: the types of the arguments in the list should match.void mergeArguments(ArgumentList *srcAl,ArgumentList *dstAl){ //printf("mergeArguments `%s', `%s'\n", // argListToString(srcAl).data(),argListToString(dstAl).data()); if (srcAl==0 || dstAl==0 || srcAl->count()!=dstAl->count()) { return; // invalid argument lists -> do not merge } ArgumentListIterator srcAli(*srcAl),dstAli(*dstAl); Argument *srcA,*dstA; for (;(srcA=srcAli.current(),dstA=dstAli.current());++srcAli,++dstAli) { if (srcA->defval.isEmpty() && !dstA->defval.isEmpty()) { //printf("Defval changing `%s'->`%s'\n",srcA->defval.data(),dstA->defval.data()); srcA->defval=dstA->defval.copy(); } else if (!srcA->defval.isEmpty() && dstA->defval.isEmpty()) { //printf("Defval changing `%s'->`%s'\n",dstA->defval.data(),srcA->defval.data()); dstA->defval=srcA->defval.copy(); } if (srcA->type==dstA->type) { if (srcA->name.isEmpty() && !dstA->name.isEmpty()) { //printf("type: `%s':=`%s'\n",srcA->type.data(),dstA->type.data()); //printf("name: `%s':=`%s'\n",srcA->name.data(),dstA->name.data()); srcA->type = dstA->type.copy(); srcA->name = dstA->name.copy(); } else if (!srcA->name.isEmpty() && dstA->name.isEmpty()) { //printf("type: `%s':=`%s'\n",dstA->type.data(),srcA->type.data()); //printf("name: `%s':=`%s'\n",dstA->name.data(),srcA->name.data()); dstA->type = srcA->type.copy(); dstA->name = dstA->name.copy(); } else if (!srcA->name.isEmpty() && !dstA->name.isEmpty()) { srcA->name = dstA->name.copy(); } } int i1=srcA->type.find("::"), i2=dstA->type.find("::"), j1=srcA->type.length()-i1-2, j2=dstA->type.length()-i2-2; if (i1!=-1 && i2==-1 && srcA->type.right(j1)==dstA->type) { //printf("type: `%s':=`%s'\n",dstA->type.data(),srcA->type.data()); //printf("name: `%s':=`%s'\n",dstA->name.data(),srcA->name.data()); dstA->type = srcA->type.left(i1+2)+dstA->type; dstA->name = dstA->name.copy(); } else if (i1==-1 && i2!=-1 && dstA->type.right(j2)==srcA->type) { //printf("type: `%s':=`%s'\n",srcA->type.data(),dstA->type.data()); //printf("name: `%s':=`%s'\n",dstA->name.data(),srcA->name.data()); srcA->type = dstA->type.left(i2+2)+srcA->type; srcA->name = dstA->name.copy(); } if (srcA->docs.isEmpty() && !dstA->docs.isEmpty()) { srcA->docs = dstA->docs.copy(); } else if (dstA->docs.isEmpty() && !srcA->docs.isEmpty()) { dstA->docs = srcA->docs.copy(); } } //printf("result mergeArguments `%s', `%s'\n", // argListToString(srcAl).data(),argListToString(dstAl).data());}/*! * Searches for a member definition given its name `memberName' as a string. * memberName may also include a (partial) scope to indicate the scope * in which the member is located. * * The parameter `scName' is a string representing the name of the scope in * which the link was found. * * In case of a function args contains a string representation of the * argument list. Passing 0 means the member has no arguments. * Passing "()" means any argument list will do, but "()" is preferred. * * The function returns TRUE if the member is known and documented or * FALSE if it is not. * If TRUE is returned parameter `md' contains a pointer to the member * definition. Furthermore exactly one of the parameter `cd', `nd', or `fd' * will be non-zero: * - if `cd' is non zero, the member was found in a class pointed to by cd. * - if `nd' is non zero, the member was found in a namespace pointed to by nd. * - if `fd' is non zero, the member was found in the global namespace of * file fd. */bool getDefs(const QCString &scName,const QCString &memberName, const char *args, MemberDef *&md, ClassDef *&cd, FileDef *&fd, NamespaceDef *&nd, GroupDef *&gd, bool forceEmptyScope, FileDef *currentFile ){ fd=0, md=0, cd=0, nd=0, gd=0; if (memberName.isEmpty()) return FALSE; /* empty name => nothing to link */ QCString scopeName=scName.copy(); //printf("Search for name=%s args=%s in scope=%s\n", // memberName.data(),args,scopeName.data()); int is,im=0,pm=0; // strip common part of the scope from the scopeName while ((is=scopeName.findRev("::"))!=-1 && (im=memberName.find("::",pm))!=-1 && (scopeName.right(scopeName.length()-is-2)==memberName.mid(pm,im-pm)) ) { scopeName=scopeName.left(is); pm=im+2; } //printf("result after scope corrections scope=%s name=%s\n", // scopeName.data(),memberName.data()); QCString mName=memberName; QCString mScope; if (memberName.left(9)!="operator " && // treat operator conversion methods // as a special case (im=memberName.findRev("::"))!=-1 ) { mScope=memberName.left(im); mName=memberName.right(memberName.length()-im-2); } // handle special the case where both scope name and member scope are equal if (mScope==scopeName) scopeName.resize(0); //printf("mScope=`%s' mName=`%s'\n",mScope.data(),mName.data()); MemberName *mn = Doxygen::memberNameSDict[mName]; if (!forceEmptyScope && mn && !(scopeName.isEmpty() && mScope.isEmpty())) { //printf(" >member name found\n"); int scopeOffset=scopeName.length(); do { QCString className = scopeName.left(scopeOffset); if (!className.isEmpty() && !mScope.isEmpty()) { className+="::"+mScope; } else if (!mScope.isEmpty()) { className=mScope.copy(); } //printf("Trying class scope %s\n",className.data()); ClassDef *fcd=0; if ((fcd=getResolvedClass(Doxygen::globalScope,className)) && // is it a documented class fcd->isLinkable() ) { //printf(" Found fcd=%p\n",fcd); MemberListIterator mmli(*mn); MemberDef *mmd; int mdist=maxInheritanceDepth; ArgumentList *argList=0; if (args) { argList=new ArgumentList; stringToArgumentList(args,argList); } for (mmli.toFirst();(mmd=mmli.current());++mmli) { if (mmd->isLinkable()) { bool match=args==0 || matchArguments(mmd->argumentList(),argList,className,0,FALSE); //printf("match=%d\n",match); if (match) { ClassDef *mcd=mmd->getClassDef(); int m=minClassDistance(fcd,mcd); if (m<mdist && mcd->isLinkable()) { mdist=m; cd=mcd; md=mmd; } } } } if (argList) { delete argList; argList=0; } if (mdist==maxInheritanceDepth && !strcmp(args,"()")) // no exact match found, but if args="()" an arbitrary member will do { //printf(" >Searching for arbitrary member\n"); for (mmli.toFirst();(mmd=mmli.current());++mmli) { if (//(mmd->protection()!=Private || Config_getBool("EXTRACT_PRIVATE")) && //( //mmd->hasDocumentation() /*mmd->detailsAreVisible()*/ //|| mmd->isReference() //) mmd->isLinkable() ) { ClassDef *mcd=mmd->getClassDef(); //printf(" >Class %s found\n",mcd->name().data()); int m=minClassDistance(fcd,mcd); if (m<mdist && mcd->isLinkable()) { //printf("Class distance %d\n",m); mdist=m; cd=mcd; md=mmd; } } } } //printf(" >Succes=%d\n",mdist<maxInheritanceDepth); if (mdist<maxInheritanceDepth) { gd=md->getGroupDef(); if (gd) cd=0; return TRUE; /* found match */ } } /* go to the parent scope */ if (scopeOffset==0) { scopeOffset=-1; } else if ((scopeOffset=scopeName.findRev("::",scopeOffset-1))==-1) { scopeOffset=0; } } while (scopeOffset>=0); // unknown or undocumented scope } // maybe an namespace, file or group member ? //printf("Testing for global function scopeName=`%s' mScope=`%s' :: mName=`%s'\n", // scopeName.data(),mScope.data(),mName.data()); if ((mn=Doxygen::functionNameSDict[mName])) // name is known { //printf(" >function name found\n"); NamespaceDef *fnd=0; int scopeOffset=scopeName.length(); do { QCString namespaceName = scopeName.left(scopeOffset); if (!namespaceName.isEmpty() && !mScope.isEmpty()) { namespaceName+="::"+mScope; } else if (!mScope.isEmpty()) { namespaceName=mScope.copy(); } if (!namespaceName.isEmpty() && (fnd=Doxygen::namespaceSDict[namespaceName]) && fnd->isLinkable() ) { //printf("Function inside existing namespace `%s'\n",namespaceName.data()); bool found=FALSE; MemberListIterator mmli(*mn); MemberDef *mmd; for (mmli.toFirst();((mmd=mmli.current()) && !found);++mmli) { //printf("mmd->getNamespaceDef()=%p fnd=%p\n", // mmd->getNamespaceDef(),fnd); if (mmd->getNamespaceDef()==fnd && mmd->isLinkable()) { // namespace is found bool match=TRUE; ArgumentList *argList=0; if (args) { argList=new ArgumentList; stringToArgumentList(args,argList); match=matchArguments(mmd->argumentList(),argList,0, namespaceName,FALSE); } if (match) { nd=fnd; md=mmd; found=TRUE; } if (args) { delete argList; argList=0; } } } if (!found && !strcmp(args,"()")) // no exact match found, but if args="()" an arbitrary // member will do { for (mmli.toFirst();((mmd=mmli.current()) && !found);++mmli) { if (mmd->getNamespaceDef()==fnd && mmd->isLinkable()) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -