diff options
Diffstat (limited to 'src/dotdirdeps.cpp')
-rw-r--r-- | src/dotdirdeps.cpp | 144 |
1 files changed, 78 insertions, 66 deletions
diff --git a/src/dotdirdeps.cpp b/src/dotdirdeps.cpp index c70128c..da6364f 100644 --- a/src/dotdirdeps.cpp +++ b/src/dotdirdeps.cpp @@ -20,6 +20,30 @@ #include "doxygen.h" #include "config.h" +/** + * Puts DOT code for drawing directory to stream and adds it to the list. + * @param[in,out] outStream stream to which the DOT code is written to + * @param[in] directory will be mapped to a node in DOT code + * @param[in] fillBackground if the node shall be explicitly filled + * @param[in,out] directoriesInGraph lists the directories which have been written to the output stream + */ +static void drawDirectory(FTextStream &outStream, const DirDef *const directory, const bool fillBackground, + QDict<DirDef> &directoriesInGraph) +{ + outStream << " " << directory->getOutputFileBase() << " [shape=box " + "label=\"" << directory->shortName() << "\" "; + if (fillBackground) + { + outStream << "fillcolor=\"white\" style=\"filled\" "; + } + if (directory->isCluster()) + { + outStream << "color=\"red\" "; + } + outStream << "URL=\"" << directory->getOutputFileBase() << Doxygen::htmlFileExtension << "\"];\n"; + directoriesInGraph.insert(directory->getOutputFileBase(), directory); +} + void writeDotDirDepGraph(FTextStream &t,const DirDef *dd,bool linkRelations) { int fontSize = Config_getInt(DOT_FONTSIZE); @@ -36,52 +60,59 @@ void writeDotDirDepGraph(FTextStream &t,const DirDef *dd,bool linkRelations) QDict<DirDef> dirsInGraph(257); dirsInGraph.insert(dd->getOutputFileBase(),dd); - if (dd->parent()) + + std::vector<const DirDef *> usedDirsNotDrawn; + for(const auto& usedDir : dd->usedDirs()) + { + usedDirsNotDrawn.push_back(usedDir->dir()); + } + + const auto parent = dd->parent(); + if (parent) { t << " subgraph cluster" << dd->parent()->getOutputFileBase() << " {\n"; - t << " graph [ bgcolor=\"#ddddee\", pencolor=\"black\", label=\"" - << dd->parent()->shortName() + t << " graph [ bgcolor=\"#ddddee\", pencolor=\"black\", label=\"" + << dd->parent()->shortName() << "\" fontname=\"" << fontName << "\", fontsize=\"" << fontSize << "\", URL=\""; t << dd->parent()->getOutputFileBase() << Doxygen::htmlFileExtension; t << "\"]\n"; + + { + // draw all directories which have `dd->parent()` as parent and `dd` as dependent + const auto newEnd = std::remove_if(usedDirsNotDrawn.begin(), usedDirsNotDrawn.end(), [&](const DirDef *const usedDir) + { + if (dd!=usedDir && dd->parent()==usedDir->parent()) + { + drawDirectory(t, usedDir, usedDir->isCluster() && !Config_getBool(DOT_TRANSPARENT), dirsInGraph); + return true; + } + return false; + } + ); + usedDirsNotDrawn.erase(newEnd, usedDirsNotDrawn.end()); + } } if (dd->isCluster()) { t << " subgraph cluster" << dd->getOutputFileBase() << " {\n"; t << " graph [ bgcolor=\"#eeeeff\", pencolor=\"black\", label=\"\"" - << " URL=\"" << dd->getOutputFileBase() << Doxygen::htmlFileExtension + << " URL=\"" << dd->getOutputFileBase() << Doxygen::htmlFileExtension << "\"];\n"; - t << " " << dd->getOutputFileBase() << " [shape=plaintext label=\"" + t << " " << dd->getOutputFileBase() << " [shape=plaintext label=\"" << dd->shortName() << "\"];\n"; // add nodes for sub directories - QListIterator<DirDef> sdi(dd->subDirs()); - const DirDef *sdir; - for (sdi.toFirst();(sdir=sdi.current());++sdi) + for(const auto sdir : dd->subDirs()) { - t << " " << sdir->getOutputFileBase() << " [shape=box label=\"" - << sdir->shortName() << "\""; - if (sdir->isCluster()) - { - t << " color=\"red\""; - } - else - { - t << " color=\"black\""; - } - t << " fillcolor=\"white\" style=\"filled\""; - t << " URL=\"" << sdir->getOutputFileBase() - << Doxygen::htmlFileExtension << "\""; - t << "];\n"; - dirsInGraph.insert(sdir->getOutputFileBase(),sdir); + drawDirectory(t, sdir, true, dirsInGraph); } t << " }\n"; } else { - t << " " << dd->getOutputFileBase() << " [shape=box, label=\"" + t << " " << dd->getOutputFileBase() << " [shape=box, label=\"" << dd->shortName() << "\", style=\"filled\", fillcolor=\"#eeeeff\"," - << " pencolor=\"black\", URL=\"" << dd->getOutputFileBase() + << " pencolor=\"black\", URL=\"" << dd->getOutputFileBase() << Doxygen::htmlFileExtension << "\"];\n"; } if (dd->parent()) @@ -90,54 +121,38 @@ void writeDotDirDepGraph(FTextStream &t,const DirDef *dd,bool linkRelations) } // add nodes for other used directories - QDictIterator<UsedDir> udi(*dd->usedDirs()); - UsedDir *udir; - //printf("*** For dir %s\n",shortName().data()); - for (udi.toFirst();(udir=udi.current());++udi) - // for each used dir (=directly used or a parent of a directly used dir) { - const DirDef *usedDir=udir->dir(); - const DirDef *dir=dd; - while (dir) + //printf("*** For dir %s\n",shortName().data()); + for (const auto &usedDir : usedDirsNotDrawn) + // for each used dir (=directly used or a parent of a directly used dir) { - //printf("*** check relation %s->%s same_parent=%d !%s->isParentOf(%s)=%d\n", - // dir->shortName().data(),usedDir->shortName().data(), - // dir->parent()==usedDir->parent(), - // usedDir->shortName().data(), - // shortName().data(), - // !usedDir->isParentOf(this) - // ); - if (dir!=usedDir && dir->parent()==usedDir->parent() && - !usedDir->isParentOf(dd)) - // include if both have the same parent (or no parent) + const DirDef *dir=dd; + while (dir) { - t << " " << usedDir->getOutputFileBase() << " [shape=box label=\"" - << usedDir->shortName() << "\""; - if (usedDir->isCluster()) + //printf("*** check relation %s->%s same_parent=%d !%s->isParentOf(%s)=%d\n", + // dir->shortName().data(),usedDir->shortName().data(), + // dir->parent()==usedDir->parent(), + // usedDir->shortName().data(), + // shortName().data(), + // !usedDir->isParentOf(this) + // ); + if (dir!=usedDir && dir->parent()==usedDir->parent()) + // include if both have the same parent (or no parent) { - if (!Config_getBool(DOT_TRANSPARENT)) - { - t << " fillcolor=\"white\" style=\"filled\""; - } - t << " color=\"red\""; + drawDirectory(t, usedDir, usedDir->isCluster() && !Config_getBool(DOT_TRANSPARENT), dirsInGraph); + break; } - t << " URL=\"" << usedDir->getOutputFileBase() - << Doxygen::htmlFileExtension << "\"];\n"; - dirsInGraph.insert(usedDir->getOutputFileBase(),usedDir); - break; + dir=dir->parent(); } - dir=dir->parent(); } } // add relations between all selected directories const DirDef *dir; QDictIterator<DirDef> di(dirsInGraph); - for (di.toFirst();(dir=di.current());++di) // foreach dir in the graph + for (;(dir=di.current());++di) // foreach dir in the graph { - QDictIterator<UsedDir> udi(*dir->usedDirs()); - UsedDir *udir; - for (udi.toFirst();(udir=udi.current());++udi) // foreach used dir + for (const auto &udir : dir->usedDirs()) { const DirDef *usedDir=udir->dir(); if ((dir!=dd || !udir->inherited()) && // only show direct dependencies for this dir @@ -147,12 +162,9 @@ void writeDotDirDepGraph(FTextStream &t,const DirDef *dd,bool linkRelations) { QCString relationName; relationName.sprintf("dir_%06d_%06d",dir->dirCount(),usedDir->dirCount()); - if (Doxygen::dirRelations.find(relationName)==0) - { - // new relation - Doxygen::dirRelations.append(relationName, - new DirRelation(relationName,dir,udir)); - } + Doxygen::dirRelations.add(relationName, + std::make_unique<DirRelation>( + relationName,dir,udir.get())); int nrefs = udir->filePairs().count(); t << " " << dir->getOutputFileBase() << "->" << usedDir->getOutputFileBase(); |