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