Root/
Source at commit 1322 created 12 years 8 months ago. By meklort, Add doxygen to utils folder | |
---|---|
1 | /******************************************************************************␊ |
2 | *␊ |
3 | * $Id: dot.h,v 1.14 2001/03/19 19:27:40 root Exp $␊ |
4 | *␊ |
5 | *␊ |
6 | * Copyright (C) 1997-2011 by Dimitri van Heesch.␊ |
7 | *␊ |
8 | * Permission to use, copy, modify, and distribute this software and its␊ |
9 | * documentation under the terms of the GNU General Public License is hereby ␊ |
10 | * granted. No representations are made about the suitability of this software ␊ |
11 | * for any purpose. It is provided "as is" without express or implied warranty.␊ |
12 | * See the GNU General Public License for more details.␊ |
13 | *␊ |
14 | * Documents produced by Doxygen are derivative works derived from the␊ |
15 | * input used in their production; they are not affected by this license.␊ |
16 | *␊ |
17 | */␊ |
18 | ␊ |
19 | #ifndef _DOT_H␊ |
20 | #define _DOT_H␊ |
21 | ␊ |
22 | #include "qtbc.h"␊ |
23 | #include <qlist.h>␊ |
24 | #include <qdict.h>␊ |
25 | #include <qwaitcondition.h>␊ |
26 | #include <qmutex.h>␊ |
27 | #include <qqueue.h>␊ |
28 | #include <qthread.h>␊ |
29 | #include "sortdict.h"␊ |
30 | ␊ |
31 | class ClassDef;␊ |
32 | class FileDef;␊ |
33 | class FTextStream;␊ |
34 | class DotNodeList;␊ |
35 | class ClassSDict;␊ |
36 | class MemberDef;␊ |
37 | class Definition;␊ |
38 | class DirDef;␊ |
39 | class GroupDef;␊ |
40 | class DotGroupCollaboration;␊ |
41 | class DotRunnerQueue;␊ |
42 | ␊ |
43 | enum GraphOutputFormat { BITMAP , EPS };␊ |
44 | ␊ |
45 | /** @brief Attributes of an edge of a dot graph */␊ |
46 | struct EdgeInfo␊ |
47 | {␊ |
48 | enum Colors { Blue=0, Green=1, Red=2, Purple=3, Grey=4, Orange=5 };␊ |
49 | enum Styles { Solid=0, Dashed=1 };␊ |
50 | EdgeInfo() : m_color(0), m_style(0), m_labColor(0) {}␊ |
51 | ~EdgeInfo() {}␊ |
52 | int m_color;␊ |
53 | int m_style;␊ |
54 | QCString m_label;␊ |
55 | QCString m_url;␊ |
56 | int m_labColor;␊ |
57 | };␊ |
58 | ␊ |
59 | /** @brief A node in a dot graph */␊ |
60 | class DotNode␊ |
61 | {␊ |
62 | public:␊ |
63 | enum GraphType { Dependency, Inheritance, Collaboration, Hierarchy, CallGraph };␊ |
64 | enum TruncState { Unknown, Truncated, Untruncated };␊ |
65 | DotNode(int n,const char *lab,const char *tip,const char *url,␊ |
66 | bool rootNode=FALSE,ClassDef *cd=0);␊ |
67 | ~DotNode();␊ |
68 | void addChild(DotNode *n,␊ |
69 | int edgeColor=EdgeInfo::Purple,␊ |
70 | int edgeStyle=EdgeInfo::Solid,␊ |
71 | const char *edgeLab=0,␊ |
72 | const char *edgeURL=0,␊ |
73 | int edgeLabCol=-1␊ |
74 | );␊ |
75 | void addParent(DotNode *n);␊ |
76 | void deleteNode(DotNodeList &deletedList,SDict<DotNode> *skipNodes=0);␊ |
77 | void removeChild(DotNode *n);␊ |
78 | void removeParent(DotNode *n);␊ |
79 | int findParent( DotNode *n );␊ |
80 | void write(FTextStream &t,GraphType gt,GraphOutputFormat f,␊ |
81 | bool topDown,bool toChildren,bool backArrows,bool reNumber);␊ |
82 | int m_subgraphId;␊ |
83 | void clearWriteFlag();␊ |
84 | void writeXML(FTextStream &t,bool isClassGraph);␊ |
85 | void writeDEF(FTextStream &t);␊ |
86 | QCString label() const { return m_label; }␊ |
87 | int number() const { return m_number; }␊ |
88 | bool isVisible() const { return m_visible; }␊ |
89 | TruncState isTruncated() const { return m_truncated; }␊ |
90 | int distance() const { return m_distance; }␊ |
91 | ␊ |
92 | private:␊ |
93 | void colorConnectedNodes(int curColor);␊ |
94 | void writeBox(FTextStream &t,GraphType gt,GraphOutputFormat f,␊ |
95 | bool hasNonReachableChildren, bool reNumber=FALSE);␊ |
96 | void writeArrow(FTextStream &t,GraphType gt,GraphOutputFormat f,DotNode *cn,␊ |
97 | EdgeInfo *ei,bool topDown, bool pointBack=TRUE, bool reNumber=FALSE);␊ |
98 | void setDistance(int distance);␊ |
99 | const DotNode *findDocNode() const; // only works for acyclic graphs!␊ |
100 | void markAsVisible(bool b=TRUE) { m_visible=b; }␊ |
101 | void markAsTruncated(bool b=TRUE) { m_truncated=b ? Truncated : Untruncated; }␊ |
102 | int m_number;␊ |
103 | QCString m_label; //!< label text␊ |
104 | QCString m_tooltip; //!< node's tooltip␊ |
105 | QCString m_url; //!< url of the node (format: remote$local)␊ |
106 | QList<DotNode> *m_parents; //!< list of parent nodes (incoming arrows)␊ |
107 | QList<DotNode> *m_children; //!< list of child nodes (outgoing arrows)␊ |
108 | QList<EdgeInfo> *m_edgeInfo; //!< edge info for each child␊ |
109 | bool m_deleted; //!< used to mark a node as deleted␊ |
110 | bool m_written; //!< used to mark a node as written␊ |
111 | bool m_hasDoc; //!< used to mark a node as documented␊ |
112 | bool m_isRoot; //!< indicates if this is a root node␊ |
113 | ClassDef * m_classDef; //!< class representing this node (can be 0)␊ |
114 | bool m_visible; //!< is the node visible in the output␊ |
115 | TruncState m_truncated; //!< does the node have non-visible children/parents␊ |
116 | int m_distance; //!< shortest path to the root node␊ |
117 | ␊ |
118 | friend class DotGfxHierarchyTable;␊ |
119 | friend class DotClassGraph;␊ |
120 | friend class DotInclDepGraph;␊ |
121 | friend class DotNodeList;␊ |
122 | friend class DotCallGraph;␊ |
123 | friend class DotGroupCollaboration;␊ |
124 | ␊ |
125 | friend QCString computeMd5Signature(␊ |
126 | DotNode *root, GraphType gt,␊ |
127 | GraphOutputFormat f, ␊ |
128 | bool lrRank, bool renderParents,␊ |
129 | bool backArrows,␊ |
130 | QCString &graphStr␊ |
131 | );␊ |
132 | };␊ |
133 | ␊ |
134 | inline int DotNode::findParent( DotNode *n )␊ |
135 | {␊ |
136 | if( !m_parents )␊ |
137 | return -1;␊ |
138 | return m_parents->find(n);␊ |
139 | }␊ |
140 | ␊ |
141 | /** @brief Represents a graphical class hierarchy */␊ |
142 | class DotGfxHierarchyTable␊ |
143 | {␊ |
144 | public:␊ |
145 | DotGfxHierarchyTable();␊ |
146 | ~DotGfxHierarchyTable();␊ |
147 | void writeGraph(FTextStream &t,const char *path, const char *fileName) const;␊ |
148 | ␊ |
149 | private:␊ |
150 | void addHierarchy(DotNode *n,ClassDef *cd,bool hide);␊ |
151 | void addClassList(ClassSDict *cl);␊ |
152 | ␊ |
153 | QList<DotNode> *m_rootNodes; ␊ |
154 | QDict<DotNode> *m_usedNodes; ␊ |
155 | static int m_curNodeNumber;␊ |
156 | DotNodeList *m_rootSubgraphs;␊ |
157 | };␊ |
158 | ␊ |
159 | /** @brief Representation of a class inheritance or dependency graph */␊ |
160 | class DotClassGraph␊ |
161 | {␊ |
162 | public:␊ |
163 | DotClassGraph(ClassDef *cd,DotNode::GraphType t);␊ |
164 | ~DotClassGraph();␊ |
165 | bool isTrivial() const;␊ |
166 | bool isTooBig() const;␊ |
167 | QCString writeGraph(FTextStream &t,GraphOutputFormat f,const char *path,␊ |
168 | const char *fileName, const char *relPath, ␊ |
169 | bool TBRank=TRUE,bool imageMap=TRUE) const;␊ |
170 | ␊ |
171 | void writeXML(FTextStream &t);␊ |
172 | void writeDEF(FTextStream &t);␊ |
173 | QCString diskName() const;␊ |
174 | ␊ |
175 | private:␊ |
176 | void buildGraph(ClassDef *cd,DotNode *n,bool base,int distance);␊ |
177 | bool determineVisibleNodes(DotNode *rootNode,int maxNodes,bool includeParents);␊ |
178 | void determineTruncatedNodes(QList<DotNode> &queue,bool includeParents);␊ |
179 | void addClass(ClassDef *cd,DotNode *n,int prot,const char *label,␊ |
180 | const char *usedName,const char *templSpec,␊ |
181 | bool base,int distance);␊ |
182 | ␊ |
183 | DotNode * m_startNode;␊ |
184 | QDict<DotNode> * m_usedNodes;␊ |
185 | static int m_curNodeNumber;␊ |
186 | DotNode::GraphType m_graphType;␊ |
187 | QCString m_diskName;␊ |
188 | bool m_lrRank;␊ |
189 | };␊ |
190 | ␊ |
191 | /** @brief Representation of an include dependency graph */␊ |
192 | class DotInclDepGraph␊ |
193 | {␊ |
194 | public:␊ |
195 | DotInclDepGraph(FileDef *fd,bool inverse);␊ |
196 | ~DotInclDepGraph();␊ |
197 | QCString writeGraph(FTextStream &t, GraphOutputFormat f,␊ |
198 | const char *path,const char *fileName,const char *relPath,␊ |
199 | bool writeImageMap=TRUE) const;␊ |
200 | bool isTrivial() const;␊ |
201 | bool isTooBig() const;␊ |
202 | QCString diskName() const;␊ |
203 | void writeXML(FTextStream &t);␊ |
204 | ␊ |
205 | private:␊ |
206 | void buildGraph(DotNode *n,FileDef *fd,int distance);␊ |
207 | void determineVisibleNodes(QList<DotNode> &queue,int &maxNodes);␊ |
208 | void determineTruncatedNodes(QList<DotNode> &queue);␊ |
209 | ␊ |
210 | DotNode *m_startNode;␊ |
211 | QDict<DotNode> *m_usedNodes;␊ |
212 | static int m_curNodeNumber;␊ |
213 | QCString m_diskName;␊ |
214 | int m_maxDistance;␊ |
215 | bool m_inverse;␊ |
216 | };␊ |
217 | ␊ |
218 | /** @brief Representation of an call graph */␊ |
219 | class DotCallGraph␊ |
220 | {␊ |
221 | public:␊ |
222 | DotCallGraph(MemberDef *md,bool inverse);␊ |
223 | ~DotCallGraph();␊ |
224 | QCString writeGraph(FTextStream &t, GraphOutputFormat f,␊ |
225 | const char *path,const char *fileName,␊ |
226 | const char *relPath,bool writeImageMap=TRUE) const;␊ |
227 | void buildGraph(DotNode *n,MemberDef *md,int distance);␊ |
228 | bool isTrivial() const;␊ |
229 | bool isTooBig() const;␊ |
230 | void determineVisibleNodes(QList<DotNode> &queue, int &maxNodes);␊ |
231 | void determineTruncatedNodes(QList<DotNode> &queue);␊ |
232 | ␊ |
233 | private:␊ |
234 | DotNode *m_startNode;␊ |
235 | static int m_curNodeNumber;␊ |
236 | QDict<DotNode> *m_usedNodes;␊ |
237 | int m_maxDistance;␊ |
238 | int m_recDepth;␊ |
239 | bool m_inverse;␊ |
240 | QCString m_diskName;␊ |
241 | Definition * m_scope;␊ |
242 | };␊ |
243 | ␊ |
244 | /** @brief Representation of an directory dependency graph */␊ |
245 | class DotDirDeps␊ |
246 | {␊ |
247 | public:␊ |
248 | DotDirDeps(DirDef *dir);␊ |
249 | ~DotDirDeps();␊ |
250 | bool isTrivial() const;␊ |
251 | QCString writeGraph(FTextStream &out,␊ |
252 | GraphOutputFormat format,␊ |
253 | const char *path,␊ |
254 | const char *fileName,␊ |
255 | const char *relPath,␊ |
256 | bool writeImageMap=TRUE) const;␊ |
257 | private:␊ |
258 | DirDef *m_dir;␊ |
259 | };␊ |
260 | ␊ |
261 | /** @brief Representation of a group collaboration graph */␊ |
262 | class DotGroupCollaboration␊ |
263 | {␊ |
264 | public :␊ |
265 | enum EdgeType ␊ |
266 | { tmember = 0,␊ |
267 | tclass,␊ |
268 | tnamespace,␊ |
269 | tfile,␊ |
270 | tpages,␊ |
271 | tdir,␊ |
272 | thierarchy ␊ |
273 | };␊ |
274 | ␊ |
275 | class Link␊ |
276 | {␊ |
277 | public:␊ |
278 | Link(const QCString lab,const QCString &u) : label(lab), url(u) {}␊ |
279 | QCString label;␊ |
280 | QCString url;␊ |
281 | };␊ |
282 | ␊ |
283 | class Edge␊ |
284 | {␊ |
285 | public :␊ |
286 | Edge(DotNode *start,DotNode *end,EdgeType type) ␊ |
287 | : pNStart(start), pNEnd(end), eType(type)␊ |
288 | { links.setAutoDelete(TRUE); }␊ |
289 | ␊ |
290 | DotNode* pNStart;␊ |
291 | DotNode* pNEnd;␊ |
292 | EdgeType eType;␊ |
293 | ␊ |
294 | QList<Link> links;␊ |
295 | void write( FTextStream &t ) const;␊ |
296 | };␊ |
297 | ␊ |
298 | DotGroupCollaboration(GroupDef* gd);␊ |
299 | ~DotGroupCollaboration();␊ |
300 | QCString writeGraph(FTextStream &t, GraphOutputFormat format,␊ |
301 | const char *path,const char *fileName,const char *relPath,␊ |
302 | bool writeImageMap=TRUE) const;␊ |
303 | void buildGraph(GroupDef* gd);␊ |
304 | bool isTrivial() const;␊ |
305 | private :␊ |
306 | void addCollaborationMember( Definition* def, QCString& url, EdgeType eType );␊ |
307 | void addMemberList( class MemberList* ml );␊ |
308 | void writeGraphHeader(FTextStream &t) const;␊ |
309 | Edge* addEdge( DotNode* _pNStart, DotNode* _pNEnd, EdgeType _eType,␊ |
310 | const QCString& _label, const QCString& _url );␊ |
311 | ␊ |
312 | DotNode *m_rootNode;␊ |
313 | int m_curNodeId;␊ |
314 | QDict<DotNode> *m_usedNodes;␊ |
315 | QCString m_diskName;␊ |
316 | QList<Edge> m_edges;␊ |
317 | };␊ |
318 | ␊ |
319 | /** @brief Helper class to run dot from doxygen.␊ |
320 | */␊ |
321 | class DotRunner␊ |
322 | {␊ |
323 | public:␊ |
324 | struct CleanupItem␊ |
325 | {␊ |
326 | QCString path;␊ |
327 | QCString file;␊ |
328 | };␊ |
329 | ␊ |
330 | /** Creates a runner for a dot \a file. */␊ |
331 | DotRunner(const QCString &file,const QCString &fontPath,bool checkResult,␊ |
332 | const QCString &imageName = QCString());␊ |
333 | ␊ |
334 | /** Adds an additional job to the run.␊ |
335 | * Performing multiple jobs one file can be faster.␊ |
336 | */␊ |
337 | void addJob(const char *format,const char *output);␊ |
338 | ␊ |
339 | void addPostProcessing(const char *cmd,const char *args);␊ |
340 | ␊ |
341 | void preventCleanUp() { m_cleanUp = FALSE; }␊ |
342 | ␊ |
343 | /** Runs dot for all jobs added. */␊ |
344 | bool run();␊ |
345 | CleanupItem cleanup() const { return m_cleanupItem; }␊ |
346 | ␊ |
347 | private:␊ |
348 | QList<QCString> m_jobs;␊ |
349 | QCString m_postArgs;␊ |
350 | QCString m_postCmd;␊ |
351 | QCString m_file;␊ |
352 | QCString m_path;␊ |
353 | bool m_checkResult;␊ |
354 | QCString m_imageName;␊ |
355 | bool m_cleanUp;␊ |
356 | CleanupItem m_cleanupItem;␊ |
357 | };␊ |
358 | ␊ |
359 | /** @brief Helper class to insert a set of map file into an output file */␊ |
360 | class DotFilePatcher␊ |
361 | {␊ |
362 | public:␊ |
363 | struct Map␊ |
364 | {␊ |
365 | QCString mapFile;␊ |
366 | QCString relPath;␊ |
367 | bool urlOnly;␊ |
368 | QCString context;␊ |
369 | QCString label;␊ |
370 | };␊ |
371 | DotFilePatcher(const char *patchFile);␊ |
372 | int addMap(const QCString &mapFile,const QCString &relPath,␊ |
373 | bool urlOnly,const QCString &context,const QCString &label);␊ |
374 | int addFigure(const QCString &baseName,␊ |
375 | const QCString &figureName,bool heightCheck);␊ |
376 | int addSVGConversion(const QCString &relPath,bool urlOnly,const QCString &context);␊ |
377 | int addSVGObject(const QCString &baseName, const QCString &figureName,␊ |
378 | const QCString &relPath);␊ |
379 | bool run();␊ |
380 | ␊ |
381 | private:␊ |
382 | QList<Map> m_maps;␊ |
383 | QCString m_patchFile;␊ |
384 | };␊ |
385 | ␊ |
386 | class DotRunnerQueue␊ |
387 | {␊ |
388 | public:␊ |
389 | void enqueue(DotRunner *runner);␊ |
390 | DotRunner *dequeue();␊ |
391 | uint count() const;␊ |
392 | private:␊ |
393 | QWaitCondition m_bufferNotEmpty;␊ |
394 | QQueue<DotRunner> m_queue;␊ |
395 | mutable QMutex m_mutex;␊ |
396 | };␊ |
397 | ␊ |
398 | class DotWorkerThread : public QThread␊ |
399 | {␊ |
400 | public:␊ |
401 | DotWorkerThread(int id,DotRunnerQueue *queue);␊ |
402 | void run();␊ |
403 | void cleanup();␊ |
404 | private:␊ |
405 | int m_id;␊ |
406 | DotRunnerQueue *m_queue;␊ |
407 | QList<DotRunner::CleanupItem> m_cleanupItems;␊ |
408 | };␊ |
409 | ␊ |
410 | /** @brief singleton that manages dot relation actions */␊ |
411 | class DotManager␊ |
412 | {␊ |
413 | public:␊ |
414 | static DotManager *instance();␊ |
415 | void addRun(DotRunner *run);␊ |
416 | int addMap(const QCString &file,const QCString &mapFile,␊ |
417 | const QCString &relPath,bool urlOnly,␊ |
418 | const QCString &context,const QCString &label);␊ |
419 | int addFigure(const QCString &file,const QCString &baseName,␊ |
420 | const QCString &figureName,bool heightCheck);␊ |
421 | int addSVGConversion(const QCString &file,const QCString &relPath,␊ |
422 | bool urlOnly,const QCString &context);␊ |
423 | int addSVGObject(const QCString &file,const QCString &baseName,␊ |
424 | const QCString &figureNAme,const QCString &relPath);␊ |
425 | bool run();␊ |
426 | ␊ |
427 | private:␊ |
428 | DotManager();␊ |
429 | virtual ~DotManager();␊ |
430 | QList<DotRunner> m_dotRuns;␊ |
431 | SDict<DotFilePatcher> m_dotMaps;␊ |
432 | static DotManager *m_theInstance;␊ |
433 | DotRunnerQueue *m_queue;␊ |
434 | QList<DotWorkerThread> m_workers;␊ |
435 | };␊ |
436 | ␊ |
437 | ␊ |
438 | /** Generated a graphs legend page */␊ |
439 | void generateGraphLegend(const char *path);␊ |
440 | ␊ |
441 | void writeDotGraphFromFile(const char *inFile,const char *outDir,␊ |
442 | const char *outFile,GraphOutputFormat format);␊ |
443 | void writeDotImageMapFromFile(FTextStream &t,␊ |
444 | const QCString& inFile, const QCString& outDir,␊ |
445 | const QCString& relPath,const QCString& baseName,␊ |
446 | const QCString& context);␊ |
447 | ␊ |
448 | void writeDotDirDepGraph(FTextStream &t,DirDef *dd);␊ |
449 | ␊ |
450 | #endif␊ |
451 |