From b34889629116ee43f26eb3444dc6e4443a3f51f5 Mon Sep 17 00:00:00 2001 From: Dimitri van Heesch Date: Fri, 15 Jan 2021 21:15:19 +0100 Subject: Refactoring: modernize various dot graphs --- src/dotcallgraph.cpp | 37 +++++++-------- src/dotcallgraph.h | 7 +-- src/dotclassgraph.cpp | 70 ++++++++++++++-------------- src/dotclassgraph.h | 6 +-- src/dotdirdeps.cpp | 17 +++---- src/dotfilepatcher.cpp | 87 ++++++++++++----------------------- src/dotfilepatcher.h | 9 +++- src/dotgroupcollaboration.cpp | 96 ++++++++++++++++++--------------------- src/dotgroupcollaboration.h | 11 ++--- src/dotincldepgraph.cpp | 49 ++++++++++---------- src/dotincldepgraph.h | 7 +-- src/dotnode.h | 10 ++++ testing/011/interface_integer.xml | 10 ++-- testing/027/struct_car.xml | 36 +++++++-------- testing/027/struct_object.xml | 20 ++++---- testing/027/struct_truck.xml | 12 ++--- testing/027/struct_vehicle.xml | 24 +++++----- 17 files changed, 241 insertions(+), 267 deletions(-) diff --git a/src/dotcallgraph.cpp b/src/dotcallgraph.cpp index 9525d52..78e9b9b 100644 --- a/src/dotcallgraph.cpp +++ b/src/dotcallgraph.cpp @@ -36,9 +36,10 @@ void DotCallGraph::buildGraph(DotNode *n,const MemberDef *md,int distance) if (rmd->showInCallGraph()) { QCString uniqueId = getUniqueId(rmd); - DotNode *bn = m_usedNodes->find(uniqueId); - if (bn) // file is already a node in the graph + auto it = m_usedNodes.find(uniqueId.str()); + if (it!=m_usedNodes.end()) // file is already a node in the graph { + DotNode *bn = it->second; n->addChild(bn,0,0,0); bn->addParent(n); bn->setDistance(distance); @@ -56,7 +57,7 @@ void DotCallGraph::buildGraph(DotNode *n,const MemberDef *md,int distance) name = rmd->qualifiedName(); } QCString tooltip = rmd->briefDescriptionAsTooltip(); - bn = new DotNode( + DotNode *bn = new DotNode( getNextNodeNumber(), linkToText(rmd->getLanguage(),name,FALSE), tooltip, @@ -66,7 +67,7 @@ void DotCallGraph::buildGraph(DotNode *n,const MemberDef *md,int distance) n->addChild(bn,0,0,0); bn->addParent(n); bn->setDistance(distance); - m_usedNodes->insert(uniqueId,bn); + m_usedNodes.insert(std::make_pair(uniqueId.str(),bn)); buildGraph(bn,rmd,distance+1); } @@ -74,11 +75,12 @@ void DotCallGraph::buildGraph(DotNode *n,const MemberDef *md,int distance) } } -void DotCallGraph::determineVisibleNodes(QList &queue, int &maxNodes) +void DotCallGraph::determineVisibleNodes(DotNodeDeque &queue, int &maxNodes) { - while (queue.count()>0 && maxNodes>0) + while (!queue.empty() && maxNodes>0) { - DotNode *n = queue.take(0); + DotNode *n = queue.front(); + queue.pop_front(); if (!n->isVisible() && n->distance()<=Config_getInt(MAX_DOT_GRAPH_DEPTH)) // not yet processed { n->markAsVisible(); @@ -86,17 +88,18 @@ void DotCallGraph::determineVisibleNodes(QList &queue, int &maxNodes) // add direct children for (const auto &dn : n->children()) { - queue.append(dn); + queue.push_back(dn); } } } } -void DotCallGraph::determineTruncatedNodes(QList &queue) +void DotCallGraph::determineTruncatedNodes(DotNodeDeque &queue) { - while (queue.count()>0) + while (!queue.empty()) { - DotNode *n = queue.take(0); + DotNode *n = queue.front(); + queue.pop_front(); if (n->isVisible() && n->isTruncated()==DotNode::Unknown) { bool truncated = FALSE; @@ -105,7 +108,7 @@ void DotCallGraph::determineTruncatedNodes(QList &queue) if (!dn->isVisible()) truncated = TRUE; else - queue.append(dn); + queue.push_back(dn); } n->markAsTruncated(truncated); } @@ -135,23 +138,21 @@ DotCallGraph::DotCallGraph(const MemberDef *md,bool inverse) TRUE // root node ); m_startNode->setDistance(0); - m_usedNodes = new QDict(1009); - m_usedNodes->insert(uniqueId,m_startNode); + m_usedNodes.insert(std::make_pair(uniqueId.str(),m_startNode)); buildGraph(m_startNode,md,1); int maxNodes = Config_getInt(DOT_GRAPH_MAX_NODES); - QList openNodeQueue; - openNodeQueue.append(m_startNode); + DotNodeDeque openNodeQueue; + openNodeQueue.push_back(m_startNode); determineVisibleNodes(openNodeQueue,maxNodes); openNodeQueue.clear(); - openNodeQueue.append(m_startNode); + openNodeQueue.push_back(m_startNode); determineTruncatedNodes(openNodeQueue); } DotCallGraph::~DotCallGraph() { DotNode::deleteNodes(m_startNode); - delete m_usedNodes; } QCString DotCallGraph::getBaseName() const diff --git a/src/dotcallgraph.h b/src/dotcallgraph.h index bba976c..1bc8882 100644 --- a/src/dotcallgraph.h +++ b/src/dotcallgraph.h @@ -16,6 +16,7 @@ #ifndef DOTCALLGRAPH_H #define DOTCALLGRAPH_H +#include "dotnode.h" #include "dotgraph.h" #include "ftextstream.h" #include "memberdef.h" @@ -41,10 +42,10 @@ class DotCallGraph : public DotGraph private: void buildGraph(DotNode *n,const MemberDef *md,int distance); - void determineVisibleNodes(QList &queue, int &maxNodes); - void determineTruncatedNodes(QList &queue); + void determineVisibleNodes(DotNodeDeque &queue, int &maxNodes); + void determineTruncatedNodes(DotNodeDeque &queue); DotNode *m_startNode; - QDict *m_usedNodes; + DotNodeMap m_usedNodes; bool m_inverse; QCString m_diskName; const Definition * m_scope; diff --git a/src/dotclassgraph.cpp b/src/dotclassgraph.cpp index cdb30e2..9146a25 100644 --- a/src/dotclassgraph.cpp +++ b/src/dotclassgraph.cpp @@ -51,9 +51,10 @@ void DotClassGraph::addClass(const ClassDef *cd,DotNode *n,int prot, } //printf("DotClassGraph::addClass(class='%s',parent=%s,prot=%d,label=%s,dist=%d,usedName=%s,templSpec=%s,base=%d)\n", // className.data(),n->label().data(),prot,label,distance,usedName,templSpec,base); - DotNode *bn = m_usedNodes->find(fullName); - if (bn) // class already inserted + auto it = m_usedNodes.find(fullName.str()); + if (it!=m_usedNodes.end()) // class already inserted { + DotNode *bn = it->second; if (base) { n->addChild(bn,prot,edgeStyle,label); @@ -81,7 +82,7 @@ void DotClassGraph::addClass(const ClassDef *cd,DotNode *n,int prot, } } QCString tooltip = cd->briefDescriptionAsTooltip(); - bn = new DotNode(getNextNodeNumber(), + DotNode *bn = new DotNode(getNextNodeNumber(), displayName, tooltip, tmp_url.data(), @@ -99,7 +100,7 @@ void DotClassGraph::addClass(const ClassDef *cd,DotNode *n,int prot, n->addParent(bn); } bn->setDistance(distance); - m_usedNodes->insert(fullName,bn); + m_usedNodes.insert(std::make_pair(fullName.str(),bn)); //printf(" add new child node '%s' to %s hidden=%d url=%s\n", // className.data(),n->label().data(),cd->isHidden(),tmp_url.data()); @@ -107,11 +108,12 @@ void DotClassGraph::addClass(const ClassDef *cd,DotNode *n,int prot, } } -void DotClassGraph::determineTruncatedNodes(QList &queue,bool includeParents) +void DotClassGraph::determineTruncatedNodes(DotNodeDeque &queue,bool includeParents) { - while (queue.count()>0) + while (!queue.empty()) { - DotNode *n = queue.take(0); + DotNode *n = queue.front(); + queue.pop_front(); if (n->isVisible() && n->isTruncated()==DotNode::Unknown) { bool truncated = FALSE; @@ -120,7 +122,7 @@ void DotClassGraph::determineTruncatedNodes(QList &queue,bool includePa if (!dn->isVisible()) truncated = TRUE; else - queue.append(dn); + queue.push_back(dn); } if (includeParents) { @@ -129,7 +131,7 @@ void DotClassGraph::determineTruncatedNodes(QList &queue,bool includePa if (!dn->isVisible()) truncated = TRUE; else - queue.append(dn); + queue.push_back(dn); } } n->markAsTruncated(truncated); @@ -140,19 +142,20 @@ void DotClassGraph::determineTruncatedNodes(QList &queue,bool includePa bool DotClassGraph::determineVisibleNodes(DotNode *rootNode, int maxNodes,bool includeParents) { - QList childQueue; - QList parentQueue; + DotNodeDeque childQueue; + DotNodeDeque parentQueue; IntVector childTreeWidth; IntVector parentTreeWidth; - childQueue.append(rootNode); - if (includeParents) parentQueue.append(rootNode); + childQueue.push_back(rootNode); + if (includeParents) parentQueue.push_back(rootNode); bool firstNode=TRUE; // flag to force reprocessing rootNode in the parent loop // despite being marked visible in the child loop - while ((childQueue.count()>0 || parentQueue.count()>0) && maxNodes>0) + while ((!childQueue.empty() || !parentQueue.empty()) && maxNodes>0) { - if (childQueue.count()>0) + if (!childQueue.empty()) { - DotNode *n = childQueue.take(0); + DotNode *n = childQueue.front(); + childQueue.pop_front(); int distance = n->distance(); if (!n->isVisible() && distance<=Config_getInt(MAX_DOT_GRAPH_DEPTH)) // not yet processed { @@ -171,13 +174,14 @@ bool DotClassGraph::determineVisibleNodes(DotNode *rootNode, // add direct children for (const auto &dn : n->children()) { - childQueue.append(dn); + childQueue.push_back(dn); } } } - if (includeParents && parentQueue.count()>0) + if (includeParents && !parentQueue.empty()) { - DotNode *n = parentQueue.take(0); + DotNode *n = parentQueue.front(); + parentQueue.pop_front(); if ((!n->isVisible() || firstNode) && n->distance()<=Config_getInt(MAX_DOT_GRAPH_DEPTH)) // not yet processed { firstNode=FALSE; @@ -197,7 +201,7 @@ bool DotClassGraph::determineVisibleNodes(DotNode *rootNode, // add direct parents for (const auto &dn : n->parents()) { - parentQueue.append(dn); + parentQueue.push_back(dn); } } } @@ -327,15 +331,14 @@ DotClassGraph::DotClassGraph(const ClassDef *cd,GraphType t) cd ); m_startNode->setDistance(0); - m_usedNodes = new QDict(1009); - m_usedNodes->insert(className,m_startNode); + m_usedNodes.insert(std::make_pair(className.str(),m_startNode)); buildGraph(cd,m_startNode,TRUE,1); if (t==Inheritance) buildGraph(cd,m_startNode,FALSE,1); m_lrRank = determineVisibleNodes(m_startNode,Config_getInt(DOT_GRAPH_MAX_NODES),t==Inheritance); - QList openNodeQueue; - openNodeQueue.append(m_startNode); + DotNodeDeque openNodeQueue; + openNodeQueue.push_back(m_startNode); determineTruncatedNodes(openNodeQueue,t==Inheritance); m_collabFileName = cd->collaborationGraphFileName(); @@ -369,7 +372,6 @@ int DotClassGraph::numNodes() const DotClassGraph::~DotClassGraph() { DotNode::deleteNodes(m_startNode); - delete m_usedNodes; } QCString DotClassGraph::getBaseName() const @@ -456,30 +458,24 @@ QCString DotClassGraph::writeGraph(FTextStream &out, void DotClassGraph::writeXML(FTextStream &t) { - QDictIterator dni(*m_usedNodes); - DotNode *node; - for (;(node=dni.current());++dni) + for (const auto &kv : m_usedNodes) { - node->writeXML(t,TRUE); + kv.second->writeXML(t,TRUE); } } void DotClassGraph::writeDocbook(FTextStream &t) { - QDictIterator dni(*m_usedNodes); - DotNode *node; - for (;(node=dni.current());++dni) + for (const auto &kv : m_usedNodes) { - node->writeDocbook(t,TRUE); + kv.second->writeDocbook(t,TRUE); } } void DotClassGraph::writeDEF(FTextStream &t) { - QDictIterator dni(*m_usedNodes); - DotNode *node; - for (;(node=dni.current());++dni) + for (const auto &kv : m_usedNodes) { - node->writeDEF(t); + kv.second->writeDEF(t); } } diff --git a/src/dotclassgraph.h b/src/dotclassgraph.h index 1874f54..168d315 100644 --- a/src/dotclassgraph.h +++ b/src/dotclassgraph.h @@ -17,7 +17,7 @@ #define DOTCLASSGRAPH_H #include "classdef.h" - +#include "dotnode.h" #include "dotgraph.h" /** Representation of a class inheritance or dependency graph */ @@ -46,13 +46,13 @@ protected: private: void buildGraph(const ClassDef *cd,DotNode *n,bool base,int distance); bool determineVisibleNodes(DotNode *rootNode,int maxNodes,bool includeParents); - void determineTruncatedNodes(QList &queue,bool includeParents); + void determineTruncatedNodes(DotNodeDeque &queue,bool includeParents); void addClass(const ClassDef *cd,DotNode *n,int prot,const char *label, const char *usedName,const char *templSpec, bool base,int distance); DotNode * m_startNode; - QDict * m_usedNodes; + DotNodeMap m_usedNodes; GraphType m_graphType; QCString m_collabFileName; QCString m_inheritFileName; diff --git a/src/dotdirdeps.cpp b/src/dotdirdeps.cpp index 8ec3a6e..4b8f1c3 100644 --- a/src/dotdirdeps.cpp +++ b/src/dotdirdeps.cpp @@ -20,6 +20,8 @@ #include "doxygen.h" #include "config.h" +using DirDefMap = std::map; + /** * 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 @@ -28,7 +30,7 @@ * @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 &directoriesInGraph) + DirDefMap &directoriesInGraph) { outStream << " " << directory->getOutputFileBase() << " [shape=box " "label=\"" << directory->shortName() << "\" "; @@ -41,7 +43,7 @@ static void drawDirectory(FTextStream &outStream, const DirDef *const directory, outStream << "color=\"red\" "; } outStream << "URL=\"" << directory->getOutputFileBase() << Doxygen::htmlFileExtension << "\"];\n"; - directoriesInGraph.insert(directory->getOutputFileBase(), directory); + directoriesInGraph.insert(std::make_pair(directory->getOutputFileBase().str(), directory)); } void writeDotDirDepGraph(FTextStream &t,const DirDef *dd,bool linkRelations) @@ -57,9 +59,9 @@ void writeDotDirDepGraph(FTextStream &t,const DirDef *dd,bool linkRelations) t << " node [ fontsize=\"" << fontSize << "\", fontname=\"" << fontName << "\"];\n"; t << " edge [ labelfontsize=\"" << fontSize << "\", labelfontname=\"" << fontName << "\"];\n"; - QDict dirsInGraph(257); + DirDefMap dirsInGraph; - dirsInGraph.insert(dd->getOutputFileBase(),dd); + dirsInGraph.insert(std::make_pair(dd->getOutputFileBase().str(),dd)); std::vector usedDirsNotDrawn; for(const auto& usedDir : dd->usedDirs()) @@ -148,17 +150,16 @@ void writeDotDirDepGraph(FTextStream &t,const DirDef *dd,bool linkRelations) } // add relations between all selected directories - const DirDef *dir; - QDictIterator di(dirsInGraph); - for (;(dir=di.current());++di) // foreach dir in the graph + for (const auto &kv : dirsInGraph) // foreach dir in the graph { + const DirDef *dir = kv.second; for (const auto &udir : dir->usedDirs()) { const DirDef *usedDir=udir->dir(); if ((dir!=dd || !udir->inherited()) && // only show direct dependencies for this dir (usedDir!=dd || !udir->inherited()) && // only show direct dependencies for this dir !usedDir->isParentOf(dir) && // don't point to own parent - dirsInGraph.find(usedDir->getOutputFileBase())) // only point to nodes that are in the graph + dirsInGraph.find(usedDir->getOutputFileBase().str())!=dirsInGraph.end()) // only point to nodes that are in the graph { QCString relationName; relationName.sprintf("dir_%06d_%06d",dir->dirCount(),usedDir->dirCount()); diff --git a/src/dotfilepatcher.cpp b/src/dotfilepatcher.cpp index 285c0bb..aafca34 100644 --- a/src/dotfilepatcher.cpp +++ b/src/dotfilepatcher.cpp @@ -255,7 +255,6 @@ bool DotFilePatcher::convertMapFile(FTextStream &t,const char *mapName, DotFilePatcher::DotFilePatcher(const char *patchFile) : m_patchFile(patchFile) { - m_maps.setAutoDelete(TRUE); } bool DotFilePatcher::isSVGFile() const @@ -266,30 +265,16 @@ bool DotFilePatcher::isSVGFile() const int DotFilePatcher::addMap(const QCString &mapFile,const QCString &relPath, bool urlOnly,const QCString &context,const QCString &label) { - int id = m_maps.count(); - Map *map = new Map; - map->mapFile = mapFile; - map->relPath = relPath; - map->urlOnly = urlOnly; - map->context = context; - map->label = label; - map->zoomable = FALSE; - map->graphId = -1; - m_maps.append(map); + int id = (int)m_maps.size(); + m_maps.emplace_back(mapFile,relPath,urlOnly,context,label); return id; } int DotFilePatcher::addFigure(const QCString &baseName, const QCString &figureName,bool heightCheck) { - int id = m_maps.count(); - Map *map = new Map; - map->mapFile = figureName; - map->urlOnly = heightCheck; - map->label = baseName; - map->zoomable = FALSE; - map->graphId = -1; - m_maps.append(map); + int id = (int)m_maps.size(); + m_maps.emplace_back(figureName,"",heightCheck,"",baseName); return id; } @@ -297,14 +282,8 @@ int DotFilePatcher::addSVGConversion(const QCString &relPath,bool urlOnly, const QCString &context,bool zoomable, int graphId) { - int id = m_maps.count(); - Map *map = new Map; - map->relPath = relPath; - map->urlOnly = urlOnly; - map->context = context; - map->zoomable = zoomable; - map->graphId = graphId; - m_maps.append(map); + int id = (int)m_maps.size(); + m_maps.emplace_back("",relPath,urlOnly,context,"",zoomable,graphId); return id; } @@ -312,14 +291,8 @@ int DotFilePatcher::addSVGObject(const QCString &baseName, const QCString &absImgName, const QCString &relPath) { - int id = m_maps.count(); - Map *map = new Map; - map->mapFile = absImgName; - map->relPath = relPath; - map->label = baseName; - map->zoomable = FALSE; - map->graphId = -1; - m_maps.append(map); + int id = (int)m_maps.size(); + m_maps.emplace_back(absImgName,relPath,false,"",baseName); return id; } @@ -332,10 +305,10 @@ bool DotFilePatcher::run() const QCString relPath; if (isSVGFile) { - Map *map = m_maps.at(0); // there is only one 'map' for a SVG file - interactiveSVG_local = interactiveSVG_local && map->zoomable; - graphId = map->graphId; - relPath = map->relPath; + const Map &map = m_maps.front(); // there is only one 'map' for a SVG file + interactiveSVG_local = interactiveSVG_local && map.zoomable; + graphId = map.graphId; + relPath = map.relPath; //printf("DotFilePatcher::addSVGConversion: file=%s zoomable=%d\n", // m_patchFile.data(),map->zoomable); } @@ -418,8 +391,8 @@ bool DotFilePatcher::run() const // unless we are inside the header of the SVG. // Then we replace it with another header. { - Map *map = m_maps.at(0); // there is only one 'map' for a SVG file - t << replaceRef(line,map->relPath,map->urlOnly,map->context,"_top"); + const Map &map = m_maps.front(); // there is only one 'map' for a SVG file + t << replaceRef(line,map.relPath,map.urlOnly,map.context,"_top"); } } else if ((i=line.find("")); - Map *map = m_maps.at(mapId); + const Map &map = m_maps.at(mapId); //printf("DotFilePatcher::writeSVGFigure: file=%s zoomable=%d\n", - // m_patchFile.data(),map->zoomable); - if (!writeSVGFigureLink(t,map->relPath,map->label,map->mapFile)) + // m_patchFile.data(),map.zoomable); + if (!writeSVGFigureLink(t,map.relPath,map.label,map.mapFile)) { - err("Problem extracting size from SVG file %s\n",map->mapFile.data()); + err("Problem extracting size from SVG file %s\n",map.mapFile.data()); } if (e!=-1) t << line.mid(e+3); } @@ -451,17 +424,17 @@ bool DotFilePatcher::run() const int mapId=-1; t << line.left(i); int n = sscanf(line.data()+i,"