summaryrefslogtreecommitdiffstats
path: root/src/doxygen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/doxygen.cpp')
-rw-r--r--src/doxygen.cpp229
1 files changed, 172 insertions, 57 deletions
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
index 7df0b4d..56787b9 100644
--- a/src/doxygen.cpp
+++ b/src/doxygen.cpp
@@ -91,6 +91,7 @@ FormulaDict formulaDict(1009); // all formulas
FormulaDict formulaNameDict(1009); // the label name of all formulas
StringDict tagDestinationDict(257); // all tag locations
// a member group
+QDict<void> compoundKeywordDict(7); // keywords recognised as compounds
OutputList *outputList = 0; // list of output generating objects
PageInfo *mainPage = 0;
@@ -369,7 +370,7 @@ static void addIncludeFile(ClassDef *cd,FileDef *ifd,Entry *root)
/*! Input is a scopeName, output is the scopename split into a
* namespace part (as large as possible) and a classname part.
*/
-void extractNamespaceName(const QCString &scopeName,
+static void extractNamespaceName(const QCString &scopeName,
QCString &className,QCString &namespaceName)
{
QCString clName=scopeName.copy();
@@ -439,7 +440,8 @@ void buildClassList(Entry *root)
{
if (
((root->section & Entry::COMPOUNDDOC_MASK) ||
- ((root->section & Entry::COMPOUND_MASK))) &&
+ ((root->section & Entry::COMPOUND_MASK))
+ ) &&
!root->name.isEmpty()
)
{
@@ -453,14 +455,16 @@ void buildClassList(Entry *root)
else
{
fullName=stripAnnonymousNamespaceScope(fullName);
- //printf("new class with name %s\n",fullName.data());
+ Debug::print(Debug::Classes,0," Found class with name %s\n",fullName.data());
bool ambig;
ClassDef *cd;
//printf("findFileDef(%s)\n",root->fileName.data());
FileDef *fd=findFileDef(&inputNameDict,root->fileName,ambig);
+
if ((cd=getClass(fullName)))
{
+ Debug::print(Debug::Classes,0," Existing class!\n",fullName.data());
if (cd->templateArguments()==0)
{
//printf("existing ClassDef tempArgList=%p specScope=%s\n",root->tArgList,root->scopeSpec.data());
@@ -529,7 +533,17 @@ void buildClassList(Entry *root)
case Entry::INTERFACE_SEC:
case Entry::INTERFACEDOC_SEC:
sec=ClassDef::Interface; break;
+ case Entry::EXCEPTION_SEC:
+ case Entry::EXCEPTIONDOC_SEC:
+ sec=ClassDef::Exception; break;
}
+ Debug::print(Debug::Classes,0," New class `%s' (sec=0x%08x)!\n",fullName.data(),root->section);
+ QCString className;
+ QCString namespaceName;
+ extractNamespaceName(fullName,className,namespaceName);
+
+ //printf("New class: namespace `%s' name=`%s'\n",className.data(),namespaceName.data());
+
ClassDef *cd=new ClassDef(fullName,sec);
cd->setDocumentation(root->doc); // copy docs to definition
cd->setBriefDescription(root->brief);
@@ -553,6 +567,7 @@ void buildClassList(Entry *root)
}
}
+ // see if the class is found inside a namespace
bool found=addNamespace(root,cd);
cd->setFileDef(fd);
@@ -561,6 +576,18 @@ void buildClassList(Entry *root)
addIncludeFile(cd,fd,root);
}
+ // namespace is part of the class name
+ if (!found && !namespaceName.isEmpty())
+ {
+ NamespaceDef *nd = namespaceDict[namespaceName];
+ if (nd)
+ {
+ cd->setNamespace(nd);
+ nd->insertClass(cd);
+ found=TRUE;
+ }
+ }
+
// if the class is not in a namespace then we insert
// it in the file definition
if (!found && fd && (root->section & Entry::COMPOUND_MASK))
@@ -968,8 +995,9 @@ void buildVarList(Entry *root)
QRegExp re("([^)]*)");
int i=-1;
if (!root->name.isEmpty() &&
- root->type!="class" && root->type!="interface" &&
- root->type!="struct" && root->type!="union" &&
+ //root->type!="class" && root->type!="interface" &&
+ //root->type!="struct" && root->type!="union" &&
+ (root->type.isEmpty() || compoundKeywordDict.find(root->type)==0) &&
(
(root->section==Entry::VARIABLE_SEC
) ||
@@ -1006,7 +1034,6 @@ void buildVarList(Entry *root)
}
else
{
- //QRegExp re("([^)]*)");
i=root->type.find(re,0);
if (i!=-1) // function variable
{
@@ -1016,14 +1043,17 @@ void buildVarList(Entry *root)
}
QCString scope,name=root->name.copy();
- //bool stat=root->stat;
+ //int si;
+ //if ((si=name.findRev("::"))!=-1)
+ //{
+ // scope=name.left(si);
+ // name=name.right(name.length()-si-2);
+ //}
- // find the scope of this variable (stripping the annonymous part
- // at the beginning
+ // find the scope of this variable
Entry *p = root->parent;
while ((p->section & Entry::SCOPE_MASK))
{
- //QCString scopeName = stripAnnonymousScope(p->name);
QCString scopeName = p->name.copy();
if (!scopeName.isEmpty())
{
@@ -1064,7 +1094,6 @@ void buildVarList(Entry *root)
else
mtype=MemberDef::Variable;
- //printf("name=`%s' scope=%s\n",name.data(),scope.data());
QCString classScope=stripAnnonymousNamespaceScope(scope);
QCString annScopePrefix=scope.left(scope.length()-classScope.length());
scope=classScope;
@@ -1423,7 +1452,11 @@ void buildMemberList(Entry *root)
NamespaceDef *nd = 0;
if (root->parent->section == Entry::NAMESPACE_SEC )
{
- nd = namespaceDict[root->parent->name];
+ QCString nscope=removeAnnonymousScopes(root->parent->name);
+ if (!nscope.isEmpty())
+ {
+ nd = namespaceDict[nscope];
+ }
}
if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@')
@@ -1544,6 +1577,8 @@ void findFriends()
void transferFunctionDocumentation()
{
//printf("transferFunctionDocumentation()\n");
+
+ // find matching function declaration and definitions.
MemberNameListIterator mnli(functionNameList);
MemberName *mn;
for (;(mn=mnli.current());++mnli)
@@ -1594,6 +1629,42 @@ void transferFunctionDocumentation()
}
}
+void transferRelatedFunctionDocumentation()
+{
+ // find match between function declaration and definition for
+ // related functions
+ MemberNameListIterator mnli(functionNameList);
+ MemberName *mn;
+ for (mnli.toFirst();(mn=mnli.current());++mnli)
+ {
+ MemberDef *md;
+ MemberNameIterator mni(*mn);
+ /* find a matching function declaration and definition for this function */
+ for (mni.toFirst();(md=mni.current());++mni) // for each global function
+ {
+ //printf(" Function `%s'\n",md->name().data());
+ MemberName *rmn;
+ if ((rmn=memberNameDict[md->name()])) // check if there is a member with the same name
+ {
+ //printf(" Member name found\n");
+ MemberDef *rmd;
+ MemberNameIterator rmni(*rmn);
+ for (rmni.toFirst();(rmd=rmni.current());++rmni) // for each member with the same name
+ {
+ //printf(" Member found: related=`%d'\n",rmd->isRelated());
+ if (rmd->isRelated() && // related function
+ matchArguments(md->argumentList(),rmd->argumentList()) // match argument lists
+ )
+ {
+ //printf(" Found related member `%s'\n",md->name().data());
+ md->makeRelated();
+ }
+ }
+ }
+ }
+ }
+}
+
//----------------------------------------------------------------------
static bool findBaseClassRelation(Entry *root,ClassDef *cd,
@@ -1685,7 +1756,7 @@ static bool findBaseClassRelation(Entry *root,ClassDef *cd,
}
if (found)
{
- //printf(">>> Documented base class = %s\n",bi->name.data());
+ Debug::print(Debug::Classes,0," Documented base class `%s'\n",bi->name.data());
// add base class to this class
cd->insertBaseClass(baseClass,bi->prot,bi->virt,templSpec);
// add this class as super class to the base class
@@ -1694,7 +1765,7 @@ static bool findBaseClassRelation(Entry *root,ClassDef *cd,
}
else if (insertUndocumented)
{
- //printf(">>> Undocumented base class = %s\n",bi->name.data());
+ Debug::print(Debug::Classes,0," Undocumented base class `%s'\n",bi->name.data());
baseClass=new ClassDef(baseClassName,ClassDef::Class);
// add base class to this class
cd->insertBaseClass(baseClass,bi->prot,bi->virt,templSpec);
@@ -1712,6 +1783,7 @@ static bool findBaseClassRelation(Entry *root,ClassDef *cd,
else
{
//printf(">>> base class %s not found!\n",bi->name.data());
+ Debug::print(Debug::Classes,0," Base class `%s' not found\n",bi->name.data());
}
}
if (scopeOffset==0)
@@ -1759,7 +1831,7 @@ void computeClassRelations(Entry *root)
{
ClassDef *cd;
QCString bName=stripAnnonymousNamespaceScope(root->name);
- //printf("Class %s\n",bName.data());
+ Debug::print(Debug::Classes,0," Class %s : \n",bName.data());
if ((cd=getClass(bName)))
{
//printf("Class %s %d\n",cd->name().data(),root->extends->count());
@@ -2007,15 +2079,17 @@ static bool findUnrelatedFunction(Entry *root,
QCString n=name;
if (n.isEmpty()) return FALSE;
if (n.find("::")!=-1) return FALSE; // skip undefined class members
- //printf("findUnrelatedFunction(namespace=%s,name=%s,tempArg=%s,decl=%s)\n",
- // namespaceName.data(),name,tempArg,decl);
+ Debug::print(Debug::FindMembers,0,
+ "2. findUnrelatedFunction(namespace=%s,name=%s,tempArg=%s,decl=%s)\n",
+ namespaceName.data(),name,tempArg,decl);
MemberName *mn=functionNameDict[n+tempArg]; // look in function dictionary
if (mn==0)
{
- mn=functionNameDict[n]; // try with template arguments
+ mn=functionNameDict[n]; // try without template arguments
}
if (mn) // function name defined
{
+ Debug::print(Debug::FindMembers,0,"3. Found function scope\n");
//int count=0;
MemberDef *md=mn->first();
bool found=FALSE;
@@ -2028,6 +2102,9 @@ static bool findUnrelatedFunction(Entry *root,
//printf("File %s\n",fd ? fd->name().data() : "<none>");
NamespaceList *nl = fd ? fd->getUsedNamespaces() : 0;
//printf("NamespaceList %p\n",nl);
+
+ // search in the list of namespaces that are imported via a
+ // using declaration
bool viaUsingDirective = nl && nd && nl->find(nd)!=-1;
if ((namespaceName.isEmpty() && nd==0) || // not in a namespace
@@ -2035,8 +2112,8 @@ static bool findUnrelatedFunction(Entry *root,
viaUsingDirective // member in `using' namespace
)
{
- //printf("Adding docs `%s' to member `%s' in namespace `%s'\n",
- // root->doc.data(),md->name().data(),namespaceName.data());
+ Debug::print(Debug::FindMembers,0,"4. Try to add member `%s' to scope `%s'\n",
+ md->name().data(),namespaceName.data());
//printf("Searching for match between %s and %s\n",
// argListToString(md->argumentList()).data(),
// argListToString(root->argList).data());
@@ -2047,7 +2124,7 @@ static bool findUnrelatedFunction(Entry *root,
matchArguments(md->argumentList(),root->argList,0,nsName);
if (matching) // add docs to the member
{
- //printf("Match found\n");
+ Debug::print(Debug::FindMembers,0,"5. Match found\n");
addMemberDocs(root,md,decl,FALSE);
found=TRUE;
}
@@ -2235,26 +2312,14 @@ void findMember(Entry *root,QCString funcDecl,QCString related,bool overloaded,
);
//printf("scopeName=`%s'\n",scopeName.data());
- bool isSpecialization = !root->scopeSpec.isEmpty() &&
- root->scopeSpec != tempArgListToString(root->tArgList);
+ //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
+ ) // template specifier that was found is for a function
{
funcTempList = root->scopeSpec;
}
@@ -2263,10 +2328,10 @@ void findMember(Entry *root,QCString funcDecl,QCString related,bool overloaded,
// if a related class name is specified and the class name could
// not be derived from the function declaration, then use the
// related field.
- //printf("scopeName=`%s' classTempList=`%s' className=`%s'\n",
- // scopeName.data(),classTempList.data(),className.data());
- if (/*scopeName.isEmpty() &&*/ !related.isEmpty() && !isRelated)
- {
+ //printf("scopeName=`%s' className=`%s' namespaceName=`%s'\n",
+ // scopeName.data(),className.data(),namespaceName.data());
+ if (!related.isEmpty() && !isRelated)
+ { // related member, prefix user specified scope
isRelated=TRUE;
//scopeName=resolveDefines(related);
if (!scopeName.isEmpty() && scopeName!=related)
@@ -2274,8 +2339,16 @@ void findMember(Entry *root,QCString funcDecl,QCString related,bool overloaded,
else
scopeName=related.copy();
}
- else if (/*scopeName.isEmpty() &&*/ related.isEmpty() && root->parent &&
- !root->parent->name.isEmpty())
+
+ // split scope into a namespace and a class part
+ extractNamespaceName(scopeName,className,namespaceName);
+ //printf("scopeName=`%s' className=`%s' namespaceName=`%s'\n",
+ // scopeName.data(),className.data(),namespaceName.data());
+
+ if (related.isEmpty() &&
+ root->parent &&
+ !root->parent->name.isEmpty()
+ ) // prefix scope in which the member was found
{
Entry *p=root->parent;
while (p) // get full scope as class name
@@ -2285,23 +2358,39 @@ void findMember(Entry *root,QCString funcDecl,QCString related,bool overloaded,
&& !sc.isEmpty() && sc[0]!='@'
)
{
+ QCString cn;
+ QCString nn;
+ extractNamespaceName(sc,cn,nn);
+ if (leftScopeMatch(nn,namespaceName) || namespaceName.isEmpty())
+ {
+ namespaceName=nn.copy();
+ }
+ if (leftScopeMatch(cn,className) || className.isEmpty())
+ {
+ className=cn.copy();
+ }
+
+ //printf("sc=`%s' cn=`%s' nn=`%s'\n",sc.data(),cn.data(),nn.data());
+
//printf("p->name=`%s' scopeName=`%s' classTempList=%s\n",
// p->name.data(),scopeName.data(),classTempList.data());
- QCString tryScope;
+ QCString tryClass;
- if (scopeName.find('<')==-1 && !classTempList.isEmpty())
- tryScope=insertTemplateSpecifierInScope(scopeName,classTempList);
+ if (className.find('<')==-1 && !classTempList.isEmpty())
+ tryClass=insertTemplateSpecifierInScope(className,classTempList);
else
- tryScope=scopeName.copy();
+ tryClass=className.copy();
- //printf("tryScope=%s\n",tryScope.data());
+ //printf("tryClass=%s\n",tryClass.data());
- if (leftScopeMatch(tryScope,sc))
+ if (leftScopeMatch(tryClass,cn))
break; // scope already present, so stop now
+
// prepend name to scope
if (!scopeName.isEmpty()) scopeName.prepend("::");
scopeName.prepend(sc);
+ break;
}
p=p->parent;
}
@@ -2309,6 +2398,25 @@ void findMember(Entry *root,QCString funcDecl,QCString related,bool overloaded,
//printf("result: scope=%s\n",scopeName.data());
}
+ namespaceName=removeAnnonymousScopes(namespaceName);
+ // merge class and namespace scopes again
+ if (!namespaceName.isEmpty())
+ {
+ if (className.isEmpty())
+ {
+ scopeName=namespaceName;
+ }
+ else
+ {
+ scopeName=namespaceName+"::"+className;
+ }
+ }
+ else if (!className.isEmpty())
+ {
+ scopeName=className;
+ }
+ //printf("new scope=`%s'\n",scopeName.data());
+
if (!scopeName.isEmpty() &&
scopeName.find('<')==-1 &&
classTempList.isEmpty()
@@ -2322,8 +2430,6 @@ void findMember(Entry *root,QCString funcDecl,QCString related,bool overloaded,
}
}
- // see if (part of) the scope name is a namespace name
- extractNamespaceName(scopeName,className,namespaceName);
QCString tempScopeName=scopeName.copy();
int ti=tempScopeName.find('<');
@@ -2613,7 +2719,7 @@ void findMember(Entry *root,QCString funcDecl,QCString related,bool overloaded,
}
}
}
- if (count==0)
+ if (count==0 && !(isFriend && funcType=="class"))
warn("Warning: no matching member found for \n%s\n"
"in file %s at line %d\n",
fullFuncDecl.data(),root->fileName.data(),root->startLine);
@@ -2846,8 +2952,8 @@ void findMemberDocumentation(Entry *root)
int i,l;
QRegExp re("([a-zA-Z0-9: ]*\\*+[ \\*]*");
Debug::print(Debug::FindMembers,0,
- "root->type=`%s' root->name=`%s' root->args=`%s' section=%x root->inLine=%d\n",
- root->type.data(),root->name.data(),root->args.data(),root->section,root->inLine
+ "root->type=`%s' root->inside=`%s' root->name=`%s' root->args=`%s' section=%x root->inLine=%d\n",
+ root->type.data(),root->inside.data(),root->name.data(),root->args.data(),root->section,root->inLine
);
bool isFunc=TRUE;
if ((i=re.match(root->type,0,&l))!=-1) // func variable/typedef to func ptr
@@ -2883,8 +2989,10 @@ void findMemberDocumentation(Entry *root)
((root->section==Entry::FUNCTION_SEC || // function
(root->section==Entry::VARIABLE_SEC &&
!root->type.isEmpty() && root->type.left(8)!="typedef " &&
- root->type!="class" && root->type!="interface" &&
- root->type!="struct" && root->type!="union")
+ compoundKeywordDict.find(root->type)==0
+ /*root->type!="class" && root->type!="interface" &&
+ root->type!="struct" && root->type!="union"*/
+ )
) &&
(!root->doc.isEmpty() || !root->brief.isEmpty() ||
root->bodyLine!=-1 || root->mGrpId!=-1 /*|| Config::extractAllFlag*/
@@ -2896,6 +3004,7 @@ void findMemberDocumentation(Entry *root)
// root->name.data(),root->args.data(),root->exception.data());
//if (root->relates.length()) printf(" Relates %s\n",root->relates.data());
//printf("Inside=%s\n Relates=%s\n",root->inside.data(),root->relates.data());
+
if (!root->type.isEmpty())
{
findMember(root,
@@ -2906,7 +3015,6 @@ void findMemberDocumentation(Entry *root)
root->exception,
root->relates,
FALSE,isFunc);
- //}
}
else
{
@@ -3364,7 +3472,7 @@ void generateFileDocs()
{
fd->writeDocumentation(*outputList);
}
- if (src) // TODO: can this be TRUE for tag files?
+ if (src && !fd->isReference()) // TODO: can this be TRUE for tag files?
{
fd->writeSource(*outputList);
}
@@ -4602,6 +4710,12 @@ int main(int argc,char **argv)
generateConfigFile(configName,shortList);
exit(1);
}
+
+ compoundKeywordDict.insert("class",(void *)8);
+ compoundKeywordDict.insert("struct",(void *)8);
+ compoundKeywordDict.insert("union",(void *)8);
+ compoundKeywordDict.insert("interface",(void *)8);
+ compoundKeywordDict.insert("exception",(void *)8);
QFileInfo configFileInfo1("Doxyfile"),configFileInfo2("doxyfile");
QCString config;
@@ -4818,6 +4932,7 @@ int main(int argc,char **argv)
msg("Searching for member function documentation...\n");
findMemberDocumentation(root); // may introduce new members !
+ transferRelatedFunctionDocumentation();
msg("Freeing entry tree\n");
delete root;