diff options
author | Dimitri van Heesch <dimitri@stack.nl> | 2000-02-20 17:34:13 (GMT) |
---|---|---|
committer | Dimitri van Heesch <dimitri@stack.nl> | 2000-02-20 17:34:13 (GMT) |
commit | a81ce4743212122ae050e5efbc4bfda92e6a664e (patch) | |
tree | f122ed1db8000e070cab7f8ad4c4af87b89adbe5 /src/doxygen.cpp | |
parent | ddbc18f5fb336d3a83521404620b6734b13e5610 (diff) | |
download | Doxygen-a81ce4743212122ae050e5efbc4bfda92e6a664e.zip Doxygen-a81ce4743212122ae050e5efbc4bfda92e6a664e.tar.gz Doxygen-a81ce4743212122ae050e5efbc4bfda92e6a664e.tar.bz2 |
+ The graphical class hierarchy was not properly generated when
template classes were used.
+ Template specialization could not be documented using the
\class command. This is now fixed. Example:
/*!
* \class T<A,int>
* My template specialization of template T.
*/
+ Fixed a bug when parsing M$-IDL code, containing
helpstring("bla") attributes. The attributes of a method are no longer
shown in the documentation (the attributes of method arguments
still visible however).
+ Improved the search algorithm that tries to connect classes with their
base classes. It should now (hopefully) work correct in all cases
where nested classes and/or namespaces are used.
+ Fixed a scanner problem that could cause doxygen to get
confused after parsing struct initializers.
+ the DOTFONTPATH environment variable is now automatically set
for Windows. This should make any "missing doxfont.ttf"
messages disappear.
+ the extra LaTeX packages specified with EXTRA_PACKAGES can now
also be used when generating formulas for HTML.
+ The documentation of a parameters that is part of a member definition,
is now used in the documentation as well.
+ Fixed a HTML output bug in the class/file group-pages.
+ Links to example files generated with \link ... \endlink where not
correct.
+ made the bullet list generation more robust. A space is now required
after the - sign. A list can now start a paragraph.
+ the configure script now detects whether or not dot is installed.
+ The VERBATIM_HEADERS option didn't have any effect any more.
It should now works again as advertised.
+ The IGNORE_PREFIX option can now also deal with a list of prefixes.
+ @verbatim ... @endverbatim blocks did not work.
+ new option SHOW_INCLUDE_FILES, which can be set to NO to turn of the
list of include files that is generated for each documented file.
+ new option STRIP_CODE_COMMENTS, which can be set to NO to keep any
special comment blocks in the generated code fragments.
Diffstat (limited to 'src/doxygen.cpp')
-rw-r--r-- | src/doxygen.cpp | 266 |
1 files changed, 145 insertions, 121 deletions
diff --git a/src/doxygen.cpp b/src/doxygen.cpp index 9e8bf7f..7df0b4d 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -339,42 +339,29 @@ static void addIncludeFile(ClassDef *cd,FileDef *ifd,Entry *root) fd=ifd; } - // if a file is found, we mark it as a source file. if (fd) { - //printf("Adding file %s used by %s\n",fd->name().data(),cd->name().data()); - //printf("fd->name()=%s fd->absFilePath()=%s\n",fd->name().data(), - // fd->absFilePath().data()); - // set include file definition - //cd->setIncludeFile(fd); - // set include supplied name - //cd->setIncludeName(root->includeName); - QCString iName = !root->includeName.isEmpty() ? root->includeName.data() : root->includeFile.data(); bool local=FALSE; - if (!iName.isEmpty()) + if (!iName.isEmpty()) // user specified include file { - local = iName.at(0)=='"'; + local = iName.at(0)=='"'; // is it a local include file if (local || iName.at(0)=='<') { - iName=iName.mid(1,iName.length()-2); + iName=iName.mid(1,iName.length()-2); // strip quotes or brackets } } - fd->setGenerateSource(TRUE); - cd->setIncludeFile(fd,iName,local); - - //if (cd->name().find('@')==-1) - //{ - // fd->setIncludeName(cd->getOutputFileBase()+"-include"); - //} - //if (!fd->absFilePath().isEmpty() && - // includeDict[fd->absFilePath()]==0) // include not inserted earlier - //{ - // includeFiles.inSort(fd); - // includeDict.insert(fd->absFilePath(),fd); - //} + if (Config::verbatimHeaderFlag) // generate code for header + { + cd->setIncludeFile(fd,iName,local); + fd->setGenerateSource(TRUE); + } + else // put #include in the class documentation without link + { + cd->setIncludeFile(0,iName,local); + } } } } @@ -1609,108 +1596,146 @@ void transferFunctionDocumentation() //---------------------------------------------------------------------- -bool findBaseClassRelation(Entry *root,ClassDef *cd,const char *scopePrefix, - bool insertUndocumented) +static bool findBaseClassRelation(Entry *root,ClassDef *cd, + BaseInfo *bi, + bool insertUndocumented + ) { - // The base class could ofcouse also be a non-nested class - QList<BaseInfo> *baseList=root->extends; - BaseInfo *bi=baseList->first(); - bool foundAny=FALSE; - while (bi) // for each base class - { - QCString baseClassName=removeRedundantWhiteSpace(scopePrefix+bi->name); - ClassDef *baseClass=getClass(baseClassName); - if (baseClassName!=root->name) // check for base class with the same name, - // look in the outer scope for a match + Entry *parentNode=root->parent; + bool lastParent=FALSE; + do // for each parent scope, starting with the largest scope + // (in case of nested classes) + { + QCString scopeName= parentNode ? parentNode->name.data() : ""; + int scopeOffset=scopeName.length(); + do // try all parent scope prefixes, starting with the largest scope { - //printf("baseClass %s of %s found (%s and %s)\n", - // baseClassName.data(), - // root->name.data(), - // (bi->prot==Private)?"private":((bi->prot==Protected)?"protected":"public"), - // (bi->virt==Normal)?"normal":"virtual" - // ); - int i; - QCString templSpec; - if (baseClass==0 && (i=baseClassName.find('<'))!=-1) - // base class has template specifiers + //printf("scopePrefix=`%s' bi->name=`%s'\n", + // scopeName.left(scopeOffset).data(),bi->name.data()); + + QCString baseClassName=removeRedundantWhiteSpace(bi->name); + if (scopeOffset>0) { - // TODO: here we should try to find the correct template specialization - // but for now, we only look for the unspecializated base class. - templSpec=baseClassName.right(baseClassName.length()-i); - baseClassName=baseClassName.left(i); - baseClass=getClass(baseClassName); - //printf("baseClass=%p baseClass=%s templSpec=%s\n", - // baseClass,baseClassName.data(),templSpec.data()); + baseClassName.prepend(scopeName.left(scopeOffset)+"::"); } - - bool found=baseClass!=0 && baseClass!=cd; - NamespaceDef *nd=cd->getNamespace(); - if (!found) + ClassDef *baseClass=getClass(baseClassName); + if (baseClassName!=root->name) // check for base class with the same name, + // look in the outer scope for a match { - FileDef *fd=cd->getFileDef(); - if (fd) + //printf("baseClass %s of %s found (%s and %s)\n", + // baseClassName.data(), + // root->name.data(), + // (bi->prot==Private)?"private":((bi->prot==Protected)?"protected":"public"), + // (bi->virt==Normal)?"normal":"virtual" + // ); + + int i; + QCString templSpec; + if (baseClass==0 && (i=baseClassName.find('<'))!=-1) + // base class has template specifiers { - // look for the using statement in this file in which the - // class was found - NamespaceList *nl = fd->getUsedNamespaces(); - if (nl) // try to prepend any of the using namespace scopes. + // TODO: here we should try to find the correct template specialization + // but for now, we only look for the unspecializated base class. + templSpec=baseClassName.right(baseClassName.length()-i); + baseClassName=baseClassName.left(i); + baseClass=getClass(baseClassName); + //printf("baseClass=%p baseClass=%s templSpec=%s\n", + // baseClass,baseClassName.data(),templSpec.data()); + } + + bool found=baseClass!=0 && baseClass!=cd; + NamespaceDef *nd=cd->getNamespace(); + if (!found) + { + FileDef *fd=cd->getFileDef(); + if (fd) { - NamespaceListIterator nli(*nl); - NamespaceDef *nd; - for (nli.toFirst() ; (nd=nli.current()) && !found ; ++nli) + // look for the using statement in this file in which the + // class was found + NamespaceList *nl = fd->getUsedNamespaces(); + if (nl) // try to prepend any of the using namespace scopes. { - QCString fName = nd->name()+"::"+baseClassName; - found = (baseClass=getClass(fName))!=0 && baseClass!=cd && - root->name!=fName; + NamespaceListIterator nli(*nl); + NamespaceDef *nd; + for (nli.toFirst() ; (nd=nli.current()) && !found ; ++nli) + { + QCString fName = nd->name()+"::"+baseClassName; + found = (baseClass=getClass(fName))!=0 && baseClass!=cd && + root->name!=fName; + } } } - } - if (!found && nd) // class is inside a namespace - { - NamespaceList *nl = nd->getUsedNamespaces(); - QCString fName = nd->name()+"::"+baseClassName; - found = (baseClass=getClass(fName))!=0 && root->name!=fName; - if (nl) // try to prepend any of the using namespace scopes. + if (!found && nd) // class is inside a namespace { - NamespaceListIterator nli(*nl); - NamespaceDef *nd; - for (nli.toFirst() ; (nd=nli.current()) && !found ; ++nli) + NamespaceList *nl = nd->getUsedNamespaces(); + QCString fName = nd->name()+"::"+baseClassName; + found = (baseClass=getClass(fName))!=0 && root->name!=fName; + if (nl) // try to prepend any of the using namespace scopes. { - fName = nd->name()+"::"+baseClassName; - found = (baseClass=getClass(fName))!=0 && baseClass!=cd && - root->name!=fName; + NamespaceListIterator nli(*nl); + NamespaceDef *nd; + for (nli.toFirst() ; (nd=nli.current()) && !found ; ++nli) + { + fName = nd->name()+"::"+baseClassName; + found = (baseClass=getClass(fName))!=0 && baseClass!=cd && + root->name!=fName; + } } } } + if (found) + { + //printf(">>> 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 + baseClass->insertSuperClass(cd,bi->prot,bi->virt,templSpec); + return TRUE; + } + else if (insertUndocumented) + { + //printf(">>> 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); + // add this class as super class to the base class + baseClass->insertSuperClass(cd,bi->prot,bi->virt,templSpec); + // the undocumented base was found in this file + baseClass->insertUsedFile(root->fileName); + // add class to the list + classList.inSort(baseClass); + //printf("ClassDict.insert(%s)\n",resolveDefines(fullName).data()); + //classDict.insert(resolveDefines(bi->name),baseClass); + classDict.insert(baseClassName,baseClass); + return TRUE; + } + else + { + //printf(">>> base class %s not found!\n",bi->name.data()); + } } - if (found) + if (scopeOffset==0) { - // add base class to this class - cd->insertBaseClass(baseClass,bi->prot,bi->virt,templSpec); - // add this class as super class to the base class - baseClass->insertSuperClass(cd,bi->prot,bi->virt,templSpec); - foundAny=TRUE; + scopeOffset=-1; } - else if (insertUndocumented) + else if ((scopeOffset=scopeName.findRev("::",scopeOffset-1))==-1) { - //printf(">>> 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); - // add this class as super class to the base class - baseClass->insertSuperClass(cd,bi->prot,bi->virt,templSpec); - // the undocumented base was found in this file - baseClass->insertUsedFile(root->fileName); - // add class to the list - classList.inSort(baseClass); - //printf("ClassDict.insert(%s)\n",resolveDefines(fullName).data()); - //classDict.insert(resolveDefines(bi->name),baseClass); - classDict.insert(baseClassName,baseClass); + scopeOffset=0; } + //printf("new scopeOffset=`%d'",scopeOffset); + } while (scopeOffset>=0); + + if (parentNode==0) + { + lastParent=TRUE; } - bi=baseList->next(); - } - return foundAny; + else + { + parentNode=parentNode->parent; + } + } while (lastParent); + + return FALSE; } //---------------------------------------------------------------------- @@ -1721,9 +1746,9 @@ void computeClassRelations(Entry *root) if ( ( ( - root->section & Entry::COMPOUND_MASK + root->section & Entry::COMPOUND_MASK ) - || + || ( (root->section & Entry::COMPOUNDDOC_MASK) && root->extends->count()>0 ) @@ -1743,20 +1768,19 @@ void computeClassRelations(Entry *root) cd->visited=TRUE; // mark class as used if (root->extends->count()>0) // there are base classes { - Entry *p=root->parent; - bool found=FALSE; - // For nested classes (or classes inside namespaces) the base class - // could also be nested (or inside a namespace)! - // To find the correct scope, we try to prepend the scope to the base - // name, starting with the largest, most inner scope. - while (p && p->section&Entry::SCOPE_MASK && - !(found=findBaseClassRelation(root,cd,p->name+"::",FALSE))) - p=p->parent; - // For classes with global scope the same search is preformed - if (!found) + // The base class could ofcouse also be a non-nested class + QList<BaseInfo> *baseList=root->extends; + BaseInfo *bi=baseList->first(); + while (bi) // for each base class { - findBaseClassRelation(root,cd,0,TRUE); - } // class not nested + // find a documented base class in the correct scope + if (!findBaseClassRelation(root,cd,bi,FALSE)) + { + // no documented base class -> try to find an undocumented one + findBaseClassRelation(root,cd,bi,TRUE); + } + bi=baseList->next(); + } } // class has no base classes } // else class is already found } |