Doxygen
Loading...
Searching...
No Matches
dotgfxhierarchytable.cpp
Go to the documentation of this file.
1/******************************************************************************
2*
3* Copyright (C) 1997-2019 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
18
19// standard includes
20#include <algorithm>
21
22// other includes
23#include "classlist.h"
24#include "dir.h"
25#include "doxygen.h"
26#include "language.h"
27#include "message.h"
28#include "util.h"
29#include "vhdldocgen.h"
30
32{
33 DString baseName;
34 if (m_prefix.empty())
35 baseName.sprintf("inherit_graph_%d", m_graphId);
36 else
37 baseName.sprintf("%sinherit_graph_%d",qPrint(m_prefix), m_graphId);
38 return baseName;
39}
40
42{
43 TextStream md5stream;
45 md5stream << " rankdir=\"LR\";\n";
46 for (auto node : m_rootNodes)
47 {
48 if (node->subgraphId()==m_rootSubgraphNode->subgraphId())
49 {
50 node->clearWriteFlag();
51 }
52 }
53 for (auto node : m_rootNodes)
54 {
55 if (node->subgraphId()==m_rootSubgraphNode->subgraphId())
56 {
57 node->write(md5stream,GraphType::Hierarchy,GraphOutputFormat::BITMAP,false,true,true);
58 }
59 }
60 writeGraphFooter(md5stream);
61 m_theGraph = md5stream.str();
62}
63
68
70 const DString &path,const DString &fileName,int id)
71{
73 m_graphId = id;
74 m_noDivTag = true;
75 m_zoomable = false;
77}
78
80 const DString &path,const DString &fileName)
81{
82 //printf("DotGfxHierarchyTable::writeGraph(%s)\n",name);
83 //printf("m_rootNodes=%p count=%d\n",m_rootNodes,m_rootNodes->count());
84
85 if (m_rootSubgraphs.empty()) return;
86
87 Dir d(path.str());
88 // store the original directory
89 if (!d.exists())
90 {
91 term("Output dir {} does not exist!\n",path);
92 }
93
94 // put each connected subgraph of the hierarchy in a row of the HTML output
95 out << "<table border=\"0\" cellspacing=\"10\" cellpadding=\"0\">\n";
96
97 int count=0;
98 std::stable_sort(m_rootSubgraphs.begin(),m_rootSubgraphs.end(),
99 [](auto n1,auto n2) { return dstricmp_sort(n1->label(),n2->label())<0; });
100 for (auto n : m_rootSubgraphs)
101 {
102 out << "<tr><td>";
103 createGraph(n,out,path,fileName,count++);
104 out << "</td></tr>\n";
105 }
106 out << "</table>\n";
107}
108
110{
111 //printf("addHierarchy '%s' baseClasses=%d\n",qPrint(cd->name()),cd->baseClasses()->count());
112 for (const auto &bcd : cd->subClasses())
113 {
114 ClassDef *bClass=bcd.classDef;
115 //printf(" Trying sub class='%s' usedNodes=%d\n",qPrint(bClass->name()),m_usedNodes->count());
116 if (bClass && bClass->isVisibleInHierarchy() && classHasVisibleRoot(bClass->baseClasses()))
117 {
118 auto it = m_usedNodes.find(bClass->name().str());
119 //printf(" Node '%s' Found visible class='%s'\n",qPrint(n->label()),
120 // qPrint(bClass->name()));
121 DotNode *root = nullptr;
122 if (it!=m_usedNodes.end()) // node already present
123 {
124 const auto &bn = it->second;
125 root = bn.get();
126 const auto &children = n->children();
127 auto child_it = std::find(children.begin(),children.end(),bn.get());
128 if (child_it==children.end()) // no arrow yet
129 {
130 n->addChild(bn.get(),EdgeInfo::protectionToColor(bcd.prot));
131 bn->addParent(n);
132 //printf(" Adding node %s to existing base node %s (c=%d,p=%d)\n",
133 // qPrint(n->label()),
134 // qPrint(bn->label()),
135 // bn->children() ? bn->children()->count() : 0,
136 // bn->parents() ? bn->parents()->count() : 0
137 // );
138 }
139 //else
140 //{
141 // printf(" Class already has an arrow!\n");
142 //}
143 }
144 else
145 {
146 DString tmp_url="";
147 if (bClass->isLinkable() && !bClass->isHidden())
148 {
149 tmp_url=bClass->getReference()+"$"+bClass->getOutputFileBase();
150 if (!bClass->anchor().empty())
151 {
152 tmp_url+="#"+bClass->anchor();
153 }
154 }
155 DString tooltip = bClass->briefDescriptionAsTooltip();
156 auto bn = std::make_unique<DotNode>(this,
157 bClass->displayName(),
158 tooltip,
159 tmp_url
160 );
161 n->addChild(bn.get(),EdgeInfo::protectionToColor(bcd.prot));
162 bn->addParent(n);
163 root = bn.get();
164 //printf(" Adding node %s to new base node %s (c=%d,p=%d)\n",
165 // qPrint(n->label()),
166 // qPrint(bn->label()),
167 // bn->children() ? bn->children()->count() : 0,
168 // bn->parents() ? bn->parents()->count() : 0
169 // );
170 //printf(" inserting %s (%p)\n",qPrint(bClass->name()),bn);
171 m_usedNodes.emplace(bClass->name().str(),std::move(bn)); // add node to the used list
172 }
173 if (visitedClasses.find(bClass)==visitedClasses.end() && !bClass->subClasses().empty())
174 {
175 visitedClasses.insert(bClass);
176 addHierarchy(root,bClass,visitedClasses);
177 }
178 }
179 }
180 //printf("end addHierarchy\n");
181}
182
184{
185 for (const auto &cd : cl)
186 {
187 //printf("Trying %s subClasses=%d\n",qPrint(cd->name()),cd->subClasses()->count());
188 if (cd->getLanguage()==SrcLangExt::VHDL &&
190 )
191 {
192 continue;
193 }
194 if (Config_getBool(OPTIMIZE_OUTPUT_SLICE) && cd->compoundType() != m_classType)
195 {
196 continue;
197 }
198 if (!classHasVisibleRoot(cd->baseClasses()) &&
199 cd->isVisibleInHierarchy()
200 ) // root node in the forest
201 {
202 DString tmp_url="";
203 if (cd->isLinkable() && !cd->isHidden())
204 {
205 tmp_url=cd->getReference()+"$"+cd->getOutputFileBase();
206 if (!cd->anchor().empty())
207 {
208 tmp_url+="#"+cd->anchor();
209 }
210 }
211 //printf("Inserting root class %s\n",qPrint(cd->name()));
212 DString tooltip = cd->briefDescriptionAsTooltip();
213 auto n = std::make_unique<DotNode>(this,
214 cd->displayName(),
215 tooltip,
216 tmp_url);
217 DotNode *root = n.get();
218
219 m_usedNodes.emplace(cd->name().str(),std::move(n));
220 m_rootNodes.push_back(root);
221 if (visitedClasses.find(cd.get())==visitedClasses.end() && !cd->subClasses().empty())
222 {
223 addHierarchy(root,cd.get(),visitedClasses);
224 visitedClasses.insert(cd.get());
225 }
226 }
227 }
228}
229
232 , m_classType(ct)
233{
234 // build a graph with each class as a node and the inheritance relations
235 // as edges
236 ClassDefSet visitedClasses;
237 addClassList(*Doxygen::classLinkedMap,visitedClasses);
239 // m_usedNodes now contains all nodes in the graph
240
241 // color the graph into a set of independent subgraphs
242 bool done=false;
243 int curColor=0;
244 while (!done) // there are still nodes to color
245 {
246 done=true; // we are done unless there are still uncolored nodes
247 for (auto n : m_rootNodes)
248 {
249 if (n->subgraphId()==-1) // not yet colored
250 {
251 //printf("Starting at node %s (%p): %d\n",qPrint(n->label()),n,curColor);
252 done=false; // still uncolored nodes
253 n->setSubgraphId(curColor);
254 n->markAsVisible();
255 n->colorConnectedNodes(curColor);
256 curColor++;
257 m_rootSubgraphs.push_back(n);
258 }
259 }
260 }
261
262 //printf("Number of independent subgraphs: %d\n",curColor);
263 for (auto n : m_rootSubgraphs)
264 {
265 //printf("Node %s color=%d (c=%d,p=%d)\n",
266 // qPrint(n->label()),n->m_subgraphId,
267 // n->children()?n->children()->count():0,
268 // n->parents()?n->parents()->count():0);
269 int number=0;
270 n->renumberNodes(number);
271 }
272}
273
constexpr auto prefix
Definition anchor.cpp:47
A abstract class representing of a compound symbol.
Definition classdef.h:100
virtual bool isVisibleInHierarchy() const =0
the class is visible in a class diagram, or class hierarchy
virtual const BaseClassList & baseClasses() const =0
Returns the list of base classes from which this class directly inherits.
CompoundType
The various compound types.
Definition classdef.h:105
virtual const BaseClassList & subClasses() const =0
Returns the list of sub classes that directly derive from this class.
A String class for use with Doxygen wrapping std::string and adding some additional functionality off...
Definition dstring.h:84
bool empty() const
Returns true iff the string is empty (std::string compatible alias for isEmpty()).
Definition dstring.h:148
DString & sprintf(const char *format,...)
Definition dstring.cpp:34
const std::string & str() const
Definition dstring.h:645
virtual bool isLinkable() const =0
virtual const DString & name() const =0
virtual DString briefDescriptionAsTooltip() const =0
virtual DString displayName(bool includeScope=true) const =0
virtual bool isHidden() const =0
virtual DString anchor() const =0
virtual DString getReference() const =0
virtual DString getOutputFileBase() const =0
Class representing a directory in the file system.
Definition dir.h:73
bool exists() const
Definition dir.cpp:263
std::vector< DotNode * > m_rootSubgraphs
void addClassList(const ClassLinkedMap &cl, ClassDefSet &visited)
DString getBaseName() const override
void addHierarchy(DotNode *n, const ClassDef *cd, ClassDefSet &visited)
void writeGraph(TextStream &t, const DString &path, const DString &fileName)
DString getMapLabel() const override
DotGfxHierarchyTable(const DString &prefix="", ClassDef::CompoundType ct=ClassDef::Class)
ClassDef::CompoundType m_classType
std::vector< DotNode * > m_rootNodes
void createGraph(DotNode *rootNode, TextStream &t, const DString &path, const DString &fileName, int id)
bool m_noDivTag
Definition dotgraph.h:98
DString m_theGraph
Definition dotgraph.h:95
static void writeGraphFooter(TextStream &t)
Definition dotgraph.cpp:295
bool m_zoomable
Definition dotgraph.h:99
DString writeGraph(TextStream &t, GraphOutputFormat gf, EmbeddedOutputFormat ef, const DString &path, const DString &fileName, const DString &relPath, bool writeImageMap=true, int graphId=-1)
Definition dotgraph.cpp:115
static void writeGraphHeader(TextStream &t, const DString &title=DString())
Definition dotgraph.cpp:270
friend class DotNode
Definition dotgraph.h:36
int subgraphId() const
Definition dotnode.h:107
void addChild(DotNode *n, EdgeInfo::Colors edgeColor=EdgeInfo::Purple, EdgeInfo::Styles edgeStyle=EdgeInfo::Solid, const DString &edgeLab=DString(), const DString &edgeURL=DString(), int edgeLabColor=-1)
Definition dotnode.cpp:340
DString label() const
Definition dotnode.h:102
const DotNodeRefVector & children() const
Definition dotnode.h:122
static ClassLinkedMap * classLinkedMap
Definition doxygen.h:88
static ClassLinkedMap * hiddenClassLinkedMap
Definition doxygen.h:89
static constexpr Colors protectionToColor(Protection prot)
Definition dotnode.h:43
Text streaming class that buffers data.
Definition textstream.h:36
std::string str() const
Return the contents of the buffer as a std::string object.
Definition textstream.h:232
virtual DString trGraphicalHierarchy()=0
static VhdlClasses convert(Protection prot)
Definition vhdldocgen.h:77
bool classHasVisibleRoot(const BaseClassList &bcl)
std::unordered_set< const ClassDef * > ClassDefSet
Definition classdef.h:91
#define Config_getBool(name)
Definition config.h:33
@ Hierarchy
Definition dotgraph.h:31
const char * qPrint(const char *s)
Definition dstring.h:783
Translator * theTranslator
Definition language.cpp:76
#define term(fmt,...)
Definition message.h:137
DString escapeCharsInString(const DString &name, bool allowDots, bool allowUnderscore)
Definition util.cpp:2688
A bunch of utility functions.