7 #include "outputlist.h"
12 #include "ftextstream.h"
14 #include "docparser.h"
16 //----------------------------------------------------------------------
17 // method implementation
19 static int g_dirCount=0;
21 DirDef::DirDef(const char *path) : Definition(path,1,1,path), visited(FALSE)
23 bool fullPathNames = Config_getBool(FULL_PATH_NAMES);
24 // get display name (stipping the paths mentioned in STRIP_FROM_PATH)
25 // get short name (last part of path)
28 if (m_shortName.at(m_shortName.length()-1)=='/')
30 m_shortName = m_shortName.left(m_shortName.length()-1);
32 int pi=m_shortName.findRev('/');
34 { // remove everything till the last /
35 m_shortName = m_shortName.mid(pi+1);
37 setLocalName(m_shortName);
38 m_dispName = fullPathNames ? stripFromPath(path) : m_shortName;
39 if (m_dispName.length()>0 && m_dispName.at(m_dispName.length()-1)=='/')
41 m_dispName = m_dispName.left(m_dispName.length()-1);
44 m_fileList = new FileList;
45 m_usedDirs = new QDict<UsedDir>(257);
46 m_usedDirs->setAutoDelete(TRUE);
47 m_dirCount = g_dirCount++;
58 bool DirDef::isLinkableInProject() const
60 return !isReference();
63 bool DirDef::isLinkable() const
65 return isReference() || isLinkableInProject();
68 void DirDef::addSubDir(DirDef *subdir)
70 m_subdirs.append(subdir);
71 subdir->setOuterScope(this);
72 subdir->m_parent=this;
75 void DirDef::addFile(FileDef *fd)
77 m_fileList->append(fd);
87 static QCString encodeDirName(const QCString &anchor)
89 // convert to md5 hash
92 MD5Buffer((const unsigned char *)anchor.data(),anchor.length(),md5_sig);
93 MD5SigToString(md5_sig,sigStr.rawData(),33);
99 // int l = anchor.length(),i;
102 // char c = anchor.at(i);
103 // if ((c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9'))
109 // static char hexStr[]="0123456789ABCDEF";
110 // char escChar[]={ '_', 0, 0, 0 };
111 // escChar[1]=hexStr[c>>4];
112 // escChar[2]=hexStr[c&0xf];
119 QCString DirDef::getOutputFileBase() const
121 //printf("DirDef::getOutputFileBase() %s->dir_%s\n",
122 // m_diskName.data(),encodeDirName(m_diskName).data());
123 return "dir_"+encodeDirName(m_diskName);
126 void DirDef::writeDetailedDescription(OutputList &ol,const QCString &title)
128 if ((!briefDescription().isEmpty() && Config_getBool(REPEAT_BRIEF)) ||
129 !documentation().isEmpty())
131 ol.pushGeneratorState();
132 ol.disable(OutputGenerator::Html);
134 ol.popGeneratorState();
135 ol.pushGeneratorState();
136 ol.disableAllBut(OutputGenerator::Html);
137 ol.writeAnchor(0,"details");
138 ol.popGeneratorState();
139 ol.startGroupHeader();
143 // repeat brief description
144 if (!briefDescription().isEmpty() && Config_getBool(REPEAT_BRIEF))
146 ol.generateDoc(briefFile(),briefLine(),this,0,briefDescription(),FALSE,FALSE);
148 // separator between brief and details
149 if (!briefDescription().isEmpty() && Config_getBool(REPEAT_BRIEF) &&
150 !documentation().isEmpty())
152 ol.pushGeneratorState();
153 ol.disable(OutputGenerator::Man);
154 ol.disable(OutputGenerator::RTF);
155 // ol.newParagraph(); // FIXME:PARA
157 ol.disableAllBut(OutputGenerator::Man);
158 ol.enable(OutputGenerator::Latex);
159 ol.writeString("\n\n");
160 ol.popGeneratorState();
163 // write documentation
164 if (!documentation().isEmpty())
166 ol.generateDoc(docFile(),docLine(),this,0,documentation()+"\n",TRUE,FALSE);
171 void DirDef::writeBriefDescription(OutputList &ol)
173 if (hasBriefDescription())
175 DocRoot *rootNode = validatingParseDoc(
176 briefFile(),briefLine(),this,0,briefDescription(),TRUE,FALSE);
177 if (rootNode && !rootNode->isEmpty())
180 ol.pushGeneratorState();
181 ol.disableAllBut(OutputGenerator::Man);
182 ol.writeString(" - ");
183 ol.popGeneratorState();
184 ol.writeDoc(rootNode,this,0);
185 ol.pushGeneratorState();
186 ol.disable(OutputGenerator::RTF);
187 ol.writeString(" \n");
188 ol.enable(OutputGenerator::RTF);
190 if (Config_getBool(REPEAT_BRIEF) ||
191 !documentation().isEmpty()
194 ol.disableAllBut(OutputGenerator::Html);
195 ol.startTextLink(0,"details");
196 ol.parseText(theTranslator->trMore());
199 ol.popGeneratorState();
208 void DirDef::writeDirectoryGraph(OutputList &ol)
210 // write graph dependency graph
211 if (Config_getBool(DIRECTORY_GRAPH) && Config_getBool(HAVE_DOT))
213 DotDirDeps dirDep(this);
214 if (!dirDep.isTrivial())
216 msg("Generating dependency graph for directory %s\n",displayName().data());
217 ol.disable(OutputGenerator::Man);
218 //ol.startParagraph();
219 ol.startDirDepGraph();
220 ol.parseText(theTranslator->trDirDepGraph(shortName()));
221 ol.endDirDepGraph(dirDep);
228 void DirDef::writeSubDirList(OutputList &ol)
231 QListIterator<DirDef> it(m_subdirs);
233 for (it.toFirst();(dd=it.current());++it)
235 if (dd->hasDocumentation() || dd->getFiles()->count()>0)
244 ol.startMemberHeader("subdirs");
245 ol.parseText(theTranslator->trDir(TRUE,FALSE));
246 ol.endMemberHeader();
247 ol.startMemberList();
248 for (it.toFirst();(dd=it.current());++it)
250 if (dd->hasDocumentation() || dd->getFiles()->count()==0)
252 ol.startMemberDeclaration();
253 ol.startMemberItem(dd->getOutputFileBase(),0);
254 ol.parseText(theTranslator->trDir(FALSE,TRUE)+" ");
255 ol.insertMemberAlign();
256 ol.writeObjectLink(dd->getReference(),dd->getOutputFileBase(),0,dd->shortName());
258 if (!dd->briefDescription().isEmpty() && Config_getBool(BRIEF_MEMBER_DESC))
260 ol.startMemberDescription(dd->getOutputFileBase());
261 ol.generateDoc(briefFile(),briefLine(),dd,0,dd->briefDescription(),
266 TRUE // link from index
268 ol.endMemberDescription();
270 ol.endMemberDeclaration(0,0);
278 void DirDef::writeFileList(OutputList &ol)
281 QListIterator<FileDef> it(*m_fileList);
283 for (it.toFirst();(fd=it.current());++it)
285 if (fd->hasDocumentation())
294 ol.startMemberHeader("files");
295 ol.parseText(theTranslator->trFile(TRUE,FALSE));
296 ol.endMemberHeader();
297 ol.startMemberList();
298 QListIterator<FileDef> it(*m_fileList);
300 for (;(fd=it.current());++it)
302 if (fd->hasDocumentation())
304 ol.startMemberDeclaration();
305 ol.startMemberItem(fd->getOutputFileBase(),0);
306 ol.docify(theTranslator->trFile(FALSE,TRUE)+" ");
307 ol.insertMemberAlign();
308 if (fd->isLinkable())
310 ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),0,fd->name());
315 ol.docify(fd->name());
318 if (fd->generateSourceFile())
320 ol.pushGeneratorState();
321 ol.disableAllBut(OutputGenerator::Html);
323 ol.startTextLink(fd->includeName(),0);
325 ol.parseText(theTranslator->trCode());
328 ol.popGeneratorState();
331 if (!fd->briefDescription().isEmpty() && Config_getBool(BRIEF_MEMBER_DESC))
333 ol.startMemberDescription(fd->getOutputFileBase());
334 ol.generateDoc(briefFile(),briefLine(),fd,0,fd->briefDescription(),
339 TRUE // link from index
341 ol.endMemberDescription();
343 ol.endMemberDeclaration(0,0);
350 void DirDef::startMemberDeclarations(OutputList &ol)
352 ol.startMemberSections();
355 void DirDef::endMemberDeclarations(OutputList &ol)
357 ol.endMemberSections();
360 QCString DirDef::shortTitle() const
362 return theTranslator->trDirReference(m_shortName);
365 bool DirDef::hasDetailedDescription() const
367 static bool repeatBrief = Config_getBool(REPEAT_BRIEF);
368 return (!briefDescription().isEmpty() && repeatBrief) || !documentation().isEmpty();
371 void DirDef::writeTagFile(FTextStream &tagFile)
373 tagFile << " <compound kind=\"dir\">" << endl;
374 tagFile << " <name>" << convertToXML(displayName()) << "</name>" << endl;
375 tagFile << " <path>" << convertToXML(name()) << "</path>" << endl;
376 tagFile << " <filename>" << convertToXML(getOutputFileBase()) << Doxygen::htmlFileExtension << "</filename>" << endl;
377 QListIterator<LayoutDocEntry> eli(
378 LayoutDocManager::instance().docEntries(LayoutDocManager::Directory));
380 for (eli.toFirst();(lde=eli.current());++eli)
384 case LayoutDocEntry::DirSubDirs:
386 if (m_subdirs.count()>0)
389 QListIterator<DirDef> it(m_subdirs);
390 for (;(dd=it.current());++it)
392 tagFile << " <dir>" << convertToXML(dd->displayName()) << "</dir>" << endl;
397 case LayoutDocEntry::DirFiles:
399 if (m_fileList->count()>0)
401 QListIterator<FileDef> it(*m_fileList);
403 for (;(fd=it.current());++it)
405 tagFile << " <file>" << convertToXML(fd->name()) << "</file>" << endl;
414 writeDocAnchorsToTagFile(tagFile);
415 tagFile << " </compound>" << endl;
418 void DirDef::writeDocumentation(OutputList &ol)
420 static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
421 ol.pushGeneratorState();
423 QCString title=theTranslator->trDirReference(m_dispName);
424 startFile(ol,getOutputFileBase(),name(),title,HLI_Files,!generateTreeView);
426 if (!generateTreeView)
428 // write navigation path
429 writeNavigationPath(ol);
430 ol.endQuickIndices();
433 startTitle(ol,getOutputFileBase());
434 ol.pushGeneratorState();
435 ol.disableAllBut(OutputGenerator::Html);
436 ol.parseText(shortTitle());
438 ol.disable(OutputGenerator::Html);
440 ol.popGeneratorState();
441 endTitle(ol,getOutputFileBase(),title);
444 //---------------------------------------- start flexible part -------------------------------
446 SrcLangExt lang = getLanguage();
447 QListIterator<LayoutDocEntry> eli(
448 LayoutDocManager::instance().docEntries(LayoutDocManager::Directory));
450 for (eli.toFirst();(lde=eli.current());++eli)
454 case LayoutDocEntry::BriefDesc:
455 writeBriefDescription(ol);
457 case LayoutDocEntry::DirGraph:
458 writeDirectoryGraph(ol);
460 case LayoutDocEntry::MemberDeclStart:
461 startMemberDeclarations(ol);
463 case LayoutDocEntry::DirSubDirs:
466 case LayoutDocEntry::DirFiles:
469 case LayoutDocEntry::MemberDeclEnd:
470 endMemberDeclarations(ol);
472 case LayoutDocEntry::DetailedDesc:
474 LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
475 writeDetailedDescription(ol,ls->title(lang));
478 case LayoutDocEntry::ClassIncludes:
479 case LayoutDocEntry::ClassInlineClasses:
480 case LayoutDocEntry::ClassInheritanceGraph:
481 case LayoutDocEntry::ClassNestedClasses:
482 case LayoutDocEntry::ClassCollaborationGraph:
483 case LayoutDocEntry::ClassAllMembersLink:
484 case LayoutDocEntry::ClassUsedFiles:
485 case LayoutDocEntry::NamespaceNestedNamespaces:
486 case LayoutDocEntry::NamespaceNestedConstantGroups:
487 case LayoutDocEntry::NamespaceClasses:
488 case LayoutDocEntry::NamespaceInterfaces:
489 case LayoutDocEntry::NamespaceStructs:
490 case LayoutDocEntry::NamespaceExceptions:
491 case LayoutDocEntry::NamespaceInlineClasses:
492 case LayoutDocEntry::FileClasses:
493 case LayoutDocEntry::FileInterfaces:
494 case LayoutDocEntry::FileStructs:
495 case LayoutDocEntry::FileExceptions:
496 case LayoutDocEntry::FileNamespaces:
497 case LayoutDocEntry::FileConstantGroups:
498 case LayoutDocEntry::FileIncludes:
499 case LayoutDocEntry::FileIncludeGraph:
500 case LayoutDocEntry::FileIncludedByGraph:
501 case LayoutDocEntry::FileSourceLink:
502 case LayoutDocEntry::FileInlineClasses:
503 case LayoutDocEntry::GroupClasses:
504 case LayoutDocEntry::GroupInlineClasses:
505 case LayoutDocEntry::GroupNamespaces:
506 case LayoutDocEntry::GroupDirs:
507 case LayoutDocEntry::GroupNestedGroups:
508 case LayoutDocEntry::GroupFiles:
509 case LayoutDocEntry::GroupGraph:
510 case LayoutDocEntry::GroupPageDocs:
511 case LayoutDocEntry::AuthorSection:
512 case LayoutDocEntry::MemberGroups:
513 case LayoutDocEntry::MemberDecl:
514 case LayoutDocEntry::MemberDef:
515 case LayoutDocEntry::MemberDefStart:
516 case LayoutDocEntry::MemberDefEnd:
517 err("Internal inconsistency: member %d should not be part of "
518 "LayoutDocManager::Directory entry list\n",lde->kind());
523 //---------------------------------------- end flexible part -------------------------------
527 endFileWithNavPath(this,ol);
529 ol.popGeneratorState();
532 void DirDef::setLevel()
534 if (m_level==-1) // level not set before
536 DirDef *p = parent();
540 m_level = p->level()+1;
549 /** Add as "uses" dependency between \a this dir and \a dir,
550 * that was caused by a dependency on file \a fd.
552 void DirDef::addUsesDependency(DirDef *dir,FileDef *srcFd,
553 FileDef *dstFd,bool inherited)
555 if (this==dir) return; // do not add self-dependencies
556 //static int count=0;
557 //printf(" %d add dependency %s->%s due to %s->%s\n",
558 // count++,shortName().data(),
559 // dir->shortName().data(),
560 // srcFd->name().data(),
561 // dstFd->name().data());
563 // levels match => add direct dependency
565 UsedDir *usedDir = m_usedDirs->find(dir->getOutputFileBase());
566 if (usedDir) // dir dependency already present
568 FilePair *usedPair = usedDir->findFilePair(
569 srcFd->getOutputFileBase()+dstFd->getOutputFileBase());
570 if (usedPair==0) // new file dependency
572 //printf(" => new file\n");
573 usedDir->addFileDep(srcFd,dstFd);
578 // dir & file dependency already added
581 else // new directory dependency
583 //printf(" => new file\n");
584 usedDir = new UsedDir(dir,inherited);
585 usedDir->addFileDep(srcFd,dstFd);
586 m_usedDirs->insert(dir->getOutputFileBase(),usedDir);
593 // add relation to parent of used dir
594 addUsesDependency(dir->parent(),srcFd,dstFd,inherited);
598 // add relation for the parent of this dir as well
599 parent()->addUsesDependency(dir,srcFd,dstFd,TRUE);
604 /** Computes the dependencies between directories
606 void DirDef::computeDependencies()
608 FileList *fl = m_fileList;
611 QListIterator<FileDef> fli(*fl);
613 for (fli.toFirst();(fd=fli.current());++fli) // foreach file in dir dd
615 //printf(" File %s\n",fd->name().data());
616 //printf("** dir=%s file=%s\n",shortName().data(),fd->name().data());
617 QList<IncludeInfo> *ifl = fd->includeFileList();
620 QListIterator<IncludeInfo> ifli(*ifl);
622 for (ifli.toFirst();(ii=ifli.current());++ifli) // foreach include file
624 //printf(" > %s\n",ii->includeName.data());
625 //printf(" #include %s\n",ii->includeName.data());
626 if (ii->fileDef && ii->fileDef->isLinkable()) // linkable file
628 DirDef *usedDir = ii->fileDef->getDirDef();
631 // add dependency: thisDir->usedDir
632 //static int count=0;
633 //printf(" %d: add dependency %s->%s\n",count++,name().data(),usedDir->name().data());
634 addUsesDependency(usedDir,fd,ii->fileDef,FALSE);
643 QDictIterator<UsedDir> udi(*m_usedDirs);
645 for (udi.toFirst();(udir=udi.current());++udi)
652 bool DirDef::isParentOf(DirDef *dir) const
654 if (dir->parent()==this) // this is a parent of dir
656 else if (dir->parent()) // repeat for the parent of dir
657 return isParentOf(dir->parent());
662 bool DirDef::depGraphIsTrivial() const
664 return m_usedDirs->count()==0;
667 //----------------------------------------------------------------------
669 int FilePairDict::compareValues(const FilePair *left,const FilePair *right) const
671 int orderHi = qstricmp(left->source()->name(),right->source()->name());
672 if (orderHi!=0) return orderHi;
673 int orderLo = qstricmp(left->destination()->name(),right->destination()->name());
677 //----------------------------------------------------------------------
679 UsedDir::UsedDir(DirDef *dir,bool inherited) :
680 m_dir(dir), m_filePairs(7), m_inherited(inherited)
682 m_filePairs.setAutoDelete(TRUE);
690 void UsedDir::addFileDep(FileDef *srcFd,FileDef *dstFd)
692 m_filePairs.append(srcFd->getOutputFileBase()+dstFd->getOutputFileBase(),
693 new FilePair(srcFd,dstFd));
701 FilePair *UsedDir::findFilePair(const char *name)
704 return n.isEmpty() ? 0 : m_filePairs.find(n);
707 DirDef *DirDef::createNewDir(const char *path)
710 DirDef *dir = Doxygen::directories->find(path);
711 if (dir==0) // new dir
713 //printf("Adding new dir %s\n",path);
714 dir = new DirDef(path);
715 //printf("createNewDir %s short=%s\n",path,dir->shortName().data());
716 Doxygen::directories->append(path,dir);
721 bool DirDef::matchPath(const QCString &path,QStrList &l)
723 const char *s=l.first();
727 if (qstricmp(prefix.left(path.length()),path)==0) // case insensitive compare
736 /*! strip part of \a path if it matches
737 * one of the paths in the Config_getList(STRIP_FROM_PATH) list
739 DirDef *DirDef::mergeDirectoryInTree(const QCString &path)
741 //printf("DirDef::mergeDirectoryInTree(%s)\n",path.data());
744 while ((i=path.find('/',p))!=-1)
746 QCString part=path.left(i+1);
747 if (!matchPath(part,Config_getList(STRIP_FROM_PATH)) && (part!="/" && part!="//"))
749 dir=createNewDir(part);
756 //----------------------------------------------------------------------
758 static void writePartialDirPath(OutputList &ol,const DirDef *root,const DirDef *target)
760 if (target->parent()!=root)
762 writePartialDirPath(ol,root,target->parent());
763 ol.writeString(" / ");
765 ol.writeObjectLink(target->getReference(),target->getOutputFileBase(),0,target->shortName());
768 static void writePartialFilePath(OutputList &ol,const DirDef *root,const FileDef *fd)
770 if (fd->getDirDef() && fd->getDirDef()!=root)
772 writePartialDirPath(ol,root,fd->getDirDef());
773 ol.writeString(" / ");
775 if (fd->isLinkable())
777 ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),0,fd->name());
782 ol.docify(fd->name());
787 void DirRelation::writeDocumentation(OutputList &ol)
789 static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
790 ol.pushGeneratorState();
791 ol.disableAllBut(OutputGenerator::Html);
793 QCString shortTitle=theTranslator->trDirRelation(
794 m_src->shortName()+" → "+
795 m_dst->dir()->shortName());
796 QCString title=theTranslator->trDirRelation(
797 m_src->displayName()+" -> "+
798 m_dst->dir()->shortName());
799 startFile(ol,getOutputFileBase(),getOutputFileBase(),
800 title,HLI_None,!generateTreeView,m_src->getOutputFileBase());
802 if (!generateTreeView)
804 // write navigation path
805 m_src->writeNavigationPath(ol);
806 ol.endQuickIndices();
810 ol.writeString("<h3>"+shortTitle+"</h3>");
811 ol.writeString("<table class=\"dirtab\">");
812 ol.writeString("<tr class=\"dirtab\">");
813 ol.writeString("<th class=\"dirtab\">");
814 ol.parseText(theTranslator->trFileIn(m_src->pathFragment()));
815 ol.writeString("</th>");
816 ol.writeString("<th class=\"dirtab\">");
817 ol.parseText(theTranslator->trIncludesFileIn(m_dst->dir()->pathFragment()));
818 ol.writeString("</th>");
819 ol.writeString("</tr>");
821 SDict<FilePair>::Iterator fpi(m_dst->filePairs());
823 for (fpi.toFirst();(fp=fpi.current());++fpi)
825 ol.writeString("<tr class=\"dirtab\">");
826 ol.writeString("<td class=\"dirtab\">");
827 writePartialFilePath(ol,m_src,fp->source());
828 ol.writeString("</td>");
829 ol.writeString("<td class=\"dirtab\">");
830 writePartialFilePath(ol,m_dst->dir(),fp->destination());
831 ol.writeString("</td>");
832 ol.writeString("</tr>");
834 ol.writeString("</table>");
838 endFileWithNavPath(m_src,ol);
840 ol.popGeneratorState();
843 //----------------------------------------------------------------------
844 // external functions
846 /** In order to create stable, but unique directory names,
847 * we compute the common part of the path shared by all directories.
849 static void computeCommonDirPrefix()
853 DirSDict::Iterator sdi(*Doxygen::directories);
854 if (Doxygen::directories->count()>0) // we have at least one dir
856 // start will full path of first dir
860 int i=path.findRev('/',path.length()-2);
871 int l = path.length();
873 for (sdi.toFirst();(dir=sdi.current());++sdi)
875 QCString dirName = dir->name();
876 if (dirName.length()>path.length())
878 if (qstrncmp(dirName,path,l)!=0) // dirName does not start with path
880 int i=path.findRev('/',l-2);
881 if (i==-1) // no unique prefix -> stop
886 else // restart with shorter path
893 else // dir is shorter than path -> take path of dir as new start
897 int i=path.findRev('/',l-2);
898 if (i==-1) // no unique prefix -> stop
903 else // restart with shorter path
911 if (count==Doxygen::directories->count())
912 // path matches for all directories -> found the common prefix
919 for (sdi.toFirst();(dir=sdi.current());++sdi)
921 QCString diskName = dir->name().right(dir->name().length()-path.length());
922 dir->setDiskName(diskName);
923 //printf("set disk name: %s -> %s\n",dir->name().data(),diskName.data());
927 void buildDirectories()
929 // for each input file
930 FileNameListIterator fnli(*Doxygen::inputNameList);
932 for (fnli.toFirst();(fn=fnli.current());++fnli)
934 FileNameIterator fni(*fn);
936 for (;(fd=fni.current());++fni)
938 //printf("buildDirectories %s\n",fd->name().data());
939 if (fd->getReference().isEmpty())
942 if ((dir=Doxygen::directories->find(fd->getPath()))==0) // new directory
944 dir = DirDef::mergeDirectoryInTree(fd->getPath());
946 if (dir && !fd->isDocumentationFile()) dir->addFile(fd);
950 // do something for file imported via tag files.
955 //DirDef *root = new DirDef("root:");
956 // compute relations between directories => introduce container dirs.
958 DirSDict::Iterator sdi(*Doxygen::directories);
959 for (sdi.toFirst();(dir=sdi.current());++sdi)
961 QCString name = dir->name();
962 int i=name.findRev('/',name.length()-2);
965 DirDef *parent = Doxygen::directories->find(name.left(i+1));
966 //if (parent==0) parent=root;
969 parent->addSubDir(dir);
970 //printf("DirDef::addSubdir(): Adding subdir\n%s to\n%s\n",
971 // dir->displayName().data(), parent->displayName().data());
975 for (sdi.toFirst();(dir=sdi.current());++sdi)
979 Doxygen::directories->sort();
980 computeCommonDirPrefix();
983 void computeDirDependencies()
986 DirSDict::Iterator sdi(*Doxygen::directories);
987 // compute nesting level for each directory
988 for (sdi.toFirst();(dir=sdi.current());++sdi)
992 // compute uses dependencies between directories
993 for (sdi.toFirst();(dir=sdi.current());++sdi)
995 //printf("computeDependencies for %s: #dirs=%d\n",dir->name().data(),Doxygen::directories.count());
996 dir->computeDependencies();
1001 void generateDirDocs(OutputList &ol)
1004 DirSDict::Iterator sdi(*Doxygen::directories);
1005 for (sdi.toFirst();(dir=sdi.current());++sdi)
1007 ol.pushGeneratorState();
1008 if (!dir->hasDocumentation())
1010 ol.disableAllBut(OutputGenerator::Html);
1012 dir->writeDocumentation(ol);
1013 ol.popGeneratorState();
1015 if (Config_getBool(DIRECTORY_GRAPH))
1017 SDict<DirRelation>::Iterator rdi(Doxygen::dirRelations);
1019 for (rdi.toFirst();(dr=rdi.current());++rdi)
1021 dr->writeDocumentation(ol);