summaryrefslogtreecommitdiffstats
path: root/src/util.cpp
diff options
context:
space:
mode:
authorDimitri van Heesch <dimitri@stack.nl>1999-12-15 19:34:06 (GMT)
committerDimitri van Heesch <dimitri@stack.nl>1999-12-15 19:34:06 (GMT)
commitee8333a5d2ecf84deeb5d05ed8b23c212729cdac (patch)
tree43e0b215b5d3d2b436509cbb1cd22102aef61b1d /src/util.cpp
parent6aa7383e23c850af36c25b87e5737a2e2f635083 (diff)
downloadDoxygen-ee8333a5d2ecf84deeb5d05ed8b23c212729cdac.zip
Doxygen-ee8333a5d2ecf84deeb5d05ed8b23c212729cdac.tar.gz
Doxygen-ee8333a5d2ecf84deeb5d05ed8b23c212729cdac.tar.bz2
mods for doxygen-0.49-990829
Diffstat (limited to 'src/util.cpp')
-rw-r--r--src/util.cpp1156
1 files changed, 150 insertions, 1006 deletions
diff --git a/src/util.cpp b/src/util.cpp
index 49fdee5..d8a4772 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -29,6 +29,7 @@
#include "defargs.h"
#include "language.h"
#include "config.h"
+#include "htmlhelp.h"
// an inheritance tree of depth of 100000 should be enough for everyone :-)
const int maxInheritanceDepth = 100000;
@@ -58,6 +59,23 @@ QCString generateMarker(int id)
return result;
}
+// strip part of the path if it matches
+// one of the paths in the stripFromPath list
+QCString stripFromPath(const QCString &path)
+{
+ const char *s=Config::stripFromPath.first();
+ while (s)
+ {
+ QCString prefix = s;
+ if (path.left(prefix.length())==prefix)
+ {
+ return path.right(path.length()-prefix.length());
+ }
+ s = Config::stripFromPath.next();
+ }
+ return path;
+}
+
// try to determine if this files is a source or a header file by looking
// at the extension (5 variations are allowed in both upper and lower case)
// If anyone knows or uses another extension please let me know :-)
@@ -74,7 +92,8 @@ int guessSection(const char *name)
n.right(3)==".hh" ||
n.right(4)==".hxx" ||
n.right(4)==".hpp" ||
- n.right(4)==".h++"
+ n.right(4)==".h++" ||
+ n.right(4)==".idl"
) return Entry::HEADER_SEC;
return 0;
}
@@ -140,64 +159,27 @@ QCString removeRedundantWhiteSpace(const QCString &s)
return result;
}
-void writeTemplatePrefix(OutputList &ol,ArgumentList *al)
+
+
+bool rightScopeMatch(const QCString &scope, const QCString &name)
{
- ol.docify("template<");
- Argument *a=al->first();
- while (a)
- {
- ol.docify(a->type);
- ol.docify(a->name);
- if (a->defval.length()!=0)
- {
- ol.docify(" = ");
- ol.docify(a->defval);
- }
- a=al->next();
- if (a) ol.docify(", ");
- }
- ol.docify("> ");
- bool latexEnabled = ol.isEnabled(OutputGenerator::Latex);
- bool manEnabled = ol.isEnabled(OutputGenerator::Man);
- if (latexEnabled) ol.disable(OutputGenerator::Latex);
- if (manEnabled) ol.disable(OutputGenerator::Man);
- ol.lineBreak();
- if (latexEnabled) ol.enable(OutputGenerator::Latex);
- if (manEnabled) ol.enable(OutputGenerator::Man);
+ return (name==scope || // equal
+ (scope.right(name.length())==name && // substring
+ scope.at(scope.length()-name.length()-1)==':' // scope
+ )
+ );
}
-QCString addTemplateNames(const QCString &s,const QCString &n,const QCString &t)
+bool leftScopeMatch(const QCString &scope, const QCString &name)
{
- //printf("addTemplateNames(%s)\n",s.data());
- QCString result;
- QCString clRealName=n;
- int p=0,i;
- if ((i=clRealName.find('<'))!=-1)
- {
- clRealName=clRealName.left(i); // strip template specialization
- }
- while ((i=s.find(clRealName,p))!=-1)
- {
- result+=s.mid(p,i-p);
- uint j=clRealName.length()+i;
- if (s.length()==j || (s.at(j)!='<' && !isId(s.at(j))))
- { // add template names
- //printf("Adding %s+%s\n",clRealName.data(),t.data());
- result+=clRealName+t;
- }
- else
- { // template names already present
- //printf("Adding %s\n",clRealName.data());
- result+=clRealName;
- }
- p=i+clRealName.length();
- }
- result+=s.right(s.length()-p);
- //printf("result=%s\n",result.data());
- return result;
+ return (name==scope || // equal
+ (scope.left(name.length())==name && // substring
+ scope.at(name.length())==':' // scope
+ )
+ );
}
-static void linkifyText(OutputList &ol,const char *scName,const char *name,const char *text)
+void linkifyText(OutputList &ol,const char *scName,const char *name,const char *text)
{
//printf("scope=`%s' name=`%s' Text: `%s'\n",scName,name,text);
QRegExp regExp("[a-z_A-Z0-9:<>]+");
@@ -214,19 +196,20 @@ static void linkifyText(OutputList &ol,const char *scName,const char *name,const
result.docify(txtStr.mid(skipIndex,newIndex-skipIndex));
// get word from string
QCString word=txtStr.mid(newIndex,matchLen);
- ClassDef *cd=0;
- FileDef *fd=0;
- MemberDef *md=0;
+ ClassDef *cd=0;
+ FileDef *fd=0;
+ MemberDef *md=0;
NamespaceDef *nd=0;
QCString scopeName=scName;
QCString searchName=name;
//printf("word=`%s' scopeName=`%s' searchName=`%s'\n",
- // word.data(),scopeName.data(),searchName.data());
+ // word.data(),scopeName.data(),searchName.data()
+ // );
// check if `word' is a documented class name
if (word.length()>0 &&
- word.right(searchName.length())!=searchName &&
- word!=scopeName.right(word.length())
+ !rightScopeMatch(word,searchName) &&
+ !rightScopeMatch(scopeName,word)
)
{
//printf("Searching...\n");
@@ -244,7 +227,7 @@ static void linkifyText(OutputList &ol,const char *scName,const char *name,const
if ((cd=getClass(fullName)))
{
// add link to the result
- if (cd->isVisible())
+ if (cd->isLinkable())
{
result.writeObjectLink(cd->getReference(),cd->getOutputFileBase(),0,word);
found=TRUE;
@@ -264,25 +247,15 @@ static void linkifyText(OutputList &ol,const char *scName,const char *name,const
if (!found &&
getDefs(scName,word,0,md,cd,fd,nd) &&
(md->isTypedef() || md->isEnumerate()) &&
- md->hasDocumentation()
+ md->isLinkable()
)
{
- if (cd && cd->isVisible()) // fullName is a member of cd
- {
- result.writeObjectLink(cd->getReference(),
- cd->getOutputFileBase(),md->anchor(),word);
- found=TRUE;
- }
- else if (nd && nd->hasDocumentation())
+ Definition *d=0;
+ if (cd) d=cd; else if (nd) d=nd; else d=fd;
+ if (d && d->isLinkable())
{
- result.writeObjectLink(nd->getReference(),
- nd->getOutputFileBase(),md->anchor(),word);
- found=TRUE;
- }
- else if (fd && fd->hasDocumentation()) // fullName is a global in file fd
- {
- result.writeObjectLink(fd->getReference(),
- fd->getOutputFileBase(),md->anchor(),word);
+ result.writeObjectLink(d->getReference(),d->getOutputFileBase(),
+ md->anchor(),word);
found=TRUE;
}
}
@@ -305,70 +278,6 @@ static void linkifyText(OutputList &ol,const char *scName,const char *name,const
ol+=result;
}
-static void writeDefArgumentList(OutputList &ol,ClassDef *cd,
- const QCString &scopeName,MemberDef *md)
-{
- ArgumentList *argList=md->argumentList();
- if (argList==0) return; // member has no function like argument list
- ol.docify(" ("); // start argument list
- Argument *a=argList->first();
- QCString cName;
- if (cd && cd->templateArguments())
- {
- cName=cd->getTemplateNameString();
- }
- while (a)
- {
- QRegExp re(")(");
- int vp;
- if ((vp=a->type.find(re))!=-1) // argument type is a function pointer
- {
- QCString n=a->type.left(vp);
- if (cName.length()>0) n=addTemplateNames(n,cd->name(),cName);
- linkifyText(ol,scopeName,md->name(),n);
- }
- else // non-function pointer type
- {
- QCString n=a->type;
- if (cName.length()>0) n=addTemplateNames(n,cd->name(),cName);
- linkifyText(ol,scopeName,md->name(),n);
- }
- if (a->name.length()>0) // argument has a name
- {
- ol.docify(" ");
- ol.disable(OutputGenerator::Man);
- ol.startEmphasis();
- ol.enable(OutputGenerator::Man);
- ol.docify(a->name);
- ol.disable(OutputGenerator::Man);
- ol.endEmphasis();
- ol.enable(OutputGenerator::Man);
- }
- if (vp!=-1) // write the part of the argument type
- // that comes after the name
- {
- linkifyText(ol,scopeName,md->name(),a->type.right(a->type.length()-vp));
- }
- if (a->defval.length()>0) // write the default value
- {
- QCString n=a->defval;
- if (cName.length()>0) n=addTemplateNames(n,cd->name(),cName);
- ol.docify(" = ");
- linkifyText(ol,scopeName,md->name(),n);
- }
- a=argList->next();
- if (a) ol.docify(", "); // there are more arguments
- }
- ol.docify(")"); // end argument list
- if (argList->constSpecifier)
- {
- ol.docify(" const");
- }
- if (argList->volatileSpecifier)
- {
- ol.docify(" volatile");
- }
-}
void writeExample(OutputList &ol,ExampleList *el)
{
@@ -409,37 +318,53 @@ QCString argListToString(ArgumentList *al)
if (al->volatileSpecifier) result+=" volatile";
return result;
}
-
-static void writeLink(OutputList &ol,ClassDef *cd,NamespaceDef *nd,
- FileDef *fd,MemberDef *md,const char *name)
-{
- if (nd)
- ol.writeObjectLink(nd->getReference(),nd->getOutputFileBase(),
- md->anchor(),name);
- else if (fd)
- ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),
- md->anchor(),name);
- else
- ol.writeObjectLink(cd->getReference(),cd->getOutputFileBase(),
- md->anchor(),name);
-}
-static void warnForUndocumentedMember(MemberDef *md)
+//QCString tempArgListToString(ArgumentList *al)
+//{
+// QCString result;
+// if (al==0) return result;
+// Argument *a=al->first();
+// result+="<";
+// while (a)
+// {
+// int ni=a->type.findRev(' ');
+// if (ni!=-1)
+// result+=a->type.right(a->type.length()-ni-1);
+// else
+// result+=a->type;
+// a = al->next();
+// if (a) result+=",";
+// }
+// result+=">";
+// return result;
+//}
+
+QCString tempArgListToString(ArgumentList *al)
{
- ClassDef *cd=md->memberClass();
- FileDef *fd=md->getFileDef();
- if (cd)
- {
- if (!md->hasDocumentation() && md->name() && md->name()[0]!='@')
- warn("Warning: Member %s of class %s is not documented\n",
- md->name().data(),cd->name().data());
- }
- else if (fd)
+ QCString result;
+ if (!al || al->count()==0) return result;
+ result="<";
+ Argument *a=al->first();
+ while (a)
{
- if (!md->hasDocumentation() && md->name() && md->name()[0]!='@')
- warn("Warning: Member %s of file %s is not documented\n",
- md->name().data(),fd->name().data());
+ if (a->name.length()>0) // add template argument name
+ {
+ result+=a->name;
+ }
+ else // extract name from type
+ {
+ int i=a->type.length()-1;
+ while (i>=0 && isId(a->type.at(i))) i--;
+ if (i>0)
+ {
+ result+=a->type.right(a->type.length()-i-1);
+ }
+ }
+ a=al->next();
+ if (a) result+=", ";
}
+ result+=">";
+ return result;
}
static bool manIsEnabled;
@@ -489,6 +414,13 @@ void writeQuickLinks(OutputList &ol,bool compact,bool ext)
}
if (annotatedClasses>0)
{
+ if (Config::alphaIndexFlag)
+ {
+ if (!compact) ol.writeListItem();
+ ol.startQuickIndexItem(extLink,absPath+"classes.html");
+ parseText(ol,theTranslator->trAlphabeticalList());
+ ol.endQuickIndexItem();
+ }
if (!compact) ol.writeListItem();
ol.startQuickIndexItem(extLink,absPath+"annotated.html");
parseText(ol,theTranslator->trCompoundList());
@@ -501,7 +433,7 @@ void writeQuickLinks(OutputList &ol,bool compact,bool ext)
parseText(ol,theTranslator->trFileList());
ol.endQuickIndexItem();
}
- if (includeFiles.count()>0 && Config::verbatimHeaderFlag)
+ if (documentedIncludeFiles>0 && Config::verbatimHeaderFlag)
{
if (!compact) ol.writeListItem();
ol.startQuickIndexItem(extLink,absPath+"headers.html");
@@ -594,427 +526,6 @@ void endFile(OutputList &ol,bool external)
ol.endFile();
}
-
-static void writeMemberDef(OutputList &ol, ClassDef *cd, NamespaceDef *nd,
- FileDef *fd, MemberDef *md)
-{
- int i,l;
- bool hasDocs=md->hasDocumentation();
- if ((!hasDocs && Config::hideMemberFlag) ||
- (Config::hideMemberFlag &&
- md->documentation().isEmpty() &&
- !Config::briefMemDescFlag &&
- !Config::repeatBriefFlag
- )
- ) return;
- QCString type=md->typeString();
- QRegExp r("@[0-9]+");
- if ((i=r.match(type,0,&l))==-1 || !md->enumUsed())
- {
- // strip `static' keyword from type
- if (type.left(7)=="static ") type=type.right(type.length()-7);
- // strip `friend' keyword from type
- if (type.left(7)=="friend ") type=type.right(type.length()-7);
-
- if (Config::genTagFile.length()>0)
- {
- tagFile << md->name() << " " << md->anchor() << " \""
- << md->argsString() << "\"\n";
- }
-
- QCString cname;
- if (cd) cname=cd->name();
- else if (nd) cname=nd->name();
- else if (fd) cname=fd->name();
-
- ol.startMemberItem();
- // If there is no detailed description we need to write the anchor here.
- bool detailsVisible = md->detailsAreVisible();
- if (!detailsVisible && !Config::extractAllFlag)
- {
- QCString doxyName=md->name().copy();
- if (!cname.isEmpty()) doxyName.prepend(cname+"::");
- ol.writeDoxyAnchor(cname,md->anchor(),doxyName);
- ol.addToIndex(md->name(),cname);
- ol.addToIndex(cname,md->name());
- ol.docify("\n");
- }
- else if (!detailsVisible) // when extractAll it true we have to write
- // a index reference and label in LaTeX because
- // detailed section not shown in LaTeX
- {
- ol.addToIndex(md->name(),cname);
- ol.addToIndex(cname,md->name());
- ol.writeLatexLabel(cname,md->anchor());
- }
-
- // write type
- if (i!=-1)
- {
- QCString newType = type.left(i) + " { ... } " +
- type.right(type.length()-i-l);
- type = newType;
- //ol.docify(type);
- linkifyText(ol,cname,md->name(),type);
- }
- else
- {
- //ol.docify(type);
- linkifyText(ol,cname,md->name(),type);
- }
- QCString name=md->name().copy();
- bool htmlOn = ol.isEnabled(OutputGenerator::Html);
- if (htmlOn && Config::htmlAlignMemberFlag && type.length()>0)
- {
- ol.disable(OutputGenerator::Html);
- }
- if (!type.isEmpty()) ol.docify(" ");
- if (htmlOn)
- {
- ol.enable(OutputGenerator::Html);
- }
-
- ol.insertMemberAlign();
-
- // write name
- if (md->hasDocumentation())
- {
- //printf("writeLink %s->%d\n",name.data(),md->hasDocumentation());
- writeLink(ol,cd,nd,fd,md,name);
- }
- else // there is a brief member description and brief member
- // descriptions are enabled or there is no detailed description.
- {
- ol.writeBoldString(name);
- }
-
- if (md->argsString())
- {
- ol.writeString(" ");
- //ol.docify(md->argsString());
- linkifyText(ol,cname,md->name(),md->argsString());
- }
-
- if (md->excpString())
- {
- ol.writeString(" ");
- ol.docify(md->excpString());
- }
-
- ol.endMemberItem();
-
- // write brief description
- if (!md->briefDescription().isEmpty() && Config::briefMemDescFlag)
- {
- ol.startMemberDescription();
- parseDoc(ol,cname,md->name(),md->briefDescription());
- //if (!md->documentation().isEmpty())
- //{
- // ol.disableAllBut(OutputGenerator::Html);
- // ol.endEmphasis();
- // ol.docify(" ");
- // ol.startTextLink(0,md->anchor());
- // parseText(ol,theTranslator->trMore());
- // ol.endTextLink();
- // ol.startEmphasis();
- // ol.enableAll();
- //}
- ol.endMemberDescription();
- ol.newParagraph();
- }
- }
- warnForUndocumentedMember(md);
-}
-
-
-// write a list in HTML of all members of a certain category
-// cd!=0 => ml is a list of class members
-// fd!=0 => ml is a list of file `members'
-void writeMemberDecs(OutputList &ol,ClassDef *cd,NamespaceDef *nd, FileDef *fd,
- const char *title, const char *subtitle,MemberList *ml)
-{
- ml->countDecMembers();
- if (ml->totalCount()==0) return;
- if (title)
- {
- ol.startMemberHeader();
- parseText(ol,title);
- ol.endMemberHeader();
- }
- if (subtitle)
- {
- ol.startMemberSubtitle();
- parseText(ol,subtitle);
- ol.endMemberSubtitle();
- }
-
- if (!fd && !nd) ol.startMemberList();
- MemberDef *md;
-
- if (fd && ml->defineCount()>0)
- {
- ol.startMemberHeader();
- parseText(ol,theTranslator->trDefines());
- ol.endMemberHeader();
- ol.startMemberList();
- MemberListIterator mli(*ml);
- for ( ; (md=mli.current()); ++mli )
- {
- if (md->isDefine() &&
- (md->argsString() || md->hasDocumentation() || Config::extractAllFlag)
- )
- writeMemberDef(ol,cd,nd,fd,md);
- }
- ol.endMemberList();
- }
-
- if ((fd || nd) && ml->protoCount()>0)
- {
- ol.startMemberHeader();
- parseText(ol,theTranslator->trFuncProtos());
- ol.startMemberList();
- MemberListIterator mli(*ml);
- for ( ; (md=mli.current()); ++mli )
- {
- if (md->isPrototype()) writeMemberDef(ol,cd,nd,fd,md);
- }
- ol.endMemberList();
- }
-
- if (ml->typedefCount()>0)
- {
- if (fd || nd)
- {
- ol.startMemberHeader();
- parseText(ol,theTranslator->trTypedefs());
- ol.endMemberHeader();
- //ol.writeMemberHeader("Typedefs");
- ol.startMemberList();
- }
- MemberListIterator mli(*ml);
- for ( ; (md=mli.current()) ; ++mli )
- {
- if (md->isTypedef()) writeMemberDef(ol,cd,nd,fd,md);
- }
- if (fd || nd) ol.endMemberList();
- }
-
- // write enums
- if (ml->enumCount()>0)
- {
- if (fd || nd)
- {
- ol.startMemberHeader();
- parseText(ol,theTranslator->trEnumerations());
- ol.endMemberHeader();
- ol.startMemberList();
- }
- MemberListIterator mli(*ml);
- for ( ; (md=mli.current()) ; ++mli )
- {
- /*bool hasDocs=md->hasDocumentation();*/
- QCString type=md->typeString();
- type=type.stripWhiteSpace();
- if (md->isEnumerate() /*&& (hasDocs || !Config::hideMemberFlag)*/)
- {
- if (!Config::hideMemberFlag || // do not hide undocumented members or
- !md->documentation().isEmpty() || // member has detailed descr. or
- md->hasDocumentedEnumValues() || // member has documented enum vales.
- Config::briefMemDescFlag || // brief descr. is shown or
- Config::repeatBriefFlag // brief descr. is repeated.
- )
- {
- OutputList typeDecl(&ol);
- QCString name=md->name().copy();
- int i=name.findRev("::");
- if (i!=-1) name=name.right(name.length()-i-2); // strip scope
- if (name[0]!='@') // not an anonymous enum
- {
- //if (Config::extractAllFlag ||
- // (md->briefDescription().isEmpty() || !Config::briefMemDescFlag) &&
- // (!md->documentation().isEmpty() || md->hasDocumentedEnumValues() ||
- // (!md->briefDescription().isEmpty() &&
- // !Config::briefMemDescFlag &&
- // Config::repeatBriefFlag
- // )
- // )
- // )
- if (md->hasDocumentation() || md->hasDocumentedEnumValues())
- {
- if (Config::genTagFile.length()>0)
- tagFile << md->name() << " " << md->anchor()
- << " \"" << md->argsString() << "\"";
- writeLink(typeDecl,cd,nd,fd,md,name);
- }
- else
- {
- typeDecl.writeBoldString(name);
- }
- typeDecl.writeChar(' ');
- }
-
- typeDecl.docify("{ ");
- QList<MemberDef> *fmdl=md->enumFieldList();
- if (fmdl)
- {
- MemberDef *fmd=fmdl->first();
- while (fmd)
- {
- if (fmd->hasDocumentation())
- {
- if (Config::genTagFile.length()>0)
- tagFile << fmd->name() << " " << fmd->anchor()
- << " \"" << fmd->argsString() << "\"";
- writeLink(typeDecl,cd,nd,fd,fmd,fmd->name());
- }
- else
- typeDecl.writeBoldString(fmd->name());
- fmd=fmdl->next();
- if (fmd) typeDecl.writeString(", ");
- typeDecl.disable(OutputGenerator::Man);
- typeDecl.writeString("\n"); // to prevent too long lines in LaTeX
- typeDecl.enable(OutputGenerator::Man);
- }
- }
- typeDecl.docify(" }");
- md->setEnumDecl(typeDecl);
- int enumVars=0;
- MemberListIterator vmli(*ml);
- MemberDef *vmd;
- if (name[0]=='@') // anonymous enum => append variables
- {
- for ( ; (vmd=vmli.current()) ; ++vmli)
- {
- QCString vtype=vmd->typeString();
- if ((vtype.find(name))!=-1) enumVars++;
- }
- }
- if (enumVars==0) // no variable of this enum type
- {
- ol.startMemberItem();
- ol.writeString("enum ");
- ol.insertMemberAlign();
- ol+=typeDecl;
- ol.endMemberItem();
- //QCString brief=md->briefDescription();
- //brief=brief.stripWhiteSpace();
- if (!md->briefDescription().isEmpty() && Config::briefMemDescFlag)
- {
- ol.startMemberDescription();
- parseDoc(ol,cd?cd->name().data():0,
- md->name().data(),md->briefDescription());
- //if (!md->documentation().isEmpty() || md->hasDocumentedEnumValues())
- //{
- // ol.disableAllBut(OutputGenerator::Html);
- // ol.endEmphasis();
- // ol.docify(" ");
- // ol.startTextLink(0,md->anchor());
- // //ol.writeObjectLink(0,0,md->anchor()," More...");
- // parseText(ol,theTranslator->trMore());
- // ol.endTextLink();
- // ol.startEmphasis();
- // ol.enableAll();
- //}
- ol.endMemberDescription();
- ol.disable(OutputGenerator::Man);
- ol.newParagraph();
- ol.enable(OutputGenerator::Man);
- }
- }
- warnForUndocumentedMember(md);
- }
- } // md->isEnumerate()
- } // enum loop
- if (fd || nd) ol.endMemberList();
- } // write enums
-
- // write functions
- if (ml->funcCount()>0)
- {
- if (fd || nd)
- {
- ol.startMemberHeader();
- parseText(ol,theTranslator->trFunctions());
- ol.endMemberHeader();
- ol.startMemberList();
- }
- MemberListIterator mli(*ml);
- for ( ; (md=mli.current()) ; ++mli )
- {
- if ( md->isFunction() || md->isSignal() ||
- md->isSlot())
- writeMemberDef(ol,cd,nd,fd,md);
- }
- if (fd || nd) ol.endMemberList();
- }
-
- if (ml->friendCount()>0)
- {
- MemberListIterator mli(*ml);
- for ( ; (md=mli.current()) ; ++mli )
- {
- if ( md->isFriend())
- {
- QCString type=md->typeString();
- //printf("Friend: type=%s name=%s\n",type.data(),md->name().data());
- if (md->hasDocumentation() && type!="friend class")
- {
- writeMemberDef(ol,cd,nd,fd,md);
- }
- else // friend is undocumented as a member but it is a class,
- // so generate a link to the class if that is documented.
- {
- ClassDef *cd=getClass(md->name());
- if (md->hasDocumentation()) // friend is documented
- {
- ol.startMemberItem();
- ol.docify("class ");
- ol.insertMemberAlign();
- ol.writeObjectLink(0,0,md->anchor(),md->name());
- ol.endMemberItem();
- }
- else if (cd && cd->isVisibleExt()) // class is documented
- {
- ol.startMemberItem();
- ol.docify("class ");
- ol.insertMemberAlign();
- ol.writeObjectLink(cd->getReference(),cd->getOutputFileBase(),0,cd->name());
- ol.endMemberItem();
- }
- else if (!Config::hideMemberFlag) // no documentation
- {
- ol.startMemberItem();
- ol.docify("class ");
- ol.insertMemberAlign();
- ol.writeBoldString(md->name());
- ol.endMemberItem();
- }
- }
- }
- }
- }
-
- // write variables
- if (ml->varCount()>0)
- {
- if (fd || nd)
- {
- ol.startMemberHeader();
- parseText(ol,theTranslator->trVariables());
- ol.endMemberHeader();
- ol.startMemberList();
- }
- MemberListIterator mli(*ml);
- for ( ; (md=mli.current()) ; ++mli )
- {
- if (md->isVariable()) writeMemberDef(ol,cd,nd,fd,md);
- }
- if (fd || nd) ol.endMemberList();
- }
-
- if (!fd && !nd) { ol.endMemberList(); ol.writeChar('\n'); }
-}
-
// compute the HTML anchors for a list of members
void setAnchors(char id,MemberList *ml)
{
@@ -1030,397 +541,6 @@ void setAnchors(char id,MemberList *ml)
}
}
-void writeMemberDocs(OutputList &ol,MemberList *ml,const char *scopeName,
- MemberDef::MemberType m)
-{
- MemberListIterator mli(*ml);
- MemberDef *md;
- for ( ; (md=mli.current()) ; ++mli)
- {
- bool hasDocs = md->detailsAreVisible();
- // !md->documentation().isEmpty() || // member has a detailed description
- // (md->memberType()==MemberDef::Enumeration && // or member is an enum and
- // md->hasDocumentedEnumValues() // one of its values is documented
- // ) || // or
- // (!md->briefDescription().isEmpty() && // member has brief description and
- // !Config::briefMemDescFlag && // brief description not shown earlier and
- // Config::repeatBriefFlag // brief description should be repeated.
- // );
- if (md->memberType()==m && // filter member type
- (Config::extractAllFlag || hasDocs)
- )
- {
- if (Config::extractAllFlag && !hasDocs)
- {
- ol.disable(OutputGenerator::Latex); // Latex cannot insert a pagebreak
- // if there are a lot of empty sections,
- // so we disable LaTeX for all empty
- // sections even if Config::extractAllFlag is enabled
- }
- QCString cname;
- NamespaceDef *nd=md->getNamespace();
- ClassDef *cd=md->memberClass();
- FileDef *fd=md->getFileDef();
- if (cd) cname=cd->name();
- else if (nd) cname=nd->name();
- else if (fd) cname=fd->name();
- // get member name
- QCString doxyName=md->name().copy();
- // prepend scope if there is any
- if (scopeName) doxyName.prepend((QCString)scopeName+"::");
-
- QCString def = md->definition();
- if (md->isEnumerate()) def.prepend("enum ");
- MemberDef *smd;
- if (md->isEnumValue() && def[0]=='@') def = def.right(def.length()-2);
- int i=0,l,dummy;
- QRegExp r("@[0-9]+");
- if (md->isEnumerate() && r.match(def,0,&l)!=-1) continue;
- if (md->isEnumValue() && (smd = md->getEnumScope())
- && r.match(smd->name(),0,&dummy)==-1) continue;
- if ((md->isVariable() || md->isTypedef()) && (i=r.match(def,0,&l))!=-1)
- {
- // find enum type an insert it in the definition
- MemberListIterator vmli(*ml);
- MemberDef *vmd;
- bool found=FALSE;
- for ( ; (vmd=vmli.current()) && !found ; ++vmli)
- {
- if (vmd->isEnumerate() && def.mid(i,l)==vmd->name())
- {
- ol.startMemberDoc(cname,md->name(),md->anchor());
- ol.writeDoxyAnchor(cname,md->anchor(),doxyName);
- linkifyText(ol,scopeName,md->name(),def.left(i));
- ol+=*vmd->enumDecl();
- linkifyText(ol,scopeName,md->name(),def.right(def.length()-i-l));
- found=TRUE;
- }
- }
- if (!found) // anonymous compound
- {
- ol.startMemberDoc(cname,md->name(),md->anchor());
- ol.writeDoxyAnchor(cname,md->anchor(),doxyName);
- linkifyText(ol,scopeName,md->name(),def.left(i));
- ol.docify(" { ... } ");
- linkifyText(ol,scopeName,md->name(),def.right(def.length()-i-l));
- }
- }
- else
- {
- ol.startMemberDoc(cname,md->name(),md->anchor());
- ol.writeDoxyAnchor(cname,md->anchor(),doxyName);
- ArgumentList *al=0;
- if (cd && (!md->isRelated() || !md->templateArguments()) &&
- ((al=md->scopeTemplateArguments()) || (al=cd->templateArguments()))
- ) // class template prefix
- {
- writeTemplatePrefix(ol,al);
- }
- if (al && md->templateArguments()) ol.docify(" ");
- al=md->templateArguments();
- if (al) // function template prefix
- {
- writeTemplatePrefix(ol,al);
- }
- if (cd && md->scopeTemplateArguments())
- {
- def=addTemplateNames(def,cd->name(),md->getScopeTemplateNameString());
- }
- else if (cd && cd->templateArguments())
- {
- // add template name lists to all occurrences of the class name.
- def=addTemplateNames(def,cd->name(),cd->getTemplateNameString());
- }
- linkifyText(ol,scopeName,md->name(),def);
- writeDefArgumentList(ol,cd,scopeName,md);
- if (md->excpString())
- {
- ol.docify(" ");
- linkifyText(ol,scopeName,md->name(),md->excpString());
- }
- }
-
- Specifier virt=md->virtualness();
- MemberDef *rmd=md->reimplements();
- while (rmd && virt==Normal)
- {
- virt = rmd->virtualness()==Normal ? Normal : Virtual;
- rmd = rmd->reimplements();
- }
-
- if (md->isStatic() || md->protection()!=Public ||
- virt!=Normal || md->isSignal() || md->isFriend() ||
- md->isRelated() || md->isSlot()
- )
- {
- // write the member specifier list
- ol.writeLatexSpacing();
- ol.startTypewriter();
- ol.docify(" [");
- QStrList sl;
- if (md->isFriend()) sl.append("friend");
- else if (md->isRelated()) sl.append("related");
- else
- {
- if (md->isStatic()) sl.append("static");
- if (md->protection()==Protected) sl.append("protected");
- else if (md->protection()==Private) sl.append("private");
- if (virt==Virtual) sl.append("virtual");
- else if (virt==Pure) sl.append("pure virtual");
- if (md->isSignal()) sl.append("signal");
- if (md->isSlot()) sl.append("slot");
- }
- const char *s=sl.first();
- while (s)
- {
- ol.docify(s);
- s=sl.next();
- if (s) ol.docify(", ");
- }
- ol.docify("]");
- ol.endTypewriter();
- }
- ol.endMemberDoc();
- ol.startIndent();
- ol.newParagraph();
-
- if (!md->briefDescription().isEmpty() &&
- (Config::repeatBriefFlag ||
- (!Config::briefMemDescFlag && md->documentation().isEmpty())
- )
- )
- {
- parseDoc(ol,scopeName,md->name(),md->briefDescription());
- ol.newParagraph();
- }
- if (!md->documentation().isEmpty())
- {
- parseDoc(ol,scopeName,md->name(),md->documentation()+"\n");
- }
- if (!md->bodyCode().isEmpty())
- {
- ol.startCodeFragment();
- parseCode(ol,scopeName,md->bodyCode(),FALSE,0);
- ol.endCodeFragment();
- }
-
- if (md->isEnumerate())
- {
- bool first=TRUE;
- MemberList *fmdl=md->enumFieldList();
- if (fmdl)
- {
- MemberDef *fmd=fmdl->first();
- while (fmd)
- {
- if (fmd->hasDocumentation())
- {
- if (first)
- {
- ol.newParagraph();
- ol.startBold();
- parseText(ol,theTranslator->trEnumerationValues());
- //ol.writeBoldString("Enumeration values:");
- ol.docify(":");
- ol.endBold();
- ol.startItemList();
- }
- ol.writeDoxyAnchor(cname,fmd->anchor(),fmd->name());
- ol.addToIndex(fmd->name(),cname);
- ol.addToIndex(cname,fmd->name());
- ol.writeListItem();
- first=FALSE;
- ol.startBold();
- ol.docify(fmd->name());
- ol.endBold();
- ol.newParagraph();
-
- if (!fmd->briefDescription().isEmpty())
- {
- parseDoc(ol,scopeName,fmd->name(),fmd->briefDescription());
- ol.newParagraph();
- }
- if (!fmd->documentation().isEmpty())
- {
- parseDoc(ol,scopeName,fmd->name(),fmd->documentation()+"\n");
- }
- ol.disable(OutputGenerator::Man);
- ol.newParagraph();
- ol.enable(OutputGenerator::Man);
- }
- fmd=fmdl->next();
- }
- }
- if (!first) { ol.endItemList(); ol.writeChar('\n'); }
- }
-
- MemberDef *bmd=md->reimplements();
- ClassDef *bcd=0;
- if (bmd && (bcd=bmd->memberClass()))
- {
- if (virt!=Normal) // search for virtual member of the deepest base class
- {
- MemberDef *lastBmd=bmd;
- while (lastBmd)
- {
- ClassDef *lastBcd = lastBmd->memberClass();
- if (lastBmd->virtualness()!=Normal &&
- lastBmd->hasDocumentation() &&
- (lastBmd->protection()!=Private || Config::extractPrivateFlag) &&
- lastBcd->hasDocumentation() &&
- (lastBcd->protection()!=Private || Config::extractPrivateFlag)
- ) { bmd=lastBmd; bcd=lastBcd; }
- lastBmd=lastBmd->reimplements();
- }
- }
- // write class that contains a member that is reimplemented by this one
- if (bcd->hasDocumentation() || bcd->isReference())
- {
- ol.newParagraph();
-
- QCString reimplFromLine = theTranslator->trReimplementedFromList(1);
- int markerPos = reimplFromLine.find("@0");
- if (markerPos!=-1) // should always pass this.
- {
- parseText(ol,reimplFromLine.left(markerPos)); //text left from marker
- if (bmd->hasDocumentation() &&
- (bmd->protection()!=Private || Config::extractPrivateFlag)
- ) // replace marker with link
- {
- ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
- bmd->anchor(),bcd->name());
- if (
- !bcd->isReference() &&
- //(bcd->hasDocumentation() || !Config::hideClassFlag) &&
- //(bcd->protection()!=Private || Config::extractPrivateFlag)
- bcd->isVisible()
- /*&& bmd->detailsAreVisible()*/
- ) ol.writePageRef(bcd->name(),bmd->anchor());
- }
- else
- {
- ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
- 0,bcd->name());
- if (
- !bcd->isReference() &&
- //(bcd->hasDocumentation() || !Config::hideClassFlag) &&
- //(bcd->protection()!=Private || Config::extractPrivateFlag)
- bcd->isVisible()
- ) ol.writePageRef(bcd->name(),0);
- }
- parseText(ol,reimplFromLine.right(
- reimplFromLine.length()-markerPos-2)); // text right from marker
-
- }
- else
- {
- err("Error: translation error: no marker in trReimplementsFromList()\n");
- }
- }
-
- //ol.writeString(".");
- }
- MemberList *bml=md->reimplementedBy();
- if (bml)
- {
- MemberListIterator mli(*bml);
- MemberDef *bmd=0;
- uint count=0;
- ClassDef *bcd=0;
- for (mli.toFirst();(bmd=mli.current()) && (bcd=bmd->memberClass());++mli)
- {
- // count the members that directly inherit from md and for
- // which the member and class are visible in the docs.
- if (bmd->hasDocumentation() &&
- (bmd->protection()!=Private || Config::extractPrivateFlag) &&
- bcd->hasDocumentation() &&
- (bcd->protection()!=Private || Config::extractPrivateFlag)
- ) count++;
- }
- if (count>0)
- {
- mli.toFirst();
- // write the list of classes that overwrite this member
- ol.newParagraph();
- //parseText(ol,theTranslator->trReimplementedIn());
- //ol.writeString("Reimplemented in ");
- //ol.docify(" ");
-
- QCString reimplInLine =
- theTranslator->trReimplementedInList(count);
- QRegExp marker("@[0-9]+");
- int index=0,newIndex,matchLen;
- // now replace all markers in reimplInLine with links to the classes
- while ((newIndex=marker.match(reimplInLine,index,&matchLen))!=-1)
- {
- parseText(ol,reimplInLine.mid(index,newIndex-index));
- bool ok;
- uint entryIndex = reimplInLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
- //bmd=bml->at(entryIndex);
-
- count=0;
- // find the entryIndex-th documented entry in the inheritance list.
- for (mli.toFirst();(bmd=mli.current()) && (bcd=bmd->memberClass());++mli)
- {
- if (bmd->hasDocumentation() &&
- (bmd->protection()!=Private || Config::extractPrivateFlag) &&
- bcd->hasDocumentation() &&
- (bcd->protection()!=Private || Config::extractPrivateFlag)
- )
- {
- if (count==entryIndex) break;
- count++;
- }
- }
-
- if (ok && bcd && bmd) // write link for marker
- {
- //if (bmd->hasDocumentation() &&
- // (bmd->protection()!=Private || Config::extractPrivateFlag)
- // )
- //{
- ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
- bmd->anchor(),bcd->name());
- if (!bcd->isReference() && bcd->isVisible())
- ol.writePageRef(bcd->name(),bmd->anchor());
- //}
- //else
- //{
- // ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
- // 0,bcd->name());
- // if (!bcd->isReference() && bcd->isVisible())
- // ol.writePageRef(bcd->name(),0);
- //}
- }
- ++mli;
- index=newIndex+matchLen;
- }
- parseText(ol,reimplInLine.right(reimplInLine.length()-index));
-
- }
- }
- // write the list of examples that use this member
- if (md->hasExamples())
- {
- ol.startDescList();
- ol.startBold();
- parseText(ol,theTranslator->trExamples()+": ");
- //ol.writeBoldString("Examples: ");
- ol.endBold();
- ol.endDescTitle();
- ol.writeDescItem();
- writeExample(ol,md->getExampleList());
- //ol.endDescItem();
- ol.endDescList();
- }
- ol.endIndent();
- // enable LaTeX again
- if (Config::extractAllFlag && !hasDocs) ol.enable(OutputGenerator::Latex);
-
- }
- }
-}
-
//----------------------------------------------------------------------------
// read a file with `name' to a string.
@@ -1607,6 +727,13 @@ bool matchArguments(ArgumentList *srcAl,ArgumentList *dstAl,
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\n",
// srcAl ? argListToString(srcAl).data() : "",
// dstAl ? argListToString(dstAl).data() : "",
@@ -1616,6 +743,8 @@ bool matchArguments(ArgumentList *srcAl,ArgumentList *dstAl,
{
return srcAl==dstAl; // at least one of the members is not a function
}
+
+ // 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)
@@ -1632,9 +761,9 @@ bool matchArguments(ArgumentList *srcAl,ArgumentList *dstAl,
dstAl->append(a);
return TRUE;
}
+
if (srcAl->count() != dstAl->count())
{
- //printf("Different number of arguments!\n");
return FALSE; // different number of arguments -> no match
}
if (srcAl->constSpecifier != dstAl->constSpecifier)
@@ -1683,6 +812,7 @@ bool matchArguments(ArgumentList *srcAl,ArgumentList *dstAl,
srcAType=trimScope(namespaceName,srcAType);
dstAType=trimScope(namespaceName,dstAType);
}
+ //printf("srcAType=%s dstAType=%s\n",srcAType.data(),dstAType.data());
//printf("`%s' <=> `%s'\n",srcAType.data(),dstAType.data());
uint srcPos=0,dstPos=0;
@@ -1796,8 +926,10 @@ bool matchArguments(ArgumentList *srcAl,ArgumentList *dstAl,
else // without scopes the names match exactly
{
}
+ return TRUE;
}
- else if (srcA->name.length()==0 && dstA->name.length()==0)
+ //printf("match exactly\n");
+ if (srcA->name.isEmpty() && dstA->name.isEmpty())
// arguments match exactly but no name ->
// see if we can find the name
{
@@ -1812,6 +944,14 @@ bool matchArguments(ArgumentList *srcAl,ArgumentList *dstAl,
dstA->type=dstAType.left(i+1).stripWhiteSpace();
}
}
+ else if (!dstA->name.isEmpty())
+ {
+ srcA->name=dstA->name.copy();
+ }
+ else if (!srcA->name.isEmpty())
+ {
+ dstA->name=srcA->name.copy();
+ }
}
//printf("Match found!\n");
return TRUE; // all arguments match
@@ -1964,7 +1104,7 @@ bool getDefs(const QCString &scName,const QCString &memberName,
ClassDef *fcd=0;
if ((fcd=getClass(className)) && // is it a documented class
- fcd->isVisibleExt()
+ fcd->isLinkable()
)
{
//printf(" Found fcd=%p\n",fcd);
@@ -1972,8 +1112,9 @@ bool getDefs(const QCString &scName,const QCString &memberName,
int mdist=maxInheritanceDepth;
while (mmd)
{
- if ((mmd->protection()!=Private || Config::extractPrivateFlag) &&
- mmd->hasDocumentation()
+ if (//(mmd->protection()!=Private || Config::extractPrivateFlag) &&
+ //mmd->hasDocumentation()
+ mmd->isLinkable()
/*mmd->detailsAreVisible()*/
/* && (args==0 || matchArgumentsOld(mmd->argsString(),args)) */
)
@@ -1990,7 +1131,7 @@ bool getDefs(const QCString &scName,const QCString &memberName,
{
ClassDef *mcd=mmd->memberClass();
int m=minClassDistance(fcd,mcd);
- if (m<mdist && mcd->isVisible())
+ if (m<mdist && mcd->isLinkable())
{
mdist=m;
cd=mcd;
@@ -2011,18 +1152,19 @@ bool getDefs(const QCString &scName,const QCString &memberName,
mmd=mn->last();
while (mmd)
{
- if ((mmd->protection()!=Private || Config::extractPrivateFlag) &&
- (
- mmd->hasDocumentation()
- /*mmd->detailsAreVisible()*/
- || mmd->isReference()
- )
+ if (//(mmd->protection()!=Private || Config::extractPrivateFlag) &&
+ //(
+ //mmd->hasDocumentation()
+ /*mmd->detailsAreVisible()*/
+ //|| mmd->isReference()
+ //)
+ mmd->isLinkable()
)
{
ClassDef *mcd=mmd->memberClass();
//printf(" >Class %s found\n",mcd->name().data());
int m=minClassDistance(fcd,mcd);
- if (m<mdist && mcd->isVisible())
+ if (m<mdist && mcd->isLinkable())
{
//printf("Class distance %d\n",m);
mdist=m;
@@ -2072,7 +1214,7 @@ bool getDefs(const QCString &scName,const QCString &memberName,
}
if (namespaceName.length()>0 &&
(fnd=namespaceDict[namespaceName]) &&
- fnd->isVisibleExt()
+ fnd->isLinkable()
)
{
//printf("Function inside existing namespace `%s'\n",namespaceName.data());
@@ -2083,7 +1225,8 @@ bool getDefs(const QCString &scName,const QCString &memberName,
//printf("mmd->getNamespace()=%p fnd=%p\n",
// mmd->getNamespace(),fnd);
if (mmd->getNamespace()==fnd &&
- (mmd->isReference() || mmd->hasDocumentation())
+ //(mmd->isReference() || mmd->hasDocumentation())
+ mmd->isLinkable()
)
{ // namespace is found
bool match=TRUE;
@@ -2116,7 +1259,8 @@ bool getDefs(const QCString &scName,const QCString &memberName,
while (mmd && !found)
{
if (mmd->getNamespace()==fnd &&
- (mmd->isReference() || mmd->hasDocumentation())
+ //(mmd->isReference() || mmd->hasDocumentation())
+ mmd->isLinkable()
)
{
nd=fnd;
@@ -2134,11 +1278,11 @@ bool getDefs(const QCString &scName,const QCString &memberName,
md=mn->first();
while (md)
{
- if (md->isReference() || md->hasDocumentation())
+ if (md->isLinkable())
{
//printf("md->name()=`%s'\n",md->name().data());
fd=md->getFileDef();
- if (fd && (fd->isReference() || fd->hasDocumentation()))
+ if (fd && fd->isLinkable())
{
//printf("fd->name()=`%s'\n",fd->name().data());
bool match=TRUE;
@@ -2162,11 +1306,11 @@ bool getDefs(const QCString &scName,const QCString &memberName,
md=mn->last();
while (md)
{
- if (md->isReference() || md->hasDocumentation())
+ if (md->isLinkable())
{
//printf("md->name()=`%s'\n",md->name().data());
fd=md->getFileDef();
- if (fd && (fd->isReference() || fd->hasDocumentation()))
+ if (fd && fd->isLinkable())
{
return TRUE;
}
@@ -2224,11 +1368,11 @@ bool getScopeDefs(const char *docScope,const char *scope,
QCString fullName=scopeName.copy();
if (scopeOffset>0) fullName.prepend(docScopeName.left(scopeOffset)+"::");
- if ((cd=getClass(fullName)) && cd->isVisibleExt())
+ if ((cd=getClass(fullName)) && cd->isLinkable())
{
return TRUE; // class link written => quit
}
- else if ((nd=namespaceDict[fullName]) && nd->isVisibleExt())
+ else if ((nd=namespaceDict[fullName]) && nd->isLinkable())
{
return TRUE; // namespace link written => quit
}
@@ -2344,7 +1488,7 @@ void generateRef(OutputList &ol,const char *scName,
if (getDefs(scopeStr,nameStr,argsStr,md,cd,fd,nd))
{
//printf("after getDefs nd=%p\n",nd);
- QCString anchor = (md->isReference() || md->hasDocumentation()) ? md->anchor() : 0;
+ QCString anchor = md->isLinkable() ? md->anchor() : 0;
QCString cName,aName;
if (cd) // nameStr is a member of cd
{
@@ -2391,7 +1535,7 @@ void generateRef(OutputList &ol,const char *scName,
if (cName.length()>0 || aName.length()>0)
{
if (
- (cd && !cd->isReference() && cd->isVisible()) ||
+ (cd && cd->isLinkableInProject()) ||
(fd && !fd->isReference()) ||
(nd /* TODO: && !nd->isReference() */)
)
@@ -2435,7 +1579,7 @@ void generateLink(OutputList &ol,const char *clName,
else if ((exampleDict[linkRef])) // link to an example
ol.writeObjectLink(0,linkRef+"-example",0,lt);
else if ((fd=findFileDef(&inputNameDict,linkRef,ambig))
- && fd->hasDocumentation())
+ && fd->isLinkable())
// link to documented input file
ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),0,lt);
else // probably a class or member reference
@@ -2449,7 +1593,7 @@ void generateFileRef(OutputList &ol,const char *name,const char *text)
FileDef *fd;
bool ambig;
if ((fd=findFileDef(&inputNameDict,name,ambig)) &&
- fd->hasDocumentation())
+ fd->isLinkable())
// link to documented input file
ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),0,linkText);
else