Chameleon

Chameleon Svn Source Tree

Root/branches/xZenu/src/util/doxygen/src/dirdef.cpp

Source at commit 1322 created 12 years 8 months ago.
By meklort, Add doxygen to utils folder
1#include "md5.h"
2
3#include "dirdef.h"
4#include "filename.h"
5#include "doxygen.h"
6#include "util.h"
7#include "outputlist.h"
8#include "language.h"
9#include "message.h"
10#include "dot.h"
11#include "layout.h"
12#include "ftextstream.h"
13
14//----------------------------------------------------------------------
15// method implementation
16
17static int g_dirCount=0;
18
19DirDef::DirDef(const char *path) : Definition(path,1,path)
20{
21 // get display name (stipping the paths mentioned in STRIP_FROM_PATH)
22 m_dispName = stripFromPath(path);
23 // get short name (last part of path)
24 m_shortName = path;
25 if (m_shortName.at(m_shortName.length()-1)=='/')
26 { // strip trailing /
27 m_shortName = m_shortName.left(m_shortName.length()-1);
28 }
29 int pi=m_shortName.findRev('/');
30 if (pi!=-1)
31 { // remove everything till the last /
32 m_shortName = m_shortName.mid(pi+1);
33 }
34 setLocalName(m_shortName);
35
36 m_fileList = new FileList;
37 m_usedDirs = new QDict<UsedDir>(257);
38 m_usedDirs->setAutoDelete(TRUE);
39 m_dirCount = g_dirCount++;
40 m_level=-1;
41 m_parent=0;
42}
43
44DirDef::~DirDef()
45{
46 delete m_fileList;
47 delete m_usedDirs;
48}
49
50bool DirDef::isLinkableInProject() const
51{
52 return !isReference() && Config_getBool("SHOW_DIRECTORIES");
53}
54
55bool DirDef::isLinkable() const
56{
57 return isReference() || isLinkableInProject();
58}
59
60void DirDef::addSubDir(DirDef *subdir)
61{
62 m_subdirs.inSort(subdir);
63 subdir->setOuterScope(this);
64 subdir->m_parent=this;
65}
66
67void DirDef::addFile(FileDef *fd)
68{
69 m_fileList->inSort(fd);
70 fd->setDirDef(this);
71}
72
73static QCString encodeDirName(const QCString &anchor)
74{
75 QCString result;
76
77 // convert to md5 hash
78 uchar md5_sig[16];
79 QCString sigStr(33);
80 MD5Buffer((const unsigned char *)anchor.data(),anchor.length(),md5_sig);
81 MD5SigToString(md5_sig,sigStr.data(),33);
82 return sigStr;
83
84 // old algorithm
85
86// int l = anchor.length(),i;
87// for (i=0;i<l;i++)
88// {
89// char c = anchor.at(i);
90// if ((c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9'))
91// {
92// result+=c;
93// }
94// else
95// {
96// static char hexStr[]="0123456789ABCDEF";
97// char escChar[]={ '_', 0, 0, 0 };
98// escChar[1]=hexStr[c>>4];
99// escChar[2]=hexStr[c&0xf];
100// result+=escChar;
101// }
102// }
103// return result;
104}
105
106QCString DirDef::getOutputFileBase() const
107{
108 return "dir_"+encodeDirName(name());
109 //return QCString().sprintf("dir_%06d",m_dirCount);
110}
111
112void DirDef::writeDetailedDescription(OutputList &ol,const QCString &title)
113{
114 if ((!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF")) ||
115 !documentation().isEmpty())
116 {
117 ol.writeRuler();
118 ol.pushGeneratorState();
119 ol.disableAllBut(OutputGenerator::Html);
120 ol.writeAnchor(0,"details");
121 ol.popGeneratorState();
122 ol.startGroupHeader();
123 ol.parseText(title);
124 ol.endGroupHeader();
125
126 // repeat brief description
127 if (!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF"))
128 {
129 ol.parseDoc(briefFile(),briefLine(),this,0,briefDescription(),FALSE,FALSE);
130 }
131 // separator between brief and details
132 if (!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF") &&
133 !documentation().isEmpty())
134 {
135 ol.pushGeneratorState();
136 ol.disable(OutputGenerator::Man);
137 ol.disable(OutputGenerator::RTF);
138 // ol.newParagraph(); // FIXME:PARA
139 ol.enableAll();
140 ol.disableAllBut(OutputGenerator::Man);
141 ol.writeString("\n\n");
142 ol.popGeneratorState();
143 }
144
145 // write documentation
146 if (!documentation().isEmpty())
147 {
148 ol.parseDoc(docFile(),docLine(),this,0,documentation()+"\n",TRUE,FALSE);
149 }
150 }
151}
152
153void DirDef::writeBriefDescription(OutputList &ol)
154{
155 if (!briefDescription().isEmpty())
156 {
157 ol.startParagraph();
158 ol.parseDoc(briefFile(),briefLine(),this,0,briefDescription(),TRUE,FALSE);
159 ol.pushGeneratorState();
160 ol.disable(OutputGenerator::RTF);
161 ol.writeString(" \n");
162 ol.enable(OutputGenerator::RTF);
163
164 if (Config_getBool("REPEAT_BRIEF") ||
165 !documentation().isEmpty()
166 )
167 {
168 ol.disableAllBut(OutputGenerator::Html);
169 ol.startTextLink(0,"details");
170 ol.parseText(theTranslator->trMore());
171 ol.endTextLink();
172 }
173 ol.popGeneratorState();
174
175 //ol.pushGeneratorState();
176 //ol.disable(OutputGenerator::RTF);
177 //ol.newParagraph();
178 //ol.popGeneratorState();
179 ol.endParagraph();
180 }
181 ol.writeSynopsis();
182}
183
184void DirDef::writeDirectoryGraph(OutputList &ol)
185{
186 // write graph dependency graph
187 if (/*Config_getBool("DIRECTORY_GRAPH") &&*/ Config_getBool("HAVE_DOT"))
188 {
189 DotDirDeps dirDep(this);
190 if (!dirDep.isTrivial())
191 {
192 msg("Generating dependency graph for directory %s\n",displayName().data());
193 ol.disable(OutputGenerator::Man);
194 //ol.startParagraph();
195 ol.startDirDepGraph();
196 //TODO: ol.parseText(theTranslator->trDirDepGraph());
197 ol.parseText((QCString)"Directory dependency graph for "+displayName()+":");
198 ol.endDirDepGraph(dirDep);
199 //ol.endParagraph();
200 ol.enableAll();
201 }
202 }
203}
204
205void DirDef::writeSubDirList(OutputList &ol)
206{
207 // write subdir list
208 if (m_subdirs.count()>0)
209 {
210 ol.startMemberHeader("subdirs");
211 ol.parseText(theTranslator->trDir(TRUE,FALSE));
212 ol.endMemberHeader();
213 ol.startMemberList();
214 DirDef *dd=m_subdirs.first();
215 while (dd)
216 {
217 ol.startMemberItem(0);
218 ol.parseText(theTranslator->trDir(FALSE,TRUE)+" ");
219 ol.insertMemberAlign();
220 ol.writeObjectLink(dd->getReference(),dd->getOutputFileBase(),0,dd->shortName());
221 ol.endMemberItem();
222 if (!Config_getString("GENERATE_TAGFILE").isEmpty())
223 {
224 Doxygen::tagFile << " <dir>" << convertToXML(dd->displayName()) << "</dir>" << endl;
225 }
226 if (!dd->briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC"))
227 {
228 ol.startParagraph();
229 ol.startMemberDescription();
230 ol.parseDoc(briefFile(),briefLine(),dd,0,dd->briefDescription(),
231 FALSE, // indexWords
232 FALSE, // isExample
233 0, // exampleName
234 FALSE, // single line
235 TRUE // link from index
236 );
237 ol.endMemberDescription();
238 ol.endParagraph();
239 }
240 dd=m_subdirs.next();
241 }
242
243 ol.endMemberList();
244 }
245}
246
247void DirDef::writeFileList(OutputList &ol)
248{
249 // write file list
250 if (m_fileList->count()>0)
251 {
252 ol.startMemberHeader("files");
253 ol.parseText(theTranslator->trFile(TRUE,FALSE));
254 ol.endMemberHeader();
255 ol.startMemberList();
256 FileDef *fd=m_fileList->first();
257 while (fd)
258 {
259 ol.startMemberItem(0);
260 ol.docify(theTranslator->trFile(FALSE,TRUE)+" ");
261 ol.insertMemberAlign();
262 if (fd->isLinkable())
263 {
264 ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),0,fd->name());
265 }
266 else
267 {
268 ol.startBold();
269 ol.docify(fd->name());
270 ol.endBold();
271 }
272 if (fd->generateSourceFile())
273 {
274 ol.pushGeneratorState();
275 ol.disableAllBut(OutputGenerator::Html);
276 ol.docify(" ");
277 ol.startTextLink(fd->includeName(),0);
278 ol.docify("[");
279 ol.parseText(theTranslator->trCode());
280 ol.docify("]");
281 ol.endTextLink();
282 ol.popGeneratorState();
283 }
284 if (!Config_getString("GENERATE_TAGFILE").isEmpty())
285 {
286 Doxygen::tagFile << " <file>" << convertToXML(fd->name()) << "</file>" << endl;
287 }
288 ol.endMemberItem();
289 if (!fd->briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC"))
290 {
291 ol.startParagraph();
292 ol.startMemberDescription();
293 ol.parseDoc(briefFile(),briefLine(),fd,0,fd->briefDescription(),
294 FALSE, // indexWords
295 FALSE, // isExample
296 0, // exampleName
297 FALSE, // single line
298 TRUE // link from index
299 );
300 ol.endMemberDescription();
301 ol.endParagraph();
302 }
303 fd=m_fileList->next();
304 }
305 ol.endMemberList();
306 }
307}
308
309void DirDef::startMemberDeclarations(OutputList &ol)
310{
311 ol.startMemberSections();
312}
313
314void DirDef::endMemberDeclarations(OutputList &ol)
315{
316 ol.endMemberSections();
317}
318
319void DirDef::writeDocumentation(OutputList &ol)
320{
321 static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
322 ol.pushGeneratorState();
323
324 QCString shortTitle=theTranslator->trDirReference(m_shortName);
325 QCString title=theTranslator->trDirReference(m_dispName);
326 startFile(ol,getOutputFileBase(),name(),title,HLI_None,!generateTreeView);
327
328 if (!generateTreeView)
329 {
330 // write navigation path
331 writeNavigationPath(ol);
332 ol.endQuickIndices();
333 }
334
335 startTitle(ol,getOutputFileBase());
336 ol.pushGeneratorState();
337 ol.disableAllBut(OutputGenerator::Html);
338 ol.parseText(shortTitle);
339 ol.enableAll();
340 ol.disable(OutputGenerator::Html);
341 ol.parseText(title);
342 ol.popGeneratorState();
343 endTitle(ol,getOutputFileBase(),title);
344 ol.startContents();
345
346 if (!Config_getString("GENERATE_TAGFILE").isEmpty())
347 {
348 Doxygen::tagFile << " <compound kind=\"dir\">" << endl;
349 Doxygen::tagFile << " <name>" << convertToXML(displayName()) << "</name>" << endl;
350 Doxygen::tagFile << " <path>" << convertToXML(name()) << "</path>" << endl;
351 Doxygen::tagFile << " <filename>" << convertToXML(getOutputFileBase()) << Doxygen::htmlFileExtension << "</filename>" << endl;
352 }
353
354 //---------------------------------------- start flexible part -------------------------------
355
356 QListIterator<LayoutDocEntry> eli(
357 LayoutDocManager::instance().docEntries(LayoutDocManager::Directory));
358 LayoutDocEntry *lde;
359 for (eli.toFirst();(lde=eli.current());++eli)
360 {
361 switch (lde->kind())
362 {
363 case LayoutDocEntry::BriefDesc:
364 writeBriefDescription(ol);
365 break;
366 case LayoutDocEntry::DirGraph:
367 writeDirectoryGraph(ol);
368 break;
369 case LayoutDocEntry::MemberDeclStart:
370 startMemberDeclarations(ol);
371 break;
372 case LayoutDocEntry::DirSubDirs:
373 writeSubDirList(ol);
374 break;
375 case LayoutDocEntry::DirFiles:
376 writeFileList(ol);
377 break;
378 case LayoutDocEntry::MemberDeclEnd:
379 endMemberDeclarations(ol);
380 break;
381 case LayoutDocEntry::DetailedDesc:
382 {
383 LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
384 writeDetailedDescription(ol,ls->title);
385 }
386 break;
387 case LayoutDocEntry::ClassIncludes:
388 case LayoutDocEntry::ClassInheritanceGraph:
389 case LayoutDocEntry::ClassNestedClasses:
390 case LayoutDocEntry::ClassCollaborationGraph:
391 case LayoutDocEntry::ClassAllMembersLink:
392 case LayoutDocEntry::ClassUsedFiles:
393 case LayoutDocEntry::NamespaceNestedNamespaces:
394 case LayoutDocEntry::NamespaceClasses:
395 case LayoutDocEntry::FileClasses:
396 case LayoutDocEntry::FileNamespaces:
397 case LayoutDocEntry::FileIncludes:
398 case LayoutDocEntry::FileIncludeGraph:
399 case LayoutDocEntry::FileIncludedByGraph:
400 case LayoutDocEntry::FileSourceLink:
401 case LayoutDocEntry::GroupClasses:
402 case LayoutDocEntry::GroupInlineClasses:
403 case LayoutDocEntry::GroupNamespaces:
404 case LayoutDocEntry::GroupDirs:
405 case LayoutDocEntry::GroupNestedGroups:
406 case LayoutDocEntry::GroupFiles:
407 case LayoutDocEntry::GroupGraph:
408 case LayoutDocEntry::GroupPageDocs:
409 case LayoutDocEntry::AuthorSection:
410 case LayoutDocEntry::MemberGroups:
411 case LayoutDocEntry::MemberDecl:
412 case LayoutDocEntry::MemberDef:
413 case LayoutDocEntry::MemberDefStart:
414 case LayoutDocEntry::MemberDefEnd:
415 err("Internal inconsistency: member %d should not be part of "
416 "LayoutDocManager::Directory entry list\n",lde->kind());
417 break;
418 }
419 }
420
421 //---------------------------------------- end flexible part -------------------------------
422
423 if (!Config_getString("GENERATE_TAGFILE").isEmpty())
424 {
425 writeDocAnchorsToTagFile();
426 Doxygen::tagFile << " </compound>" << endl;
427 }
428
429 ol.endContents();
430
431 if (generateTreeView)
432 {
433 writeNavigationPath(ol);
434 }
435
436 endFile(ol,TRUE);
437 ol.popGeneratorState();
438
439
440}
441
442void DirDef::setLevel()
443{
444 if (m_level==-1) // level not set before
445 {
446 DirDef *p = parent();
447 if (p)
448 {
449 p->setLevel();
450 m_level = p->level()+1;
451 }
452 else
453 {
454 m_level = 0;
455 }
456 }
457}
458
459/** Add as "uses" dependency between \a this dir and \a dir,
460 * that was caused by a dependency on file \a fd.
461 */
462void DirDef::addUsesDependency(DirDef *dir,FileDef *srcFd,
463 FileDef *dstFd,bool inherited)
464{
465 if (this==dir) return; // do not add self-dependencies
466 //static int count=0;
467 //printf(" %d add dependency %s->%s due to %s->%s\n",
468 // count++,shortName().data(),
469 // dir->shortName().data(),
470 // srcFd->name().data(),
471 // dstFd->name().data());
472
473 // levels match => add direct dependency
474 bool added=FALSE;
475 UsedDir *usedDir = m_usedDirs->find(dir->getOutputFileBase());
476 if (usedDir) // dir dependency already present
477 {
478 FilePair *usedPair = usedDir->findFilePair(
479 srcFd->getOutputFileBase()+dstFd->getOutputFileBase());
480 if (usedPair==0) // new file dependency
481 {
482 //printf(" => new file\n");
483 usedDir->addFileDep(srcFd,dstFd);
484 added=TRUE;
485 }
486 else
487 {
488 // dir & file dependency already added
489 }
490 }
491 else // new directory dependency
492 {
493 //printf(" => new file\n");
494 usedDir = new UsedDir(dir,inherited);
495 usedDir->addFileDep(srcFd,dstFd);
496 m_usedDirs->insert(dir->getOutputFileBase(),usedDir);
497 added=TRUE;
498 }
499 if (added)
500 {
501 if (dir->parent())
502 {
503 // add relation to parent of used dir
504 addUsesDependency(dir->parent(),srcFd,dstFd,inherited);
505 }
506 if (parent())
507 {
508 // add relation for the parent of this dir as well
509 parent()->addUsesDependency(dir,srcFd,dstFd,TRUE);
510 }
511 }
512}
513
514/** Computes the dependencies between directories
515 */
516void DirDef::computeDependencies()
517{
518 FileList *fl = m_fileList;
519 if (fl)
520 {
521 QListIterator<FileDef> fli(*fl);
522 FileDef *fd;
523 for (fli.toFirst();(fd=fli.current());++fli) // foreach file in dir dd
524 {
525 //printf(" File %s\n",fd->name().data());
526 //printf("** dir=%s file=%s\n",shortName().data(),fd->name().data());
527 QList<IncludeInfo> *ifl = fd->includeFileList();
528 if (ifl)
529 {
530 QListIterator<IncludeInfo> ifli(*ifl);
531 IncludeInfo *ii;
532 for (ifli.toFirst();(ii=ifli.current());++ifli) // foreach include file
533 {
534 //printf(" > %s\n",ii->includeName.data());
535 //printf(" #include %s\n",ii->includeName.data());
536 if (ii->fileDef && ii->fileDef->isLinkable()) // linkable file
537 {
538 DirDef *usedDir = ii->fileDef->getDirDef();
539 if (usedDir)
540 {
541 // add dependency: thisDir->usedDir
542 //static int count=0;
543 //printf(" %d: add dependency %s->%s\n",count++,name().data(),usedDir->name().data());
544 addUsesDependency(usedDir,fd,ii->fileDef,FALSE);
545 }
546 }
547 }
548 }
549 }
550 }
551}
552
553bool DirDef::isParentOf(DirDef *dir) const
554{
555 if (dir->parent()==this) // this is a parent of dir
556 return TRUE;
557 else if (dir->parent()) // repeat for the parent of dir
558 return isParentOf(dir->parent());
559 else
560 return FALSE;
561}
562
563bool DirDef::depGraphIsTrivial() const
564{
565 return FALSE;
566}
567
568//----------------------------------------------------------------------
569
570int FilePairDict::compareItems(GCI item1,GCI item2)
571{
572 FilePair *left = (FilePair*)item1;
573 FilePair *right = (FilePair*)item2;
574 int orderHi = stricmp(left->source()->name(),right->source()->name());
575 int orderLo = stricmp(left->destination()->name(),right->destination()->name());
576 return orderHi==0 ? orderLo : orderHi;
577}
578
579//----------------------------------------------------------------------
580
581UsedDir::UsedDir(DirDef *dir,bool inherited) :
582 m_dir(dir), m_filePairs(7), m_inherited(inherited)
583{
584 m_filePairs.setAutoDelete(TRUE);
585}
586
587UsedDir::~UsedDir()
588{
589}
590
591
592void UsedDir::addFileDep(FileDef *srcFd,FileDef *dstFd)
593{
594 m_filePairs.inSort(srcFd->getOutputFileBase()+dstFd->getOutputFileBase(),
595 new FilePair(srcFd,dstFd));
596}
597
598FilePair *UsedDir::findFilePair(const char *name)
599{
600 QCString n=name;
601 return n.isEmpty() ? 0 : m_filePairs.find(n);
602}
603
604DirDef *DirDef::createNewDir(const char *path)
605{
606 ASSERT(path!=0);
607 DirDef *dir = Doxygen::directories->find(path);
608 if (dir==0) // new dir
609 {
610 //printf("Adding new dir %s\n",path);
611 dir = new DirDef(path);
612 //printf("createNewDir %s short=%s\n",path,dir->shortName().data());
613 Doxygen::directories->inSort(path,dir);
614 }
615 return dir;
616}
617
618bool DirDef::matchPath(const QCString &path,QStrList &l)
619{
620 const char *s=l.first();
621 while (s)
622 {
623 QCString prefix = s;
624 if (stricmp(prefix.left(path.length()),path)==0) // case insensitive compare
625 {
626 return TRUE;
627 }
628 s = l.next();
629 }
630 return FALSE;
631}
632
633/*! strip part of \a path if it matches
634 * one of the paths in the Config_getList("STRIP_FROM_PATH") list
635 */
636DirDef *DirDef::mergeDirectoryInTree(const QCString &path)
637{
638 //printf("DirDef::mergeDirectoryInTree(%s)\n",path.data());
639 int p=0,i=0;
640 DirDef *dir=0;
641 while ((i=path.find('/',p))!=-1)
642 {
643 QCString part=path.left(i+1);
644 if (!matchPath(part,Config_getList("STRIP_FROM_PATH")) && part!="/")
645 {
646 dir=createNewDir(part);
647 }
648 p=i+1;
649 }
650 return dir;
651}
652
653void DirDef::writeDepGraph(FTextStream &t)
654{
655 writeDotDirDepGraph(t,this);
656}
657
658//----------------------------------------------------------------------
659
660static void writePartialDirPath(OutputList &ol,const DirDef *root,const DirDef *target)
661{
662 if (target->parent()!=root)
663 {
664 writePartialDirPath(ol,root,target->parent());
665 ol.writeString("&#160;/&#160;");
666 }
667 ol.writeObjectLink(target->getReference(),target->getOutputFileBase(),0,target->shortName());
668}
669
670static void writePartialFilePath(OutputList &ol,const DirDef *root,const FileDef *fd)
671{
672 if (fd->getDirDef() && fd->getDirDef()!=root)
673 {
674 writePartialDirPath(ol,root,fd->getDirDef());
675 ol.writeString("&#160;/&#160;");
676 }
677 if (fd->isLinkable())
678 {
679 ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),0,fd->name());
680 }
681 else
682 {
683 ol.startBold();
684 ol.docify(fd->name());
685 ol.endBold();
686 }
687}
688
689void DirRelation::writeDocumentation(OutputList &ol)
690{
691 static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
692 ol.pushGeneratorState();
693 ol.disableAllBut(OutputGenerator::Html);
694
695 QCString shortTitle=theTranslator->trDirRelation(
696 m_src->shortName()+" &rarr; "+
697 m_dst->dir()->shortName());
698 QCString title=theTranslator->trDirRelation(
699 m_src->displayName()+" -> "+
700 m_dst->dir()->shortName());
701 startFile(ol,getOutputFileBase(),getOutputFileBase(),
702 title,HLI_None,!generateTreeView,m_src->getOutputFileBase());
703
704 if (!generateTreeView)
705 {
706 // write navigation path
707 m_src->writeNavigationPath(ol);
708 ol.endQuickIndices();
709 }
710 ol.startContents();
711
712 ol.writeString("<h3>"+shortTitle+"</h3>");
713 ol.writeString("<table class=\"dirtab\">");
714 ol.writeString("<tr class=\"dirtab\">");
715 ol.writeString("<th class=\"dirtab\">");
716 ol.parseText(theTranslator->trFileIn(m_src->pathFragment()));
717 ol.writeString("</th>");
718 ol.writeString("<th class=\"dirtab\">");
719 ol.parseText(theTranslator->trIncludesFileIn(m_dst->dir()->pathFragment()));
720 ol.writeString("</th>");
721 ol.writeString("</tr>");
722
723 SDict<FilePair>::Iterator fpi(m_dst->filePairs());
724 FilePair *fp;
725 for (fpi.toFirst();(fp=fpi.current());++fpi)
726 {
727 ol.writeString("<tr class=\"dirtab\">");
728 ol.writeString("<td class=\"dirtab\">");
729 writePartialFilePath(ol,m_src,fp->source());
730 ol.writeString("</td>");
731 ol.writeString("<td class=\"dirtab\">");
732 writePartialFilePath(ol,m_dst->dir(),fp->destination());
733 ol.writeString("</td>");
734 ol.writeString("</tr>");
735 }
736 ol.writeString("</table>");
737
738 ol.endContents();
739
740 if (generateTreeView)
741 {
742 m_src->writeNavigationPath(ol);
743 }
744
745 endFile(ol,TRUE);
746 ol.popGeneratorState();
747}
748
749//----------------------------------------------------------------------
750// external functions
751
752void buildDirectories()
753{
754 // for each input file
755 FileNameListIterator fnli(*Doxygen::inputNameList);
756 FileName *fn;
757 for (fnli.toFirst();(fn=fnli.current());++fnli)
758 {
759 FileNameIterator fni(*fn);
760 FileDef *fd;
761 for (;(fd=fni.current());++fni)
762 {
763 //printf("buildDirectories %s\n",fd->name().data());
764 if (fd->getReference().isEmpty() && !fd->isDocumentationFile())
765 {
766 DirDef *dir;
767 if ((dir=Doxygen::directories->find(fd->getPath()))==0) // new directory
768 {
769 dir = DirDef::mergeDirectoryInTree(fd->getPath());
770 }
771 if (dir) dir->addFile(fd);
772 }
773 else
774 {
775 // do something for file imported via tag files.
776 }
777 }
778 }
779
780 //DirDef *root = new DirDef("root:");
781 // compute relations between directories => introduce container dirs.
782 DirDef *dir;
783 DirSDict::Iterator sdi(*Doxygen::directories);
784 for (sdi.toFirst();(dir=sdi.current());++sdi)
785 {
786 //printf("New dir %s\n",dir->displayName().data());
787 QCString name = dir->name();
788 int i=name.findRev('/',name.length()-2);
789 if (i>0)
790 {
791 DirDef *parent = Doxygen::directories->find(name.left(i+1));
792 //if (parent==0) parent=root;
793 if (parent)
794 {
795 parent->addSubDir(dir);
796 //printf("DirDef::addSubdir(): Adding subdir\n%s to\n%s\n",
797 // dir->displayName().data(), parent->displayName().data());
798 }
799 }
800 }
801}
802
803void computeDirDependencies()
804{
805 DirDef *dir;
806 DirSDict::Iterator sdi(*Doxygen::directories);
807 // compute nesting level for each directory
808 for (sdi.toFirst();(dir=sdi.current());++sdi)
809 {
810 dir->setLevel();
811 }
812 // compute uses dependencies between directories
813 for (sdi.toFirst();(dir=sdi.current());++sdi)
814 {
815 //printf("computeDependencies for %s: #dirs=%d\n",dir->name().data(),Doxygen::directories.count());
816 dir->computeDependencies();
817 }
818
819#if 0
820 printf("-------------------------------------------------------------\n");
821 // print dependencies (for debugging)
822 for (sdi.toFirst();(dir=sdi.current());++sdi)
823 {
824 if (dir->usedDirs())
825 {
826 QDictIterator<UsedDir> udi(*dir->usedDirs());
827 UsedDir *usedDir;
828 for (udi.toFirst();(usedDir=udi.current());++udi)
829 {
830 printf("%s depends on %s due to ",
831 dir->shortName().data(),usedDir->dir()->shortName().data());
832 QDictIterator<FileDef> fdi(usedDir->files());
833 FileDef *fd;
834 for (fdi.toFirst();(fd=fdi.current());++fdi)
835 {
836 printf("%s ",fd->name().data());
837 }
838 printf("\n");
839 }
840 }
841 }
842 printf("^-^-^-^-^-^-^-^-^-^-^-^-^-^-^-^-^-^-^-^-^-^-^-^-^-^-^-^-^-^-^\n");
843#endif
844}
845
846#if 0
847void writeDirDependencyGraph(const char *dirName)
848{
849 QString path;
850 DirDef *dir;
851 DirSDict::Iterator sdi(*Doxygen::directories);
852 QFile htmlPage(QCString(dirName)+"/dirdeps.html");
853 if (htmlPage.open(IO_WriteOnly))
854 {
855 QTextStream out(&htmlPage);
856 out << "<html><body>";
857 for (sdi.toFirst();(dir=sdi.current());++sdi)
858 {
859 path=dirName;
860 path+="/";
861 path+=dir->getOutputFileBase();
862 path+="_dep.dot";
863 out << "<h4>" << dir->displayName() << "</h4>" << endl;
864 out << "<img src=\"" << dir->getOutputFileBase() << "_dep.gif\">" << endl;
865 QFile f(path);
866 if (f.open(IO_WriteOnly))
867 {
868 QTextStream t(&f);
869 dir->writeDepGraph(t);
870 }
871 f.close();
872
873 QCString imgExt = Config_getEnum("DOT_IMAGE_FORMAT");
874 QCString outFile = QCString(dirName)+"/"+
875 dir->getOutputFileBase()+"_dep."+imgExt;
876 DotRunner dotRun(path);
877 dotRun.addJob(imgExt,outFile);
878 dotRun.run();
879
880 //QCString dotArgs(4096);
881 //dotArgs.sprintf("%s -Tgif -o %s",path.data(),outFile.data());
882 //if (portable_system(Config_getString("DOT_PATH")+"dot",dotArgs,FALSE)!=0)
883 //{
884 // err("Problems running dot. Check your installation!\n");
885 //}
886 }
887 out << "</body></html>";
888 }
889 htmlPage.close();
890}
891#endif
892
893void generateDirDocs(OutputList &ol)
894{
895 DirDef *dir;
896 DirSDict::Iterator sdi(*Doxygen::directories);
897 for (sdi.toFirst();(dir=sdi.current());++sdi)
898 {
899 dir->writeDocumentation(ol);
900 }
901 if (Config_getBool("DIRECTORY_GRAPH"))
902 {
903 SDict<DirRelation>::Iterator rdi(Doxygen::dirRelations);
904 DirRelation *dr;
905 for (rdi.toFirst();(dr=rdi.current());++rdi)
906 {
907 dr->writeDocumentation(ol);
908 }
909 }
910}
911
912

Archive Download this file

Revision: 1322