diff options
Diffstat (limited to 'src/filedef.cpp')
-rw-r--r-- | src/filedef.cpp | 1656 |
1 files changed, 1656 insertions, 0 deletions
diff --git a/src/filedef.cpp b/src/filedef.cpp new file mode 100644 index 0000000..e7f257a --- /dev/null +++ b/src/filedef.cpp @@ -0,0 +1,1656 @@ +/****************************************************************************** + * + * $Id: filedef.cpp,v 1.55 2001/03/19 19:27:40 root Exp $ + * + * Copyright (C) 1997-2011 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + * Documents produced by Doxygen are derivative works derived from the + * input used in their production; they are not affected by this license. + * + */ + +#include "qtbc.h" +#include "memberlist.h" +#include "classlist.h" +#include "filedef.h" +#include "doxygen.h" +#include "memberdef.h" +#include "classdef.h" +#include "namespacedef.h" +#include "util.h" +#include "language.h" +#include "outputlist.h" +#include "dot.h" +#include "message.h" +#include "docparser.h" +#include "searchindex.h" +#include "htags.h" +#include "parserintf.h" +#include "portable.h" +#include "vhdldocgen.h" +#include "debug.h" +#include "layout.h" + +//--------------------------------------------------------------------------- + +class DevNullCodeDocInterface : public CodeOutputInterface +{ + public: + virtual void codify(const char *) {} + virtual void writeCodeLink(const char *,const char *, + const char *,const char *, + const char *) {} + virtual void writeLineNumber(const char *,const char *, + const char *,int) {} + virtual void startCodeLine() {} + virtual void endCodeLine() {} + virtual void startCodeAnchor(const char *) {} + virtual void endCodeAnchor() {} + virtual void startFontClass(const char *) {} + virtual void endFontClass() {} + virtual void writeCodeAnchor(const char *) {} + virtual void linkableSymbol(int, const char *,Definition *,Definition *) {} +}; + +//--------------------------------------------------------------------------- + +/*! create a new file definition, where \a p is the file path, + \a nm the file name, and \a lref is an HTML anchor name if the + file was read from a tag file or 0 otherwise +*/ +FileDef::FileDef(const char *p,const char *nm, + const char *lref,const char *dn) + : Definition((QCString)p+nm,1,nm) +{ + path=p; + filepath=path+nm; + filename=nm; + diskname=dn; + if (diskname.isEmpty()) diskname=nm; + setReference(lref); + classSDict = 0; + includeList = 0; + includeDict = 0; + includedByList = 0; + includedByDict = 0; + namespaceSDict = 0; + srcDefDict = 0; + srcMemberDict = 0; + usingDirList = 0; + usingDeclList = 0; + package = 0; + isSource = FALSE; + docname = nm; + dir = 0; + if (Config_getBool("FULL_PATH_NAMES")) + { + docname.prepend(stripFromPath(path.copy())); + } + SrcLangExt lang = getLanguageFromFileName(name()); + m_isJava = lang==SrcLangExt_Java; + m_isCSharp = lang==SrcLangExt_CSharp; + memberGroupSDict = 0; + acquireFileVersion(); + m_subGrouping=Config_getBool("SUBGROUPING"); +} + +/*! destroy the file definition */ +FileDef::~FileDef() +{ + delete classSDict; + delete includeDict; + delete includeList; + delete includedByDict; + delete includedByList; + delete namespaceSDict; + delete srcDefDict; + delete srcMemberDict; + delete usingDirList; + delete usingDeclList; + delete memberGroupSDict; +} + +/*! Compute the HTML anchor names for all members in the class */ +void FileDef::computeAnchors() +{ + MemberList *ml = getMemberList(MemberList::allMembersList); + if (ml) setAnchors(0,'a',ml); +} + +void FileDef::distributeMemberGroupDocumentation() +{ + //printf("FileDef::distributeMemberGroupDocumentation()\n"); + if (memberGroupSDict) + { + MemberGroupSDict::Iterator mgli(*memberGroupSDict); + MemberGroup *mg; + for (;(mg=mgli.current());++mgli) + { + mg->distributeMemberGroupDocumentation(); + } + } +} + +void FileDef::findSectionsInDocumentation() +{ + docFindSections(documentation(),this,0,docFile()); + if (memberGroupSDict) + { + MemberGroupSDict::Iterator mgli(*memberGroupSDict); + MemberGroup *mg; + for (;(mg=mgli.current());++mgli) + { + mg->findSectionsInDocumentation(); + } + } + + QListIterator<MemberList> mli(m_memberLists); + MemberList *ml; + for (mli.toFirst();(ml=mli.current());++mli) + { + if (ml->listType()&MemberList::declarationLists) + { + ml->findSectionsInDocumentation(); + } + } +} + +void FileDef::writeDetailedDescription(OutputList &ol,const QCString &title) +{ + if ((!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF")) || + !documentation().isEmpty() || + (Config_getBool("SOURCE_BROWSER") && getStartBodyLine()!=-1 && getBodyDef()) + ) + { + ol.writeRuler(); + ol.pushGeneratorState(); + ol.disableAllBut(OutputGenerator::Html); + ol.writeAnchor(0,"details"); + ol.popGeneratorState(); + ol.startGroupHeader(); + ol.parseText(title); + ol.endGroupHeader(); + + ol.startTextBlock(); + if (!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF")) + { + ol.parseDoc(briefFile(),briefLine(),this,0,briefDescription(),FALSE,FALSE); + } + if (!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF") && + !documentation().isEmpty()) + { + ol.pushGeneratorState(); + ol.disable(OutputGenerator::Man); + ol.disable(OutputGenerator::RTF); + // ol.newParagraph(); // FIXME:PARA + ol.enableAll(); + ol.disableAllBut(OutputGenerator::Man); + ol.writeString("\n\n"); + ol.popGeneratorState(); + } + if (!documentation().isEmpty()) + { + ol.parseDoc(docFile(),docLine(),this,0,documentation()+"\n",TRUE,FALSE); + } + //printf("Writing source ref for file %s\n",name().data()); + if (Config_getBool("SOURCE_BROWSER")) + { + ol.startParagraph(); + QCString refText = theTranslator->trDefinedInSourceFile(); + int fileMarkerPos = refText.find("@0"); + if (fileMarkerPos!=-1) // should always pass this. + { + ol.parseText(refText.left(fileMarkerPos)); //text left from marker 1 + ol.writeObjectLink(0,getSourceFileBase(), + 0,name()); + ol.parseText(refText.right( + refText.length()-fileMarkerPos-2)); // text right from marker 2 + } + ol.endParagraph(); + } + ol.endTextBlock(); + } +} + +void FileDef::writeBriefDescription(OutputList &ol) +{ + if (!briefDescription().isEmpty()) + { + ol.startParagraph(); + ol.parseDoc(briefFile(),briefLine(),this,0, + briefDescription(),TRUE,FALSE,0,TRUE,FALSE); + ol.pushGeneratorState(); + ol.disable(OutputGenerator::RTF); + ol.writeString(" \n"); + ol.enable(OutputGenerator::RTF); + + if (Config_getBool("REPEAT_BRIEF") || + !documentation().isEmpty() + ) + { + ol.disableAllBut(OutputGenerator::Html); + ol.startTextLink(0,"details"); + ol.parseText(theTranslator->trMore()); + ol.endTextLink(); + } + ol.popGeneratorState(); + ol.endParagraph(); + + //ol.pushGeneratorState(); + //ol.disable(OutputGenerator::RTF); + //ol.newParagraph(); + //ol.popGeneratorState(); + } + ol.writeSynopsis(); +} + +void FileDef::writeIncludeFiles(OutputList &ol) +{ + if (/*Config_getBool("SHOW_INCLUDE_FILES") &&*/ includeList && + includeList->count()>0) + { + ol.startTextBlock(TRUE); + QListIterator<IncludeInfo> ili(*includeList); + IncludeInfo *ii; + for (;(ii=ili.current());++ili) + { + FileDef *fd=ii->fileDef; + bool isIDLorJava = FALSE; + if (fd) + { + SrcLangExt lang = getLanguageFromFileName(fd->name()); + isIDLorJava = lang==SrcLangExt_IDL || lang==SrcLangExt_Java; + } + ol.startTypewriter(); + if (isIDLorJava) // IDL/Java include + { + ol.docify("import "); + } + else if (ii->imported) // Objective-C include + { + ol.docify("#import "); + } + else // C/C++ include + { + ol.docify("#include "); + } + if (ii->local || isIDLorJava) + ol.docify("\""); + else + ol.docify("<"); + ol.disable(OutputGenerator::Html); + ol.docify(ii->includeName); + ol.enableAll(); + ol.disableAllBut(OutputGenerator::Html); + + // Here we use the include file name as it appears in the file. + // we could also we the name as it is used within doxygen, + // then we should have used fd->docName() instead of ii->includeName + if (fd && fd->isLinkable()) + { + ol.writeObjectLink(fd->getReference(), + fd->generateSourceFile() ? fd->includeName() : fd->getOutputFileBase(), + 0,ii->includeName); + if (!Config_getString("GENERATE_TAGFILE").isEmpty() && !fd->isReference()) + { + const char *locStr = (ii->local || isIDLorJava) ? "yes" : "no"; + const char *impStr = (ii->imported || isIDLorJava) ? "yes" : "no"; + Doxygen::tagFile << " <includes id=\"" + << convertToXML(fd->getOutputFileBase()) << "\" " + << "name=\"" << convertToXML(fd->name()) << "\" " + << "local=\"" << locStr << "\" " + << "imported=\"" << impStr << "\">" + << convertToXML(ii->includeName) + << "</includes>" + << endl; + } + } + else + { + ol.docify(ii->includeName); + } + + ol.enableAll(); + if (ii->local || isIDLorJava) + ol.docify("\""); + else + ol.docify(">"); + if (isIDLorJava) + ol.docify(";"); + ol.endTypewriter(); + ol.lineBreak(); + } + ol.endTextBlock(); + } +} + +void FileDef::writeIncludeGraph(OutputList &ol) +{ + if (Config_getBool("HAVE_DOT") /*&& Config_getBool("INCLUDE_GRAPH")*/) + { + //printf("Graph for file %s\n",name().data()); + DotInclDepGraph incDepGraph(this,FALSE); + if (!incDepGraph.isTrivial() && !incDepGraph.isTooBig()) + { + ol.startTextBlock(); + ol.disable(OutputGenerator::Man); + ol.startInclDepGraph(); + ol.parseText(theTranslator->trInclDepGraph(name())); + ol.endInclDepGraph(incDepGraph); + ol.enableAll(); + ol.endTextBlock(TRUE); + } + //incDepGraph.writeGraph(Config_getString("HTML_OUTPUT"),fd->getOutputFileBase()); + } +} + +void FileDef::writeIncludedByGraph(OutputList &ol) +{ + if (Config_getBool("HAVE_DOT") /*&& Config_getBool("INCLUDED_BY_GRAPH")*/) + { + //printf("Graph for file %s\n",name().data()); + DotInclDepGraph incDepGraph(this,TRUE); + if (!incDepGraph.isTrivial() && !incDepGraph.isTooBig()) + { + ol.startTextBlock(); + ol.disable(OutputGenerator::Man); + ol.startInclDepGraph(); + ol.parseText(theTranslator->trInclByDepGraph()); + ol.endInclDepGraph(incDepGraph); + ol.enableAll(); + ol.endTextBlock(TRUE); + } + //incDepGraph.writeGraph(Config_getString("HTML_OUTPUT"),fd->getOutputFileBase()); + } +} + + +void FileDef::writeSourceLink(OutputList &ol) +{ + //printf("%s: generateSourceFile()=%d\n",name().data(),generateSourceFile()); + if (generateSourceFile()) + { + ol.disableAllBut(OutputGenerator::Html); + ol.startParagraph(); + ol.startTextLink(includeName(),0); + ol.parseText(theTranslator->trGotoSourceCode()); + ol.endTextLink(); + ol.endParagraph(); + ol.enableAll(); + } +} + +void FileDef::writeNamespaceDeclarations(OutputList &ol,const QCString &title) +{ + // write list of namespaces + if (namespaceSDict) namespaceSDict->writeDeclaration(ol,title); +} + +void FileDef::writeClassDeclarations(OutputList &ol,const QCString &title) +{ + // write list of classes + if (classSDict) classSDict->writeDeclaration(ol,0,title,FALSE); +} + +void FileDef::startMemberDeclarations(OutputList &ol) +{ + ol.startMemberSections(); +} + +void FileDef::endMemberDeclarations(OutputList &ol) +{ + ol.endMemberSections(); +} + +void FileDef::startMemberDocumentation(OutputList &ol) +{ + if (Config_getBool("SEPARATE_MEMBER_PAGES")) + { + ol.disable(OutputGenerator::Html); + Doxygen::suppressDocWarnings = TRUE; + } +} + +void FileDef::endMemberDocumentation(OutputList &ol) +{ + if (Config_getBool("SEPARATE_MEMBER_PAGES")) + { + ol.enable(OutputGenerator::Html); + Doxygen::suppressDocWarnings = FALSE; + } +} + +void FileDef::writeMemberGroups(OutputList &ol) +{ + /* write user defined member groups */ + if (memberGroupSDict) + { + memberGroupSDict->sort(); + MemberGroupSDict::Iterator mgli(*memberGroupSDict); + MemberGroup *mg; + for (;(mg=mgli.current());++mgli) + { + if ((!mg->allMembersInSameSection() || !m_subGrouping) + && mg->header()!="[NOHEADER]") + { + mg->writeDeclarations(ol,0,0,this,0); + } + } + } +} + +void FileDef::writeAuthorSection(OutputList &ol) +{ + // write Author section (Man only) + ol.pushGeneratorState(); + ol.disableAllBut(OutputGenerator::Man); + ol.startGroupHeader(); + ol.parseText(theTranslator->trAuthor(TRUE,TRUE)); + ol.endGroupHeader(); + ol.parseText(theTranslator->trGeneratedAutomatically(Config_getString("PROJECT_NAME"))); + ol.popGeneratorState(); +} + +void FileDef::writeSummaryLinks(OutputList &ol) +{ + ol.pushGeneratorState(); + ol.disableAllBut(OutputGenerator::Html); + QListIterator<LayoutDocEntry> eli( + LayoutDocManager::instance().docEntries(LayoutDocManager::File)); + LayoutDocEntry *lde; + bool first=TRUE; + for (eli.toFirst();(lde=eli.current());++eli) + { + if ((lde->kind()==LayoutDocEntry::FileClasses && classSDict && classSDict->declVisible()) || + (lde->kind()==LayoutDocEntry::FileNamespaces && namespaceSDict && namespaceSDict->declVisible()) + ) + { + LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; + QCString label = lde->kind()==LayoutDocEntry::FileClasses ? "nested-classes" : "namespaces"; + writeSummaryLink(ol,label,ls->title,first); + } + else if (lde->kind()==LayoutDocEntry::MemberDecl) + { + LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde; + MemberList * ml = getMemberList(lmd->type); + if (ml && ml->declVisible()) + { + writeSummaryLink(ol,ml->listTypeAsString(),lmd->title,first); + } + } + } + if (!first) + { + ol.writeString(" </div>\n"); + } + ol.popGeneratorState(); +} + +/*! Write the documentation page for this file to the file of output + generators \a ol. +*/ +void FileDef::writeDocumentation(OutputList &ol) +{ + static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW"); + //funcList->countDecMembers(); + + //QCString fn = name(); + //if (Config_getBool("FULL_PATH_NAMES")) + //{ + // fn.prepend(stripFromPath(getPath().copy())); + //} + + //printf("WriteDocumentation diskname=%s\n",diskname.data()); + + QCString versionTitle; + if (!fileVersion.isEmpty()) + { + versionTitle=("("+fileVersion+")"); + } + QCString title = docname+versionTitle; + QCString pageTitle=theTranslator->trFileReference(docname); + + if (Config_getBool("SHOW_DIRECTORIES") && getDirDef()) + { + startFile(ol,getOutputFileBase(),name(),pageTitle,HLI_FileVisible,!generateTreeView); + if (!generateTreeView) + { + getDirDef()->writeNavigationPath(ol); + ol.endQuickIndices(); + } + QCString pageTitleShort=theTranslator->trFileReference(name()); + startTitle(ol,getOutputFileBase(),this); + ol.pushGeneratorState(); + ol.disableAllBut(OutputGenerator::Html); + ol.parseText(pageTitleShort); // Html only + ol.enableAll(); + ol.disable(OutputGenerator::Html); + ol.parseText(pageTitle); // other output formats + ol.popGeneratorState(); + addGroupListToTitle(ol,this); + endTitle(ol,getOutputFileBase(),title); + } + else + { + startFile(ol,getOutputFileBase(),name(),pageTitle,HLI_FileVisible,!generateTreeView); + if (!generateTreeView) + { + ol.endQuickIndices(); + } + startTitle(ol,getOutputFileBase(),this); + ol.parseText(pageTitle); + addGroupListToTitle(ol,this); + endTitle(ol,getOutputFileBase(),title); + } + + ol.startContents(); + + if (!fileVersion.isEmpty()) + { + ol.disableAllBut(OutputGenerator::Html); + ol.startProjectNumber(); + ol.docify(versionTitle); + ol.endProjectNumber(); + ol.enableAll(); + } + + if (Doxygen::searchIndex) + { + Doxygen::searchIndex->setCurrentDoc(pageTitle,getOutputFileBase()); + Doxygen::searchIndex->addWord(localName(),TRUE); + } + + if (!Config_getString("GENERATE_TAGFILE").isEmpty()) + { + Doxygen::tagFile << " <compound kind=\"file\">" << endl; + Doxygen::tagFile << " <name>" << convertToXML(name()) << "</name>" << endl; + Doxygen::tagFile << " <path>" << convertToXML(getPath()) << "</path>" << endl; + Doxygen::tagFile << " <filename>" + << convertToXML(getOutputFileBase()) + << "</filename>" << endl; + } + + //---------------------------------------- start flexible part ------------------------------- + + QListIterator<LayoutDocEntry> eli( + LayoutDocManager::instance().docEntries(LayoutDocManager::File)); + LayoutDocEntry *lde; + for (eli.toFirst();(lde=eli.current());++eli) + { + switch (lde->kind()) + { + case LayoutDocEntry::BriefDesc: + writeBriefDescription(ol); + break; + case LayoutDocEntry::MemberDeclStart: + startMemberDeclarations(ol); + break; + case LayoutDocEntry::FileIncludes: + writeIncludeFiles(ol); + break; + case LayoutDocEntry::FileIncludeGraph: + writeIncludeGraph(ol); + break; + case LayoutDocEntry::FileIncludedByGraph: + writeIncludedByGraph(ol); + break; + case LayoutDocEntry::FileSourceLink: + writeSourceLink(ol); + break; + case LayoutDocEntry::FileClasses: + { + LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; + writeClassDeclarations(ol,ls->title); + } + break; + case LayoutDocEntry::FileNamespaces: + { + LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; + writeNamespaceDeclarations(ol,ls->title); + } + break; + case LayoutDocEntry::MemberGroups: + writeMemberGroups(ol); + break; + case LayoutDocEntry::MemberDecl: + { + LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde; + writeMemberDeclarations(ol,lmd->type,lmd->title); + } + break; + case LayoutDocEntry::MemberDeclEnd: + endMemberDeclarations(ol); + break; + case LayoutDocEntry::DetailedDesc: + { + LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; + writeDetailedDescription(ol,ls->title); + } + break; + case LayoutDocEntry::MemberDefStart: + startMemberDocumentation(ol); + break; + case LayoutDocEntry::MemberDef: + { + LayoutDocEntryMemberDef *lmd = (LayoutDocEntryMemberDef*)lde; + writeMemberDocumentation(ol,lmd->type,lmd->title); + } + break; + case LayoutDocEntry::MemberDefEnd: + endMemberDocumentation(ol); + break; + case LayoutDocEntry::AuthorSection: + writeAuthorSection(ol); + break; + case LayoutDocEntry::ClassIncludes: + case LayoutDocEntry::ClassInheritanceGraph: + case LayoutDocEntry::ClassNestedClasses: + case LayoutDocEntry::ClassCollaborationGraph: + case LayoutDocEntry::ClassAllMembersLink: + case LayoutDocEntry::ClassUsedFiles: + case LayoutDocEntry::NamespaceNestedNamespaces: + case LayoutDocEntry::NamespaceClasses: + case LayoutDocEntry::GroupClasses: + case LayoutDocEntry::GroupInlineClasses: + case LayoutDocEntry::GroupNamespaces: + case LayoutDocEntry::GroupDirs: + case LayoutDocEntry::GroupNestedGroups: + case LayoutDocEntry::GroupFiles: + case LayoutDocEntry::GroupGraph: + case LayoutDocEntry::GroupPageDocs: + case LayoutDocEntry::DirSubDirs: + case LayoutDocEntry::DirFiles: + case LayoutDocEntry::DirGraph: + err("Internal inconsistency: member %d should not be part of " + "LayoutDocManager::File entry list\n",lde->kind()); + break; + } + } + + //---------------------------------------- end flexible part ------------------------------- + + if (!Config_getString("GENERATE_TAGFILE").isEmpty()) + { + writeDocAnchorsToTagFile(); + Doxygen::tagFile << " </compound>" << endl; + } + + ol.endContents(); + + if (generateTreeView) + { + writeNavigationPath(ol); + } + + endFile(ol,TRUE); + + if (Config_getBool("SEPARATE_MEMBER_PAGES")) + { + MemberList *ml = getMemberList(MemberList::allMembersList); + if (ml) ml->sort(); + writeMemberPages(ol); + } +} + +void FileDef::writeMemberPages(OutputList &ol) +{ + ol.pushGeneratorState(); + ol.disableAllBut(OutputGenerator::Html); + + QListIterator<MemberList> mli(m_memberLists); + MemberList *ml; + for (mli.toFirst();(ml=mli.current());++mli) + { + if (ml->listType()&MemberList::documentationLists) + { + ml->writeDocumentationPage(ol,name(),this); + } + } + + ol.popGeneratorState(); +} + +void FileDef::writeQuickMemberLinks(OutputList &ol,MemberDef *currentMd) const +{ + static bool createSubDirs=Config_getBool("CREATE_SUBDIRS"); + + ol.writeString(" <div class=\"navtab\">\n"); + ol.writeString(" <table>\n"); + + MemberList *allMemberList = getMemberList(MemberList::allMembersList); + if (allMemberList) + { + MemberListIterator mli(*allMemberList); + MemberDef *md; + for (mli.toFirst();(md=mli.current());++mli) + { + if (md->getFileDef()==this && md->getNamespaceDef()==0 && md->isLinkable()) + { + ol.writeString(" <tr><td class=\"navtab\">"); + if (md->isLinkableInProject()) + { + if (md==currentMd) // selected item => highlight + { + ol.writeString("<a class=\"qindexHL\" "); + } + else + { + ol.writeString("<a class=\"qindex\" "); + } + ol.writeString("href=\""); + if (createSubDirs) ol.writeString("../../"); + ol.writeString(md->getOutputFileBase()+Doxygen::htmlFileExtension+"#"+md->anchor()); + ol.writeString("\">"); + ol.writeString(md->localName()); + ol.writeString("</a>"); + } + ol.writeString("</td></tr>\n"); + } + } + } + + ol.writeString(" </table>\n"); + ol.writeString(" </div>\n"); +} + +/*! Write a source listing of this file to the output */ +void FileDef::writeSource(OutputList &ol) +{ + static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW"); + static bool filterSourceFiles = Config_getBool("FILTER_SOURCE_FILES"); + static bool latexSourceCode = Config_getBool("LATEX_SOURCE_CODE"); + QCString title = docname; + if (!fileVersion.isEmpty()) + { + title+=(" ("+fileVersion+")"); + } + QCString pageTitle = theTranslator->trSourceFile(title); + ol.disable(OutputGenerator::Man); + ol.disable(OutputGenerator::RTF); + if (!latexSourceCode) ol.disable(OutputGenerator::Latex); + + if (Config_getBool("SHOW_DIRECTORIES") && getDirDef()) + { + startFile(ol,getSourceFileBase(),0,pageTitle,HLI_FileVisible, + !generateTreeView,getOutputFileBase()); + if (!generateTreeView) + { + getDirDef()->writeNavigationPath(ol); + ol.endQuickIndices(); + } + startTitle(ol,getOutputFileBase()); + ol.parseText(name()); + endTitle(ol,getOutputFileBase(),title); + } + else + { + startFile(ol,getSourceFileBase(),0,pageTitle,HLI_FileVisible, + !generateTreeView,getOutputFileBase()); + startTitle(ol,getSourceFileBase()); + ol.parseText(title); + endTitle(ol,getSourceFileBase(),0); + } + + ol.startContents(); + + if (isLinkable()) + { + if (latexSourceCode) ol.disable(OutputGenerator::Latex); + ol.startTextLink(getOutputFileBase(),0); + ol.parseText(theTranslator->trGotoDocumentation()); + ol.endTextLink(); + if (latexSourceCode) ol.enable(OutputGenerator::Latex); + } + + ParserInterface *pIntf = Doxygen::parserManager->getParser(getDefFileExtension()); + pIntf->resetCodeParserState(); + ol.startCodeFragment(); + pIntf->parseCode(ol,0, + fileToString(absFilePath(),filterSourceFiles,TRUE), + FALSE,0,this + ); + ol.endCodeFragment(); + ol.endContents(); + if (generateTreeView) + { + writeNavigationPath(ol); + endFile(ol,TRUE); + } + else + { + endFile(ol); + } + ol.enableAll(); +} + +void FileDef::parseSource() +{ + static bool filterSourceFiles = Config_getBool("FILTER_SOURCE_FILES"); + DevNullCodeDocInterface devNullIntf; + ParserInterface *pIntf = Doxygen::parserManager->getParser(getDefFileExtension()); + pIntf->resetCodeParserState(); + pIntf->parseCode( + devNullIntf,0, + fileToString(absFilePath(),filterSourceFiles,TRUE), + FALSE,0,this + ); +} + +void FileDef::addMembersToMemberGroup() +{ + QListIterator<MemberList> mli(m_memberLists); + MemberList *ml; + for (mli.toFirst();(ml=mli.current());++mli) + { + if (ml->listType()&MemberList::declarationLists) + { + ::addMembersToMemberGroup(ml,&memberGroupSDict,this); + } + } + + // add members inside sections to their groups + if (memberGroupSDict) + { + MemberGroupSDict::Iterator mgli(*memberGroupSDict); + MemberGroup *mg; + for (;(mg=mgli.current());++mgli) + { + if (mg->allMembersInSameSection() && m_subGrouping) + { + //printf("----> addToDeclarationSection(%s)\n",mg->header().data()); + mg->addToDeclarationSection(); + } + } + } +} + +/*! Adds member definition \a md to the list of all members of this file */ +void FileDef::insertMember(MemberDef *md) +{ + if (md->isHidden()) return; + //printf("%s:FileDef::insertMember(%s (=%p) list has %d elements)\n", + // name().data(),md->name().data(),md,allMemberList.count()); + MemberList *allMemberList = getMemberList(MemberList::allMembersList); + if (allMemberList && allMemberList->findRef(md)!=-1) // TODO optimize the findRef! + { + return; + } + + if (allMemberList==0) + { + allMemberList = new MemberList(MemberList::allMembersList);; + m_memberLists.append(allMemberList); + } + allMemberList->append(md); + //::addFileMemberNameToIndex(md); + switch (md->memberType()) + { + case MemberDef::Variable: + case MemberDef::Property: + addMemberToList(MemberList::decVarMembers,md); + addMemberToList(MemberList::docVarMembers,md); + break; + case MemberDef::Function: + addMemberToList(MemberList::decFuncMembers,md); + addMemberToList(MemberList::docFuncMembers,md); + break; + case MemberDef::Typedef: + addMemberToList(MemberList::decTypedefMembers,md); + addMemberToList(MemberList::docTypedefMembers,md); + break; + case MemberDef::Enumeration: + addMemberToList(MemberList::decEnumMembers,md); + addMemberToList(MemberList::docEnumMembers,md); + break; + case MemberDef::EnumValue: // enum values are shown inside their enums + break; + case MemberDef::Define: + addMemberToList(MemberList::decDefineMembers,md); + addMemberToList(MemberList::docDefineMembers,md); + break; + default: + err("FileDef::insertMembers(): " + "member `%s' with class scope `%s' inserted in file scope `%s'!\n", + md->name().data(), + md->getClassDef() ? md->getClassDef()->name().data() : "<global>", + name().data()); + } + //addMemberToGroup(md,groupId); +} + +/*! Adds compound definition \a cd to the list of all compounds of this file */ +void FileDef::insertClass(ClassDef *cd) +{ + if (cd->isHidden()) return; + if (classSDict==0) + { + classSDict = new ClassSDict(17); + } + if (Config_getBool("SORT_BRIEF_DOCS")) + classSDict->inSort(cd->name(),cd); + else + classSDict->append(cd->name(),cd); +} + +/*! Adds namespace definition \a nd to the list of all compounds of this file */ +void FileDef::insertNamespace(NamespaceDef *nd) +{ + if (nd->isHidden()) return; + if (!nd->name().isEmpty() && + (namespaceSDict==0 || namespaceSDict->find(nd->name())==0)) + { + if (namespaceSDict==0) + { + namespaceSDict = new NamespaceSDict; + } + if (Config_getBool("SORT_BRIEF_DOCS")) + namespaceSDict->inSort(nd->name(),nd); + else + namespaceSDict->append(nd->name(),nd); + } +} + +void FileDef::addSourceRef(int line,Definition *d,MemberDef *md) +{ + //printf("FileDef::addSourceDef(%d,%p,%p)\n",line,d,md); + if (d) + { + if (srcDefDict==0) srcDefDict = new QIntDict<Definition>(257); + if (srcMemberDict==0) srcMemberDict = new QIntDict<MemberDef>(257); + srcDefDict->insert(line,d); + if (md) srcMemberDict->insert(line,md); + //printf("Adding member %s with anchor %s at line %d to file %s\n", + // md->name().data(),md->anchor().data(),line,name().data()); + } +} + +Definition *FileDef::getSourceDefinition(int lineNr) +{ + Definition *result=0; + if (srcDefDict) + { + result = srcDefDict->find(lineNr); + } + return result; +} + +MemberDef *FileDef::getSourceMember(int lineNr) +{ + MemberDef *result=0; + if (srcMemberDict) + { + result = srcMemberDict->find(lineNr); + } + return result; +} + + +void FileDef::addUsingDirective(NamespaceDef *nd) +{ + if (usingDirList==0) + { + usingDirList = new NamespaceSDict; + } + if (usingDirList->find(nd->qualifiedName())==0) + { + usingDirList->append(nd->qualifiedName(),nd); + } + //printf("%p: FileDef::addUsingDirective: %s:%d\n",this,name().data(),usingDirList->count()); +} + +NamespaceSDict *FileDef::getUsedNamespaces() const +{ + //printf("%p: FileDef::getUsedNamespace: %s:%d\n",this,name().data(),usingDirList?usingDirList->count():0); + return usingDirList; +} + +void FileDef::addUsingDeclaration(Definition *d) +{ + if (usingDeclList==0) + { + usingDeclList = new SDict<Definition>(17); + } + if (usingDeclList->find(d->qualifiedName())==0) + { + usingDeclList->append(d->qualifiedName(),d); + } +} + +void FileDef::addIncludeDependency(FileDef *fd,const char *incName,bool local, + bool imported) +{ + //printf("FileDef::addIncludeDependency(%p,%s,%d)\n",fd,incName,local); + QCString iName = fd ? fd->absFilePath().data() : incName; + if (!iName.isEmpty() && (!includeDict || includeDict->find(iName)==0)) + { + if (includeDict==0) + { + includeDict = new QDict<IncludeInfo>(61); + includeList = new QList<IncludeInfo>; + includeList->setAutoDelete(TRUE); + } + IncludeInfo *ii = new IncludeInfo; + ii->fileDef = fd; + ii->includeName = incName; + ii->local = local; + ii->imported = imported; + includeList->append(ii); + includeDict->insert(iName,ii); + } +} + +void FileDef::addIncludedUsingDirectives() +{ + if (visited) return; + visited=TRUE; + //printf("( FileDef::addIncludedUsingDirectives for file %s\n",name().data()); + + NamespaceList nl; + if (includeList) // file contains #includes + { + { + QListIterator<IncludeInfo> iii(*includeList); + IncludeInfo *ii; + for (iii.toFirst();(ii=iii.current());++iii) // foreach #include... + { + if (ii->fileDef && !ii->fileDef->visited) // ...that is a known file + { + // recurse into this file + ii->fileDef->addIncludedUsingDirectives(); + } + } + } + { + QListIterator<IncludeInfo> iii(*includeList); + IncludeInfo *ii; + // iterate through list from last to first + for (iii.toLast();(ii=iii.current());--iii) + { + if (ii->fileDef && ii->fileDef!=this) + { + // add using directives + NamespaceSDict *unl = ii->fileDef->usingDirList; + if (unl) + { + NamespaceSDict::Iterator nli(*unl); + NamespaceDef *nd; + for (nli.toLast();(nd=nli.current());--nli) + { + // append each using directive found in a #include file + if (usingDirList==0) usingDirList = new NamespaceSDict; + //printf("Prepending used namespace %s to the list of file %s\n", + // nd->name().data(),name().data()); + if (usingDirList->find(nd->qualifiedName())==0) // not yet added + { + usingDirList->prepend(nd->qualifiedName(),nd); + } + } + } + // add using declarations + SDict<Definition> *udl = ii->fileDef->usingDeclList; + if (udl) + { + SDict<Definition>::Iterator udi(*udl); + Definition *d; + for (udi.toLast();(d=udi.current());--udi) + { + //printf("Adding using declaration %s\n",d->name().data()); + if (usingDeclList==0) + { + usingDeclList = new SDict<Definition>(17); + } + if (usingDeclList->find(d->qualifiedName())==0) + { + usingDeclList->prepend(d->qualifiedName(),d); + } + } + } + } + } + } + } + //printf(") end FileDef::addIncludedUsingDirectives for file %s\n",name().data()); +} + + +void FileDef::addIncludedByDependency(FileDef *fd,const char *incName, + bool local,bool imported) +{ + //printf("FileDef::addIncludedByDependency(%p,%s,%d)\n",fd,incName,local); + QCString iName = fd ? fd->absFilePath().data() : incName; + if (!iName.isEmpty() && (includedByDict==0 || includedByDict->find(iName)==0)) + { + if (includedByDict==0) + { + includedByDict = new QDict<IncludeInfo>(61); + includedByList = new QList<IncludeInfo>; + includedByList->setAutoDelete(TRUE); + } + IncludeInfo *ii = new IncludeInfo; + ii->fileDef = fd; + ii->includeName = incName; + ii->local = local; + ii->imported = imported; + includedByList->append(ii); + includedByDict->insert(iName,ii); + } +} + +bool FileDef::isIncluded(const QCString &name) const +{ + if (name.isEmpty()) return FALSE; + return includeDict!=0 && includeDict->find(name)!=0; +} + +bool FileDef::generateSourceFile() const +{ + QCString extension = name().right(4); + return !isReference() && + (Config_getBool("SOURCE_BROWSER") || + (Config_getBool("VERBATIM_HEADERS") && guessSection(name())==Entry::HEADER_SEC) + ) && + extension!=".doc" && extension!=".txt" && extension!=".dox"; +} + + +void FileDef::addListReferences() +{ + { + LockingPtr< QList<ListItemInfo> > xrefItems = xrefListItems(); + addRefItem(xrefItems.pointer(), + getOutputFileBase(), + theTranslator->trFile(TRUE,TRUE), + getOutputFileBase(),name(), + 0 + ); + } + if (memberGroupSDict) + { + MemberGroupSDict::Iterator mgli(*memberGroupSDict); + MemberGroup *mg; + for (;(mg=mgli.current());++mgli) + { + mg->addListReferences(this); + } + } + QListIterator<MemberList> mli(m_memberLists); + MemberList *ml; + for (mli.toFirst();(ml=mli.current());++mli) + { + if (ml->listType()&MemberList::documentationLists) + { + ml->addListReferences(this); + } + } +} + +//------------------------------------------------------------------- + +static int findMatchingPart(const QCString &path,const QCString dir) +{ + int si1; + int pos1=0,pos2=0; + while ((si1=path.find('/',pos1))!=-1) + { + int si2=dir.find('/',pos2); + //printf(" found slash at pos %d in path %d: %s<->%s\n",si1,si2, + // path.mid(pos1,si1-pos2).data(),dir.mid(pos2).data()); + if (si2==-1 && path.mid(pos1,si1-pos2)==dir.mid(pos2)) // match at end + { + return dir.length(); + } + if (si1!=si2 || path.mid(pos1,si1-pos2)!=dir.mid(pos2,si2-pos2)) // no match in middle + { + return QMAX(pos1-1,0); + } + pos1=si1+1; + pos2=si2+1; + } + return 0; +} + +static Directory *findDirNode(Directory *root,const QCString &name) +{ + QListIterator<DirEntry> dli(root->children()); + DirEntry *de; + for (dli.toFirst();(de=dli.current());++dli) + { + if (de->kind()==DirEntry::Dir) + { + Directory *dir = (Directory *)de; + QCString dirName=dir->name(); + int sp=findMatchingPart(name,dirName); + //printf("findMatchingPart(%s,%s)=%d\n",name.data(),dirName.data(),sp); + if (sp>0) // match found + { + if ((uint)sp==dirName.length()) // whole directory matches + { + // recurse into the directory + return findDirNode(dir,name.mid(dirName.length()+1)); + } + else // partial match => we need to split the path into three parts + { + QCString baseName =dirName.left(sp); + QCString oldBranchName=dirName.mid(sp+1); + QCString newBranchName=name.mid(sp+1); + // strip file name from path + int newIndex=newBranchName.findRev('/'); + if (newIndex>0) newBranchName=newBranchName.left(newIndex); + + //printf("Splitting off part in new branch \n" + // "base=%s old=%s new=%s\n", + // baseName.data(), + // oldBranchName.data(), + // newBranchName.data() + // ); + Directory *base = new Directory(root,baseName); + Directory *newBranch = new Directory(base,newBranchName); + dir->reParent(base); + dir->rename(oldBranchName); + base->addChild(dir); + base->addChild(newBranch); + dir->setLast(FALSE); + // remove DirEntry container from list (without deleting it) + root->children().setAutoDelete(FALSE); + root->children().removeRef(dir); + root->children().setAutoDelete(TRUE); + // add new branch to the root + if (!root->children().isEmpty()) + { + root->children().last()->setLast(FALSE); + } + root->addChild(base); + return newBranch; + } + } + } + } + int si=name.findRev('/'); + if (si==-1) // no subdir + { + return root; // put the file under the root node. + } + else // need to create a subdir + { + QCString baseName = name.left(si); + //printf("new subdir %s\n",baseName.data()); + Directory *newBranch = new Directory(root,baseName); + if (!root->children().isEmpty()) + { + root->children().last()->setLast(FALSE); + } + root->addChild(newBranch); + return newBranch; + } +} + +static void mergeFileDef(Directory *root,FileDef *fd) +{ + QCString rootPath = root->name(); + QCString filePath = fd->absFilePath(); + //printf("merging %s\n",filePath.data()); + Directory *dirNode = findDirNode(root,filePath); + if (!dirNode->children().isEmpty()) + { + dirNode->children().last()->setLast(FALSE); + } + DirEntry *e=new DirEntry(dirNode,fd); + dirNode->addChild(e); +} + +#if 0 +static void generateIndent(QTextStream &t,DirEntry *de,int level) +{ + if (de->parent()) + { + generateIndent(t,de->parent(),level+1); + } + // from the root up to node n do... + if (level==0) // item before a dir or document + { + if (de->isLast()) + { + if (de->kind()==DirEntry::Dir) + { + t << "<img " << FTV_IMGATTRIBS(plastnode) << "/>"; + } + else + { + t << "<img " << FTV_IMGATTRIBS(lastnode) << "/>"; + } + } + else + { + if (de->kind()==DirEntry::Dir) + { + t << "<img " << FTV_IMGATTRIBS(pnode) << "/>"; + } + else + { + t << "<img " << FTV_IMGATTRIBS(node) << "/>"; + } + } + } + else // item at another level + { + if (de->isLast()) + { + t << "<img " << FTV_IMGATTRIBS(blank) << "/>"; + } + else + { + t << "<img " << FTV_IMGATTRIBS(vertline) << "/>"; + } + } +} + +static void writeDirTreeNode(QTextStream &t,Directory *root,int level) +{ + QCString indent; + indent.fill(' ',level*2); + QListIterator<DirEntry> dli(root->children()); + DirEntry *de; + for (dli.toFirst();(de=dli.current());++dli) + { + t << indent << "<p>"; + generateIndent(t,de,0); + if (de->kind()==DirEntry::Dir) + { + Directory *dir=(Directory *)de; + //printf("%s [dir]: %s (last=%d,dir=%d)\n",indent.data(),dir->name().data(),dir->isLast(),dir->kind()==DirEntry::Dir); + t << "<img " << FTV_IMGATTRIBS(folderclosed) << "/>"; + t << dir->name(); + t << "</p>\n"; + t << indent << "<div>\n"; + writeDirTreeNode(t,dir,level+1); + t << indent << "</div>\n"; + } + else + { + //printf("%s [file]: %s (last=%d,dir=%d)\n",indent.data(),de->file()->name().data(),de->isLast(),de->kind()==DirEntry::Dir); + t << "<img " << FTV_IMGATTRIBS(doc) << "/>"; + t << de->file()->name(); + t << "</p>\n"; + } + } +} +#endif + +static void addDirsAsGroups(Directory *root,GroupDef *parent,int level) +{ + GroupDef *gd=0; + if (root->kind()==DirEntry::Dir) + { + gd = new GroupDef("[generated]", + 1, + root->path(), // name + root->name() // title + ); + if (parent) + { + parent->addGroup(gd); + gd->makePartOfGroup(parent); + } + else + { + Doxygen::groupSDict->append(root->path(),gd); + } + } + QListIterator<DirEntry> dli(root->children()); + DirEntry *de; + for (dli.toFirst();(de=dli.current());++dli) + { + if (de->kind()==DirEntry::Dir) + { + addDirsAsGroups((Directory *)de,gd,level+1); + } + } +} + +void generateFileTree() +{ + Directory *root=new Directory(0,"root"); + root->setLast(TRUE); + FileNameListIterator fnli(*Doxygen::inputNameList); + FileName *fn; + for (fnli.toFirst();(fn=fnli.current());++fnli) + { + FileNameIterator fni(*fn); + FileDef *fd; + for (;(fd=fni.current());++fni) + { + mergeFileDef(root,fd); + } + } + //t << "<div class=\"directory\">\n"; + //writeDirTreeNode(t,root,0); + //t << "</div>\n"; + addDirsAsGroups(root,0,0); + delete root; +} + +//------------------------------------------------------------------- + +void FileDef::combineUsingRelations() +{ + if (visited) return; // already done + visited=TRUE; + if (usingDirList) + { + NamespaceSDict::Iterator nli(*usingDirList); + NamespaceDef *nd; + for (nli.toFirst();(nd=nli.current());++nli) + { + nd->combineUsingRelations(); + } + for (nli.toFirst();(nd=nli.current());++nli) + { + // add used namespaces of namespace nd to this namespace + if (nd->getUsedNamespaces()) + { + NamespaceSDict::Iterator unli(*nd->getUsedNamespaces()); + NamespaceDef *und; + for (unli.toFirst();(und=unli.current());++unli) + { + //printf("Adding namespace %s to the using list of %s\n",und->qualifiedName().data(),qualifiedName().data()); + addUsingDirective(und); + } + } + // add used classes of namespace nd to this namespace + if (nd->getUsedClasses()) + { + SDict<Definition>::Iterator cli(*nd->getUsedClasses()); + Definition *ucd; + for (cli.toFirst();(ucd=cli.current());++cli) + { + //printf("Adding class %s to the using list of %s\n",cd->qualifiedName().data(),qualifiedName().data()); + addUsingDeclaration(ucd); + } + } + } + } +} + +bool FileDef::isDocumentationFile() const +{ + return name().right(4)==".doc" || + name().right(4)==".txt" || + name().right(4)==".dox"; +} + +void FileDef::acquireFileVersion() +{ + QCString vercmd = Config_getString("FILE_VERSION_FILTER"); + if (!vercmd.isEmpty() && filepath!="generated") + { + msg("Version of %s : ",filepath.data()); + QCString cmd = vercmd+" \""+filepath+"\""; + Debug::print(Debug::ExtCmd,0,"Executing popen(`%s`)\n",cmd.data()); + FILE *f=portable_popen(cmd,"r"); + if (!f) + { + err("error: could not execute %s\n",vercmd.data()); + return; + } + const int bufSize=1024; + char buf[bufSize]; + int numRead = fread(buf,1,bufSize,f); + portable_pclose(f); + if (numRead > 0) + { + fileVersion = QCString(buf,numRead).stripWhiteSpace(); + msg("%s\n",fileVersion.data()); + } + else + { + msg("no version available\n"); + } + } +} + + +QCString FileDef::getSourceFileBase() const +{ + if (Htags::useHtags) + { + return Htags::path2URL(filepath); + } + else + { + return convertNameToFile(diskname)+"_source"; + } +} + +/*! Returns the name of the verbatim copy of this file (if any). */ +QCString FileDef::includeName() const +{ + if (Htags::useHtags) + { + return Htags::path2URL(filepath); + } + else + { + return convertNameToFile(diskname)+"_source"; + } +} + +MemberList *FileDef::createMemberList(MemberList::ListType lt) +{ + m_memberLists.setAutoDelete(TRUE); + QListIterator<MemberList> mli(m_memberLists); + MemberList *ml; + for (mli.toFirst();(ml=mli.current());++mli) + { + if (ml->listType()==lt) + { + return ml; + } + } + // not found, create a new member list + ml = new MemberList(lt); + m_memberLists.append(ml); + return ml; +} + +void FileDef::addMemberToList(MemberList::ListType lt,MemberDef *md) +{ + static bool sortBriefDocs = Config_getBool("SORT_BRIEF_DOCS"); + static bool sortMemberDocs = Config_getBool("SORT_MEMBER_DOCS"); + MemberList *ml = createMemberList(lt); + ml->setNeedsSorting( + ((ml->listType()&MemberList::declarationLists) && sortBriefDocs) || + ((ml->listType()&MemberList::documentationLists) && sortMemberDocs)); + ml->append(md); +#if 0 + if (ml->needsSorting()) + ml->inSort(md); + else + ml->append(md); +#endif + if (lt&MemberList::documentationLists) + { + ml->setInFile(TRUE); + } + if (ml->listType()&MemberList::declarationLists) md->setSectionList(this,ml); +} + +void FileDef::sortMemberLists() +{ + MemberList *ml = m_memberLists.first(); + while (ml) + { + if (ml->needsSorting()) { ml->sort(); ml->setNeedsSorting(FALSE); } + ml = m_memberLists.next(); + } +} + +MemberList *FileDef::getMemberList(MemberList::ListType lt) const +{ + FileDef *that = (FileDef*)this; + MemberList *ml = that->m_memberLists.first(); + while (ml) + { + if (ml->listType()==lt) + { + return ml; + } + ml = that->m_memberLists.next(); + } + return 0; +} + +void FileDef::writeMemberDeclarations(OutputList &ol,MemberList::ListType lt,const QCString &title) +{ + static bool optVhdl = Config_getBool("OPTIMIZE_OUTPUT_VHDL"); + MemberList * ml = getMemberList(lt); + if (ml) + { + if (optVhdl) // use specific declarations function + { + VhdlDocGen::writeVhdlDeclarations(ml,ol,0,0,this); + } + else + { + ml->writeDeclarations(ol,0,0,this,0,title,0); + } + } +} + +void FileDef::writeMemberDocumentation(OutputList &ol,MemberList::ListType lt,const QCString &title) +{ + MemberList * ml = getMemberList(lt); + if (ml) ml->writeDocumentation(ol,name(),this,title); +} + +bool FileDef::isLinkableInProject() const +{ + static bool showFiles = Config_getBool("SHOW_FILES"); + return hasDocumentation() && !isReference() && showFiles; +} + +bool FileDef::includes(FileDef *incFile,QDict<FileDef> *includedFiles) const +{ + if (incFile==this) return TRUE; + //printf("%s::includes(%s)\n",name().data(),incFile->name().data()); + includedFiles->insert(absFilePath(),this); + if (includeList) + { + QListIterator<IncludeInfo> ili(*includeList); + IncludeInfo *ii; + for (;(ii=ili.current());++ili) + { + if (ii->fileDef && + includedFiles->find(ii->fileDef->absFilePath())==0 && + ii->fileDef->includes(incFile,includedFiles)) return TRUE; + } + } + return FALSE; +} + + |