CACAO
GraphPrinter.hpp
Go to the documentation of this file.
1 /* toolbox/GraphPrinter.hpp - Graph Printer
2 
3  Copyright (C) 2013
4  CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 
6  This file is part of CACAO.
7 
8  This program is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 2, or (at
11  your option) any later version.
12 
13  This program is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  02110-1301, USA.
22 
23 */
24 
25 #ifndef _GRAPH_PRINTER_HPP
26 #define _GRAPH_PRINTER_HPP
27 
28 #include "toolbox/OStream.hpp"
29 
30 #include <string>
31 #include <set>
32 #include <map>
33 #include <utility>
34 
35 #include <cstdio>
36 
37 namespace cacao {
38 
39 template<typename GraphTy, typename NodeTy>
41 public:
42  typedef NodeTy NodeType;
43  typedef std::pair<NodeType,NodeType> EdgeType;
44  typedef typename std::set<NodeType> NodeListType;
45  typedef typename std::set<NodeType>::iterator iterator;
46  typedef typename std::set<NodeType>::const_iterator const_iterator;
47  typedef typename std::set<EdgeType>::iterator edge_iterator;
48  typedef typename std::set<EdgeType>::const_iterator const_edge_iterator;
49  typedef typename std::map<unsigned long,std::set<NodeType> >::iterator cluster_iterator;
50  typedef typename std::map<unsigned long,std::set<NodeType> >::const_iterator const_cluster_iterator;
51  typedef typename std::map<unsigned long,std::string>::iterator cluster_name_iterator;
52  typedef typename std::map<unsigned long,std::string>::const_iterator const_cluster_name_iterator;
53 
54 protected:
55  std::set<NodeType> nodes;
56  std::set<EdgeType> edges;
57  std::set<EdgeType> successors;
58  std::map<unsigned long,NodeListType> clusters;
59  std::map<unsigned long,std::string> cluster_name;
60 public:
61 
63  return nodes.begin();
64  }
65 
66  const_iterator end() const {
67  return nodes.end();
68  }
69 
71  return nodes.begin();
72  }
73 
75  return nodes.end();
76  }
77 
79  return edges.begin();
80  }
81 
83  return edges.end();
84  }
85 
87  return edges.begin();
88  }
89 
91  return edges.end();
92  }
93 
95  return clusters.begin();
96  }
97 
99  return clusters.begin();
100  }
101 
103  return clusters.end();
104  }
105 
107  return clusters.end();
108  }
109 
111  return cluster_name.begin();
112  }
113 
115  return cluster_name.begin();
116  }
117 
119  return cluster_name.end();
120  }
121 
123  return cluster_name.end();
124  }
125 
127  return cluster_name.find(k);
128  }
129 
131  return cluster_name.find(k);
132  }
133 
134  virtual OStream& getGraphName(OStream &OS) const {
135  return OS;
136  }
137 
138  virtual unsigned long getNodeID(const NodeType &node) const {
139  return (unsigned long)node;
140  }
141 
142  virtual OStream& getNodeLabel(OStream &OS, const NodeType &node) const {
143  return OS;
144  }
145 
146  virtual OStream& getNodeAttributes(OStream &OS, const NodeType &node) const {
147  return OS;
148  }
149 
150  virtual OStream& getEdgeLabel(OStream &OS, const EdgeType &e) const {
151  return OS;
152  }
153 
154  virtual OStream& getEdgeAttributes(OStream &OS, const EdgeType &e) const {
155  return OS;
156  }
157 
158 };
159 
160 template <class PrintableGraphTy>
162 public:
163  static void print(const char *filename, const PrintableGraphTy &G) {
164  FILE* file = fopen(filename,"w");
165  OStream OS(file);
166  printHeader(OS,G);
167  printNodes(OS,G);
168  printEdges(OS,G);
169  printCluster(OS,G);
170  printFooter(OS,G);
171  fclose(file);
172  }
173 
174  static void printHeader(OStream &OS, const PrintableGraphTy &G) {
175  OS<<"digraph g1 {\n";
176  OS<<"node [shape = box];\n";
177  OS<<"label = \"";
178  G.getGraphName(OS) <<"\";\n";
179  }
180 
181  static void printNodes(OStream &OS, const PrintableGraphTy &G) {
182  for(typename PrintableGraphTy::const_iterator i = G.begin(), e = G.end(); i != e; ++i) {
183  typename PrintableGraphTy::NodeType node(*i);
184  OS<< "\"node_" << G.getNodeID(node) << "\"" << "[label=\"";
185  G.getNodeLabel(OS,node) << "\", ";
186  G.getNodeAttributes(OS,node) << "];\n";
187  }
188  }
189 
190  static void printCluster(OStream &OS, const PrintableGraphTy &G) {
191  for(typename PrintableGraphTy::const_cluster_iterator i = G.cluster_begin(),
192  e = G.cluster_end(); i != e; ++i) {
193  unsigned long cid = i->first;
194  const std::set<typename PrintableGraphTy::NodeType> &set = i->second;
195  OS<<"subgraph cluster_" << cid << " {\n";
196  typename PrintableGraphTy::const_cluster_name_iterator name_it = G.cluster_name_find(cid);
197  if (name_it != G.cluster_name_end()) {
198  OS<<"label = \""<< name_it->second <<"\";\n";
199  }
200  for (typename std::set<typename PrintableGraphTy::NodeType>::const_iterator ii = set.begin(),
201  ee = set.end(); ii != ee; ++ii) {
202  typename PrintableGraphTy::NodeType node = (*ii);
203  OS<< "\"node_" << G.getNodeID(node) << "\";\n";
204  }
205  OS<<"}\n";
206  }
207  }
208  static void printEdges(OStream &OS, const PrintableGraphTy &G) {
209  for(typename PrintableGraphTy::const_edge_iterator i = G.edge_begin(),
210  e = G.edge_end(); i != e; ++i) {
211  typename PrintableGraphTy::NodeType a(i->first);
212  typename PrintableGraphTy::NodeType b(i->second);
213  OS<< "\"node_" << G.getNodeID(a) << "\" -> " << "\"node_" << G.getNodeID(b) << "\""
214  << "[label=\"";
215  G.getEdgeLabel(OS,*i) << "\", ";
216  G.getEdgeAttributes(OS,*i) << "];\n";
217  }
218  }
219 
220  static void printFooter(OStream &OS, const PrintableGraphTy &G) {
221  OS<<"}\n";
222  }
223 };
224 
225 } // end namespace cacao
226 
227 #endif // _GRAPH_PRINTER_HPP
228 
229 /*
230  * These are local overrides for various environment variables in Emacs.
231  * Please do not remove this and leave it at the end of the file, where
232  * Emacs will automagically detect them.
233  * ---------------------------------------------------------------------
234  * Local variables:
235  * mode: c++
236  * indent-tabs-mode: t
237  * c-basic-offset: 4
238  * tab-width: 4
239  * End:
240  * vim:noexpandtab:sw=4:ts=4:
241  */
const_cluster_iterator cluster_begin() const
std::set< NodeType > NodeListType
std::map< unsigned long, std::string > cluster_name
std::set< NodeType >::const_iterator const_iterator
edge_iterator edge_begin()
static void print(const char *filename, const PrintableGraphTy &G)
const_iterator begin() const
const_cluster_name_iterator cluster_name_begin() const
virtual OStream & getEdgeAttributes(OStream &OS, const EdgeType &e) const
std::map< unsigned long, std::set< NodeType > >::iterator cluster_iterator
std::set< NodeType >::iterator iterator
cluster_iterator cluster_begin()
virtual unsigned long getNodeID(const NodeType &node) const
std::set< NodeType > nodes
const_cluster_name_iterator cluster_name_find(unsigned long k) const
std::map< unsigned long, std::string >::iterator cluster_name_iterator
std::map< unsigned long, NodeListType > clusters
edge_iterator edge_end()
static void printNodes(OStream &OS, const PrintableGraphTy &G)
const_edge_iterator edge_begin() const
std::pair< NodeType, NodeType > EdgeType
cluster_name_iterator cluster_name_begin()
virtual OStream & getEdgeLabel(OStream &OS, const EdgeType &e) const
static void printHeader(OStream &OS, const PrintableGraphTy &G)
const_iterator end() const
Definition: set.cpp:44
Simple stream class for formatted output.
Definition: OStream.hpp:141
static void printFooter(OStream &OS, const PrintableGraphTy &G)
MIIterator i
cluster_name_iterator cluster_name_end()
OStream & OS
MIIterator e
virtual OStream & getNodeAttributes(OStream &OS, const NodeType &node) const
virtual OStream & getNodeLabel(OStream &OS, const NodeType &node) const
cluster_name_iterator cluster_name_find(unsigned long k)
std::set< EdgeType >::iterator edge_iterator
virtual OStream & getGraphName(OStream &OS) const
const_edge_iterator edge_end() const
std::set< EdgeType > successors
cluster_iterator cluster_end()
const_cluster_iterator cluster_end() const
std::map< unsigned long, std::set< NodeType > >::const_iterator const_cluster_iterator
static void printEdges(OStream &OS, const PrintableGraphTy &G)
std::map< unsigned long, std::string >::const_iterator const_cluster_name_iterator
std::set< EdgeType >::const_iterator const_edge_iterator
static void printCluster(OStream &OS, const PrintableGraphTy &G)
const_cluster_name_iterator cluster_name_end() const
std::set< EdgeType > edges