diff options
author | dimitri <dimitri@afe2bf4a-e733-0410-8a33-86f594647bc7> | 2002-08-11 20:15:10 (GMT) |
---|---|---|
committer | dimitri <dimitri@afe2bf4a-e733-0410-8a33-86f594647bc7> | 2002-08-11 20:15:10 (GMT) |
commit | 17e35fd285d98df3c7fe59ee8805152726c3572e (patch) | |
tree | 9e4492a0b5642a047896b46030df4d8a97e2f4f8 /src/util.cpp | |
parent | 5d63a37e7097d6a0467da4895296688abd366b0a (diff) | |
download | Doxygen-17e35fd285d98df3c7fe59ee8805152726c3572e.zip Doxygen-17e35fd285d98df3c7fe59ee8805152726c3572e.tar.gz Doxygen-17e35fd285d98df3c7fe59ee8805152726c3572e.tar.bz2 |
Release-1.2.17-20020811
Diffstat (limited to 'src/util.cpp')
-rw-r--r-- | src/util.cpp | 378 |
1 files changed, 183 insertions, 195 deletions
diff --git a/src/util.cpp b/src/util.cpp index 5b0ed19..5be38ca 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -2274,92 +2274,61 @@ static bool isLowerCase(QCString &s) return TRUE; } -/*! - * generate a reference to a class, namespace or member. - * `scName' is the name of the scope that contains the documentation - * string that is returned. - * `name' is the name that we want to link to. - * `name' may have five formats: - * 1) "ScopeName" - * 2) "memberName()" one of the (overloaded) function or define - * with name memberName. - * 3) "memberName(...)" a specific (overloaded) function or define - * with name memberName - * 4) "::name a global variable or define - * 4) "#memberName member variable, global variable or define - * 5) ("ScopeName::")+"memberName()" - * 6) ("ScopeName::")+"memberName(...)" - * 7) ("ScopeName::")+"memberName" - * instead of :: the # symbol may also be used. - */ -bool generateRef(OutputDocInterface &od,const char *scName, - const char *name,bool inSeeBlock,const char *rt) + +/*! Returns an object to reference to given its name and context + * @post return value TRUE implies *resContext!=0 or *resMember!=0 + */ +bool resolveRef(/* in */ const char *scName, + /* in */ const char *name, + /* in */ bool inSeeBlock, + /* out */ Definition **resContext, + /* out */ MemberDef **resMember + ) { - //printf("generateRef(scName=%s,name=%s,rt=%s)\n",scName,name,rt); + //printf("resolveRef(scName=%s,name=%s,inSeeBlock=%d,rt=%s)\n",scName,name,inSeeBlock,rt); QCString tsName = name; bool memberScopeFirst = tsName.find('#')!=-1; - QCString tmpName = substitute(tsName,"#","::"); - QCString linkText = rt; - int scopePos=tmpName.findRev("::"); - int bracePos=tmpName.findRev('('); // reverse is needed for operator()(...) + QCString fullName = substitute(tsName,"#","::"); + int scopePos=fullName.findRev("::"); + int bracePos=fullName.findRev('('); // reverse is needed for operator()(...) + + // default result values + *resContext=0; + *resMember=0; + if (bracePos==-1) // simple name { ClassDef *cd=0; NamespaceDef *nd=0; - if (linkText.isEmpty()) - { - linkText=tmpName; - // strip :: prefix if present - if (linkText.at(0)==':' && linkText.at(1)==':') - { - linkText=linkText.right(linkText.length()-2); - } - } - if (scopePos==-1 && isLowerCase(tsName)) { // link to lower case only name => do not try to autolink - od.docify(linkText); - // text has been written, stop now. return FALSE; } //printf("scName=%s tmpName=%s\n",scName,tmpName.data()); // check if this is a class or namespace reference - if (scName!=tmpName && getScopeDefs(scName,name,cd,nd)) + if (scName!=fullName && getScopeDefs(scName,name,cd,nd)) { if (cd) // scope matches that of a class { - od.writeObjectLink(cd->getReference(), - cd->getOutputFileBase(),0,linkText); - if (!cd->isReference() /*&& !Config_getBool("PDF_HYPERLINKS")*/) - { - writePageRef(od,cd->getOutputFileBase(),0); - } + *resContext = cd; } else // scope matches that of a namespace { - od.writeObjectLink(nd->getReference(), - nd->getOutputFileBase(),0,linkText); - if (!nd->getReference() /*&& !Config_getBool("PDF_HYPERLINKS")*/) - { - writePageRef(od,nd->getOutputFileBase(),0); - } + ASSERT(nd!=0); + *resContext = nd; } - // link has been written, stop now. return TRUE; } - else if (scName==tmpName || (!inSeeBlock && scopePos==-1)) // nothing to link => output plain text + else if (scName==fullName || (!inSeeBlock && scopePos==-1)) // nothing to link => output plain text { - od.docify(linkText); - // text has been written, stop now. return FALSE; } // continue search... - linkText = rt; } // extract scope @@ -2368,22 +2337,15 @@ bool generateRef(OutputDocInterface &od,const char *scName, //printf("scopeContext=%s scopeUser=%s\n",scopeContext.data(),scopeUser.data()); // extract userscope+name - int endNamePos=bracePos!=-1 ? bracePos : tmpName.length(); - QCString nameStr=tmpName.left(endNamePos); + int endNamePos=bracePos!=-1 ? bracePos : fullName.length(); + QCString nameStr=fullName.left(endNamePos); // extract arguments QCString argsStr; - if (bracePos!=-1) argsStr=tmpName.right(tmpName.length()-bracePos); + if (bracePos!=-1) argsStr=fullName.right(fullName.length()-bracePos); - // create a default link text if none was explicitly given - if (linkText.isEmpty()) - { - //if (!scopeUser.isEmpty()) linkText=scopeUser+"::"; - linkText=nameStr; - if (linkText.left(2)=="::") linkText=linkText.right(linkText.length()-2); - } - //printf("scope=`%s' name=`%s' arg=`%s' linkText=`%s'\n", - // scopeStr.data(),nameStr.data(),argsStr.data(),linkText.data()); + //printf("scope=`%s' name=`%s' arg=`%s'\n", + // scopeStr.data(),nameStr.data(),argsStr.data()); // strip template specifier // TODO: match against the correct partial template instantiation @@ -2394,14 +2356,11 @@ bool generateRef(OutputDocInterface &od,const char *scName, nameStr=nameStr.left(templPos)+nameStr.right(nameStr.length()-endTemplPos-1); } - MemberDef *md = 0; - ClassDef *cd = 0; - FileDef *fd = 0; + MemberDef *md = 0; + ClassDef *cd = 0; + FileDef *fd = 0; NamespaceDef *nd = 0; - GroupDef *gd = 0; - - //printf("Try with scName=`%s' nameStr=`%s' argsStr=`%s'\n", - // scopeStr.data(),nameStr.data(),argsStr.data()); + GroupDef *gd = 0; // check if nameStr is a member or global. if (getDefs(scopeStr,nameStr,argsStr, @@ -2413,112 +2372,119 @@ bool generateRef(OutputDocInterface &od,const char *scName, ) { //printf("after getDefs md=%p cd=%p fd=%p nd=%p gd=%p\n",md,cd,fd,nd,gd); - QCString anchor; - if (md->isLinkable()) anchor = md->anchor(); - QCString cName,aName; - if (cd) // nameStr is a member of cd - { - //printf("addObjectLink(%s,%s,%s,%s)\n",cd->getReference(), - // cd->getOutputFileBase(),anchor.data(),resultName.stripWhiteSpace().data()); - od.writeObjectLink(cd->getReference(),cd->getOutputFileBase(), - anchor,linkText.stripWhiteSpace()); - cName=cd->getOutputFileBase(); - aName=md->anchor(); - } - else if (nd) // nameStr is a member of nd - { - //printf("writing namespace link\n"); - od.writeObjectLink(nd->getReference(),nd->getOutputFileBase(), - anchor,linkText.stripWhiteSpace()); - cName=nd->getOutputFileBase(); - aName=md->anchor(); - } - else if (fd) // nameStr is a global in file fd - { - //printf("addFileLink(%s,%s,%s)\n",fd->getOutputFileBase(),anchor.data(), - // resultName.stripWhiteSpace().data()); - od.writeObjectLink(fd->getReference(),fd->getOutputFileBase(), - anchor,linkText.stripWhiteSpace()); - cName=fd->getOutputFileBase(); - aName=md->anchor(); - } - else if (gd) - { - //printf("addGroupLink(%s,%s,%s)\n",fd->getOutputFileBase().data(),anchor.data(), - // gd->name().data()); - od.writeObjectLink(gd->getReference(),gd->getOutputFileBase(), - anchor,linkText.stripWhiteSpace()); - cName=gd->getOutputFileBase(); - aName=md->anchor(); - } - else // should not be reached - { - //printf("add no link fd=cd=0\n"); - od.docify(linkText); - } + *resMember=md; + if (cd) *resContext=cd; + else if (nd) *resContext=nd; + else if (fd) *resContext=fd; + else if (gd) *resContext=gd; + else { *resContext=0; *resMember=0; return FALSE; } + return TRUE; + } + else if (inSeeBlock && !nameStr.isEmpty() && (gd=Doxygen::groupSDict[nameStr])) + { // group link + *resContext=gd; + return TRUE; + } - // for functions we add the arguments if explicitly specified or else "()" - if (!rt && (md->isFunction() || md->isPrototype() || md->isSignal() || md->isSlot() || md->isDefine())) - { - if (argsStr.isEmpty() && (!md->isDefine() || md->argsString()!=0)) - // od.writeString("()") - ; - else - od.docify(argsStr); - } + return FALSE; +} + +/*! + * generate a reference to a class, namespace or member. + * `scName' is the name of the scope that contains the documentation + * string that is returned. + * `name' is the name that we want to link to. + * `name' may have five formats: + * 1) "ScopeName" + * 2) "memberName()" one of the (overloaded) function or define + * with name memberName. + * 3) "memberName(...)" a specific (overloaded) function or define + * with name memberName + * 4) "::name a global variable or define + * 4) "#memberName member variable, global variable or define + * 5) ("ScopeName::")+"memberName()" + * 6) ("ScopeName::")+"memberName(...)" + * 7) ("ScopeName::")+"memberName" + * instead of :: the # symbol may also be used. + */ + +bool generateRef(OutputDocInterface &od,const char *scName, + const char *name,bool inSeeBlock,const char *rt) +{ + //printf("generateRef(scName=%s,name=%s,rt=%s)\n",scName,name,rt); + + Definition *compound; + MemberDef *md; - // generate the page reference (for LaTeX) - if ((!cName.isEmpty() || !aName.isEmpty()) && md->isLinkableInProject()) + // create default link text + QCString linkText = rt; + if (linkText.isEmpty()) + { + linkText=substitute(name,"#","::"); + // strip :: prefix if present + if (linkText.at(0)==':' && linkText.at(1)==':') { - writePageRef(od,cName,aName); + linkText=linkText.right(linkText.length()-2); } - return TRUE; } - else if (inSeeBlock && !nameStr.isEmpty() && (gd=Doxygen::groupSDict[nameStr])) - { // group link - od.startTextLink(gd->getOutputFileBase(),0); - if (rt) // explict link text + + if (resolveRef(scName,name,inSeeBlock,&compound,&md)) + { + if (md) // link to member { - od.docify(rt); + od.writeObjectLink(compound->getReference(), + compound->getOutputFileBase(), + md->anchor(),linkText); + // generate the page reference (for LaTeX) + if (!compound->isReference() && !md->anchor().isEmpty() && + md->isLinkableInProject()) + { + writePageRef(od,compound->getOutputFileBase(),md->anchor()); + } } - else // use group title as the default link text + else // link to compound { - od.docify(gd->groupTitle()); + if (rt==0 && compound->definitionType()==Definition::TypeGroup) + { + linkText=((GroupDef *)compound)->groupTitle(); + } + od.writeObjectLink(compound->getReference(), + compound->getOutputFileBase(), + 0,linkText); + if (!compound->isReference()) + { + writePageRef(od,compound->getOutputFileBase(),0); + } } - od.endTextLink(); return TRUE; } - - // nothing found - if (rt) - od.docify(rt); - else + else // no link possible { od.docify(linkText); - if (!argsStr.isEmpty()) od.docify(argsStr); + return FALSE; } - return FALSE; } -//---------------------------------------------------------------------- -// General function that generates the HTML code for a reference to some -// file, class or member from text `lr' within the context of class `clName'. -// This link has the text 'lt' (if not 0), otherwise `lr' is used as a -// basis for the link's text. -// returns TRUE if a link could be generated. - -bool generateLink(OutputDocInterface &od,const char *clName, - const char *lr,bool inSeeBlock,const char *lt) +bool resolveLink(/* in */ const char *scName, + /* in */ const char *lr, + /* in */ bool inSeeBlock, + /* out */ Definition **resContext, + /* out */ PageInfo **resPageInfo, + /* out */ QCString &resAnchor + ) { - //printf("generateLink clName=`%s' lr=`%s' lt=`%s'\n",clName,lr,lt); + //printf("resolveLink clName=`%s' lr=`%s' lt=`%s'\n",clName,lr,lt); + + *resContext=0; + *resPageInfo=0; + QCString linkRef=lr; - FileDef *fd; + FileDef *fd; GroupDef *gd; PageInfo *pi; bool ambig; if (linkRef.isEmpty()) // no reference name! { - od.docify(lt); return FALSE; } else if ((pi=Doxygen::pageSDict->find(linkRef))) // link to a page @@ -2528,62 +2494,84 @@ bool generateLink(OutputDocInterface &od,const char *clName, { SectionInfo *si=0; if (!pi->name.isEmpty()) si=Doxygen::sectionDict[pi->name]; - od.writeObjectLink(gd->getReference(),gd->getOutputFileBase(),si ? si->label.data() : 0,lt); - if (gd->isLinkableInProject()) - { - writePageRef(od,gd->getOutputFileBase(),si ? si->label.data() : 0); - } + *resContext=gd; + if (si) resAnchor = si->label; } else { - od.writeObjectLink(pi->getReference(),pi->getOutputFileBase(),0,lt); - if (!pi->isReference()) - { - writePageRef(od,pi->name,0); - } + *resPageInfo=pi; } return TRUE; } else if ((pi=Doxygen::exampleSDict->find(linkRef))) // link to an example { - od.writeObjectLink(0,convertNameToFile(pi->name+"-example"),0,lt); - if (!pi->isReference()) - { - writePageRef(od,convertNameToFile(pi->name+"-example"),0); - } + *resPageInfo=pi; return TRUE; } else if ((gd=Doxygen::groupSDict[linkRef])) // link to a group { - //od.startTextLink(gd->getOutputFileBase(),0); - //if (lt) - // od.docify(lt); - //else - // od.docify(gd->groupTitle()); - //od.endTextLink(); - QCString title; - if (lt) title=lt; else title=gd->groupTitle(); - od.writeObjectLink(gd->getReference(),gd->getOutputFileBase(),0,title); - if (gd->isLinkableInProject()) - { - writePageRef(od,gd->getOutputFileBase(),0); - } + *resContext=gd; + return TRUE; + } + else if ((fd=findFileDef(Doxygen::inputNameDict,linkRef,ambig)) // file link + && fd->isLinkable()) + { + *resContext=fd; return TRUE; } - else if ((fd=findFileDef(Doxygen::inputNameDict,linkRef,ambig)) - && fd->isLinkable()) + else // probably a class or member reference { - // link to documented input file - od.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),0,lt); - if (fd->isLinkableInProject()) + MemberDef *md; + bool res = resolveRef(scName,lr,inSeeBlock,resContext,&md); + if (md) resAnchor=md->anchor(); + return res; + } +} + + +//---------------------------------------------------------------------- +// General function that generates the HTML code for a reference to some +// file, class or member from text `lr' within the context of class `clName'. +// This link has the text 'lt' (if not 0), otherwise `lr' is used as a +// basis for the link's text. +// returns TRUE if a link could be generated. + +bool generateLink(OutputDocInterface &od,const char *clName, + const char *lr,bool inSeeBlock,const char *lt) +{ + Definition *compound; + PageInfo *pageInfo; + QCString anchor,linkText=lt; + if (resolveLink(clName,lr,inSeeBlock,&compound,&pageInfo,anchor)) + { + if (pageInfo) // link to page { - writePageRef(od,fd->getOutputFileBase(),0); + od.writeObjectLink(pageInfo->getReference(), + pageInfo->getOutputFileBase(),anchor,linkText); + if (!pageInfo->isReference()) + { + writePageRef(od,pageInfo->getOutputFileBase(),anchor); + } + } + else if (compound) // link to compound + { + if (lt==0 && compound->definitionType()==Definition::TypeGroup) + { + linkText=((GroupDef *)compound)->groupTitle(); + } + od.writeObjectLink(compound->getReference(), + compound->getOutputFileBase(),anchor,linkText); + if (!compound->isReference()) + { + writePageRef(od,compound->getOutputFileBase(),anchor); + } } return TRUE; } - else // probably a class or member reference + else // link could not be found { - return generateRef(od,clName,lr,inSeeBlock,lt); + od.docify(linkText); + return FALSE; } } @@ -3408,8 +3396,8 @@ void addRelatedPage(const char *name,const QCString &ptitle, QCString baseName=name; if (baseName.right(4)==".tex") baseName=baseName.left(baseName.length()-4); - else if (baseName.right(htmlFileExtensionLength)==htmlFileExtension) - baseName=baseName.left(baseName.length()-htmlFileExtensionLength); + else if (baseName.right(Doxygen::htmlFileExtension.length())==Doxygen::htmlFileExtension) + baseName=baseName.left(baseName.length()-Doxygen::htmlFileExtension.length()); QCString title=ptitle.stripWhiteSpace(); pi=new PageInfo(fileName,startLine,baseName,doc,title); |