1 /******************************************************************************
5 * Copyright (C) 1997-2014 by Dimitri van Heesch.
7 * Permission to use, copy, modify, and distribute this software and its
8 * documentation under the terms of the GNU General Public License is hereby
9 * granted. No representations are made about the suitability of this software
10 * for any purpose. It is provided "as is" without express or implied warranty.
11 * See the GNU General Public License for more details.
13 * Documents produced by Doxygen are derivative works derived from the
14 * input used in their production; they are not affected by this license.
18 #include "memberlist.h"
19 #include "classlist.h"
22 #include "memberdef.h"
24 #include "namespacedef.h"
27 #include "outputlist.h"
30 #include "docparser.h"
31 #include "searchindex.h"
33 #include "parserintf.h"
35 #include "vhdldocgen.h"
41 #include "membergroup.h"
44 #include "clangparser.h"
47 //---------------------------------------------------------------------------
49 /** Class implementing CodeOutputInterface by throwing away everything. */
50 class DevNullCodeDocInterface : public CodeOutputInterface
53 virtual void codify(const char *) {}
54 virtual void writeCodeLink(const char *,const char *,
55 const char *,const char *,
57 virtual void writeTooltip(const char *, const DocLinkInfo &, const char *,
58 const char *, const SourceLinkInfo &, const SourceLinkInfo &
60 virtual void writeLineNumber(const char *,const char *,
62 virtual void startCodeLine(bool) {}
63 virtual void endCodeLine() {}
64 virtual void startFontClass(const char *) {}
65 virtual void endFontClass() {}
66 virtual void writeCodeAnchor(const char *) {}
67 virtual void linkableSymbol(int, const char *,Definition *,Definition *) {}
68 virtual void setCurrentDoc(Definition *,const char *,bool) {}
69 virtual void addWord(const char *,bool) {}
72 //---------------------------------------------------------------------------
74 /*! create a new file definition, where \a p is the file path,
75 \a nm the file name, and \a lref is an HTML anchor name if the
76 file was read from a tag file or 0 otherwise
78 FileDef::FileDef(const char *p,const char *nm,
79 const char *lref,const char *dn)
80 : Definition((QCString)p+nm,1,1,nm)
86 if (m_diskName.isEmpty()) m_diskName=nm;
99 m_isSource = guessSection(nm)==Entry::SOURCE_SEC;
102 if (Config_getBool("FULL_PATH_NAMES"))
104 m_docname.prepend(stripFromPath(m_path.copy()));
106 setLanguage(getLanguageFromFileName(name()));
107 m_memberGroupSDict = 0;
108 acquireFileVersion();
109 m_subGrouping=Config_getBool("SUBGROUPING");
112 /*! destroy the file definition */
116 delete m_includeDict;
117 delete m_includeList;
118 delete m_includedByDict;
119 delete m_includedByList;
120 delete m_namespaceSDict;
122 delete m_srcMemberDict;
123 delete m_usingDirList;
124 delete m_usingDeclList;
125 delete m_memberGroupSDict;
128 /*! Compute the HTML anchor names for all members in the class */
129 void FileDef::computeAnchors()
131 MemberList *ml = getMemberList(MemberListType_allMembersList);
132 if (ml) setAnchors(ml);
135 void FileDef::distributeMemberGroupDocumentation()
137 //printf("FileDef::distributeMemberGroupDocumentation()\n");
138 if (m_memberGroupSDict)
140 MemberGroupSDict::Iterator mgli(*m_memberGroupSDict);
142 for (;(mg=mgli.current());++mgli)
144 mg->distributeMemberGroupDocumentation();
149 void FileDef::findSectionsInDocumentation()
151 docFindSections(documentation(),this,0,docFile());
152 if (m_memberGroupSDict)
154 MemberGroupSDict::Iterator mgli(*m_memberGroupSDict);
156 for (;(mg=mgli.current());++mgli)
158 mg->findSectionsInDocumentation();
162 QListIterator<MemberList> mli(m_memberLists);
164 for (mli.toFirst();(ml=mli.current());++mli)
166 if (ml->listType()&MemberListType_declarationLists)
168 ml->findSectionsInDocumentation();
173 bool FileDef::hasDetailedDescription() const
175 static bool repeatBrief = Config_getBool("REPEAT_BRIEF");
176 static bool sourceBrowser = Config_getBool("SOURCE_BROWSER");
177 return ((!briefDescription().isEmpty() && repeatBrief) ||
178 !documentation().stripWhiteSpace().isEmpty() || // avail empty section
179 (sourceBrowser && getStartBodyLine()!=-1 && getBodyDef())
183 void FileDef::writeDetailedDescription(OutputList &ol,const QCString &title)
185 if (hasDetailedDescription())
187 ol.pushGeneratorState();
188 ol.disable(OutputGenerator::Html);
190 ol.popGeneratorState();
191 ol.pushGeneratorState();
192 ol.disableAllBut(OutputGenerator::Html);
193 ol.writeAnchor(0,"details");
194 ol.popGeneratorState();
195 ol.startGroupHeader();
200 if (!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF"))
202 ol.generateDoc(briefFile(),briefLine(),this,0,briefDescription(),FALSE,FALSE);
204 if (!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF") &&
205 !documentation().isEmpty())
207 ol.pushGeneratorState();
208 ol.disable(OutputGenerator::Man);
209 ol.disable(OutputGenerator::RTF);
210 // ol.newParagraph(); // FIXME:PARA
212 ol.disableAllBut(OutputGenerator::Man);
213 ol.enable(OutputGenerator::Latex);
214 ol.writeString("\n\n");
215 ol.popGeneratorState();
217 if (!documentation().isEmpty())
219 ol.generateDoc(docFile(),docLine(),this,0,documentation()+"\n",TRUE,FALSE);
221 //printf("Writing source ref for file %s\n",name().data());
222 if (Config_getBool("SOURCE_BROWSER"))
225 QCString refText = theTranslator->trDefinedInSourceFile();
226 int fileMarkerPos = refText.find("@0");
227 if (fileMarkerPos!=-1) // should always pass this.
229 ol.parseText(refText.left(fileMarkerPos)); //text left from marker 1
230 ol.writeObjectLink(0,getSourceFileBase(),
232 ol.parseText(refText.right(
233 refText.length()-fileMarkerPos-2)); // text right from marker 2
241 void FileDef::writeBriefDescription(OutputList &ol)
243 if (!briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC"))
245 DocRoot *rootNode = validatingParseDoc(briefFile(),briefLine(),this,0,
246 briefDescription(),TRUE,FALSE,0,TRUE,FALSE);
248 if (rootNode && !rootNode->isEmpty())
251 ol.writeDoc(rootNode,this,0);
252 ol.pushGeneratorState();
253 ol.disable(OutputGenerator::RTF);
254 ol.writeString(" \n");
255 ol.enable(OutputGenerator::RTF);
257 if (Config_getBool("REPEAT_BRIEF") ||
258 !documentation().isEmpty()
261 ol.disableAllBut(OutputGenerator::Html);
262 ol.startTextLink(0,"details");
263 ol.parseText(theTranslator->trMore());
266 ol.popGeneratorState();
274 void FileDef::writeIncludeFiles(OutputList &ol)
276 if (m_includeList && m_includeList->count()>0)
278 ol.startTextBlock(TRUE);
279 QListIterator<IncludeInfo> ili(*m_includeList);
281 for (;(ii=ili.current());++ili)
285 FileDef *fd=ii->fileDef;
286 bool isIDLorJava = FALSE;
289 SrcLangExt lang = fd->getLanguage();
290 isIDLorJava = lang==SrcLangExt_IDL || lang==SrcLangExt_Java;
292 ol.startTypewriter();
293 if (isIDLorJava) // IDL/Java include
295 ol.docify("import ");
297 else if (ii->imported) // Objective-C include
299 ol.docify("#import ");
301 else // C/C++ include
303 ol.docify("#include ");
305 if (ii->local || isIDLorJava)
309 ol.disable(OutputGenerator::Html);
310 ol.docify(ii->includeName);
312 ol.disableAllBut(OutputGenerator::Html);
314 // Here we use the include file name as it appears in the file.
315 // we could also we the name as it is used within doxygen,
316 // then we should have used fd->docName() instead of ii->includeName
317 if (fd && fd->isLinkable())
319 ol.writeObjectLink(fd->getReference(),
320 fd->generateSourceFile() ? fd->includeName() : fd->getOutputFileBase(),
322 if (!Config_getString("GENERATE_TAGFILE").isEmpty() && !fd->isReference())
324 const char *locStr = (ii->local || isIDLorJava) ? "yes" : "no";
325 const char *impStr = (ii->imported || isIDLorJava) ? "yes" : "no";
326 Doxygen::tagFile << " <includes id=\""
327 << convertToXML(fd->getOutputFileBase()) << "\" "
328 << "name=\"" << convertToXML(fd->name()) << "\" "
329 << "local=\"" << locStr << "\" "
330 << "imported=\"" << impStr << "\">"
331 << convertToXML(ii->includeName)
338 ol.docify(ii->includeName);
342 if (ii->local || isIDLorJava)
356 void FileDef::writeIncludeGraph(OutputList &ol)
358 if (Config_getBool("HAVE_DOT") /*&& Config_getBool("INCLUDE_GRAPH")*/)
360 //printf("Graph for file %s\n",name().data());
361 DotInclDepGraph incDepGraph(this,FALSE);
362 if (incDepGraph.isTooBig())
364 warn_uncond("Include graph for '%s' not generated, too many nodes. Consider increasing DOT_GRAPH_MAX_NODES.\n",name().data());
366 else if (!incDepGraph.isTrivial())
369 ol.disable(OutputGenerator::Man);
370 ol.startInclDepGraph();
371 ol.parseText(theTranslator->trInclDepGraph(name()));
372 ol.endInclDepGraph(incDepGraph);
374 ol.endTextBlock(TRUE);
376 //incDepGraph.writeGraph(Config_getString("HTML_OUTPUT"),fd->getOutputFileBase());
380 void FileDef::writeIncludedByGraph(OutputList &ol)
382 if (Config_getBool("HAVE_DOT") /*&& Config_getBool("INCLUDED_BY_GRAPH")*/)
384 //printf("Graph for file %s\n",name().data());
385 DotInclDepGraph incDepGraph(this,TRUE);
386 if (incDepGraph.isTooBig())
388 warn_uncond("Included by graph for '%s' not generated, too many nodes. Consider increasing DOT_GRAPH_MAX_NODES.\n",name().data());
390 else if (!incDepGraph.isTrivial())
393 ol.disable(OutputGenerator::Man);
394 ol.startInclDepGraph();
395 ol.parseText(theTranslator->trInclByDepGraph());
396 ol.endInclDepGraph(incDepGraph);
398 ol.endTextBlock(TRUE);
400 //incDepGraph.writeGraph(Config_getString("HTML_OUTPUT"),fd->getOutputFileBase());
405 void FileDef::writeSourceLink(OutputList &ol)
407 //printf("%s: generateSourceFile()=%d\n",name().data(),generateSourceFile());
408 if (generateSourceFile())
410 ol.disableAllBut(OutputGenerator::Html);
412 ol.startTextLink(includeName(),0);
413 ol.parseText(theTranslator->trGotoSourceCode());
420 void FileDef::writeNamespaceDeclarations(OutputList &ol,const QCString &title,
421 bool const isConstantGroup)
423 // write list of namespaces
424 if (m_namespaceSDict) m_namespaceSDict->writeDeclaration(ol,title,isConstantGroup);
427 void FileDef::writeClassDeclarations(OutputList &ol,const QCString &title)
429 // write list of classes
430 if (m_classSDict) m_classSDict->writeDeclaration(ol,0,title,FALSE);
433 void FileDef::writeInlineClasses(OutputList &ol)
435 // temporarily undo the disbling could be done by startMemberDocumentation()
436 // as a result of setting SEPARATE_MEMBER_PAGES to YES; see bug730512
437 bool isEnabled = ol.isEnabled(OutputGenerator::Html);
438 ol.enable(OutputGenerator::Html);
440 if (m_classSDict) m_classSDict->writeDocumentation(ol,this);
442 // restore the initial state if needed
443 if (!isEnabled) ol.disable(OutputGenerator::Html);
446 void FileDef::startMemberDeclarations(OutputList &ol)
448 ol.startMemberSections();
451 void FileDef::endMemberDeclarations(OutputList &ol)
453 ol.endMemberSections();
456 void FileDef::startMemberDocumentation(OutputList &ol)
458 if (Config_getBool("SEPARATE_MEMBER_PAGES"))
460 ol.disable(OutputGenerator::Html);
461 Doxygen::suppressDocWarnings = TRUE;
465 void FileDef::endMemberDocumentation(OutputList &ol)
467 if (Config_getBool("SEPARATE_MEMBER_PAGES"))
469 ol.enable(OutputGenerator::Html);
470 Doxygen::suppressDocWarnings = FALSE;
474 void FileDef::writeMemberGroups(OutputList &ol)
476 /* write user defined member groups */
477 if (m_memberGroupSDict)
479 m_memberGroupSDict->sort();
480 MemberGroupSDict::Iterator mgli(*m_memberGroupSDict);
482 for (;(mg=mgli.current());++mgli)
484 if ((!mg->allMembersInSameSection() || !m_subGrouping)
485 && mg->header()!="[NOHEADER]")
487 mg->writeDeclarations(ol,0,0,this,0);
493 void FileDef::writeAuthorSection(OutputList &ol)
495 // write Author section (Man only)
496 ol.pushGeneratorState();
497 ol.disableAllBut(OutputGenerator::Man);
498 ol.startGroupHeader();
499 ol.parseText(theTranslator->trAuthor(TRUE,TRUE));
501 ol.parseText(theTranslator->trGeneratedAutomatically(Config_getString("PROJECT_NAME")));
502 ol.popGeneratorState();
505 void FileDef::writeSummaryLinks(OutputList &ol)
507 ol.pushGeneratorState();
508 ol.disableAllBut(OutputGenerator::Html);
509 QListIterator<LayoutDocEntry> eli(
510 LayoutDocManager::instance().docEntries(LayoutDocManager::File));
513 SrcLangExt lang=getLanguage();
514 for (eli.toFirst();(lde=eli.current());++eli)
516 if ((lde->kind()==LayoutDocEntry::FileClasses &&
517 m_classSDict && m_classSDict->declVisible()) ||
518 (lde->kind()==LayoutDocEntry::FileNamespaces &&
519 m_namespaceSDict && m_namespaceSDict->declVisible())
522 LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
523 QCString label = lde->kind()==LayoutDocEntry::FileClasses ? "nested-classes" : "namespaces";
524 ol.writeSummaryLink(0,label,ls->title(lang),first);
527 else if (lde->kind()==LayoutDocEntry::MemberDecl)
529 LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;
530 MemberList * ml = getMemberList(lmd->type);
531 if (ml && ml->declVisible())
533 ol.writeSummaryLink(0,MemberList::listTypeAsString(ml->listType()),lmd->title(lang),first);
540 ol.writeString(" </div>\n");
542 ol.popGeneratorState();
545 /*! Write the documentation page for this file to the file of output
548 void FileDef::writeDocumentation(OutputList &ol)
550 static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
551 //funcList->countDecMembers();
553 //QCString fn = name();
554 //if (Config_getBool("FULL_PATH_NAMES"))
556 // fn.prepend(stripFromPath(getPath().copy()));
559 //printf("WriteDocumentation diskname=%s\n",diskname.data());
561 QCString versionTitle;
562 if (!m_fileVersion.isEmpty())
564 versionTitle=("("+m_fileVersion+")");
566 QCString title = m_docname+versionTitle;
567 QCString pageTitle=theTranslator->trFileReference(m_docname);
571 startFile(ol,getOutputFileBase(),name(),pageTitle,HLI_FileVisible,!generateTreeView);
572 if (!generateTreeView)
574 getDirDef()->writeNavigationPath(ol);
575 ol.endQuickIndices();
577 QCString pageTitleShort=theTranslator->trFileReference(name());
578 startTitle(ol,getOutputFileBase(),this);
579 ol.pushGeneratorState();
580 ol.disableAllBut(OutputGenerator::Html);
581 ol.parseText(pageTitleShort); // Html only
583 ol.disable(OutputGenerator::Html);
584 ol.parseText(pageTitle); // other output formats
585 ol.popGeneratorState();
586 addGroupListToTitle(ol,this);
587 endTitle(ol,getOutputFileBase(),title);
591 startFile(ol,getOutputFileBase(),name(),pageTitle,HLI_FileVisible,!generateTreeView);
592 if (!generateTreeView)
594 ol.endQuickIndices();
596 startTitle(ol,getOutputFileBase(),this);
597 ol.parseText(pageTitle);
598 addGroupListToTitle(ol,this);
599 endTitle(ol,getOutputFileBase(),title);
604 if (!m_fileVersion.isEmpty())
606 ol.disableAllBut(OutputGenerator::Html);
607 ol.startProjectNumber();
608 ol.docify(versionTitle);
609 ol.endProjectNumber();
613 if (Doxygen::searchIndex)
615 Doxygen::searchIndex->setCurrentDoc(this,anchor(),FALSE);
616 Doxygen::searchIndex->addWord(localName(),TRUE);
619 if (!Config_getString("GENERATE_TAGFILE").isEmpty())
621 Doxygen::tagFile << " <compound kind=\"file\">" << endl;
622 Doxygen::tagFile << " <name>" << convertToXML(name()) << "</name>" << endl;
623 Doxygen::tagFile << " <path>" << convertToXML(getPath()) << "</path>" << endl;
624 Doxygen::tagFile << " <filename>"
625 << convertToXML(getOutputFileBase())
626 << "</filename>" << endl;
629 //---------------------------------------- start flexible part -------------------------------
631 SrcLangExt lang = getLanguage();
632 QListIterator<LayoutDocEntry> eli(
633 LayoutDocManager::instance().docEntries(LayoutDocManager::File));
635 for (eli.toFirst();(lde=eli.current());++eli)
639 case LayoutDocEntry::BriefDesc:
640 writeBriefDescription(ol);
642 case LayoutDocEntry::MemberDeclStart:
643 startMemberDeclarations(ol);
645 case LayoutDocEntry::FileIncludes:
646 writeIncludeFiles(ol);
648 case LayoutDocEntry::FileIncludeGraph:
649 writeIncludeGraph(ol);
651 case LayoutDocEntry::FileIncludedByGraph:
652 writeIncludedByGraph(ol);
654 case LayoutDocEntry::FileSourceLink:
657 case LayoutDocEntry::FileClasses:
659 LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
660 writeClassDeclarations(ol,ls->title(lang));
663 case LayoutDocEntry::FileNamespaces:
665 LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
666 writeNamespaceDeclarations(ol,ls->title(lang),false);
669 case LayoutDocEntry::FileConstantGroups:
671 LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
672 writeNamespaceDeclarations(ol,ls->title(lang),true);
675 case LayoutDocEntry::MemberGroups:
676 writeMemberGroups(ol);
678 case LayoutDocEntry::MemberDecl:
680 LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;
681 writeMemberDeclarations(ol,lmd->type,lmd->title(lang));
684 case LayoutDocEntry::MemberDeclEnd:
685 endMemberDeclarations(ol);
687 case LayoutDocEntry::DetailedDesc:
689 LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
690 writeDetailedDescription(ol,ls->title(lang));
693 case LayoutDocEntry::MemberDefStart:
694 startMemberDocumentation(ol);
696 case LayoutDocEntry::FileInlineClasses:
697 writeInlineClasses(ol);
699 case LayoutDocEntry::MemberDef:
701 LayoutDocEntryMemberDef *lmd = (LayoutDocEntryMemberDef*)lde;
702 writeMemberDocumentation(ol,lmd->type,lmd->title(lang));
705 case LayoutDocEntry::MemberDefEnd:
706 endMemberDocumentation(ol);
708 case LayoutDocEntry::AuthorSection:
709 writeAuthorSection(ol);
711 case LayoutDocEntry::ClassIncludes:
712 case LayoutDocEntry::ClassInheritanceGraph:
713 case LayoutDocEntry::ClassNestedClasses:
714 case LayoutDocEntry::ClassCollaborationGraph:
715 case LayoutDocEntry::ClassAllMembersLink:
716 case LayoutDocEntry::ClassUsedFiles:
717 case LayoutDocEntry::ClassInlineClasses:
718 case LayoutDocEntry::NamespaceNestedNamespaces:
719 case LayoutDocEntry::NamespaceNestedConstantGroups:
720 case LayoutDocEntry::NamespaceClasses:
721 case LayoutDocEntry::NamespaceInlineClasses:
722 case LayoutDocEntry::GroupClasses:
723 case LayoutDocEntry::GroupInlineClasses:
724 case LayoutDocEntry::GroupNamespaces:
725 case LayoutDocEntry::GroupDirs:
726 case LayoutDocEntry::GroupNestedGroups:
727 case LayoutDocEntry::GroupFiles:
728 case LayoutDocEntry::GroupGraph:
729 case LayoutDocEntry::GroupPageDocs:
730 case LayoutDocEntry::DirSubDirs:
731 case LayoutDocEntry::DirFiles:
732 case LayoutDocEntry::DirGraph:
733 err("Internal inconsistency: member %d should not be part of "
734 "LayoutDocManager::File entry list\n",lde->kind());
739 //---------------------------------------- end flexible part -------------------------------
741 if (!Config_getString("GENERATE_TAGFILE").isEmpty())
743 writeDocAnchorsToTagFile();
744 Doxygen::tagFile << " </compound>" << endl;
749 endFileWithNavPath(this,ol);
751 if (Config_getBool("SEPARATE_MEMBER_PAGES"))
753 MemberList *ml = getMemberList(MemberListType_allMembersList);
755 writeMemberPages(ol);
759 void FileDef::writeMemberPages(OutputList &ol)
761 ol.pushGeneratorState();
762 ol.disableAllBut(OutputGenerator::Html);
764 QListIterator<MemberList> mli(m_memberLists);
766 for (mli.toFirst();(ml=mli.current());++mli)
768 if (ml->listType()&MemberListType_documentationLists)
770 ml->writeDocumentationPage(ol,name(),this);
774 ol.popGeneratorState();
777 void FileDef::writeQuickMemberLinks(OutputList &ol,MemberDef *currentMd) const
779 static bool createSubDirs=Config_getBool("CREATE_SUBDIRS");
781 ol.writeString(" <div class=\"navtab\">\n");
782 ol.writeString(" <table>\n");
784 MemberList *allMemberList = getMemberList(MemberListType_allMembersList);
787 MemberListIterator mli(*allMemberList);
789 for (mli.toFirst();(md=mli.current());++mli)
791 if (md->getFileDef()==this && md->getNamespaceDef()==0 && md->isLinkable() && !md->isEnumValue())
793 ol.writeString(" <tr><td class=\"navtab\">");
794 if (md->isLinkableInProject())
796 if (md==currentMd) // selected item => highlight
798 ol.writeString("<a class=\"qindexHL\" ");
802 ol.writeString("<a class=\"qindex\" ");
804 ol.writeString("href=\"");
805 if (createSubDirs) ol.writeString("../../");
806 ol.writeString(md->getOutputFileBase()+Doxygen::htmlFileExtension+"#"+md->anchor());
807 ol.writeString("\">");
808 ol.writeString(convertToHtml(md->localName()));
809 ol.writeString("</a>");
811 ol.writeString("</td></tr>\n");
816 ol.writeString(" </table>\n");
817 ol.writeString(" </div>\n");
820 /*! Write a source listing of this file to the output */
821 void FileDef::writeSource(OutputList &ol,bool sameTu,QStrList &filesInSameTu)
823 static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
824 static bool filterSourceFiles = Config_getBool("FILTER_SOURCE_FILES");
825 static bool latexSourceCode = Config_getBool("LATEX_SOURCE_CODE");
826 DevNullCodeDocInterface devNullIntf;
827 QCString title = m_docname;
828 if (!m_fileVersion.isEmpty())
830 title+=(" ("+m_fileVersion+")");
832 QCString pageTitle = theTranslator->trSourceFile(title);
833 ol.disable(OutputGenerator::Man);
834 ol.disable(OutputGenerator::RTF);
835 if (!latexSourceCode) ol.disable(OutputGenerator::Latex);
837 bool isDocFile = isDocumentationFile();
838 bool genSourceFile = !isDocFile && generateSourceFile();
841 startFile(ol,getSourceFileBase(),0,pageTitle,HLI_FileVisible,
843 !isDocFile && genSourceFile ? QCString() : getOutputFileBase());
844 if (!generateTreeView)
846 getDirDef()->writeNavigationPath(ol);
847 ol.endQuickIndices();
849 startTitle(ol,getSourceFileBase());
850 ol.parseText(name());
851 endTitle(ol,getSourceFileBase(),title);
855 startFile(ol,getSourceFileBase(),0,pageTitle,HLI_FileVisible,FALSE,
856 !isDocFile && genSourceFile ? QCString() : getOutputFileBase());
857 startTitle(ol,getSourceFileBase());
859 endTitle(ol,getSourceFileBase(),0);
866 if (latexSourceCode) ol.disable(OutputGenerator::Latex);
867 ol.startTextLink(getOutputFileBase(),0);
868 ol.parseText(theTranslator->trGotoDocumentation());
870 if (latexSourceCode) ol.enable(OutputGenerator::Latex);
876 static bool clangAssistedParsing = Config_getBool("CLANG_ASSISTED_PARSING");
877 if (clangAssistedParsing &&
878 (getLanguage()==SrcLangExt_Cpp || getLanguage()==SrcLangExt_ObjC))
880 ol.startCodeFragment();
883 ClangParser::instance()->start(absFilePath(),filesInSameTu);
887 ClangParser::instance()->switchToFile(absFilePath());
889 ClangParser::instance()->writeSources(ol,this);
890 ol.endCodeFragment();
895 ParserInterface *pIntf = Doxygen::parserManager->getParser(getDefFileExtension());
896 pIntf->resetCodeParserState();
897 ol.startCodeFragment();
898 bool needs2PassParsing =
899 Doxygen::parseSourcesNeeded && // we need to parse (filtered) sources for cross-references
900 !filterSourceFiles && // but user wants to show sources as-is
901 !getFileFilter(absFilePath(),TRUE).isEmpty(); // and there is a filter used while parsing
903 if (needs2PassParsing)
905 // parse code for cross-references only (see bug707641)
906 pIntf->parseCode(devNullIntf,0,
907 fileToString(absFilePath(),TRUE,TRUE),
912 pIntf->parseCode(ol,0,
913 fileToString(absFilePath(),filterSourceFiles,TRUE),
914 getLanguage(), // lang
915 FALSE, // isExampleBlock
920 FALSE, // inlineFragment
922 TRUE, // showLineNumbers
924 !needs2PassParsing // collectXRefs
926 ol.endCodeFragment();
929 endFileWithNavPath(this,ol);
933 void FileDef::parseSource(bool sameTu,QStrList &filesInSameTu)
935 static bool filterSourceFiles = Config_getBool("FILTER_SOURCE_FILES");
936 DevNullCodeDocInterface devNullIntf;
940 static bool clangAssistedParsing = Config_getBool("CLANG_ASSISTED_PARSING");
941 if (clangAssistedParsing &&
942 (getLanguage()==SrcLangExt_Cpp || getLanguage()==SrcLangExt_ObjC))
946 ClangParser::instance()->start(absFilePath(),filesInSameTu);
950 ClangParser::instance()->switchToFile(absFilePath());
952 ClangParser::instance()->writeSources(devNullIntf,this);
957 ParserInterface *pIntf = Doxygen::parserManager->getParser(getDefFileExtension());
958 pIntf->resetCodeParserState();
961 fileToString(absFilePath(),filterSourceFiles,TRUE),
968 void FileDef::startParsing()
972 void FileDef::finishParsing()
974 ClangParser::instance()->finish();
977 void FileDef::addMembersToMemberGroup()
979 QListIterator<MemberList> mli(m_memberLists);
981 for (mli.toFirst();(ml=mli.current());++mli)
983 if (ml->listType()&MemberListType_declarationLists)
985 ::addMembersToMemberGroup(ml,&m_memberGroupSDict,this);
989 // add members inside sections to their groups
990 if (m_memberGroupSDict)
992 MemberGroupSDict::Iterator mgli(*m_memberGroupSDict);
994 for (;(mg=mgli.current());++mgli)
996 if (mg->allMembersInSameSection() && m_subGrouping)
998 //printf("----> addToDeclarationSection(%s)\n",mg->header().data());
999 mg->addToDeclarationSection();
1005 /*! Adds member definition \a md to the list of all members of this file */
1006 void FileDef::insertMember(MemberDef *md)
1008 if (md->isHidden()) return;
1009 //printf("%s:FileDef::insertMember(%s (=%p) list has %d elements)\n",
1010 // name().data(),md->name().data(),md,allMemberList.count());
1011 MemberList *allMemberList = getMemberList(MemberListType_allMembersList);
1012 if (allMemberList && allMemberList->findRef(md)!=-1) // TODO optimize the findRef!
1017 if (allMemberList==0)
1019 allMemberList = new MemberList(MemberListType_allMembersList);
1020 m_memberLists.append(allMemberList);
1022 allMemberList->append(md);
1023 //::addFileMemberNameToIndex(md);
1024 switch (md->memberType())
1026 case MemberType_Variable:
1027 case MemberType_Property:
1028 addMemberToList(MemberListType_decVarMembers,md);
1029 addMemberToList(MemberListType_docVarMembers,md);
1031 case MemberType_Function:
1032 addMemberToList(MemberListType_decFuncMembers,md);
1033 addMemberToList(MemberListType_docFuncMembers,md);
1035 case MemberType_Typedef:
1036 addMemberToList(MemberListType_decTypedefMembers,md);
1037 addMemberToList(MemberListType_docTypedefMembers,md);
1039 case MemberType_Enumeration:
1040 addMemberToList(MemberListType_decEnumMembers,md);
1041 addMemberToList(MemberListType_docEnumMembers,md);
1043 case MemberType_EnumValue: // enum values are shown inside their enums
1045 case MemberType_Define:
1046 addMemberToList(MemberListType_decDefineMembers,md);
1047 addMemberToList(MemberListType_docDefineMembers,md);
1050 err("FileDef::insertMembers(): "
1051 "member `%s' with class scope `%s' inserted in file scope `%s'!\n",
1053 md->getClassDef() ? md->getClassDef()->name().data() : "<global>",
1056 //addMemberToGroup(md,groupId);
1059 /*! Adds compound definition \a cd to the list of all compounds of this file */
1060 void FileDef::insertClass(ClassDef *cd)
1062 if (cd->isHidden()) return;
1063 if (m_classSDict==0)
1065 m_classSDict = new ClassSDict(17);
1067 if (Config_getBool("SORT_BRIEF_DOCS"))
1069 m_classSDict->inSort(cd->name(),cd);
1073 m_classSDict->append(cd->name(),cd);
1077 /*! Adds namespace definition \a nd to the list of all compounds of this file */
1078 void FileDef::insertNamespace(NamespaceDef *nd)
1080 if (nd->isHidden()) return;
1081 if (!nd->name().isEmpty() &&
1082 (m_namespaceSDict==0 || m_namespaceSDict->find(nd->name())==0))
1084 if (m_namespaceSDict==0)
1086 m_namespaceSDict = new NamespaceSDict;
1088 if (Config_getBool("SORT_BRIEF_DOCS"))
1090 m_namespaceSDict->inSort(nd->name(),nd);
1094 m_namespaceSDict->append(nd->name(),nd);
1099 QCString FileDef::name() const
1101 if (Config_getBool("FULL_PATH_NAMES"))
1104 return Definition::name();
1107 void FileDef::addSourceRef(int line,Definition *d,MemberDef *md)
1109 //printf("FileDef::addSourceDef(%d,%p,%p)\n",line,d,md);
1112 if (m_srcDefDict==0) m_srcDefDict = new QIntDict<Definition>(257);
1113 if (m_srcMemberDict==0) m_srcMemberDict = new QIntDict<MemberDef>(257);
1114 m_srcDefDict->insert(line,d);
1115 if (md) m_srcMemberDict->insert(line,md);
1116 //printf("Adding member %s with anchor %s at line %d to file %s\n",
1117 // md?md->name().data():"<none>",md?md->anchor().data():"<none>",line,name().data());
1121 Definition *FileDef::getSourceDefinition(int lineNr) const
1123 Definition *result=0;
1126 result = m_srcDefDict->find(lineNr);
1128 //printf("%s::getSourceDefinition(%d)=%s\n",name().data(),lineNr,result?result->name().data():"none");
1132 MemberDef *FileDef::getSourceMember(int lineNr) const
1134 MemberDef *result=0;
1135 if (m_srcMemberDict)
1137 result = m_srcMemberDict->find(lineNr);
1139 //printf("%s::getSourceMember(%d)=%s\n",name().data(),lineNr,result?result->name().data():"none");
1144 void FileDef::addUsingDirective(NamespaceDef *nd)
1146 if (m_usingDirList==0)
1148 m_usingDirList = new NamespaceSDict;
1150 if (m_usingDirList->find(nd->qualifiedName())==0)
1152 m_usingDirList->append(nd->qualifiedName(),nd);
1154 //printf("%p: FileDef::addUsingDirective: %s:%d\n",this,name().data(),usingDirList->count());
1157 NamespaceSDict *FileDef::getUsedNamespaces() const
1159 //printf("%p: FileDef::getUsedNamespace: %s:%d\n",this,name().data(),usingDirList?usingDirList->count():0);
1160 return m_usingDirList;
1163 void FileDef::addUsingDeclaration(Definition *d)
1165 if (m_usingDeclList==0)
1167 m_usingDeclList = new SDict<Definition>(17);
1169 if (m_usingDeclList->find(d->qualifiedName())==0)
1171 m_usingDeclList->append(d->qualifiedName(),d);
1175 void FileDef::addIncludeDependency(FileDef *fd,const char *incName,bool local,
1176 bool imported,bool indirect)
1178 //printf("FileDef::addIncludeDependency(%p,%s,%d)\n",fd,incName,local);
1179 QCString iName = fd ? fd->absFilePath().data() : incName;
1180 if (!iName.isEmpty() && (!m_includeDict || m_includeDict->find(iName)==0))
1182 if (m_includeDict==0)
1184 m_includeDict = new QDict<IncludeInfo>(61);
1185 m_includeList = new QList<IncludeInfo>;
1186 m_includeList->setAutoDelete(TRUE);
1188 IncludeInfo *ii = new IncludeInfo;
1190 ii->includeName = incName;
1192 ii->imported = imported;
1193 ii->indirect = indirect;
1194 m_includeList->append(ii);
1195 m_includeDict->insert(iName,ii);
1199 void FileDef::addIncludedUsingDirectives()
1201 if (visited) return;
1203 //printf("( FileDef::addIncludedUsingDirectives for file %s\n",name().data());
1206 if (m_includeList) // file contains #includes
1209 QListIterator<IncludeInfo> iii(*m_includeList);
1211 for (iii.toFirst();(ii=iii.current());++iii) // foreach #include...
1213 if (ii->fileDef && !ii->fileDef->visited) // ...that is a known file
1215 // recurse into this file
1216 ii->fileDef->addIncludedUsingDirectives();
1221 QListIterator<IncludeInfo> iii(*m_includeList);
1223 // iterate through list from last to first
1224 for (iii.toLast();(ii=iii.current());--iii)
1226 if (ii->fileDef && ii->fileDef!=this)
1228 // add using directives
1229 NamespaceSDict *unl = ii->fileDef->m_usingDirList;
1232 NamespaceSDict::Iterator nli(*unl);
1234 for (nli.toLast();(nd=nli.current());--nli)
1236 // append each using directive found in a #include file
1237 if (m_usingDirList==0) m_usingDirList = new NamespaceSDict;
1238 //printf("Prepending used namespace %s to the list of file %s\n",
1239 // nd->name().data(),name().data());
1240 if (m_usingDirList->find(nd->qualifiedName())==0) // not yet added
1242 m_usingDirList->prepend(nd->qualifiedName(),nd);
1246 // add using declarations
1247 SDict<Definition> *udl = ii->fileDef->m_usingDeclList;
1250 SDict<Definition>::Iterator udi(*udl);
1252 for (udi.toLast();(d=udi.current());--udi)
1254 //printf("Adding using declaration %s\n",d->name().data());
1255 if (m_usingDeclList==0)
1257 m_usingDeclList = new SDict<Definition>(17);
1259 if (m_usingDeclList->find(d->qualifiedName())==0)
1261 m_usingDeclList->prepend(d->qualifiedName(),d);
1269 //printf(") end FileDef::addIncludedUsingDirectives for file %s\n",name().data());
1273 void FileDef::addIncludedByDependency(FileDef *fd,const char *incName,
1274 bool local,bool imported)
1276 //printf("FileDef::addIncludedByDependency(%p,%s,%d)\n",fd,incName,local);
1277 QCString iName = fd ? fd->absFilePath().data() : incName;
1278 if (!iName.isEmpty() && (m_includedByDict==0 || m_includedByDict->find(iName)==0))
1280 if (m_includedByDict==0)
1282 m_includedByDict = new QDict<IncludeInfo>(61);
1283 m_includedByList = new QList<IncludeInfo>;
1284 m_includedByList->setAutoDelete(TRUE);
1286 IncludeInfo *ii = new IncludeInfo;
1288 ii->includeName = incName;
1290 ii->imported = imported;
1291 ii->indirect = FALSE;
1292 m_includedByList->append(ii);
1293 m_includedByDict->insert(iName,ii);
1297 bool FileDef::isIncluded(const QCString &name) const
1299 if (name.isEmpty()) return FALSE;
1300 return m_includeDict!=0 && m_includeDict->find(name)!=0;
1303 bool FileDef::generateSourceFile() const
1305 static bool sourceBrowser = Config_getBool("SOURCE_BROWSER");
1306 static bool verbatimHeaders = Config_getBool("VERBATIM_HEADERS");
1307 QCString extension = name().right(4);
1308 return !isReference() &&
1310 (verbatimHeaders && guessSection(name())==Entry::HEADER_SEC)
1312 extension!=".doc" && extension!=".txt" && extension!=".dox" &&
1313 extension!=".md" && name().right(9)!=".markdown";
1317 void FileDef::addListReferences()
1320 QList<ListItemInfo> *xrefItems = xrefListItems();
1321 addRefItem(xrefItems,
1322 getOutputFileBase(),
1323 theTranslator->trFile(TRUE,TRUE),
1324 getOutputFileBase(),name(),
1328 if (m_memberGroupSDict)
1330 MemberGroupSDict::Iterator mgli(*m_memberGroupSDict);
1332 for (;(mg=mgli.current());++mgli)
1334 mg->addListReferences(this);
1337 QListIterator<MemberList> mli(m_memberLists);
1339 for (mli.toFirst();(ml=mli.current());++mli)
1341 if (ml->listType()&MemberListType_documentationLists)
1343 ml->addListReferences(this);
1348 //-------------------------------------------------------------------
1350 static int findMatchingPart(const QCString &path,const QCString dir)
1354 while ((si1=path.find('/',pos1))!=-1)
1356 int si2=dir.find('/',pos2);
1357 //printf(" found slash at pos %d in path %d: %s<->%s\n",si1,si2,
1358 // path.mid(pos1,si1-pos2).data(),dir.mid(pos2).data());
1359 if (si2==-1 && path.mid(pos1,si1-pos2)==dir.mid(pos2)) // match at end
1361 return dir.length();
1363 if (si1!=si2 || path.mid(pos1,si1-pos2)!=dir.mid(pos2,si2-pos2)) // no match in middle
1365 return QMAX(pos1-1,0);
1373 static Directory *findDirNode(Directory *root,const QCString &name)
1375 QListIterator<DirEntry> dli(root->children());
1377 for (dli.toFirst();(de=dli.current());++dli)
1379 if (de->kind()==DirEntry::Dir)
1381 Directory *dir = (Directory *)de;
1382 QCString dirName=dir->name();
1383 int sp=findMatchingPart(name,dirName);
1384 //printf("findMatchingPart(%s,%s)=%d\n",name.data(),dirName.data(),sp);
1385 if (sp>0) // match found
1387 if ((uint)sp==dirName.length()) // whole directory matches
1389 // recurse into the directory
1390 return findDirNode(dir,name.mid(dirName.length()+1));
1392 else // partial match => we need to split the path into three parts
1394 QCString baseName =dirName.left(sp);
1395 QCString oldBranchName=dirName.mid(sp+1);
1396 QCString newBranchName=name.mid(sp+1);
1397 // strip file name from path
1398 int newIndex=newBranchName.findRev('/');
1399 if (newIndex>0) newBranchName=newBranchName.left(newIndex);
1401 //printf("Splitting off part in new branch \n"
1402 // "base=%s old=%s new=%s\n",
1404 // oldBranchName.data(),
1405 // newBranchName.data()
1407 Directory *base = new Directory(root,baseName);
1408 Directory *newBranch = new Directory(base,newBranchName);
1409 dir->reParent(base);
1410 dir->rename(oldBranchName);
1411 base->addChild(dir);
1412 base->addChild(newBranch);
1413 dir->setLast(FALSE);
1414 // remove DirEntry container from list (without deleting it)
1415 root->children().setAutoDelete(FALSE);
1416 root->children().removeRef(dir);
1417 root->children().setAutoDelete(TRUE);
1418 // add new branch to the root
1419 if (!root->children().isEmpty())
1421 root->children().getLast()->setLast(FALSE);
1423 root->addChild(base);
1429 int si=name.findRev('/');
1430 if (si==-1) // no subdir
1432 return root; // put the file under the root node.
1434 else // need to create a subdir
1436 QCString baseName = name.left(si);
1437 //printf("new subdir %s\n",baseName.data());
1438 Directory *newBranch = new Directory(root,baseName);
1439 if (!root->children().isEmpty())
1441 root->children().getLast()->setLast(FALSE);
1443 root->addChild(newBranch);
1448 static void mergeFileDef(Directory *root,FileDef *fd)
1450 QCString rootPath = root->name();
1451 QCString filePath = fd->absFilePath();
1452 //printf("merging %s\n",filePath.data());
1453 Directory *dirNode = findDirNode(root,filePath);
1454 if (!dirNode->children().isEmpty())
1456 dirNode->children().getLast()->setLast(FALSE);
1458 DirEntry *e=new DirEntry(dirNode,fd);
1459 dirNode->addChild(e);
1463 static void generateIndent(QTextStream &t,DirEntry *de,int level)
1467 generateIndent(t,de->parent(),level+1);
1469 // from the root up to node n do...
1470 if (level==0) // item before a dir or document
1474 if (de->kind()==DirEntry::Dir)
1476 t << "<img " << FTV_IMGATTRIBS(plastnode) << "/>";
1480 t << "<img " << FTV_IMGATTRIBS(lastnode) << "/>";
1485 if (de->kind()==DirEntry::Dir)
1487 t << "<img " << FTV_IMGATTRIBS(pnode) << "/>";
1491 t << "<img " << FTV_IMGATTRIBS(node) << "/>";
1495 else // item at another level
1499 t << "<img " << FTV_IMGATTRIBS(blank) << "/>";
1503 t << "<img " << FTV_IMGATTRIBS(vertline) << "/>";
1508 static void writeDirTreeNode(QTextStream &t,Directory *root,int level)
1511 indent.fill(' ',level*2);
1512 QListIterator<DirEntry> dli(root->children());
1514 for (dli.toFirst();(de=dli.current());++dli)
1516 t << indent << "<p>";
1517 generateIndent(t,de,0);
1518 if (de->kind()==DirEntry::Dir)
1520 Directory *dir=(Directory *)de;
1521 //printf("%s [dir]: %s (last=%d,dir=%d)\n",indent.data(),dir->name().data(),dir->isLast(),dir->kind()==DirEntry::Dir);
1522 t << "<img " << FTV_IMGATTRIBS(folderclosed) << "/>";
1525 t << indent << "<div>\n";
1526 writeDirTreeNode(t,dir,level+1);
1527 t << indent << "</div>\n";
1531 //printf("%s [file]: %s (last=%d,dir=%d)\n",indent.data(),de->file()->name().data(),de->isLast(),de->kind()==DirEntry::Dir);
1532 t << "<img " << FTV_IMGATTRIBS(doc) << "/>";
1533 t << de->file()->name();
1540 static void addDirsAsGroups(Directory *root,GroupDef *parent,int level)
1543 if (root->kind()==DirEntry::Dir)
1545 gd = new GroupDef("[generated]",
1547 root->path(), // name
1548 root->name() // title
1552 parent->addGroup(gd);
1553 gd->makePartOfGroup(parent);
1557 Doxygen::groupSDict->append(root->path(),gd);
1560 QListIterator<DirEntry> dli(root->children());
1562 for (dli.toFirst();(de=dli.current());++dli)
1564 if (de->kind()==DirEntry::Dir)
1566 addDirsAsGroups((Directory *)de,gd,level+1);
1571 void generateFileTree()
1573 Directory *root=new Directory(0,"root");
1574 root->setLast(TRUE);
1575 FileNameListIterator fnli(*Doxygen::inputNameList);
1577 for (fnli.toFirst();(fn=fnli.current());++fnli)
1579 FileNameIterator fni(*fn);
1581 for (;(fd=fni.current());++fni)
1583 mergeFileDef(root,fd);
1586 //t << "<div class=\"directory\">\n";
1587 //writeDirTreeNode(t,root,0);
1589 addDirsAsGroups(root,0,0);
1593 //-------------------------------------------------------------------
1595 void FileDef::combineUsingRelations()
1597 if (visited) return; // already done
1601 NamespaceSDict::Iterator nli(*m_usingDirList);
1603 for (nli.toFirst();(nd=nli.current());++nli)
1605 nd->combineUsingRelations();
1607 for (nli.toFirst();(nd=nli.current());++nli)
1609 // add used namespaces of namespace nd to this namespace
1610 if (nd->getUsedNamespaces())
1612 NamespaceSDict::Iterator unli(*nd->getUsedNamespaces());
1614 for (unli.toFirst();(und=unli.current());++unli)
1616 //printf("Adding namespace %s to the using list of %s\n",und->qualifiedName().data(),qualifiedName().data());
1617 addUsingDirective(und);
1620 // add used classes of namespace nd to this namespace
1621 if (nd->getUsedClasses())
1623 SDict<Definition>::Iterator cli(*nd->getUsedClasses());
1625 for (cli.toFirst();(ucd=cli.current());++cli)
1627 //printf("Adding class %s to the using list of %s\n",cd->qualifiedName().data(),qualifiedName().data());
1628 addUsingDeclaration(ucd);
1635 bool FileDef::isDocumentationFile() const
1637 return name().right(4)==".doc" ||
1638 name().right(4)==".txt" ||
1639 name().right(4)==".dox" ||
1640 name().right(3)==".md" ||
1641 name().right(9)==".markdown";
1644 void FileDef::acquireFileVersion()
1646 QCString vercmd = Config_getString("FILE_VERSION_FILTER");
1647 if (!vercmd.isEmpty() && !m_filePath.isEmpty() && m_filePath!="generated")
1649 msg("Version of %s : ",m_filePath.data());
1650 QCString cmd = vercmd+" \""+m_filePath+"\"";
1651 Debug::print(Debug::ExtCmd,0,"Executing popen(`%s`)\n",cmd.data());
1652 FILE *f=portable_popen(cmd,"r");
1655 err("could not execute %s\n",vercmd.data());
1658 const int bufSize=1024;
1660 int numRead = (int)fread(buf,1,bufSize,f);
1662 if (numRead>0 && !(m_fileVersion=QCString(buf,numRead).stripWhiteSpace()).isEmpty())
1664 msg("%s\n",m_fileVersion.data());
1668 msg("no version available\n");
1674 QCString FileDef::getSourceFileBase() const
1676 if (Htags::useHtags)
1678 return Htags::path2URL(m_filePath);
1682 return convertNameToFile(m_diskName)+"_source";
1686 /*! Returns the name of the verbatim copy of this file (if any). */
1687 QCString FileDef::includeName() const
1689 return getSourceFileBase();
1692 MemberList *FileDef::createMemberList(MemberListType lt)
1694 m_memberLists.setAutoDelete(TRUE);
1695 QListIterator<MemberList> mli(m_memberLists);
1697 for (mli.toFirst();(ml=mli.current());++mli)
1699 if (ml->listType()==lt)
1704 // not found, create a new member list
1705 ml = new MemberList(lt);
1706 m_memberLists.append(ml);
1710 void FileDef::addMemberToList(MemberListType lt,MemberDef *md)
1712 static bool sortBriefDocs = Config_getBool("SORT_BRIEF_DOCS");
1713 static bool sortMemberDocs = Config_getBool("SORT_MEMBER_DOCS");
1714 MemberList *ml = createMemberList(lt);
1715 ml->setNeedsSorting(
1716 ((ml->listType()&MemberListType_declarationLists) && sortBriefDocs) ||
1717 ((ml->listType()&MemberListType_documentationLists) && sortMemberDocs));
1720 if (ml->needsSorting())
1725 if (lt&MemberListType_documentationLists)
1727 ml->setInFile(TRUE);
1729 if (ml->listType()&MemberListType_declarationLists) md->setSectionList(this,ml);
1732 void FileDef::sortMemberLists()
1734 QListIterator<MemberList> mli(m_memberLists);
1736 for (;(ml=mli.current());++mli)
1738 if (ml->needsSorting()) { ml->sort(); ml->setNeedsSorting(FALSE); }
1742 MemberList *FileDef::getMemberList(MemberListType lt) const
1744 QListIterator<MemberList> mli(m_memberLists);
1746 for (;(ml=mli.current());++mli)
1748 if (ml->listType()==lt)
1756 void FileDef::writeMemberDeclarations(OutputList &ol,MemberListType lt,const QCString &title)
1758 static bool optVhdl = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
1759 MemberList * ml = getMemberList(lt);
1762 if (optVhdl) // use specific declarations function
1765 VhdlDocGen::writeVhdlDeclarations(ml,ol,0,0,this,0);
1769 ml->writeDeclarations(ol,0,0,this,0,title,0,definitionType());
1774 void FileDef::writeMemberDocumentation(OutputList &ol,MemberListType lt,const QCString &title)
1776 MemberList * ml = getMemberList(lt);
1777 if (ml) ml->writeDocumentation(ol,name(),this,title);
1780 bool FileDef::isLinkableInProject() const
1782 static bool showFiles = Config_getBool("SHOW_FILES");
1783 return hasDocumentation() && !isReference() && showFiles;
1786 static void getAllIncludeFilesRecursively(
1787 QDict<void> *filesVisited,const FileDef *fd,QStrList &incFiles)
1789 if (fd->includeFileList())
1791 QListIterator<IncludeInfo> iii(*fd->includeFileList());
1793 for (iii.toFirst();(ii=iii.current());++iii)
1795 if (ii->fileDef && !ii->fileDef->isReference() &&
1796 !filesVisited->find(ii->fileDef->absFilePath()))
1798 //printf("FileDef::addIncludeDependency(%s)\n",ii->fileDef->absFilePath().data());
1799 incFiles.append(ii->fileDef->absFilePath());
1800 filesVisited->insert(ii->fileDef->absFilePath(),(void*)0x8);
1801 getAllIncludeFilesRecursively(filesVisited,ii->fileDef,incFiles);
1807 void FileDef::getAllIncludeFilesRecursively(QStrList &incFiles) const
1809 QDict<void> includes(257);
1810 ::getAllIncludeFilesRecursively(&includes,this,incFiles);
1813 QCString FileDef::title() const
1815 return theTranslator->trFileReference(name());
1818 QCString FileDef::fileVersion() const
1820 return m_fileVersion;