summaryrefslogtreecommitdiffstats
path: root/src/dotincldepgraph.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/dotincldepgraph.cpp')
-rw-r--r--src/dotincldepgraph.cpp238
1 files changed, 238 insertions, 0 deletions
diff --git a/src/dotincldepgraph.cpp b/src/dotincldepgraph.cpp
new file mode 100644
index 0000000..c968b68
--- /dev/null
+++ b/src/dotincldepgraph.cpp
@@ -0,0 +1,238 @@
+/******************************************************************************
+*
+* Copyright (C) 1997-2019 by Dimitri van Heesch.
+*
+* Permission to use, copy, modify, and distribute this software and its
+* documentation under the terms of the GNU General Public License is hereby
+* granted. No representations are made about the suitability of this software
+* for any purpose. It is provided "as is" without express or implied warranty.
+* See the GNU General Public License for more details.
+*
+* Documents produced by Doxygen are derivative works derived from the
+* input used in their production; they are not affected by this license.
+*
+*/
+
+#include "dotincldepgraph.h"
+#include "dotnode.h"
+#include "util.h"
+#include "config.h"
+
+void DotInclDepGraph::buildGraph(DotNode *n,const FileDef *fd,int distance)
+{
+ QList<IncludeInfo> *includeFiles = m_inverse ? fd->includedByFileList() : fd->includeFileList();
+ if (includeFiles)
+ {
+ QListIterator<IncludeInfo> ili(*includeFiles);
+ IncludeInfo *ii;
+ for (;(ii=ili.current());++ili)
+ {
+ const FileDef *bfd = ii->fileDef;
+ QCString in = ii->includeName;
+ //printf(">>>> in=`%s' bfd=%p\n",ii->includeName.data(),bfd);
+ bool doc=TRUE,src=FALSE;
+ if (bfd)
+ {
+ in = bfd->absFilePath();
+ doc = bfd->isLinkable() && !bfd->isHidden();
+ src = bfd->generateSourceFile();
+ }
+ if (doc || src || !Config_getBool(HIDE_UNDOC_RELATIONS))
+ {
+ QCString url="";
+ if (bfd) url=bfd->getOutputFileBase().copy();
+ if (!doc && src)
+ {
+ url=bfd->getSourceFileBase();
+ }
+ DotNode *bn = m_usedNodes->find(in);
+ if (bn) // file is already a node in the graph
+ {
+ n->addChild(bn,0,0,0);
+ bn->addParent(n);
+ bn->setDistance(distance);
+ }
+ else
+ {
+ QCString tmp_url;
+ QCString tooltip;
+ if (bfd)
+ {
+ tmp_url=doc || src ? bfd->getReference()+"$"+url : QCString();
+ tooltip = bfd->briefDescriptionAsTooltip();
+ }
+ bn = new DotNode(getNextNodeNumber(),// n
+ ii->includeName, // label
+ tooltip, // tip
+ tmp_url, // url
+ FALSE, // rootNode
+ 0); // cd
+ n->addChild(bn,0,0,0);
+ bn->addParent(n);
+ m_usedNodes->insert(in,bn);
+ bn->setDistance(distance);
+
+ if (bfd) buildGraph(bn,bfd,distance+1);
+ }
+ }
+ }
+ }
+}
+
+void DotInclDepGraph::determineVisibleNodes(QList<DotNode> &queue, int &maxNodes)
+{
+ while (queue.count()>0 && maxNodes>0)
+ {
+ DotNode *n = queue.take(0);
+ if (!n->isVisible() && n->distance()<=Config_getInt(MAX_DOT_GRAPH_DEPTH)) // not yet processed
+ {
+ n->markAsVisible();
+ maxNodes--;
+ // add direct children
+ if (n->children())
+ {
+ QListIterator<DotNode> li(*n->children());
+ const DotNode *dn;
+ for (li.toFirst();(dn=li.current());++li)
+ {
+ queue.append(dn);
+ }
+ }
+ }
+ }
+}
+
+void DotInclDepGraph::determineTruncatedNodes(QList<DotNode> &queue)
+{
+ while (queue.count()>0)
+ {
+ DotNode *n = queue.take(0);
+ if (n->isVisible() && n->isTruncated()==DotNode::Unknown)
+ {
+ bool truncated = FALSE;
+ if (n->children())
+ {
+ QListIterator<DotNode> li(*n->children());
+ const DotNode *dn;
+ for (li.toFirst();(dn=li.current());++li)
+ {
+ if (!dn->isVisible())
+ {
+ truncated = TRUE;
+ }
+ else
+ {
+ queue.append(dn);
+ }
+ }
+ }
+ n->markAsTruncated(truncated);
+ }
+ }
+}
+
+DotInclDepGraph::DotInclDepGraph(const FileDef *fd,bool inverse)
+{
+ m_inverse = inverse;
+ ASSERT(fd!=0);
+ m_inclDepFileName = fd->includeDependencyGraphFileName();
+ m_inclByDepFileName = fd->includedByDependencyGraphFileName();
+ QCString tmp_url=fd->getReference()+"$"+fd->getOutputFileBase();
+ QCString tooltip = fd->briefDescriptionAsTooltip();
+ m_startNode = new DotNode(getNextNodeNumber(),
+ fd->docName(),
+ tooltip,
+ tmp_url.data(),
+ TRUE); // root node
+ m_startNode->setDistance(0);
+ m_usedNodes = new QDict<DotNode>(1009);
+ m_usedNodes->insert(fd->absFilePath(),m_startNode);
+ buildGraph(m_startNode,fd,1);
+
+ int maxNodes = Config_getInt(DOT_GRAPH_MAX_NODES);
+ QList<DotNode> openNodeQueue;
+ openNodeQueue.append(m_startNode);
+ determineVisibleNodes(openNodeQueue,maxNodes);
+ openNodeQueue.clear();
+ openNodeQueue.append(m_startNode);
+ determineTruncatedNodes(openNodeQueue);
+}
+
+DotInclDepGraph::~DotInclDepGraph()
+{
+ DotNode::deleteNodes(m_startNode);
+ delete m_usedNodes;
+}
+
+QCString DotInclDepGraph::getBaseName() const
+{
+ if (m_inverse)
+ {
+ return m_inclByDepFileName;
+ }
+ else
+ {
+ return m_inclDepFileName;
+ }
+}
+
+void DotInclDepGraph::computeTheGraph()
+{
+ computeGraph(m_startNode, Dependency, m_graphFormat, "", FALSE,
+ m_inverse, m_startNode->label(), m_theGraph);
+}
+
+QCString DotInclDepGraph::getMapLabel() const
+{
+ if (m_inverse)
+ {
+ return escapeCharsInString(m_startNode->label(),FALSE) + "dep";
+ }
+ else
+ {
+ return escapeCharsInString(m_startNode->label(),FALSE);
+ }
+}
+
+QCString DotInclDepGraph::writeGraph(FTextStream &out,
+ GraphOutputFormat graphFormat,
+ EmbeddedOutputFormat textFormat,
+ const char *path,
+ const char *fileName,
+ const char *relPath,
+ bool generateImageMap,
+ int graphId)
+{
+ return DotGraph::writeGraph(out, graphFormat, textFormat, path, fileName, relPath, generateImageMap, graphId);
+}
+
+bool DotInclDepGraph::isTrivial() const
+{
+ return m_startNode->children()==0;
+}
+
+bool DotInclDepGraph::isTooBig() const
+{
+ int numNodes = m_startNode->children() ? m_startNode->children()->count() : 0;
+ return numNodes>=Config_getInt(DOT_GRAPH_MAX_NODES);
+}
+
+void DotInclDepGraph::writeXML(FTextStream &t)
+{
+ QDictIterator<DotNode> dni(*m_usedNodes);
+ DotNode *node;
+ for (;(node=dni.current());++dni)
+ {
+ node->writeXML(t,FALSE);
+ }
+}
+
+void DotInclDepGraph::writeDocbook(FTextStream &t)
+{
+ QDictIterator<DotNode> dni(*m_usedNodes);
+ DotNode *node;
+ for (;(node=dni.current());++dni)
+ {
+ node->writeDocbook(t,FALSE);
+ }
+}