]> git.ipfire.org Git - thirdparty/gcc.git/blob - libbanshee/engine/dot.c
Merge tree-ssa-20020619-branch into mainline.
[thirdparty/gcc.git] / libbanshee / engine / dot.c
1 /*
2 * Copyright (c) 2000-2001
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 */
30
31 #include <assert.h>
32 #include <regions.h>
33 #include "dot.h"
34 #include "hash.h"
35
36 static FILE *of;
37 static hash_table node_hash_table;
38 static region dot_region;
39 static int node_count;
40 static const char *edge_op;
41
42 static void print_n_attrs(node_attr *attrs, int n)
43 {
44 int i;
45 fputc('[',of);
46
47 for (i = 0; i < n; i++)
48 {
49 const char *name;
50 switch (attrs[i].name)
51 {
52 case n_color:
53 name = "color";
54 break;
55 case n_fontcolor:
56 name = "fontcolor";
57 break;
58 case n_fontname:
59 name = "fontname";
60 break;
61 case n_fontsize:
62 name = "fontsize";
63 break;
64 case n_height:
65 name = "height";
66 break;
67 case n_width:
68 name = "width";
69 break;
70 case n_label:
71 name = "label";
72 break;
73 case n_layer:
74 name = "layer";
75 break;
76 case n_shape:
77 name = "shape";
78 break;
79 case n_shapefile:
80 name = "shapefile";
81 break;
82 case n_style:
83 name = "style";
84 break;
85 default:
86 name = "";
87 assert(0);
88 break;
89 }
90 if (i > 0)
91 fputc(',',of);
92 fprintf(of,"%s = %s",name,attrs[i].value);
93 }
94
95 fputc(']',of);
96 }
97
98 static void print_e_attrs(edge_attr *attrs, int n)
99 {
100 int i;
101 fputc('[',of);
102 for (i = 0; i < n; i++)
103 {
104 const char *name;
105 switch(attrs[i].name)
106 {
107 case e_color:
108 name = "color";
109 break;
110 case e_decorate:
111 name = "decorate";
112 break;
113 case e_dir:
114 name = "dir";
115 break;
116 case e_fontcolor:
117 name = "fontcolor";
118 break;
119 case e_fontname:
120 name = "fontname";
121 break;
122 case e_fontsize:
123 name = "fontsize";
124 break;
125 case e_id:
126 name = "id";
127 break;
128 case e_label:
129 name = "label";
130 break;
131 case e_layer:
132 name = "layer";
133 break;
134 case e_minlen:
135 name = "minlen";
136 break;
137 case e_style:
138 name = "style";
139 break;
140 case e_weight:
141 name = "weight";
142 break;
143 default :
144 name = "";
145 assert(0);
146 break;
147 }
148 if (i > 0)
149 fputc(',',of);
150 fprintf(of,"%s = %s",name,attrs[i].value);
151 }
152 fputc(']',of);
153 }
154
155 static void print_g_attrs(graph_attr *attrs, int n)
156 {
157 int i;
158 fputc('[',of);
159
160 for (i = 0; i < n; i++)
161 {
162 const char *name;
163 switch (attrs[i].name)
164 {
165 case g_center:
166 name = "center";
167 break;
168 case g_clusterrank:
169 name = "clusterrank";
170 break;
171 case g_color:
172 name = "color";
173 break;
174 case g_concentrate:
175 name = "concentrate";
176 break;
177 case g_fontcolor:
178 name = "fontcolor";
179 break;
180 case g_fontname:
181 name = "fontname";
182 break;
183 case g_fontsize:
184 name = "fontsize";
185 break;
186 case g_label:
187 name = "label";
188 break;
189 case g_layerseq:
190 name = "layerseq";
191 break;
192 case g_margin:
193 name = "margin";
194 break;
195 case g_mclimit:
196 name = "mclimit";
197 break;
198 case g_nodesep:
199 name = "nodesep";
200 break;
201 case g_nslimit:
202 name = "nslimit";
203 break;
204 case g_ordering:
205 name = "ordering";
206 break;
207 case g_orientation:
208 name = "orientation";
209 break;
210 case g_page:
211 name = "page";
212 break;
213 case g_rank:
214 name = "rank";
215 break;
216 case g_rankdir:
217 name = "rankdir";
218 break;
219 case g_ranksep:
220 name = "ranksep";
221 break;
222 case g_ratio:
223 name = "ratio";
224 break;
225 case g_size:
226 name = "size";
227 break;
228 default :
229 name = "";
230 assert(0);
231 break;
232 }
233 if (i > 0)
234 fputc(',',of);
235 fprintf(of,"%s = %s",name,attrs[i].value);
236 }
237 fputc(']',of);
238 }
239
240
241 void dot_start(FILE *to,const char *name,bool is_directed,bool is_strict)
242 {
243 const char *graph_type,*strict;
244
245
246 node_count = 0;
247 dot_region = newregion();
248 node_hash_table = make_string_hash_table(dot_region,8,TRUE);
249 of = to;
250
251 if (is_directed)
252 {
253 edge_op = "->";
254 graph_type = "digraph";
255 }
256 else
257 {
258 edge_op = "--";
259 graph_type = "graph";
260 }
261
262 if (is_strict)
263 strict = "strict";
264 else
265 strict = "";
266
267 fprintf(of,"%s %s %s{\n",strict,graph_type,name);
268
269 }
270
271 void dot_global_graph_style(graph_attr *attrs, int n)
272 {
273 fputs("graph ",of);
274 print_g_attrs(attrs,n);
275 fputc(';',of);
276 fputc('\n',of);
277 }
278
279 void dot_global_edge_style(edge_attr *attrs, int n)
280 {
281 fputs("edge ",of);
282 print_e_attrs(attrs,n);
283 fputc(';',of);
284 fputc('\n',of);
285 }
286
287 void dot_global_node_style(node_attr *attrs, int n)
288 {
289 fputs("node ",of);
290 print_n_attrs(attrs,n);
291 fputc(';',of);
292 fputc('\n',of);
293 }
294
295 /* by default, set the node's name to label */
296 static void declare_node(dot_node n, char *label)
297 {
298 int i;
299 char mangled[512];
300
301 if (label[0] == '\"')
302 mangled[0] = 's';
303 else
304 mangled[0] = label[0];
305
306 for (i = 1; label[i] && i < 512 ;i++)
307 {
308 if (label[i] == '\"')
309 mangled[i] = '_';
310 else mangled[i] = label[i];
311 }
312 mangled[i] = '\0';
313
314 fprintf(of,"nd_%d [label=\"%s\"]\n",n,mangled);
315 }
316
317 dot_node dot_get_node(char *label) deletes
318 {
319 dot_node result;
320 if (!hash_table_lookup(node_hash_table,(hash_key)label,(hash_data *)(char *)&result))
321 {
322 dot_node newnode = node_count++;
323
324 declare_node(newnode,label);
325 hash_table_insert(node_hash_table,
326 (hash_key)rstrdup(dot_region,label),
327 (hash_data)newnode);
328
329 return newnode;
330 }
331 else
332 return result;
333
334 }
335
336 void dot_node_style(dot_node node,node_attr *attrs, int n)
337 {
338 fprintf(of,"nd_%d ",node);
339 print_n_attrs(attrs,n);
340 fputc(';',of);
341 fputc('\n',of);
342 }
343
344 void dot_plain_edge(dot_node from, dot_node to)
345 {
346 fprintf(of,"nd_%d %s nd_%d;\n",from,edge_op,to);
347 }
348
349 void dot_styled_edge(dot_node from, dot_node to, edge_attr *attrs, int n)
350 {
351 fprintf(of,"nd_%d %s nd_%d ",from,edge_op,to);
352 print_e_attrs(attrs,n);
353 fputc(';',of);
354 fputc('\n',of);
355 }
356
357 void dot_end(void) deletes
358 {
359 fputc('}',of);
360 hash_table_delete(node_hash_table);
361 deleteregion_ptr(&dot_region);
362 }