Doxygen
Loading...
Searching...
No Matches
dirdef.cpp
Go to the documentation of this file.
1/******************************************************************************
2 *
3 * Copyright (C) 1997-2020 by Dimitri van Heesch.
4 *
5 * Permission to use, copy, modify, and distribute this software and its
6 * documentation under the terms of the GNU General Public License is hereby
7 * granted. No representations are made about the suitability of this software
8 * for any purpose. It is provided "as is" without express or implied warranty.
9 * See the GNU General Public License for more details.
10 *
11 * Documents produced by Doxygen are derivative works derived from the
12 * input used in their production; they are not affected by this license.
13 *
14 */
15
16#include <algorithm>
17
18#include "dirdef.h"
19#include "md5.h"
20#include "filename.h"
21#include "doxygen.h"
22#include "util.h"
23#include "outputlist.h"
24#include "language.h"
25#include "message.h"
26#include "dot.h"
27#include "dotdirdeps.h"
28#include "layout.h"
29#include "config.h"
30#include "docparser.h"
31#include "definitionimpl.h"
32#include "filedef.h"
33#include "trace.h"
34
35//----------------------------------------------------------------------
36
37class DirDefImpl : public DefinitionMixin<DirDef>
38{
39 public:
40 DirDefImpl(const QCString &path);
41 ~DirDefImpl() override;
43
44 DefType definitionType() const override { return TypeDir; }
46 QCString getOutputFileBase() const override;
47 QCString anchor() const override { return QCString(); }
48 bool isLinkableInProject() const override;
49 bool isLinkable() const override;
50 QCString displayName(bool=TRUE) const override { return m_dispName; }
51 const QCString shortName() const override { return m_shortName; }
52 void addSubDir(DirDef *subdir) override;
53 const FileList &getFiles() const override { return m_fileList; }
54 void addFile(FileDef *fd) override;
55 const DirList &subDirs() const override { return m_subdirs; }
56 bool hasSubdirs() const override { return !m_subdirs.empty(); }
57 int level() const override { return m_level; }
58 DirDef *parent() const override { return m_parent; }
59 int dirIndex() const override { return m_dirIndex; }
60 const UsedDirLinkedMap &usedDirs() const override { return m_usedDirs; }
61 bool isParentOf(const DirDef *dir) const override;
62 bool depGraphIsTrivial() const override;
63 QCString shortTitle() const override;
64 bool hasDetailedDescription() const override;
65 void writeDocumentation(OutputList &ol) override;
66 void writePageNavigation(OutputList &ol) const override;
67 void writeTagFile(TextStream &t) override;
68 void setDiskName(const QCString &name) override { m_diskName = name; }
69 void sort() override;
70 void setParent(DirDef *parent) override;
71 void setDirIndex(int index) override;
72 void setLevel() override;
73 void addUsesDependency(const DirDef *usedDir,const FileDef *srcFd,
74 const FileDef *dstFd,bool srcDirect, bool dstDirect) override;
75 void computeDependencies() override;
76 void findSectionsInDocumentation() override;
77
78 bool hasDirectoryGraph() const override;
79 void overrideDirectoryGraph(bool e) override;
80
81 public:
82 static DirDef *mergeDirectoryInTree(const QCString &path);
83
84 private:
85
86 void writeDetailedDescription(OutputList &ol,const QCString &title);
90 void writeFileList(OutputList &ol);
93
94 static DirDef *createNewDir(const QCString &path);
95 static bool matchPath(const QCString &path,const StringVector &l);
96
101 FileList m_fileList; // list of files in the group
102 int m_dirIndex = -1;
107};
108
110{
111 return new DirDefImpl(path);
112}
113
114
115//----------------------------------------------------------------------
116// method implementation
117
119{
120 bool fullPathNames = Config_getBool(FULL_PATH_NAMES);
121 // get display name (stripping the paths mentioned in STRIP_FROM_PATH)
122 // get short name (last part of path)
123 m_shortName = path;
124 m_diskName = path;
125 if (m_shortName.at(m_shortName.length()-1)=='/')
126 { // strip trailing /
127 m_shortName = m_shortName.left(m_shortName.length()-1);
128 }
129 int pi=m_shortName.findRev('/');
130 if (pi!=-1)
131 { // remove everything till the last /
132 m_shortName = m_shortName.mid(pi+1);
133 }
135 m_dispName = fullPathNames ? stripFromPath(path) : m_shortName;
136 if (m_dispName.length()>0 && m_dispName.at(m_dispName.length()-1)=='/')
137 { // strip trailing /
138 m_dispName = m_dispName.left(m_dispName.length()-1);
139 }
140
141 m_level=-1;
142 m_parent=nullptr;
143 m_hasDirectoryGraph=Config_getBool(DIRECTORY_GRAPH);
144
145}
146
150
152{
153 return !isReference() && hasDocumentation();
154}
155
157{
158 return isReference() || isLinkableInProject();
159}
160
162{
163 m_subdirs.push_back(subdir);
164 subdir->setOuterScope(this);
165 subdir->setParent(this);
166}
167
169{
170 m_parent=p;
171}
172
174{
175 m_dirIndex=index;
176}
177
179{
180 m_fileList.push_back(fd);
181 fd->setDirDef(this);
182}
183
185{
186 std::stable_sort(m_subdirs.begin(), m_subdirs.end(), compareDirDefs);
187 std::stable_sort(m_fileList.begin(), m_fileList.end(), compareFileDefs);
188}
189
190static QCString encodeDirName(const QCString &anchor)
191{
192 AUTO_TRACE();
193 // convert to md5 hash
194 uint8_t md5_sig[16];
195 char sigStr[33];
196 MD5Buffer(anchor.data(),static_cast<unsigned int>(anchor.length()),md5_sig);
197 MD5SigToString(md5_sig,sigStr);
198 AUTO_TRACE_EXIT("result={}",sigStr);
199 return sigStr;
200
201 // old algorithm
202// QCString result;
203
204// int l = anchor.length(),i;
205// for (i=0;i<l;i++)
206// {
207// char c = anchor.at(i);
208// if ((c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9'))
209// {
210// result+=c;
211// }
212// else
213// {
214// static char hexStr[]="0123456789ABCDEF";
215// char escChar[]={ '_', 0, 0, 0 };
216// escChar[1]=hexStr[c>>4];
217// escChar[2]=hexStr[c&0xf];
218// result+=escChar;
219// }
220// }
221// return result;
222}
223
225{
226 QCString dir = "dir_"+encodeDirName(m_diskName);
227 AUTO_TRACE("diskName={} result={}",m_diskName,dir);
228 return dir;
229}
230
232{
233 AUTO_TRACE();
234 if ((!briefDescription().isEmpty() && Config_getBool(REPEAT_BRIEF)) ||
235 !documentation().isEmpty())
236 {
239 ol.writeRuler();
243 ol.writeAnchor(QCString(),"details");
245 ol.startGroupHeader("details");
246 ol.parseText(title);
247 ol.endGroupHeader();
248
249 // repeat brief description
250 if (!briefDescription().isEmpty() && Config_getBool(REPEAT_BRIEF))
251 {
253 briefLine(),
254 this,
255 nullptr,
257 DocOptions());
258 }
259 // separator between brief and details
260 if (!briefDescription().isEmpty() && Config_getBool(REPEAT_BRIEF) &&
261 !documentation().isEmpty())
262 {
266 ol.enableAll();
269 ol.writeString("\n\n");
271 }
272
273 // write documentation
274 if (!documentation().isEmpty())
275 {
276 ol.generateDoc(docFile(),
277 docLine(),
278 this,
279 nullptr,
280 documentation()+"\n",
281 DocOptions()
282 .setIndexWords(true));
283 }
284 }
285}
286
288{
289 AUTO_TRACE();
291 {
292 auto parser { createDocParser() };
293 auto ast { validatingParseDoc(*parser.get(),
294 briefFile(),
295 briefLine(),
296 this,
297 nullptr,
299 DocOptions()
300 .setIndexWords(true))
301 };
302 if (!ast->isEmpty())
303 {
304 ol.startParagraph();
307 ol.writeString(" - ");
309 ol.writeDoc(ast.get(),this,nullptr);
312 ol.writeString(" \n");
314
315 if (Config_getBool(REPEAT_BRIEF) ||
316 !documentation().isEmpty()
317 )
318 {
320 ol.startTextLink(QCString(),"details");
321 ol.parseText(theTranslator->trMore());
322 ol.endTextLink();
323 }
325
326 ol.endParagraph();
327 }
328 }
329 ol.writeSynopsis();
330}
331
336
338{
339 // write graph dependency graph
340 if (Config_getBool(HAVE_DOT) && m_hasDirectoryGraph /*&& Config_getBool(DIRECTORY_GRAPH)*/)
341 {
342 DotDirDeps dirDep(this);
343 if (!dirDep.isTrivial())
344 {
345 msg("Generating dependency graph for directory {}\n",displayName());
347 //ol.startParagraph();
348 ol.startDirDepGraph();
349 ol.parseText(theTranslator->trDirDepGraph(shortName()));
350 ol.endDirDepGraph(dirDep);
351 //ol.endParagraph();
352 ol.enableAll();
353 }
354 }
355}
356
358{
359 AUTO_TRACE();
360 int numSubdirs = 0;
361 for(const auto dd : m_subdirs)
362 {
363 if (dd->hasDocumentation() || !dd->getFiles().empty())
364 {
365 numSubdirs++;
366 }
367 }
368
369 AUTO_TRACE_ADD("numSubdirs={}",numSubdirs);
370 // write subdir list
371 if (numSubdirs>0)
372 {
373 ol.startMemberHeader("subdirs");
374 ol.parseText(theTranslator->trDir(TRUE,FALSE));
375 ol.endMemberHeader();
376 ol.startMemberList();
377 for(const auto dd : m_subdirs)
378 {
379 if (dd->hasDocumentation() || !dd->getFiles().empty())
380 {
382 QCString anc=dd->anchor();
383 if (anc.isEmpty()) anc=dd->shortName(); else anc.prepend(dd->shortName()+"_");
385 {
388 ol.writeString("<span class=\"iconfolder\"><div class=\"folder-icon\"></div></span>");
389 ol.enableAll();
391 ol.parseText(theTranslator->trDir(FALSE,TRUE)+" ");
393 }
395 ol.writeObjectLink(dd->getReference(),dd->getOutputFileBase(),QCString(),dd->shortName());
397 if (!dd->briefDescription().isEmpty() && Config_getBool(BRIEF_MEMBER_DESC))
398 {
399 ol.startMemberDescription(dd->getOutputFileBase());
401 briefLine(),
402 dd,
403 nullptr,
404 dd->briefDescription(),
405 DocOptions()
406 .setSingleLine(true)
407 .setLinkFromIndex(true));
409 }
410 ol.endMemberDeclaration(dd->anchor(),QCString());
411 }
412 }
413
414 ol.endMemberList();
415 }
416}
417
419{
420 AUTO_TRACE();
421 int numFiles = 0;
422 for (const auto &fd : m_fileList)
423 {
424 bool genSourceFile=false;
425 if (fileVisibleInIndex(fd,genSourceFile))
426 {
427 numFiles++;
428 }
429 else if (genSourceFile)
430 {
431 numFiles++;
432 }
433 }
434
435 AUTO_TRACE_ADD("numFiles={}",numFiles);
436 // write file list
437 if (numFiles>0)
438 {
439 ol.startMemberHeader("files");
440 ol.parseText(theTranslator->trFile(TRUE,FALSE));
441 ol.endMemberHeader();
442 ol.startMemberList();
443 for (const auto &fd : m_fileList)
444 {
445 bool src = false;
446 bool doc = fileVisibleInIndex(fd,src);
447 if (doc || src)
448 {
450 QCString anc = fd->anchor();
451 if (anc.isEmpty()) anc=fd->displayName(); else anc.prepend(fd->displayName()+"_");
453 {
456 bool genSrc = fd->generateSourceFile();
457 if (genSrc)
458 {
459 ol.startTextLink(fd->includeName(),QCString());
460 }
461 ol.writeString("<span class=\"icondoc\"><div class=\"doc-icon\"></div></span>");
462 if (genSrc)
463 {
464 ol.endTextLink();
465 }
466 ol.enableAll();
468 ol.docify(theTranslator->trFile(FALSE,TRUE)+" ");
470 }
472 if (fd->isLinkable())
473 {
474 ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),QCString(),fd->displayName());
475 }
476 else
477 {
478 ol.startBold();
479 ol.docify(fd->displayName());
480 ol.endBold();
481 }
483 if (!fd->briefDescription().isEmpty() && Config_getBool(BRIEF_MEMBER_DESC))
484 {
485 ol.startMemberDescription(fd->getOutputFileBase());
487 briefLine(),
488 fd,
489 nullptr,
490 fd->briefDescription(),
491 DocOptions()
492 .setSingleLine(true)
493 .setLinkFromIndex(true));
495 }
496 ol.endMemberDeclaration(fd->anchor(),QCString());
497 }
498 }
499 ol.endMemberList();
500 }
501}
502
507
512
514{
515 if (Config_getBool(HIDE_COMPOUND_REFERENCE))
516 {
517 return m_shortName;
518 }
519 else
520 {
521 return theTranslator->trDirReference(m_shortName);
522 }
523}
524
526{
527 bool repeatBrief = Config_getBool(REPEAT_BRIEF);
528 return (!briefDescription().isEmpty() && repeatBrief) || !documentation().isEmpty();
529}
530
532{
533 tagFile << " <compound kind=\"dir\">\n";
534 tagFile << " <name>" << convertToXML(displayName()) << "</name>\n";
535 tagFile << " <path>" << convertToXML(stripFromPath(name())) << "</path>\n";
538 tagFile << " <filename>" << fn << "</filename>\n";
539 for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::Directory))
540 {
541 switch (lde->kind())
542 {
543 case LayoutDocEntry::DirSubDirs:
544 {
545 if (m_subdirs.size()>0)
546 {
547 for(const auto dd : m_subdirs)
548 {
549 tagFile << " <dir>" << convertToXML(dd->displayName()) << "</dir>\n";
550 }
551 }
552 }
553 break;
554 case LayoutDocEntry::DirFiles:
555 {
556 for (const auto &fd : m_fileList)
557 {
558 tagFile << " <file>" << convertToXML(fd->name()) << "</file>\n";
559 }
560 }
561 break;
562 default:
563 break;
564 }
565 }
567 tagFile << " </compound>\n";
568}
569
571{
572 bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
574
575 QCString title;
576 if (Config_getBool(HIDE_COMPOUND_REFERENCE))
577 {
578 title=m_dispName;
579 }
580 else
581 {
582 title=theTranslator->trDirReference(m_dispName);
583 }
584 AUTO_TRACE("title={}",title);
585 startFile(ol,getOutputFileBase(),false,name(),title,HighlightedItem::Files,!generateTreeView);
586
587 if (!generateTreeView)
588 {
589 // write navigation path
591 ol.endQuickIndices();
592 }
593
597 ol.parseText(shortTitle());
598 ol.enableAll();
600 ol.parseText(title);
602 endTitle(ol,getOutputFileBase(),title);
603 ol.startContents();
604
605 //---------------------------------------- start flexible part -------------------------------
606
607 SrcLangExt lang = getLanguage();
608 for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::Directory))
609 {
610 switch (lde->kind())
611 {
612 case LayoutDocEntry::BriefDesc:
614 break;
615 case LayoutDocEntry::DirGraph:
617 break;
618 case LayoutDocEntry::MemberDeclStart:
620 break;
621 case LayoutDocEntry::DirSubDirs:
622 writeSubDirList(ol);
623 break;
624 case LayoutDocEntry::DirFiles:
625 writeFileList(ol);
626 break;
627 case LayoutDocEntry::MemberDeclEnd:
629 break;
630 case LayoutDocEntry::DetailedDesc:
631 {
632 const LayoutDocEntrySection *ls = dynamic_cast<const LayoutDocEntrySection*>(lde.get());
633 if (ls)
634 {
635 writeDetailedDescription(ol,ls->title(lang));
636 }
637 }
638 break;
639 case LayoutDocEntry::ClassIncludes:
640 case LayoutDocEntry::ClassInlineClasses:
641 case LayoutDocEntry::ClassInheritanceGraph:
642 case LayoutDocEntry::ClassNestedClasses:
643 case LayoutDocEntry::ClassCollaborationGraph:
644 case LayoutDocEntry::ClassAllMembersLink:
645 case LayoutDocEntry::ClassUsedFiles:
646 case LayoutDocEntry::NamespaceNestedNamespaces:
647 case LayoutDocEntry::NamespaceNestedConstantGroups:
648 case LayoutDocEntry::NamespaceClasses:
649 case LayoutDocEntry::NamespaceConcepts:
650 case LayoutDocEntry::NamespaceInterfaces:
651 case LayoutDocEntry::NamespaceStructs:
652 case LayoutDocEntry::NamespaceExceptions:
653 case LayoutDocEntry::NamespaceInlineClasses:
654 case LayoutDocEntry::ConceptDefinition:
655 case LayoutDocEntry::FileClasses:
656 case LayoutDocEntry::FileConcepts:
657 case LayoutDocEntry::FileInterfaces:
658 case LayoutDocEntry::FileStructs:
659 case LayoutDocEntry::FileExceptions:
660 case LayoutDocEntry::FileNamespaces:
661 case LayoutDocEntry::FileConstantGroups:
662 case LayoutDocEntry::FileIncludes:
663 case LayoutDocEntry::FileIncludeGraph:
664 case LayoutDocEntry::FileIncludedByGraph:
665 case LayoutDocEntry::FileSourceLink:
666 case LayoutDocEntry::FileInlineClasses:
667 case LayoutDocEntry::GroupClasses:
668 case LayoutDocEntry::GroupConcepts:
669 case LayoutDocEntry::GroupModules:
670 case LayoutDocEntry::GroupInlineClasses:
671 case LayoutDocEntry::GroupNamespaces:
672 case LayoutDocEntry::GroupDirs:
673 case LayoutDocEntry::GroupNestedGroups:
674 case LayoutDocEntry::GroupFiles:
675 case LayoutDocEntry::GroupGraph:
676 case LayoutDocEntry::GroupPageDocs:
677 case LayoutDocEntry::ModuleExports:
678 case LayoutDocEntry::ModuleClasses:
679 case LayoutDocEntry::ModuleConcepts:
680 case LayoutDocEntry::ModuleUsedFiles:
681 case LayoutDocEntry::AuthorSection:
682 case LayoutDocEntry::MemberGroups:
683 case LayoutDocEntry::MemberDecl:
684 case LayoutDocEntry::MemberDef:
685 case LayoutDocEntry::MemberDefStart:
686 case LayoutDocEntry::MemberDefEnd:
687 err("Internal inconsistency: member '{}' should not be part of "
688 "LayoutDocManager::Directory entry list\n",qPrint(lde->entryToString()));
689 break;
690 }
691 }
692
693 //---------------------------------------- end flexible part -------------------------------
694
695 ol.endContents();
696
697 endFileWithNavPath(ol,this);
698
700}
701
703{
704 if (m_level==-1) // level not set before
705 {
706 DirDef *p = parent();
707 if (p)
708 {
709 p->setLevel();
710 m_level = p->level()+1;
711 }
712 else
713 {
714 m_level = 0;
715 }
716 }
717}
718
719/** Add as "uses" dependency between \a this dir and \a dir,
720 * that was caused by a dependency on file \a fd.
721 * srcDirect and dstDirect indicate if it is a direct dependencies (true) or if
722 * the dependencies was indirect (e.g. a parent dir that has a child dir that has the dependencies)
723 */
724void DirDefImpl::addUsesDependency(const DirDef *dir,const FileDef *srcFd,
725 const FileDef *dstFd,bool srcDirect, bool dstDirect)
726{
727 if (this==dir) return; // do not add self-dependencies
728 AUTO_TRACE("add dependency {}->{} due to {}->{}",
729 qPrint(shortName()),
730 qPrint(dir->shortName()),
731 qPrint(srcFd->name()),
732 qPrint(dstFd->name()));
733
734 // levels match => add direct dependency
735 bool added=FALSE;
736 UsedDir *usedDir = m_usedDirs.find(dir->getOutputFileBase());
737 if (usedDir) // dir dependency already present
738 {
739 const FilePair *usedPair = usedDir->findFilePair(FilePair::key(srcFd,dstFd));
740 if (usedPair==nullptr) // new file dependency
741 {
742 AUTO_TRACE_ADD("{} => {} new file dependency",srcFd->name(),dstFd->name());
743 usedDir->addFileDep(srcFd,dstFd, srcDirect, dstDirect);
744 added=TRUE;
745 }
746 else
747 {
748 // dir & file dependency already added
749 }
750 }
751 else // new directory dependency
752 {
753 AUTO_TRACE_ADD("{} => {} new file dependency",srcFd->name(),dstFd->name());
754 auto newUsedDir = std::make_unique<UsedDir>(dir);
755 newUsedDir->addFileDep(srcFd,dstFd, srcDirect, dstDirect);
756 m_usedDirs.add(dir->getOutputFileBase(),std::move(newUsedDir));
757 added=TRUE;
758 }
759 if (added)
760 {
761 if (dir->parent())
762 {
763 // add relation to parent of used dir
765 srcFd,
766 dstFd,
767 srcDirect,
768 false); // indirect dependency on dest dir
769 }
770 if (parent())
771 {
772 // add relation for the parent of this dir as well
774 srcFd,
775 dstFd,
776 false, // indirect dependency from source dir
777 dstDirect);
778 }
779 }
780}
781
787
788/** Computes the dependencies between directories
789 */
791{
792 AUTO_TRACE();
793 for (const auto &fd : m_fileList)
794 {
795 AUTO_TRACE_ADD("dir={} file={}",shortName(),fd->name());
796 for (const auto &ii : fd->includeFileList())
797 {
798 AUTO_TRACE_ADD("#include {}",ii.includeName);
799 if (ii.fileDef && ii.fileDef->isLinkable()) // linkable file
800 {
801 DirDef *usedDir = ii.fileDef->getDirDef();
802 if (usedDir)
803 {
804 // add dependency: thisDir->usedDir
805 AUTO_TRACE_ADD("add dependency {}->{}",name(),usedDir->name());
806 addUsesDependency(usedDir,fd,ii.fileDef,true,true);
807 }
808 }
809 }
810 }
811
812 std::stable_sort(m_usedDirs.begin(),m_usedDirs.end(),
813 [](const auto &u1,const auto &u2)
814 { return qstricmp_sort(u1->dir()->getOutputFileBase(),u2->dir()->getOutputFileBase())<0; });
815
816 for (const auto& usedDirectory : m_usedDirs)
817 {
818 usedDirectory->sort();
819 }
820}
821
822bool DirDefImpl::isParentOf(const DirDef *dir) const
823{
824 if (dir->parent()==this) // this is a parent of dir
825 return TRUE;
826 else if (dir->parent()) // repeat for the parent of dir
827 return isParentOf(dir->parent());
828 else
829 return FALSE;
830}
831
833{
834 return m_usedDirs.empty() && m_parent==nullptr;
835}
836
837//----------------------------------------------------------------------
838
840 m_dir(dir)
841{
842}
843
844void UsedDir::addFileDep(const FileDef *srcFd,const FileDef *dstFd, bool srcDirect, bool dstDirect)
845{
846 m_filePairs.add(FilePair::key(srcFd,dstFd),std::make_unique<FilePair>(srcFd,dstFd));
847 m_hasDirectDeps = m_hasDirectDeps || (srcDirect && dstDirect);
850}
851
853{
854 std::stable_sort(m_filePairs.begin(),
855 m_filePairs.end(),
856 [](const auto &left,const auto &right)
857 {
858 int orderHi = qstricmp_sort(left->source()->name(),right->source()->name());
859 if (orderHi!=0) return orderHi<0;
860 int orderLo = qstricmp_sort(left->destination()->name(),right->destination()->name());
861 return orderLo<0;
862 });
863}
864
866{
867 return m_filePairs.find(name);
868}
869
871{
872 AUTO_TRACE();
873 ASSERT(path!=nullptr);
874 DirDef *dir = Doxygen::dirLinkedMap->find(path);
875 if (dir==nullptr) // new dir
876 {
877 dir = Doxygen::dirLinkedMap->add(path,
878 std::unique_ptr<DirDef>(
879 createDirDef(path)));
880 AUTO_TRACE_ADD("Adding new dir {} shortName {}",path,dir->shortName());
881 }
882 return dir;
883}
884
886{
887 for (const auto &s : l)
888 {
889 std::string prefix = s.substr(0,path.length());
890 if (qstricmp_sort(prefix.c_str(),path)==0) // case insensitive compare
891 {
892 return TRUE;
893 }
894 }
895 return FALSE;
896}
897
898/*! strip part of \a path if it matches
899 * one of the paths in the Config_getList(STRIP_FROM_PATH) list
900 */
902{
903 AUTO_TRACE("path={}",path);
904 int p=0,i=0;
905 DirDef *dir=nullptr;
906 while ((i=path.find('/',p))!=-1)
907 {
908 QCString part=path.left(i+1);
909 if (!matchPath(part,Config_getList(STRIP_FROM_PATH)) && (part!="/" && part!="//" && part!="//?/"))
910 {
912 }
913 p=i+1;
914 }
915 return dir;
916}
917
922
924{
925 return m_hasDirectoryGraph;
926}
927
928//----------------------------------------------------------------------
929
930QCString FilePair::key(const FileDef *srcFd,const FileDef *dstFd)
931{
932 return srcFd->getOutputFileBase()+";"+dstFd->getOutputFileBase();
933}
934
935//----------------------------------------------------------------------
936
937static void writePartialDirPath(OutputList &ol,const DirDef *root,const DirDef *target)
938{
939 if (target->parent()!=root)
940 {
941 writePartialDirPath(ol,root,target->parent());
942 ol.writeString("&#160;/&#160;");
943 }
944 ol.writeObjectLink(target->getReference(),target->getOutputFileBase(),QCString(),target->shortName());
945}
946
947static void writePartialFilePath(OutputList &ol,const DirDef *root,const FileDef *fd)
948{
949 if (fd->getDirDef() && fd->getDirDef()!=root)
950 {
951 writePartialDirPath(ol,root,fd->getDirDef());
952 ol.writeString("&#160;/&#160;");
953 }
954 if (fd->isLinkable())
955 {
957 }
958 else
959 {
960 ol.startBold();
961 ol.docify(fd->name());
962 ol.endBold();
963 }
964}
965
967{
968 bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
971
972 QCString shortTitle=theTranslator->trDirRelation(
973 (m_src->shortName()+" &rarr; "+m_dst->dir()->shortName()));
974 QCString title=theTranslator->trDirRelation(
975 (m_src->displayName()+" -> "+m_dst->dir()->shortName()));
976 AUTO_TRACE("title={}",title);
978 title,HighlightedItem::None,!generateTreeView,m_src->getOutputFileBase());
979
980 if (!generateTreeView)
981 {
982 // write navigation path
983 m_src->writeNavigationPath(ol);
984 ol.endQuickIndices();
985 }
986 ol.startContents();
987
988 ol.writeString("<h3>"+shortTitle+"</h3>");
989 ol.writeString("<table class=\"dirtab\">");
990 ol.writeString("<tr class=\"dirtab\">");
991 ol.writeString("<th class=\"dirtab\">");
992 ol.parseText(theTranslator->trFileIn(m_src->pathFragment()));
993 ol.writeString("</th>");
994 ol.writeString("<th class=\"dirtab\">");
995 ol.parseText(theTranslator->trIncludesFileIn(m_dst->dir()->pathFragment()));
996 ol.writeString("</th>");
997 ol.writeString("</tr>");
998
999 for (const auto &fp : m_dst->filePairs())
1000 {
1001 ol.writeString("<tr class=\"dirtab\">");
1002 ol.writeString("<td class=\"dirtab\">");
1003 writePartialFilePath(ol,m_src,fp->source());
1004 ol.writeString("</td>");
1005 ol.writeString("<td class=\"dirtab\">");
1006 writePartialFilePath(ol,m_dst->dir(),fp->destination());
1007 ol.writeString("</td>");
1008 ol.writeString("</tr>");
1009 }
1010 ol.writeString("</table>");
1011
1012 ol.endContents();
1013
1015
1016 ol.popGeneratorState();
1017}
1018
1019//----------------------------------------------------------------------
1020// external functions
1021
1022/** In order to create stable, but unique directory names,
1023 * we compute the common part of the path shared by all directories.
1024 */
1026{
1027 AUTO_TRACE();
1028 QCString path;
1029 auto it = Doxygen::dirLinkedMap->begin();
1030 if (!Doxygen::dirLinkedMap->empty()) // we have at least one dir
1031 {
1032 // start will full path of first dir
1033 path=removeLongPathMarker((*it)->name());
1034 int i=path.findRev('/',static_cast<int>(path.length())-2);
1035 path=path.left(i+1);
1036 bool done=FALSE;
1037 if (i==-1)
1038 {
1039 path="";
1040 }
1041 else
1042 {
1043 while (!done)
1044 {
1045 int l = static_cast<int>(path.length());
1046 size_t count=0;
1047 for (const auto &dir : *Doxygen::dirLinkedMap)
1048 {
1049 QCString dirName = removeLongPathMarker(dir->name());
1050 //printf("dirName='%s' (l=%d) path='%s' (l=%d)\n",qPrint(dirName),dirName.length(),qPrint(path),path.length());
1051 if (dirName.length()>path.length())
1052 {
1053 if (dirName.left(l)!=path) // dirName does not start with path
1054 {
1055 i = l>=2 ? path.findRev('/',l-2) : -1;
1056 if (i==-1) // no unique prefix -> stop
1057 {
1058 path="";
1059 done=TRUE;
1060 }
1061 else // restart with shorter path
1062 {
1063 path=path.left(i+1);
1064 break;
1065 }
1066 }
1067 }
1068 else // dir is shorter than path -> take path of dir as new start
1069 {
1070 path=dir->name();
1071 l=static_cast<int>(path.length());
1072 i=path.findRev('/',l-2);
1073 if (i==-1) // no unique prefix -> stop
1074 {
1075 path="";
1076 done=TRUE;
1077 }
1078 else // restart with shorter path
1079 {
1080 path=path.left(i+1);
1081 }
1082 break;
1083 }
1084 count++;
1085 }
1086 if (count==Doxygen::dirLinkedMap->size())
1087 // path matches for all directories -> found the common prefix
1088 {
1089 done=TRUE;
1090 }
1091 }
1092 }
1093 }
1094 for (const auto &dir : *Doxygen::dirLinkedMap)
1095 {
1096 QCString diskName = dir->name().right(dir->name().length()-path.length());
1097 dir->setDiskName(diskName);
1098 AUTO_TRACE_ADD("set disk name: {} -> {}",dir->name(),diskName);
1099 }
1100}
1101
1103{
1104 AUTO_TRACE();
1105 // for each input file
1106 for (const auto &fn : *Doxygen::inputNameLinkedMap)
1107 {
1108 for (const auto &fd : *fn)
1109 {
1110 if (fd->getReference().isEmpty())
1111 {
1112 DirDef *dir=Doxygen::dirLinkedMap->find(fd->getPath());
1113 if (dir==nullptr) // new directory
1114 {
1115 dir = DirDefImpl::mergeDirectoryInTree(fd->getPath());
1116 }
1117 if (dir && !fd->isDocumentationFile()) dir->addFile(fd.get());
1118 }
1119 else
1120 {
1121 // do something for file imported via tag files.
1122 }
1123 }
1124 }
1125
1126 // compute relations between directories => introduce container dirs.
1127 for (const auto &dir : *Doxygen::dirLinkedMap)
1128 {
1129 QCString name = dir->name();
1130 int i=name.findRev('/',static_cast<int>(name.length())-2);
1131 if (i>0)
1132 {
1133 DirDef *parent = Doxygen::dirLinkedMap->find(name.left(i+1));
1134 //if (parent==0) parent=root;
1135 if (parent)
1136 {
1137 parent->addSubDir(dir.get());
1138 AUTO_TRACE_ADD("DirDefImpl::addSubdir(): Adding subdir {} to {}",
1139 dir->displayName(), parent->displayName());
1140 }
1141 }
1142 }
1143
1144 // sort the directory contents
1145 for (const auto &dir : *Doxygen::dirLinkedMap)
1146 {
1147 dir->sort();
1148 }
1149
1150 // short the directories themselves
1151 std::stable_sort(Doxygen::dirLinkedMap->begin(),
1153 [](const auto &d1,const auto &d2)
1154 {
1155 QCString s1 = d1->shortName(), s2 = d2->shortName();
1156 int i = qstricmp_sort(s1,s2);
1157 if (i==0) // if sort name are equal, sort on full path
1158 {
1159 QCString n1 = d1->name(), n2 = d2->name();
1160 int n = qstricmp_sort(n1,n2);
1161 return n < 0;
1162 }
1163 return i < 0;
1164 });
1165
1166 // set the directory index identifier
1167 int dirIndex=0;
1168 for (const auto &dir : *Doxygen::dirLinkedMap)
1169 {
1170 dir->setDirIndex(dirIndex++);
1171 }
1172
1174}
1175
1177{
1178 AUTO_TRACE();
1179 // compute nesting level for each directory
1180 for (const auto &dir : *Doxygen::dirLinkedMap)
1181 {
1182 dir->setLevel();
1183 }
1184
1185 // compute uses dependencies between directories
1186 for (const auto &dir : *Doxygen::dirLinkedMap)
1187 {
1188 AUTO_TRACE_ADD("computeDependencies for {}: #dirs={}",dir->name(),Doxygen::dirLinkedMap->size());
1189 dir->computeDependencies();
1190 }
1191}
1192
1194{
1195 AUTO_TRACE();
1196 for (const auto &dir : *Doxygen::dirLinkedMap)
1197 {
1198 ol.pushGeneratorState();
1199 if (!dir->hasDocumentation())
1200 {
1202 }
1203 dir->writeDocumentation(ol);
1204 ol.popGeneratorState();
1205 }
1206 //if (Config_getBool(DIRECTORY_GRAPH))
1207 {
1208 for (const auto &dr : Doxygen::dirRelations)
1209 {
1210 dr->writeDocumentation(ol);
1211 }
1212 }
1213}
1214
1215bool compareDirDefs(const DirDef *item1, const DirDef *item2)
1216{
1217 return qstricmp_sort(item1->shortName(),item2->shortName()) < 0;
1218}
1219
1220// --- Cast functions
1221
1223{
1224 if (d==nullptr) return nullptr;
1225 if (d && typeid(*d)==typeid(DirDefImpl))
1226 {
1227 return static_cast<DirDef*>(d);
1228 }
1229 else
1230 {
1231 return nullptr;
1232 }
1233}
1234
1236{
1237 if (d==nullptr) return nullptr;
1238 if (d && typeid(*d)==typeid(DirDefImpl))
1239 {
1240 return static_cast<const DirDef*>(d);
1241 }
1242 else
1243 {
1244 return nullptr;
1245 }
1246}
1247
constexpr auto prefix
Definition anchor.cpp:44
The common base class of all entity definitions found in the sources.
Definition definition.h:76
virtual bool isLinkable() const =0
virtual QCString getReference() const =0
virtual QCString getOutputFileBase() const =0
virtual const QCString & name() const =0
bool isReference() const override
const QCString & name() const override
void writeNavigationPath(OutputList &ol) const override
bool hasBriefDescription() const override
QCString docFile() const override
QCString briefFile() const override
QCString briefDescription(bool abbreviate=FALSE) const override
DefinitionMixin(const QCString &defFileName, int defLine, int defColumn, const QCString &name, const char *b=nullptr, const char *d=nullptr, bool isSymbol=TRUE)
void setLocalName(const QCString &name) override
int docLine() const override
int briefLine() const override
QCString documentation() const override
void writeDocAnchorsToTagFile(TextStream &fs) const override
bool hasDocumentation() const override
SrcLangExt getLanguage() const override
virtual void setOuterScope(Definition *d)=0
A model of a directory symbol.
Definition dirdef.h:110
virtual int level() const =0
virtual void setLevel()=0
virtual void addFile(FileDef *fd)=0
virtual DirDef * parent() const =0
virtual void addUsesDependency(const DirDef *usedDir, const FileDef *srcFd, const FileDef *dstFd, bool srcDirect, bool dstDirect)=0
virtual void setParent(DirDef *parent)=0
virtual const QCString shortName() const =0
void writeDocumentation(OutputList &ol) override
Definition dirdef.cpp:570
int m_dirIndex
Definition dirdef.cpp:102
void writeSubDirList(OutputList &ol)
Definition dirdef.cpp:357
void setLevel() override
Definition dirdef.cpp:702
static DirDef * createNewDir(const QCString &path)
Definition dirdef.cpp:870
DirDef * m_parent
Definition dirdef.cpp:104
static bool matchPath(const QCString &path, const StringVector &l)
Definition dirdef.cpp:885
QCString m_diskName
Definition dirdef.cpp:100
bool hasSubdirs() const override
Definition dirdef.cpp:56
QCString m_shortName
Definition dirdef.cpp:99
void writeTagFile(TextStream &t) override
Definition dirdef.cpp:531
const FileList & getFiles() const override
Definition dirdef.cpp:53
const QCString shortName() const override
Definition dirdef.cpp:51
bool isLinkable() const override
Definition dirdef.cpp:156
const UsedDirLinkedMap & usedDirs() const override
Definition dirdef.cpp:60
void addSubDir(DirDef *subdir) override
Definition dirdef.cpp:161
bool hasDetailedDescription() const override
Definition dirdef.cpp:525
DirDef * parent() const override
Definition dirdef.cpp:58
void startMemberDeclarations(OutputList &ol)
Definition dirdef.cpp:503
int level() const override
Definition dirdef.cpp:57
bool isLinkableInProject() const override
Definition dirdef.cpp:151
void writePageNavigation(OutputList &ol) const override
Definition dirdef.cpp:332
void writeDetailedDescription(OutputList &ol, const QCString &title)
Definition dirdef.cpp:231
DirList m_subdirs
Definition dirdef.cpp:97
DefType definitionType() const override
Definition dirdef.cpp:44
bool isParentOf(const DirDef *dir) const override
Definition dirdef.cpp:822
QCString getOutputFileBase() const override
Definition dirdef.cpp:224
int dirIndex() const override
Definition dirdef.cpp:59
QCString m_dispName
Definition dirdef.cpp:98
QCString anchor() const override
Definition dirdef.cpp:47
CodeSymbolType codeSymbolType() const override
Definition dirdef.cpp:45
void addFile(FileDef *fd) override
Definition dirdef.cpp:178
bool depGraphIsTrivial() const override
Definition dirdef.cpp:832
void findSectionsInDocumentation() override
Definition dirdef.cpp:782
void overrideDirectoryGraph(bool e) override
Definition dirdef.cpp:918
void addUsesDependency(const DirDef *usedDir, const FileDef *srcFd, const FileDef *dstFd, bool srcDirect, bool dstDirect) override
Add as "uses" dependency between this dir and dir, that was caused by a dependency on file fd.
Definition dirdef.cpp:724
void writeDirectoryGraph(OutputList &ol)
Definition dirdef.cpp:337
const DirList & subDirs() const override
Definition dirdef.cpp:55
UsedDirLinkedMap m_usedDirs
Definition dirdef.cpp:105
void setDiskName(const QCString &name) override
Definition dirdef.cpp:68
static DirDef * mergeDirectoryInTree(const QCString &path)
Definition dirdef.cpp:901
void writeFileList(OutputList &ol)
Definition dirdef.cpp:418
QCString shortTitle() const override
Definition dirdef.cpp:513
DirDefImpl(const QCString &path)
Definition dirdef.cpp:118
void setDirIndex(int index) override
Definition dirdef.cpp:173
void endMemberDeclarations(OutputList &ol)
Definition dirdef.cpp:508
int m_level
Definition dirdef.cpp:103
FileList m_fileList
Definition dirdef.cpp:101
void sort() override
Definition dirdef.cpp:184
~DirDefImpl() override
Definition dirdef.cpp:147
void writeBriefDescription(OutputList &ol)
Definition dirdef.cpp:287
void computeDependencies() override
Computes the dependencies between directories.
Definition dirdef.cpp:790
QCString displayName(bool=TRUE) const override
Definition dirdef.cpp:50
void setParent(DirDef *parent) override
Definition dirdef.cpp:168
bool m_hasDirectoryGraph
Definition dirdef.cpp:106
bool hasDirectoryGraph() const override
Definition dirdef.cpp:923
A list of directories.
Definition dirdef.h:178
const DirDef * m_src
Definition dirdef.h:167
UsedDir * m_dst
Definition dirdef.h:168
void writeDocumentation(OutputList &ol)
Definition dirdef.cpp:966
QCString getOutputFileBase() const
Definition dirdef.h:163
Representation of an directory dependency graph.
Definition dotdirdeps.h:26
bool isTrivial() const
static FileNameLinkedMap * inputNameLinkedMap
Definition doxygen.h:105
static DirLinkedMap * dirLinkedMap
Definition doxygen.h:129
static DirRelationLinkedMap dirRelations
Definition doxygen.h:130
A model of a file symbol.
Definition filedef.h:99
virtual void setDirDef(DirDef *dd)=0
virtual DirDef * getDirDef() const =0
Class representing a pair of FileDef objects.
Definition dirdef.h:42
static QCString key(const FileDef *srcFd, const FileDef *dstFd)
Definition dirdef.cpp:930
static LayoutDocManager & instance()
Returns a reference to this singleton.
Definition layout.cpp:1435
Class representing a list of output generators that are written to in parallel.
Definition outputlist.h:315
void writeDoc(const IDocNodeAST *ast, const Definition *ctx, const MemberDef *md, int sectionLevel=-1)
Definition outputlist.h:383
void writeString(const QCString &text)
Definition outputlist.h:411
void startMemberDeclaration()
Definition outputlist.h:569
void disable(OutputType o)
void endDirDepGraph(DotDirDeps &g)
Definition outputlist.h:662
void writeRuler()
Definition outputlist.h:521
void startGroupHeader(const QCString &id=QCString(), int extraLevels=0)
Definition outputlist.h:453
void enable(OutputType o)
void endContents()
Definition outputlist.h:620
void endMemberDescription()
Definition outputlist.h:567
void writeObjectLink(const QCString &ref, const QCString &file, const QCString &anchor, const QCString &name)
Definition outputlist.h:439
void startMemberDescription(const QCString &anchor, const QCString &inheritId=QCString(), bool typ=false)
Definition outputlist.h:565
void docify(const QCString &s)
Definition outputlist.h:437
void generateDoc(const QCString &fileName, int startLine, const Definition *ctx, const MemberDef *md, const QCString &docStr, const DocOptions &options)
void startParagraph(const QCString &classDef=QCString())
Definition outputlist.h:407
void endParagraph()
Definition outputlist.h:409
void startDirDepGraph()
Definition outputlist.h:660
void startMemberSections()
Definition outputlist.h:461
void startMemberList()
Definition outputlist.h:481
void endTextLink()
Definition outputlist.h:444
void startBold()
Definition outputlist.h:561
void endMemberItem(OutputGenerator::MemberItemType type)
Definition outputlist.h:495
void endMemberList()
Definition outputlist.h:483
void writeSynopsis()
Definition outputlist.h:592
void pushGeneratorState()
void insertMemberAlign(bool templ=FALSE)
Definition outputlist.h:517
void disableAllBut(OutputType o)
void popGeneratorState()
void writeAnchor(const QCString &fileName, const QCString &name)
Definition outputlist.h:523
void endBold()
Definition outputlist.h:563
void endGroupHeader(int extraLevels=0)
Definition outputlist.h:455
void endQuickIndices()
Definition outputlist.h:604
void writePageOutline()
Definition outputlist.h:616
void startContents()
Definition outputlist.h:618
void endMemberDeclaration(const QCString &anchor, const QCString &inheritId)
Definition outputlist.h:571
void enableAll()
void endMemberHeader()
Definition outputlist.h:471
void startMemberItem(const QCString &anchor, OutputGenerator::MemberItemType type, const QCString &id=QCString())
Definition outputlist.h:493
void parseText(const QCString &textStr)
void startTextLink(const QCString &file, const QCString &anchor)
Definition outputlist.h:442
void startMemberHeader(const QCString &anchor, int typ=2)
Definition outputlist.h:469
void endMemberSections()
Definition outputlist.h:463
This is an alternative implementation of QCString.
Definition qcstring.h:101
int find(char c, int index=0, bool cs=TRUE) const
Definition qcstring.cpp:43
QCString & prepend(const char *s)
Definition qcstring.h:422
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition qcstring.h:166
bool isEmpty() const
Returns TRUE iff the string is empty.
Definition qcstring.h:163
QCString right(size_t len) const
Definition qcstring.h:234
int findRev(char c, int index=-1, bool cs=TRUE) const
Definition qcstring.cpp:96
const char * data() const
Returns a pointer to the contents of the string in the form of a 0-terminated C string.
Definition qcstring.h:172
QCString left(size_t len) const
Definition qcstring.h:229
Text streaming class that buffers data.
Definition textstream.h:36
Usage information of a directory.
Definition dirdef.h:64
bool m_hasDirectDstDeps
Definition dirdef.h:103
void sort()
Definition dirdef.cpp:852
FilePairLinkedMap m_filePairs
Definition dirdef.h:99
bool m_hasDirectDeps
Definition dirdef.h:101
void addFileDep(const FileDef *srcFd, const FileDef *dstFd, bool srcDirect, bool dstDirect)
Take up dependency between files.
Definition dirdef.cpp:844
const DirDef * dir() const
Definition dirdef.h:78
UsedDir(const DirDef *dir)
Definition dirdef.cpp:839
FilePair * findFilePair(const QCString &name)
Definition dirdef.cpp:865
bool m_hasDirectSrcDeps
Definition dirdef.h:102
const DirDef * m_dir
Definition dirdef.h:98
#define Config_getList(name)
Definition config.h:38
#define Config_getBool(name)
Definition config.h:33
#define NON_COPYABLE(cls)
Macro to help implementing the rule of 5 for a non-copyable & movable class.
Definition construct.h:37
std::vector< std::string > StringVector
Definition containers.h:33
DirIterator begin(DirIterator it) noexcept
Definition dir.cpp:170
DirIterator end(const DirIterator &) noexcept
Definition dir.cpp:175
DirDef * createDirDef(const QCString &path)
Definition dirdef.cpp:109
static void writePartialFilePath(OutputList &ol, const DirDef *root, const FileDef *fd)
Definition dirdef.cpp:947
bool compareDirDefs(const DirDef *item1, const DirDef *item2)
Definition dirdef.cpp:1215
static void writePartialDirPath(OutputList &ol, const DirDef *root, const DirDef *target)
Definition dirdef.cpp:937
static QCString encodeDirName(const QCString &anchor)
Definition dirdef.cpp:190
void buildDirectories()
Definition dirdef.cpp:1102
void computeDirDependencies()
Definition dirdef.cpp:1176
DirDef * toDirDef(Definition *d)
Definition dirdef.cpp:1222
static void computeCommonDirPrefix()
In order to create stable, but unique directory names, we compute the common part of the path shared ...
Definition dirdef.cpp:1025
void generateDirDocs(OutputList &ol)
Definition dirdef.cpp:1193
#define AUTO_TRACE_ADD(...)
Definition docnode.cpp:47
#define AUTO_TRACE(...)
Definition docnode.cpp:46
#define AUTO_TRACE_EXIT(...)
Definition docnode.cpp:48
constexpr DocNodeVariant * parent(DocNodeVariant *n)
returns the parent node of a given node n or nullptr if the node has no parent.
Definition docnode.h:1330
void docFindSections(const QCString &input, const Definition *d, const QCString &fileName)
IDocNodeASTPtr validatingParseDoc(IDocParser &parserIntf, const QCString &fileName, int startLine, const Definition *ctx, const MemberDef *md, const QCString &input, const DocOptions &options)
IDocParserPtr createDocParser()
factory function to create a parser
Definition docparser.cpp:55
static void writeTagFile()
bool compareFileDefs(const FileDef *fd1, const FileDef *fd2)
Definition filedef.cpp:1947
void startTitle(OutputList &ol, const QCString &fileName, const DefinitionMutable *def)
Definition index.cpp:384
void endTitle(OutputList &ol, const QCString &fileName, const QCString &name)
Definition index.cpp:394
void startFile(OutputList &ol, const QCString &name, bool isSource, const QCString &manName, const QCString &title, HighlightedItem hli, bool additionalIndices, const QCString &altSidebarName, int hierarchyLevel, const QCString &allMembersFile)
Definition index.cpp:401
void endFileWithNavPath(OutputList &ol, const DefinitionMutable *d, bool showPageNavigation)
Definition index.cpp:448
Translator * theTranslator
Definition language.cpp:71
#define msg(fmt,...)
Definition message.h:94
#define err(fmt,...)
Definition message.h:127
int qstricmp_sort(const char *str1, const char *str2)
Definition qcstring.h:86
const char * qPrint(const char *s)
Definition qcstring.h:687
#define TRUE
Definition qcstring.h:37
#define FALSE
Definition qcstring.h:34
#define ASSERT(x)
Definition qcstring.h:39
Definition layout.h:102
QCString title(SrcLangExt lang) const
Definition layout.cpp:1779
CodeSymbolType
Definition types.h:481
SrcLangExt
Definition types.h:207
bool fileVisibleInIndex(const FileDef *fd, bool &genSourceFile)
Definition util.cpp:5999
static QCString stripFromPath(const QCString &p, const StringVector &l)
Definition util.cpp:307
QCString convertToXML(const QCString &s, bool keepEntities)
Definition util.cpp:3833
QCString removeLongPathMarker(QCString path)
Definition util.cpp:296
void addHtmlExtensionIfMissing(QCString &fName)
Definition util.cpp:4823
A bunch of utility functions.