summaryrefslogtreecommitdiffstats
path: root/src/doxygen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/doxygen.cpp')
-rw-r--r--src/doxygen.cpp630
1 files changed, 443 insertions, 187 deletions
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
index 76518ba..01ac9b6 100644
--- a/src/doxygen.cpp
+++ b/src/doxygen.cpp
@@ -47,6 +47,8 @@
#include "mangen.h"
#include "language.h"
#include "debug.h"
+#include "htmlhelp.h"
+#include "defargs.h"
#if defined(_MSC_VER)
#define popen _popen
@@ -60,7 +62,6 @@ PageList exampleList; // list of all example files
PageList pageList; // list of all related documentation pages
MemberNameList memberNameList; // list of class member + related functions
MemberNameList functionNameList; // list of all unrelated functions
-//MemberNameList namespaceNameList; // list of namespace members;
FileNameList inputNameList; // list of all input files
StringList inputFiles;
FileList includeFiles;
@@ -74,7 +75,6 @@ ClassDict classDict(1009); // dictionary of all documented classes
NamespaceDict namespaceDict(257); // dictionary of all documented namespaces
MemberNameDict memberNameDict(10007); // dictionary of all class member names
MemberNameDict functionNameDict(10007); // dictionary of all functions
-//MemberNameDict namespaceNameDict(10007);// dictionaty of all namespace member names
StringDict substituteDict(1009); // dictionary of class name substitutes
SectionDict sectionDict(257); // dictionary of all page sections
FileNameDict inputNameDict(1009); // dictionary of sections
@@ -87,6 +87,7 @@ StringDict typedefDict(1009); // dictionary of all typedefs
GroupDict groupDict(257); // dictionary of all groups
FormulaDict formulaDict(1009); // dictionary of all formulas
FormulaDict formulaNameDict(1009); // dictionary of the label name of all formulas
+ // a member group
OutputList *outputList; // list of output generating objects
@@ -103,6 +104,7 @@ int documentedFiles;
int documentedGroups;
int documentedNamespaces;
int documentedNamespaceMembers;
+int documentedIncludeFiles;
QTextStream tagFile;
@@ -260,6 +262,7 @@ void addIncludeFile(ClassDef *cd,FileDef *ifd,Entry *root)
bool ambig;
FileDef *fd=0;
// see if we need to include a verbatim copy of the header file
+ //printf("root->includeFile=%s\n",root->includeFile.data());
if (!root->includeFile.isNull() &&
(fd=findFileDef(&inputNameDict,root->includeFile,ambig))==0
)
@@ -280,9 +283,9 @@ void addIncludeFile(ClassDef *cd,FileDef *ifd,Entry *root)
else // name is not an input file
warn("is not an input file\n");
}
- else if (root->includeFile.length()==0 &&
+ else if (root->includeFile.isEmpty() && ifd &&
// see if the file extension makes sense
- guessSection(root->includeFile)==Entry::HEADER_SEC)
+ guessSection(ifd->name())==Entry::HEADER_SEC)
{ // implicit assumption
fd=ifd;
}
@@ -296,7 +299,8 @@ void addIncludeFile(ClassDef *cd,FileDef *ifd,Entry *root)
cd->setIncludeFile(fd);
// set include supplied name
cd->setIncludeName(root->includeName);
- fd->setIncludeName(cd->getOutputFileBase()+"-include");
+ if (cd->name().find('@')==-1)
+ fd->setIncludeName(cd->getOutputFileBase()+"-include");
if (includeDict[fd->absFilePath()]==0) // include not inserted earlier
{
includeFiles.inSort(fd);
@@ -317,6 +321,8 @@ void extractNamespaceName(const QCString &scopeName,
{ // the whole name is a namespace
namespaceName=clName.copy();
className.resize(0);
+ //printf("extractNamespace `%s' => `%s|%s'\n",scopeName.data(),
+ // className.data(),namespaceName.data());
return;
}
int i,p=clName.length()-2;
@@ -327,12 +333,16 @@ void extractNamespaceName(const QCString &scopeName,
{
namespaceName=clName.left(i);
className=clName.right(clName.length()-i-2);
+ //printf("extractNamespace `%s' => `%s|%s'\n",scopeName.data(),
+ // className.data(),namespaceName.data());
return;
}
p=i-2; // try a smaller piece of the scope
}
className=scopeName.copy();
namespaceName.resize(0);
+ //printf("extractNamespace `%s' => `%s|%s'\n",scopeName.data(),
+ // className.data(),namespaceName.data());
return;
}
@@ -384,6 +394,7 @@ void buildClassList(Entry *root)
else
{
fullName=stripAnnonymousScope(fullName);
+ //printf("new class with name %s\n",fullName.data());
bool ambig;
ClassDef *cd;
@@ -391,7 +402,7 @@ void buildClassList(Entry *root)
{
if (cd->templateArguments()==0)
{
- //printf("existing ClassDef tempArgList=%p\n",root->tArgList);
+ //printf("existing ClassDef tempArgList=%p specScope=%s\n",root->tArgList,root->scopeSpec.data());
cd->setTemplateArguments(root->tArgList);
}
if (root->doc.length()>0 || root->brief.length()>0) // block contains docs
@@ -430,10 +441,14 @@ void buildClassList(Entry *root)
case Entry::STRUCT_SEC:
case Entry::STRUCTDOC_SEC:
sec=ClassDef::Struct; break;
+ case Entry::INTERFACE_SEC:
+ case Entry::INTERFACEDOC_SEC:
+ sec=ClassDef::Interface; break;
}
ClassDef *cd=new ClassDef(fullName,sec);
cd->setDocumentation(root->doc); // copy docs to definition
cd->setBriefDescription(root->brief);
+ //printf("new ClassDef tempArgList=%p specScope=%s\n",root->tArgList,root->scopeSpec.data());
cd->setTemplateArguments(root->tArgList);
cd->setProtection(root->protection);
cd->addSectionsToDefinition(root->anchors);
@@ -531,6 +546,12 @@ void buildNamespaceList(Entry *root)
fullName.data(),root->fileName.data(),root->startLine);
}
}
+
+ bool ambig;
+ // file definition containing the namespace nd
+ FileDef *fd=findFileDef(&inputNameDict,root->fileName,ambig);
+ // insert the namespace in the file definition
+ if (fd) fd->insertNamespace(nd);
}
else /* if (root->doc.length()>0 ||
root->brief.length()>0 ||
@@ -553,7 +574,7 @@ void buildNamespaceList(Entry *root)
}
bool ambig;
- // file definition containing the class cd
+ // file definition containing the namespace nd
FileDef *fd=findFileDef(&inputNameDict,root->fileName,ambig);
// insert the namespace in the file definition
if (fd) fd->insertNamespace(nd);
@@ -575,6 +596,98 @@ void buildNamespaceList(Entry *root)
}
}
+static MemberDef *addVariableToClass(Entry *root,ClassDef *cd,
+ MemberDef::MemberType mtype,const QCString &scope,const QCString &name,
+ bool fromAnnScope,int indentDepth,MemberDef *fromAnnMemb)
+{
+ Debug::print(Debug::Variables,0,
+ " class variable:\n"
+ " %s' %s'::`%s' `%s' prot=`%d\n",
+ root->type.data(),
+ scope.data(),
+ name.data(),
+ root->args.data(),
+ root->protection
+ );
+ // add template names, if the class is a non-specialized template
+ //if (scope.find('<')==-1 && cd->templateArguments())
+ //{
+ // scope+=cd->getTemplateNameString();
+ //}
+ // generate member definition.
+ QCString def;
+ if (root->type.length()>0)
+ {
+ if (mtype==MemberDef::Friend)
+ {
+ def=root->type+" "+name+root->args;
+ }
+ else
+ {
+ def=root->type+" "+scope+"::"+name+root->args;
+ }
+ }
+ else
+ {
+ def=scope+"::"+name+root->args;
+ }
+ if (def.left(7)=="static ") def=def.right(def.length()-7);
+
+ // see if the member is already found in the same scope
+ // (this may be the case for a static member that is initialized
+ // outside the class)
+ MemberName *mn=memberNameDict[name];
+ if (mn)
+ {
+ MemberDef *md=mn->first();
+ while (md)
+ {
+ if (md->memberClass()==cd) // member already in the scope
+ {
+ addMemberDocs(root,md,def,FALSE);
+ return md;
+ }
+ md=mn->next();
+ }
+ }
+ // new member variable, typedef or enum value
+ MemberDef *md=new MemberDef(root->type,name,root->args,0,
+ root->protection,Normal,root->stat,FALSE,
+ mtype,0,0);
+ md->setMemberClass(cd);
+ md->setDefFile(root->fileName);
+ md->setDefLine(root->startLine);
+ md->setDocumentation(root->doc);
+ md->setBriefDescription(root->brief);
+ md->setDefinition(def);
+ md->addSectionsToDefinition(root->anchors);
+ md->setFromAnnonymousScope(fromAnnScope);
+ md->setFromAnnonymousMember(fromAnnMemb);
+ md->setIndentDepth(indentDepth);
+
+ // add the member to the global list
+ if (mn)
+ {
+ //printf("Member already found! %s\n",md->name());
+ //addMemberDocs(root,mn->first(),def,FALSE);
+ //delete md;
+ mn->inSort(md);
+ }
+ else // new variable name
+ {
+ mn = new MemberName(name);
+ mn->inSort(md);
+ //printf("Adding memberName=%s\n",mn->memberName());
+ memberNameDict.insert(name,mn);
+ memberNameList.inSort(mn);
+ // add the member to the class
+ }
+ cd->insertMember(md);
+
+ //TODO: insert FileDef instead of filename strings.
+ cd->insertUsedFile(root->fileName);
+ return md;
+}
//----------------------------------------------------------------------
// Searches the Entry tree for Variable documentation sections.
@@ -611,7 +724,7 @@ void buildVarList(Entry *root)
// recover from parse error caused by redundant braces
root->type=root->name;
QRegExp re("[a-z_A-Z][a-z_A-Z0-9]*");
- int i,l;
+ int l;
i=re.match(root->args,0,&l);
root->name=root->args.mid(i,l);
root->args=root->args.mid(i+l,
@@ -621,7 +734,7 @@ void buildVarList(Entry *root)
}
else
{
- QRegExp re("([^)]*)");
+ //QRegExp re("([^)]*)");
i=root->type.find(re,0);
if (i!=-1) // function variable
{
@@ -631,7 +744,10 @@ void buildVarList(Entry *root)
}
QCString scope,name=root->name.copy();
- bool stat=root->stat;
+ //bool stat=root->stat;
+
+ // find the scope of this variable (stripping the annonymous part
+ // at the beginning
Entry *p = root->parent;
while ((p->section & Entry::SCOPE_MASK))
{
@@ -641,16 +757,17 @@ void buildVarList(Entry *root)
scope.prepend(scopeName);
break;
}
- //if (p->name.length()>0 && p->name[0]!='@')
- //{
- // if (!scope.isEmpty()) scope.prepend("::");
- // scope.prepend(p->name);
- // break;
- //}
p=p->parent;
}
-
- //printf("scope=%s\n",scope.data());
+ // scope annonymous scope name at the end to determine the scope
+ // where we can put this variable
+
+ //while ((i=scope.findRev("::"))!=-1 && (int)scope.length()>i+2 &&
+ // scope.at(i+2)=='@'
+ // )
+ //{
+ // scope=scope.left(i);
+ //}
int ni;
if ((ni=root->name.findRev("::"))!=-1) goto nextMember;
@@ -676,94 +793,28 @@ void buildVarList(Entry *root)
ClassDef *cd=0;
if (scope.length()>0 && name.length()>0 && (cd=getClass(scope)))
{
-
- Debug::print(Debug::Variables,0,
- " class variable:\n"
- " %s' %s'::`%s' `%s' prot=`%d\n",
- root->type.data(),
- scope.data(),
- name.data(),
- root->args.data(),
- root->protection
- );
- // add template names, if the class is a non-specialized template
- //if (scope.find('<')==-1 && cd->templateArguments())
- //{
- // scope+=cd->getTemplateNameString();
- //}
- // generate member definition.
- QCString def;
- if (root->type.length()>0)
- {
- if (mtype==MemberDef::Friend)
- {
- def=root->type+" "+name+root->args;
- }
- else
- {
- def=root->type+" "+scope+"::"+name+root->args;
- }
- }
- else
- {
- def=scope+"::"+name+root->args;
- }
- if (def.left(7)=="static ") def=def.right(def.length()-7);
-
- // see if the member is already found in the same scope
- // (this may be the case for a static member that is initialized
- // outside the class)
- bool found=FALSE;
- MemberName *mn=memberNameDict[name];
- if (mn)
- {
- MemberDef *md=mn->first();
- while (md && !found)
- {
- if (md->memberClass()==cd) // member already in the scope
- {
- addMemberDocs(root,md,def,FALSE);
- found=TRUE;
- }
- md=mn->next();
- }
- }
- if (!found) // found a fresh variable
+ MemberDef *md=0;
+ // if cd is an annonymous scope we insert the member
+ // into a non-annonymous scope as well.
+ int indentDepth=0;
+ if (scope.find('@')!=-1)
{
- // new member variable, typedef or enum value
- MemberDef *md=new MemberDef(root->type,name,root->args,0,
- root->protection,Normal,stat,FALSE,
- mtype,0,0);
- md->setMemberClass(cd);
- md->setDefFile(root->fileName);
- md->setDefLine(root->startLine);
- md->setDocumentation(root->doc);
- md->setBriefDescription(root->brief);
- md->setDefinition(def);
- md->addSectionsToDefinition(root->anchors);
-
- // add the member to the global list
- if (mn)
+ QCString pScope = scope.copy();
+ ClassDef *pcd=0;
+ while ((i=pScope.findRev("::"))!=-1 && (int)pScope.length()>i+2 &&
+ pScope.at(i+2)=='@'
+ )
{
- //printf("Member already found! %s\n",md->name());
- //addMemberDocs(root,mn->first(),def,FALSE);
- //delete md;
- mn->inSort(md);
+ pScope=pScope.left(i);
+ indentDepth++;
}
- else // new variable name
+ if ((pcd=getClass(pScope)))
{
- mn = new MemberName(name);
- mn->inSort(md);
- //printf("Adding memberName=%s\n",mn->memberName());
- memberNameDict.insert(name,mn);
- memberNameList.inSort(mn);
- // add the member to the class
+ //printf("Inserting member in parent scope!\n");
+ md=addVariableToClass(root,pcd,mtype,pScope,name,TRUE,indentDepth,0);
}
- cd->insertMember(md);
-
- //TODO: insert FileDef instead of filename strings.
- cd->insertUsedFile(root->fileName);
- }
+ }
+ addVariableToClass(root,cd,mtype,scope,name,FALSE,indentDepth,md);
}
else if (name.length()>0) // global variable
{
@@ -874,7 +925,7 @@ void buildMemberList(Entry *root)
{
Debug::print(Debug::Functions,0,
"FUNCTION_SEC:\n"
- " `%s' `%s'::`%s' `%s' relates=`%s' file=`%s' #targs=%d docs=`%s'\n",
+ " `%s' `%s'::`%s' `%s' relates=`%s' file=`%s' #targs=%d #mtargs=%d mGrpId=%d\n",
root->type.data(),
root->parent->name.data(),
root->name.data(),
@@ -882,7 +933,8 @@ void buildMemberList(Entry *root)
root->relates.data(),
root->fileName.data(),
root->tArgList ? (int)root->tArgList->count() : -1,
- root->doc.data()
+ root->mtArgList ? (int)root->mtArgList->count() : -1,
+ root->mGrpId
);
bool isFriend=root->type.find("friend ")!=-1;
@@ -924,6 +976,13 @@ void buildMemberList(Entry *root)
else if (root->slot) mtype=MemberDef::Slot;
else mtype=MemberDef::Function;
+ // strip redundant template specifier for constructors
+ if ((i=name.find('<'))!=-1 && name.find('>')!=-1)
+ {
+ name=name.left(i);
+ }
+
+
//if (Config::includeSourceFlag && !root->body.isEmpty())
//{
// printf("Function: %s\n-----------------\n%s\n------------------\n",
@@ -935,14 +994,15 @@ void buildMemberList(Entry *root)
// root->args.data(),argListToString(cd->templateArguments()).data());
MemberDef *md=new MemberDef(root->type,name,root->args,root->exception,
root->protection,root->virt,root->stat,root->relates.length()>0,
- mtype,root->tArgList,root->argList);
+ mtype,root->mtArgList,root->argList);
md->setMemberClass(cd);
md->setDefFile(root->fileName);
md->setDefLine(root->startLine);
md->setDocumentation(root->doc);
md->setBriefDescription(root->brief);
md->setBody(root->body);
- //md->setScopeTemplateArguments(cd->templateArguments());
+ md->setGroupId(root->mGrpId);
+ //md->setScopeTemplateArguments(root->tArgList);
md->addSectionsToDefinition(root->anchors);
QCString def;
if (root->relates.length()>0 || isFriend)
@@ -1090,6 +1150,7 @@ void buildMemberList(Entry *root)
md->setPrototype(root->proto);
md->setBody(root->body);
md->addSectionsToDefinition(root->anchors);
+ md->setGroupId(root->mGrpId);
QCString def;
if (root->type.length()>0)
{
@@ -1323,14 +1384,14 @@ void computeClassRelations(Entry *root)
// For nested classes the base class could also be nested!
// To find the correct scope, we try to prepend the scope to the base
// name, starting with the largest, most inner scope.
- while (p->section&Entry::COMPOUND_MASK && !found)
+ while (p->section&Entry::SCOPE_MASK && !found)
{
scopePrefix=p->name+"::";
QList<BaseInfo> *baseList=root->extends;
BaseInfo *bi=baseList->first();
while (bi && !found) // for each base class
{
- QCString cName=scopePrefix+bi->name;
+ QCString cName=removeRedundantWhiteSpace(scopePrefix+bi->name);
//printf("Base class %s\n",cName.data());
ClassDef *baseClass=getClass(cName);
if (baseClass) // base class is documented
@@ -1358,21 +1419,22 @@ void computeClassRelations(Entry *root)
BaseInfo *bi=baseList->first();
while (bi) // for each base class
{
- ClassDef *baseClass=getClass(bi->name);
+ QCString baseClassName=removeRedundantWhiteSpace(bi->name);
+ ClassDef *baseClass=getClass(baseClassName);
//printf("baseClass %s of %s found (%s and %s)\n",
- // bi->name.data(),
+ // baseClassName.data(),
// root->name.data(),
// (bi->prot==Private)?"private":((bi->prot==Protected)?"protected":"public"),
// (bi->virt==Normal)?"normal":"virtual"
// );
int i;
- QCString templSpec,baseClassName=bi->name.copy();
- if (!baseClass && (i=bi->name.find('<'))!=-1)
+ QCString templSpec;
+ if (!baseClass && (i=baseClassName.find('<'))!=-1)
// base class has template specifiers
{
// TODO: here we should try to find the correct template specialization
// but for now, we only look for the unspecializated base class.
- baseClassName=bi->name.left(i);
+ baseClassName=baseClassName.left(i);
baseClass=getClass(baseClassName);
templSpec=bi->name.right(bi->name.length()-i);
}
@@ -1415,27 +1477,8 @@ void computeClassRelations(Entry *root)
}
bi=baseList->next();
}
- }
- }
-// else // class has no base classes
-// {
-// QCString resName=resolveDefines(root->name);
-// int i;
-// // Check if this class is a template instance of another class.
-// // If this is the case, we act as if this class `inherits' from the
-// // template class.
-// if ((i=resName.find('<'))!=-1)
-// {
-// ClassDef *baseClass=getClass(resName.left(i));
-// if (baseClass)
-// {
-// // add base class to this class
-// cd->insertBaseClass(baseClass,Public,Normal);
-// // add this class as super class to the base class
-// baseClass->insertSuperClass(cd,Public,Normal);
-// }
-// }
-// }
+ } // class not nested
+ } // class has no base classes
} // else class is already found
}
else if (root->name.right(2)!="::")
@@ -1564,6 +1607,22 @@ void addMemberDocs(Entry *root,MemberDef *md, const char *funcDecl,
md->setDefLine(root->startLine);
md->addSectionsToDefinition(root->anchors);
if (cd) cd->insertUsedFile(root->fileName);
+ if (root->mGrpId!=-1)
+ {
+ if (md->groupId()!=-1)
+ {
+ if (md->groupId()!=root->mGrpId)
+ {
+ warn("Warning: member %s belongs to two different group. The second "
+ "one is found at line %d of %s and will be ignored\n",
+ md->name().data(),root->startLine,root->fileName.data());
+ }
+ }
+ else // copy group id
+ {
+ md->setGroupId(root->mGrpId);
+ }
+ }
}
//----------------------------------------------------------------------
@@ -1656,7 +1715,7 @@ void substituteTemplateArgNames(ArgumentList *src,
while ((i=re.match(s,p,&l))!=-1) // for each template name found at the
// member definition
{
- Argument *ta = tempArgs->at(c);
+ Argument *ta = c<(int)tempArgs->count() ? tempArgs->at(c) : 0;
if (ta) // get matching template argument of the class
{
QCString dstName=s.mid(i,l);
@@ -1724,6 +1783,31 @@ void substituteTemplateArgNames(ArgumentList *src,
}
+QCString insertTemplateSpecifierInScope(const QCString &scope,const QCString &templ)
+{
+ QCString result=scope.copy();
+ if (!templ.isEmpty() && scope.find('<')==-1)
+ {
+ int si,pi=0;
+ while ((si=scope.find("::",pi))!=-1 && !getClass(scope.left(si)+templ)
+ && !getClass(scope.left(si)))
+ { //printf("Tried `%s'\n",(scope.left(si)+templ).data());
+ pi=si+2;
+ }
+ if (si==-1) // not nested => append template specifier
+ {
+ result+=templ;
+ }
+ else // nested => insert template specifier before after first class name
+ {
+ result=scope.left(si) + templ + scope.right(scope.length()-si);
+ }
+ }
+ //printf("insertTemplateSpecifierInScope(`%s',`%s')=%s\n",
+ // scope.data(),templ.data(),result.data());
+ return result;
+}
+
//----------------------------------------------------------------------
// This function tries to find a member (in a documented class/file/namespace)
// that corresponds to the function declaration given in `funcDecl'.
@@ -1739,8 +1823,10 @@ void findMember(Entry *root,QCString funcDecl,QCString related,bool overloaded,
bool isFunc)
{
Debug::print(Debug::FindMembers,0,
- "findMember(root=%p,funcDecl=`%s',related=`%s',overload=%d,isFunc=%d\n====\ndoc=%s\n====\n)\n",
- root,funcDecl.data(),related.data(),overloaded,isFunc,root->doc.data()
+ "findMember(root=%p,funcDecl=`%s',related=`%s',overload=%d,isFunc=%d mGrpId=%d tArgList=%p=\"%s\" scopeSpec=%s memberSpec=%s\n",
+ root,funcDecl.data(),related.data(),overloaded,isFunc,root->mGrpId,
+ root->tArgList,tempArgListToString(root->tArgList).data(),
+ root->scopeSpec.data(),root->memberSpec.data()
);
if (Config::includeSourceFlag && !root->body.isEmpty())
{
@@ -1789,6 +1875,31 @@ void findMember(Entry *root,QCString funcDecl,QCString related,bool overloaded,
parseFuncDecl(funcDecl,scopeName,classTempList,funcType,funcName,
funcArgs,funcTempList,exceptions
);
+ //printf("scopeName=`%s'\n",scopeName.data());
+
+ bool isSpecialization = !root->scopeSpec.isEmpty() &&
+ root->scopeSpec != tempArgListToString(root->tArgList);
+
+ //printf("1. scopeName=`%s' specialization=%d\n",
+ // scopeName.data(),isSpecialization
+ // );
+ // include template specifier in the scope if needed
+ if (!scopeName.isEmpty() && !root->scopeSpec.isEmpty() && isSpecialization)
+ {
+ //scopeName = insertTemplateSpecifierInScope(
+ // scopeName,removeRedundantWhiteSpace(root->scopeSpec));
+ //printf("2. scopeName=`%s'\n",scopeName.data());
+ }
+
+ // if this is a member template inside non template class, the parser puts
+ // template specifier in scopeSepc, so we copy it to the right location here
+ if (scopeName.isEmpty() && !root->scopeSpec.isEmpty() &&
+ root->memberSpec.isEmpty() && funcTempList.isEmpty()
+ )
+ // template specifier that was found is for a function
+ {
+ funcTempList = root->scopeSpec;
+ }
// the class name can also be a namespace name, we decide this later.
// if a related class name is specified and the class name could
@@ -1811,13 +1922,23 @@ void findMember(Entry *root,QCString funcDecl,QCString related,bool overloaded,
Entry *p=root->parent;
while (p) // get full scope as class name
{
- //printf("++++++ scope=`%s'\n",p->name.data());
- if (((p->section & Entry::COMPOUND_MASK) ||
- p->section == Entry::NAMESPACE_SEC
- ) && !p->name.isEmpty() && p->name[0]!='@'
+ if ((p->section & Entry::SCOPE_MASK)
+ && !p->name.isEmpty() && p->name[0]!='@'
)
{
- if (scopeName.left(p->name.length())==p->name)
+ //printf("p->name=`%s' scopeName=`%s' classTempList=%s\n",
+ // p->name.data(),scopeName.data(),classTempList.data());
+
+ QCString tryScope;
+
+ if (scopeName.find('<')==-1 && !classTempList.isEmpty())
+ tryScope=insertTemplateSpecifierInScope(scopeName,classTempList);
+ else
+ tryScope=scopeName.copy();
+
+ //printf("tryScope=%s\n",tryScope.data());
+
+ if (leftScopeMatch(tryScope,p->name))
break; // scope already present, so stop now
// prepend name to scope
if (!scopeName.isEmpty()) scopeName.prepend("::");
@@ -1825,14 +1946,20 @@ void findMember(Entry *root,QCString funcDecl,QCString related,bool overloaded,
}
p=p->parent;
}
+ //printf("3. scopeName=`%s'\n",scopeName.data());
+ //printf("result: scope=%s\n",scopeName.data());
}
- if (scopeName.length()>0 && scopeName.find('<')==-1 && classTempList.length()==0 )
- { // class is a template, but no template name list found
- ClassDef *cd=getClass(scopeName);
- if (cd) // class exists
+ if (!scopeName.isEmpty() &&
+ scopeName.find('<')==-1 &&
+ classTempList.length()==0
+ )
+ {
+ ClassDef *cd=getClass(scopeName);
+ // class is a template, but no template name list found
+ if (root->tArgList && cd && cd->templateArguments())
{
- classTempList = cd->getTemplateNameString();
+ classTempList = tempArgListToString(root->tArgList);
}
}
@@ -1840,17 +1967,20 @@ void findMember(Entry *root,QCString funcDecl,QCString related,bool overloaded,
extractNamespaceName(scopeName,className,namespaceName);
QCString tempScopeName=scopeName.copy();
- int ti;
- int spi = namespaceName.isEmpty() ? 0 : namespaceName.length()+2;
- if ((ti=tempScopeName.find("::",spi))!=-1 && !classTempList.isEmpty())
- {
- // insert template parameters after the first scope name
- tempScopeName=tempScopeName.left(ti)+classTempList+
- tempScopeName.right(tempScopeName.length()-ti);
- }
- else
+ int ti=tempScopeName.find('<');
+ if (ti==-1)
{
- tempScopeName+=classTempList;
+ int spi = namespaceName.isEmpty() ? 0 : namespaceName.length()+2;
+ if ((ti=tempScopeName.find("::",spi))!=-1 && !classTempList.isEmpty())
+ {
+ // insert template parameters after the first scope name
+ tempScopeName=tempScopeName.left(ti)+classTempList+
+ tempScopeName.right(tempScopeName.length()-ti);
+ }
+ else
+ {
+ tempScopeName+=classTempList;
+ }
}
@@ -1958,33 +2088,54 @@ void findMember(Entry *root,QCString funcDecl,QCString related,bool overloaded,
isFunc
);
- MemberName *mn;
+ MemberName *mn=0;
if (funcName.length()>0) // function name is valid
{
- if (!isRelated && (mn=memberNameDict[funcName])) // function name already found
+ Debug::print(Debug::FindMembers,0,
+ "1. funcName=`%s'\n",funcName.data());
+ //if (funcTempList.length()>0) // try with member specialization
+ //{
+ // mn=memberNameDict[funcName+funcTempList];
+ //}
+ if (mn==0) // try without specialization
{
+ mn=memberNameDict[funcName];
+ }
+ if (!isRelated && mn) // function name already found
+ {
+ Debug::print(Debug::FindMembers,0,
+ "2. member name exists \n");
if (className.length()>0) // class name is valid
{
int count=0;
MemberDef *md=mn->first(); // for each member with that name
while (md)
{
+ Debug::print(Debug::FindMembers,0,
+ "3. member definition found scopeName=`%s'\n",scopeName.data());
ClassDef *cd=md->memberClass();
//printf("Member %s (member scopeName=%s) (this scopeName=%s) classTempList=%s\n",md->name().data(),cd->name().data(),scopeName.data(),classTempList.data());
ClassDef *tcd=0;
if (classTempList.length()>0) // try to find the correct specialization
{
- tcd=getClass(scopeName+classTempList);
- if (!tcd) tcd=getClass(scopeName); // try general class
+ tcd=getClass(
+ insertTemplateSpecifierInScope(
+ scopeName,
+ classTempList
+ )
+ ); // try specialization
}
- else
+ if (tcd==0)
{
- tcd=getClass(scopeName);
+ tcd=getClass(scopeName); // try general class
}
if (cd && tcd==cd) // member's classes match
{
+ Debug::print(Debug::FindMembers,0,
+ "4. class definition %s found\n",cd->name().data());
int ci;
ArgumentList *classTemplArgs = cd->templateArguments();
+ ArgumentList *funcTemplArgs = md->templateArguments();
if ((ci=cd->name().find("::"))!=-1) // nested class
{
ClassDef *parentClass = getClass(cd->name().left(ci));
@@ -1993,8 +2144,13 @@ void findMember(Entry *root,QCString funcDecl,QCString related,bool overloaded,
}
//printf("cd->name=%s classTemplArgs=%s\n",cd->name().data(),
// argListToString(classTemplArgs).data());
+
ArgumentList *argList = 0;
bool substDone=FALSE;
+
+ /* substitute the occurrences of class template names in the
+ * argument list before matching
+ */
if (!classTempList.isEmpty() &&
classTemplArgs &&
md->argumentList()
@@ -2019,17 +2175,53 @@ void findMember(Entry *root,QCString funcDecl,QCString related,bool overloaded,
{
argList = md->argumentList();
}
+
+ /* substitute the occurrences of member template names in the
+ * argument list before matching
+ */
+ if (!funcTempList.isEmpty() &&
+ funcTemplArgs &&
+ md->argumentList()
+ )
+ {
+ ArgumentList *oldArgList = argList;
+ argList = new ArgumentList;
+ substituteTemplateArgNames(
+ oldArgList, /* source argument list */
+ funcTempList, /* template names source */
+ funcTemplArgs, /* template names dest */
+ argList /* dest argument list */
+ );
+ if (substDone) // delete old argument list
+ delete oldArgList;
+ substDone=TRUE;
+ }
+
+ Debug::print(Debug::FindMembers,0,
+ "5. matching `%s'<=>`%s' className=%s namespaceName=%s\n",
+ argListToString(argList).data(),argListToString(root->argList).data(),
+ className.data(),namespaceName.data()
+ );
+
+ // TODO: match loop for all possible scopes
bool matching=
md->isVariable() || md->isTypedef() || // needed for function pointers
(md->argumentList()==0 && root->argList->count()==0) ||
matchArguments(argList, root->argList,className,namespaceName);
+ Debug::print(Debug::FindMembers,0,
+ "6. match results = %d\n",matching);
+
if (substDone) // found a new argument list
{
//printf("root->tArgList=`%s'\n",argListToString(root->tArgList).data());
if (matching) // replace member's argument list
{
- md->setScopeTemplateArguments(root->tArgList);
+ //printf("Setting scope template argument of member to %s\n",
+ // argListToString(root->tArgList).data()
+ // );
+ md->setScopeDefTemplateArguments(root->tArgList);
+ md->setMemberDefTemplateArguments(root->mtArgList);
md->setArgumentList(argList);
}
else // no match -> delete argument list
@@ -2265,7 +2457,7 @@ void findMemberDocumentation(Entry *root)
else if
(root->section==Entry::FUNCTION_SEC &&
(!root->doc.isEmpty() || !root->brief.isEmpty() ||
- !root->body.isEmpty() /*|| Config::extractAllFlag*/
+ !root->body.isEmpty() || root->mGrpId!=-1 /*|| Config::extractAllFlag*/
)
)
{
@@ -2275,15 +2467,37 @@ void findMemberDocumentation(Entry *root)
//printf("Inside=%s\n Relates=%s\n",root->inside.data(),root->relates.data());
if (root->type.length()>0)
{
- findMember(root,
- root->type+" "+root->inside+root->name+root->args+root->exception,
- root->relates,
- FALSE,isFunc);
+ //if (root->tArgList && root->mtArgList) // add member template specifier
+ //{
+ // findMember(root,
+ // root->type+" "+
+ // root->inside+
+ // root->name+
+ // tempArgListToString(root->mtArgList)+
+ // root->args+
+ // root->exception,
+ // root->relates,
+ // FALSE,isFunc);
+ //
+ //else
+ //
+ findMember(root,
+ root->type+" "+
+ root->inside+
+ root->name+
+ root->args+
+ root->exception,
+ root->relates,
+ FALSE,isFunc);
+ //}
}
else
{
findMember(root,
- root->inside+root->name+root->args+root->exception,
+ root->inside+
+ root->name+
+ root->args+
+ root->exception,
root->relates,
FALSE,isFunc);
}
@@ -2586,7 +2800,7 @@ static void findDEV(const MemberNameList &mnl)
// for each enum value
while (fmd)
{
- if (fmd->hasDocumentation()) documentedEnumValues++;
+ if (fmd->isLinkableInProject()) documentedEnumValues++;
fmd=fmdl->next();
}
}
@@ -2661,7 +2875,7 @@ void computeMemberRelations()
{
//printf(" match found!\n");
if (mcd && bmcd &&
- mcd->isVisibleExt() && bmcd->isVisibleExt()
+ mcd->isLinkable() && bmcd->isLinkable()
)
{
md->setReimplements(bmd);
@@ -2866,7 +3080,7 @@ void generateFileDocs()
FileDef *fd=fn->first();
while (fd)
{
- if (!fd->isReference() && fd->hasDocumentation())
+ if (fd->isLinkableInProject())
{
msg("Generating docs for file %s...\n",fd->name().data());
fd->writeDocumentation(*outputList);
@@ -2891,13 +3105,19 @@ void generateClassDocs()
msg("Generating index page...\n");
writeIndex(*outputList);
- msg("Generating compound index...\n");
+ msg("Generating annotated compound index...\n");
writeAnnotatedIndex(*outputList);
+ if (Config::alphaIndexFlag)
+ {
+ msg("Generating alphabetical compound index...\n");
+ writeAlphabeticalIndex(*outputList);
+ }
+
msg("Generating hierarchical class index...\n");
writeHierarchicalIndex(*outputList);
- if (includeFiles.count()>0)
+ if (documentedIncludeFiles>0)
{
msg("Generating header index...\n");
writeHeaderIndex(*outputList);
@@ -2915,13 +3135,7 @@ void generateClassDocs()
for ( ; cli.current() ; ++cli )
{
ClassDef *cd=cli.current();
- if (!cd->isReference() &&
- //!cd->name().isEmpty() &&
- //cd->name().at(0)!='@' &&
- //(cd->protection()!=Private || Config::extractPrivateFlag) &&
- //(cd->hasDocumentation() || !Config::hideClassFlag)
- cd->isVisible()
- )
+ if ( cd->isLinkableInProject() )
// skip external references and anonymous compounds
{
msg("Generating docs for compound %s...\n",cd->name().data());
@@ -2996,7 +3210,7 @@ void findDefineDocumentation(Entry *root)
// root->startLine,root->fileName.data());
}
}
- else // define not found
+ else if (root->doc.length()>0 || root->brief.length()>0) // define not found
{
warn("Warning: documentation for unknown define %s found at line %d of "
"file %s\n",root->name.data(),root->startLine,root->fileName.data());
@@ -3166,6 +3380,7 @@ void buildExampleList(Entry *root)
void generateExampleDocs()
{
+ outputList->disable(OutputGenerator::Man);
PageInfo *pi=exampleList.first();
while (pi)
{
@@ -3177,6 +3392,7 @@ void generateExampleDocs()
endFile(*outputList);
pi=exampleList.next();
}
+ outputList->enable(OutputGenerator::Man);
}
//----------------------------------------------------------------------------
@@ -3194,6 +3410,34 @@ void generateGroupDocs()
}
//----------------------------------------------------------------------------
+// create member group documentation based on the documentation of the
+// group's members.
+
+void computeMemberGroupDocumentation()
+{
+ MemberGroupDictIterator mgdi(memberGroupDict);
+ MemberGroup *mg;
+ for (;(mg=mgdi.current());++mgdi)
+ {
+ mg->addDocumentation();
+ }
+}
+
+//----------------------------------------------------------------------------
+// generate member group pages
+
+void generateMemberGroupDocs()
+{
+ MemberGroupDictIterator mgdi(memberGroupDict);
+ MemberGroup *mg;
+ for (;(mg=mgdi.current());++mgdi)
+ {
+ mg->writeDocumentation(*outputList);
+ }
+}
+
+
+//----------------------------------------------------------------------------
// generate module pages
void generateNamespaceDocs()
@@ -3204,8 +3448,7 @@ void generateNamespaceDocs()
NamespaceDef *nd;
for (;(nd=nli.current());++nli)
{
- if ((nd->getReference() || nd->hasDocumentation()) &&
- !nd->name().isEmpty() && nd->name().at(0)!='@')
+ if (nd->isLinkableInProject())
{
msg("Generating docs for namespace %s\n",nd->name().data());
nd->writeDocumentation(*outputList);
@@ -3524,9 +3767,10 @@ void readFiles(BufStr &output)
}
s=inputFiles.next();
+ //printf("-------> adding new line\n");
+ output.addChar('\n'); /* to prevent problems under Windows ? */
}
// *p++='\0';
- output.addChar('\n'); /* to prevent problems under Windows ? */
output.addChar(0);
//printf("Output after preprocessing:\n---------\n%s\n----------\n",output.data());
//printf("Final length = %d\n",p-output.data());
@@ -3835,7 +4079,7 @@ int main(int argc,char **argv)
}
}
else
- config=fileToString(argv[1]);
+ config=fileToString(argv[optind]);
parseConfig(config);
checkConfig();
@@ -3849,6 +4093,7 @@ int main(int argc,char **argv)
{
outputList->add(new HtmlGenerator);
HtmlGenerator::init();
+ if (Config::htmlHelpFlag) HtmlHelp::getInstance()->initialize();
}
if (Config::generateLatex)
{
@@ -4016,7 +4261,6 @@ int main(int argc,char **argv)
msg("Searching for member function documentation...\n");
findMemberDocumentation(root); // may introduce new members !
-
msg("Freeing entry tree\n");
delete root;
@@ -4035,6 +4279,9 @@ int main(int argc,char **argv)
msg("Building full member lists recursively...\n");
buildCompleteMemberLists();
+ msg("Determining member group documentation...\n");
+ computeMemberGroupDocumentation();
+
//unrelatedFunctionsUsed=hasUnrelatedFunctions();
/**************************************************************************
@@ -4053,6 +4300,7 @@ int main(int argc,char **argv)
documentedGroups = countGroups();
documentedNamespaces = countNamespaces();
documentedNamespaceMembers = countNamespaceMembers();
+ documentedIncludeFiles = countIncludeFiles();
// compute the shortest possible names of all files
// without loosing the uniqueness of the file names.
@@ -4077,6 +4325,9 @@ int main(int argc,char **argv)
msg("Generating group documentation...\n");
generateGroupDocs();
+ msg("Generating member group documentation...\n");
+ generateMemberGroupDocs();
+
msg("Generating namespace index...\n");
generateNamespaceDocs();
@@ -4132,6 +4383,11 @@ int main(int argc,char **argv)
Config::htmlOutputDir.data());
}
+ if (Config::generateHtml && Config::htmlHelpFlag)
+ {
+ HtmlHelp::getInstance()->finalize();
+ }
+
delete tag;
return 0;
}