Graphviz  2.39.20141220.0545
dotinit.c
Go to the documentation of this file.
1 /* $Id$ $Revision$ */
2 /* vim:set shiftwidth=4 ts=8: */
3 
4 /*************************************************************************
5  * Copyright (c) 2011 AT&T Intellectual Property
6  * All rights reserved. This program and the accompanying materials
7  * are made available under the terms of the Eclipse Public License v1.0
8  * which accompanies this distribution, and is available at
9  * http://www.eclipse.org/legal/epl-v10.html
10  *
11  * Contributors: See CVS logs. Details at http://www.graphviz.org/
12  *************************************************************************/
13 
14 
15 #include <time.h>
16 #include "dot.h"
17 #include "pack.h"
18 #include "aspect.h"
19 
20 static void
21 dot_init_subg(graph_t * g, graph_t* droot)
22 {
23  graph_t* subg;
24 
25  if ((g != agroot(g)))
26  agbindrec(g, "Agraphinfo_t", sizeof(Agraphinfo_t), TRUE);
27  if (g == droot)
28  GD_dotroot(agroot(g)) = droot;
29 
30  for (subg = agfstsubg(g); subg; subg = agnxtsubg(subg)) {
31  dot_init_subg(subg, droot);
32  }
33 }
34 
35 
36 static void
37 dot_init_node(node_t * n)
38 {
39  agbindrec(n, "Agnodeinfo_t", sizeof(Agnodeinfo_t), TRUE); //graph custom data
42  alloc_elist(4, ND_in(n));
43  alloc_elist(4, ND_out(n));
44  alloc_elist(2, ND_flat_in(n));
45  alloc_elist(2, ND_flat_out(n));
46  alloc_elist(2, ND_other(n));
47  ND_UF_size(n) = 1;
48 }
49 
50 static void
51 dot_init_edge(edge_t * e)
52 {
53  char *tailgroup, *headgroup;
54  agbindrec(e, "Agedgeinfo_t", sizeof(Agedgeinfo_t), TRUE); //graph custom data
56 
57  ED_weight(e) = late_int(e, E_weight, 1, 0);
58  tailgroup = late_string(agtail(e), N_group, "");
59  headgroup = late_string(aghead(e), N_group, "");
60  ED_count(e) = ED_xpenalty(e) = 1;
61  if (tailgroup[0] && (tailgroup == headgroup)) {
62  ED_xpenalty(e) = CL_CROSS;
63  ED_weight(e) *= 100;
64  }
65  if (nonconstraint_edge(e)) {
66  ED_xpenalty(e) = 0;
67  ED_weight(e) = 0;
68  }
69 
70  ED_showboxes(e) = late_int(e, E_showboxes, 0, 0);
71  ED_minlen(e) = late_int(e, E_minlen, 1, 0);
72 }
73 
74 void
76 {
77  node_t *n;
78  edge_t *e;
79 
80  for (n = agfstnode(g); n; n = agnxtnode(g, n))
81  dot_init_node(n);
82  for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
83  for (e = agfstout(g, n); e; e = agnxtout(g, e))
84  dot_init_edge(e);
85  }
86 }
87 
88 #if 0 /* not used */
89 static void free_edge_list(elist L)
90 {
91  edge_t *e;
92  int i;
93 
94  for (i = 0; i < L.size; i++) {
95  e = L.list[i];
96  free(e);
97  }
98 }
99 #endif
100 
101 static void
102 dot_cleanup_node(node_t * n)
103 {
104  free_list(ND_in(n));
105  free_list(ND_out(n));
107  free_list(ND_flat_in(n));
108  free_list(ND_other(n));
109  free_label(ND_label(n));
110  free_label(ND_xlabel(n));
111  if (ND_shape(n))
112  ND_shape(n)->fns->freefn(n);
113  agdelrec(n, "Agnodeinfo_t");
114 }
115 
116 static void free_virtual_edge_list(node_t * n)
117 {
118  edge_t *e;
119  int i;
120 
121  for (i = ND_in(n).size - 1; i >= 0; i--) {
122  e = ND_in(n).list[i];
123  delete_fast_edge(e);
124  free(e->base.data);
125  free(e);
126  }
127  for (i = ND_out(n).size - 1; i >= 0; i--) {
128  e = ND_out(n).list[i];
129  delete_fast_edge(e);
130  free(e->base.data);
131  free(e);
132  }
133 }
134 
135 static void free_virtual_node_list(node_t * vn)
136 {
137  node_t *next_vn;
138 
139  while (vn) {
140  next_vn = ND_next(vn);
141  free_virtual_edge_list(vn);
142  if (ND_node_type(vn) == VIRTUAL) {
143  free_list(ND_out(vn));
144  free_list(ND_in(vn));
145  free(vn->base.data);
146  free(vn);
147  }
148  vn = next_vn;
149  }
150 }
151 
152 static void
153 dot_cleanup_graph(graph_t * g)
154 {
155  int i;
156  graph_t *subg;
157  for (subg = agfstsubg(g); subg; subg = agnxtsubg(subg)) {
158  dot_cleanup_graph(subg);
159  }
160  if (GD_clust(g)) free (GD_clust(g));
161  if (GD_rankleader(g)) free (GD_rankleader(g));
162 
163  free_list(GD_comp(g));
164  if (GD_rank(g)) {
165  for (i = GD_minrank(g); i <= GD_maxrank(g); i++)
166  free(GD_rank(g)[i].av);
167  if (GD_minrank(g) == -1)
168  free(GD_rank(g)-1);
169  else
170  free(GD_rank(g));
171  }
172  if (g != agroot(g)) {
173  free_label (GD_label(g));
174  agdelrec(g,"Agraphinfo_t");
175  }
176 }
177 
178 /* delete the layout (but retain the underlying graph) */
180 {
181  node_t *n;
182  edge_t *e;
183 
184  free_virtual_node_list(GD_nlist(g));
185  for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
186  for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
187  gv_cleanup_edge(e);
188  }
189  dot_cleanup_node(n);
190  }
191  dot_cleanup_graph(g);
192 }
193 
194 #ifdef DEBUG
195 int
196 fastn (graph_t * g)
197 {
198  node_t* u;
199  int cnt = 0;
200  for (u = GD_nlist(g); u; u = ND_next(u)) cnt++;
201  return cnt;
202 }
203 
204 static void
205 dumpRanks (graph_t * g)
206 {
207  int i, j;
208  node_t* u;
209  rank_t *rank = GD_rank(g);
210  int rcnt = 0;
211  for (i = GD_minrank(g); i <= GD_maxrank(g); i++) {
212  fprintf (stderr, "[%d] :", i);
213  for (j = 0; j < rank[i].n; j++) {
214  u = rank[i].v[j];
215  rcnt++;
216  if (streq(agnameof(u),"virtual"))
217  fprintf (stderr, " %x", u);
218  else
219  fprintf (stderr, " %s", agnameof(u));
220 
221  }
222  fprintf (stderr, "\n");
223  }
224  fprintf (stderr, "count %d rank count = %d\n", fastn(g), rcnt);
225 }
226 #endif
227 
228 
229 static void
230 remove_from_rank (Agraph_t * g, Agnode_t* n)
231 {
232  Agnode_t* v = NULL;
233  int j, rk = ND_rank(n);
234 
235  for (j = 0; j < GD_rank(g)[rk].n; j++) {
236  v = GD_rank(g)[rk].v[j];
237  if (v == n) {
238  for (j++; j < GD_rank(g)[rk].n; j++) {
239  GD_rank(g)[rk].v[j-1] = GD_rank(g)[rk].v[j];
240  }
241  GD_rank(g)[rk].n--;
242  break;
243  }
244  }
245  assert (v == n); /* if found */
246 }
247 
248 /* removeFill:
249  * This removes all of the fill nodes added in mincross.
250  * It appears to be sufficient to remove them only from the
251  * rank array and fast node list of the root graph.
252  */
253 static void
254 removeFill (Agraph_t * g)
255 {
256  Agnode_t* n;
257  Agnode_t* nxt;
258  Agraph_t* sg = agsubg (g, "_new_rank", 0);
259 
260  if (!sg) return;
261  for (n = agfstnode(sg); n; n = nxt) {
262  nxt = agnxtnode(sg, n);
263  delete_fast_node (g, n);
264  remove_from_rank (g, n);
265  dot_cleanup_node (n);
266  agdelnode(g, n);
267  }
268  agdelsubg (g, sg);
269 
270 }
271 
272 #define ag_xset(x,a,v) agxset(x,a,v)
273 #define agnodeattr(g,n,v) agattr(g,AGNODE,n,v)
274 
275 static void
276 attach_phase_attrs (Agraph_t * g, int maxphase)
277 {
278  Agsym_t* rk = agnodeattr(g,"rank","");
279  Agsym_t* order = agnodeattr(g,"order","");
280  Agnode_t* n;
281  char buf[BUFSIZ];
282 
283  for (n = agfstnode(g); n; n = agnxtnode(g,n)) {
284  if (maxphase >= 1) {
285  sprintf(buf, "%d", ND_rank(n));
286  ag_xset(n,rk,buf);
287  }
288  if (maxphase >= 2) {
289  sprintf(buf, "%d", ND_order(n));
290  ag_xset(n,order,buf);
291  }
292  }
293 }
294 
295 static void dotLayout(Agraph_t * g)
296 {
297  aspect_t aspect;
298  aspect_t* asp;
299  int maxphase = late_int(g, agfindgraphattr(g,"phase"), -1, 1);
300 
301  setEdgeType (g, ET_SPLINE);
302  asp = setAspect (g, &aspect);
303 
304  dot_init_subg(g,g);
306 
307  do {
308  dot_rank(g, asp);
309  if (maxphase == 1) {
310  attach_phase_attrs (g, 1);
311  return;
312  }
313  if (aspect.badGraph) {
314  agerr(AGWARN, "dot does not support the aspect attribute for disconnected graphs or graphs with clusters\n");
315  asp = NULL;
316  aspect.nextIter = 0;
317  }
318  dot_mincross(g, (asp != NULL));
319  if (maxphase == 2) {
320  attach_phase_attrs (g, 2);
321  return;
322  }
323  dot_position(g, asp);
324  if (maxphase == 3) {
325  attach_phase_attrs (g, 2); /* positions will be attached on output */
326  return;
327  }
328  aspect.nPasses--;
329  } while (aspect.nextIter && aspect.nPasses);
330  if (GD_flags(g) & NEW_RANK)
331  removeFill (g);
332  dot_sameports(g);
333  dot_splines(g);
334  if (mapbool(agget(g, "compound")))
336 }
337 
338 static void
339 initSubg (Agraph_t* sg, Agraph_t* g)
340 {
341  agbindrec(sg, "Agraphinfo_t", sizeof(Agraphinfo_t), TRUE);
342  GD_drawing(sg) = NEW(layout_t);
343  GD_drawing(sg)->quantum = GD_drawing(g)->quantum;
344  GD_drawing(sg)->dpi = GD_drawing(g)->dpi;
345  GD_gvc(sg) = GD_gvc (g);
346  GD_charset(sg) = GD_charset (g);
347  GD_rankdir2(sg) = GD_rankdir2 (g);
348  GD_nodesep(sg) = GD_nodesep(g);
349  GD_ranksep(sg) = GD_ranksep(g);
350  GD_fontnames(sg) = GD_fontnames(g);
351 }
352 
353 /* attachPos:
354  * the packing library assumes all units are in inches stored in ND_pos, so we
355  * have to copy the position info there.
356  */
357 static void
358 attachPos (Agraph_t* g)
359 {
360  node_t* np;
361  double* ps = N_NEW(2*agnnodes(g), double);
362 
363  for (np = agfstnode(g); np; np = agnxtnode(g, np)) {
364  ND_pos(np) = ps;
365  ps[0] = PS2INCH(ND_coord(np).x);
366  ps[1] = PS2INCH(ND_coord(np).y);
367  ps += 2;
368  }
369 }
370 
371 /* resetCoord:
372  * Store new position info from pack library call, stored in ND_pos in inches,
373  * back to ND_coord in points.
374  */
375 static void
376 resetCoord (Agraph_t* g)
377 {
378  node_t* np = agfstnode(g);
379  double* sp = ND_pos(np);
380  double* ps = sp;
381 
382  for (np = agfstnode(g); np; np = agnxtnode(g, np)) {
383  ND_pos(np) = 0;
384  ND_coord(np).x = INCH2PS(ps[0]);
385  ND_coord(np).y = INCH2PS(ps[1]);
386  ps += 2;
387  }
388  free (sp);
389 }
390 
391 /* copyCluster:
392  */
393 static void
394 copyCluster (Agraph_t* scl, Agraph_t* cl)
395 {
396  int nclust, j;
397  Agraph_t* cg;
398 
399  agbindrec(cl, "Agraphinfo_t", sizeof(Agraphinfo_t), TRUE);
400  GD_bb(cl) = GD_bb(scl);
401  GD_label_pos(cl) = GD_label_pos(scl);
402  memcpy(GD_border(cl), GD_border(scl), 4*sizeof(pointf));
403  nclust = GD_n_cluster(cl) = GD_n_cluster(scl);
404  GD_clust(cl) = N_NEW(nclust+1,Agraph_t*);
405  for (j = 1; j <= nclust; j++) {
406  cg = mapClust(GD_clust(scl)[j]);
407  GD_clust(cl)[j] = cg;
408  copyCluster (GD_clust(scl)[j], cg);
409  }
410  /* transfer cluster label to original cluster */
411  GD_label(cl) = GD_label(scl);
412  GD_label(scl) = NULL;
413 }
414 
415 /* copyClusterInfo:
416  * Copy cluster tree and info from components to main graph.
417  * Note that the original clusters have no Agraphinfo_t at this time.
418  */
419 static void
420 copyClusterInfo (int ncc, Agraph_t** ccs, Agraph_t* root)
421 {
422  int j, i, nclust = 0;
423  Agraph_t* sg;
424  Agraph_t* cg;
425 
426  for (i = 0; i < ncc; i++)
427  nclust += GD_n_cluster(ccs[i]);
428 
429  GD_n_cluster(root) = nclust;
430  GD_clust(root) = N_NEW(nclust+1,Agraph_t*);
431  nclust = 1;
432  for (i = 0; i < ncc; i++) {
433  sg = ccs[i];
434  for (j = 1; j <= GD_n_cluster(sg); j++) {
435  cg = mapClust(GD_clust(sg)[j]);
436  GD_clust(root)[nclust++] = cg;
437  copyCluster (GD_clust(sg)[j], cg);
438  }
439  }
440 }
441 
442 /* doDot:
443  * Assume g has nodes.
444  */
445 static void doDot (Agraph_t* g)
446 {
447  Agraph_t **ccs;
448  Agraph_t *sg;
449  int ncc;
450  int i;
451  pack_info pinfo;
452  int Pack = getPack(g, -1, CL_OFFSET);
453  pack_mode mode = getPackModeInfo (g, l_undef, &pinfo);
454  getPackInfo(g, l_node, CL_OFFSET, &pinfo);
455 
456  if ((mode == l_undef) && (Pack < 0)) {
457  /* No pack information; use old dot with components
458  * handled during layout
459  */
460  dotLayout(g);
461  } else {
462  /* fill in default values */
463  if (mode == l_undef)
464  pinfo.mode = l_graph;
465  else if (Pack < 0)
466  Pack = CL_OFFSET;
467  pinfo.margin = Pack;
468  pinfo.fixed = 0;
469 
470  /* components using clusters */
471  ccs = cccomps(g, &ncc, 0);
472  if (ncc == 1) {
473  dotLayout(g);
474  } else if (GD_drawing(g)->ratio_kind == R_NONE) {
475  pinfo.doSplines = 1;
476 
477  for (i = 0; i < ncc; i++) {
478  sg = ccs[i];
479  initSubg (sg, g);
480  dotLayout (sg);
481  }
482  attachPos (g);
483  packSubgraphs(ncc, ccs, g, &pinfo);
484  resetCoord (g);
485  copyClusterInfo (ncc, ccs, g);
486  } else {
487  /* Not sure what semantics should be for non-trivial ratio
488  * attribute with multiple components.
489  * One possibility is to layout nodes, pack, then apply the ratio
490  * adjustment. We would then have to re-adjust all positions.
491  */
492  dotLayout(g);
493  }
494 
495  for (i = 0; i < ncc; i++) {
496  free (GD_drawing(ccs[i]));
497  dot_cleanup_graph(ccs[i]);
498  agdelete(g, ccs[i]);
499  }
500  free(ccs);
501  }
502 }
503 
505 {
506  if (agnnodes(g)) doDot (g);
508 }
509 
510 Agraph_t * dot_root (void* p)
511 {
512  return GD_dotroot(agroot(p));
513 }
514 
void dotneato_postprocess(Agraph_t *g)
Definition: postproc.c:693
#define GD_label(g)
Definition: types.h:361
void free_label(textlabel_t *p)
Definition: labels.c:209
#define ND_rank(n)
Definition: types.h:490
Agnode_t * agtail(Agedge_t *e)
Definition: edge.c:494
#define GD_nlist(g)
Definition: types.h:381
#define ET_SPLINE
Definition: const.h:274
Agnode_t * aghead(Agedge_t *e)
Definition: edge.c:502
#define N_NEW(n, t)
Definition: memory.h:36
void delete_fast_node(Agraph_t *, Agnode_t *)
Definition: fastgr.c:229
int nextIter
Definition: aspect.h:22
#define CL_CROSS
Definition: const.h:157
pack_mode
Definition: pack.h:37
#define GD_rankleader(g)
Definition: types.h:385
#define agnodeattr(g, n, v)
Definition: dotinit.c:273
Definition: pack.h:49
#define ND_xlabel(n)
Definition: types.h:471
int agdelete(Agraph_t *g, void *obj)
Definition: obj.c:16
Definition: pack.h:37
int nPasses
Definition: aspect.h:23
#define GD_n_cluster(g)
Definition: types.h:376
#define GD_border(g)
Definition: types.h:342
#define GD_rankdir2(g)
Definition: types.h:363
#define ND_node_type(n)
Definition: types.h:479
#define ND_flat_in(n)
Definition: types.h:459
Agedge_t * agfstout(Agraph_t *g, Agnode_t *n)
Definition: edge.c:25
#define assert(x)
Definition: cghdr.h:48
void dot_sameports(Agraph_t *)
Definition: sameport.c:34
Definition: geom.h:30
#define ND_UF_size(n)
Definition: types.h:454
#define ED_weight(e)
Definition: types.h:560
#define GD_flags(g)
Definition: types.h:349
void dot_splines(Agraph_t *)
Definition: dotsplines.c:506
void common_init_node(node_t *n)
Definition: utils.c:627
int agnnodes(Agraph_t *g)
Agobj_t base
Definition: cgraph.h:121
#define ND_pos(n)
Definition: types.h:487
#define alloc_elist(n, L)
Definition: types.h:263
int agerr(agerrlevel_t level, const char *fmt,...)
Definition: agerror.c:142
void delete_fast_edge(Agedge_t *)
Definition: fastgr.c:115
void gv_cleanup_edge(Agedge_t *e)
Definition: utils.c:1907
Agraph_t ** cccomps(Agraph_t *g, int *ncc, char *pfx)
Definition: ccomps.c:608
pack_mode getPackInfo(Agraph_t *g, pack_mode dflt, int dfltMargin, pack_info *pinfo)
Definition: pack.c:1398
#define GD_dotroot(g)
Definition: types.h:345
pack_mode mode
Definition: pack.h:54
#define ND_label(n)
Definition: types.h:470
#define GD_ranksep(g)
Definition: types.h:386
#define GD_gvc(g)
Definition: types.h:338
Definition: cgraph.h:389
char * agget(void *obj, char *name)
Definition: attr.c:428
#define NEW_RANK
Definition: const.h:278
boolean * fixed
Definition: pack.h:55
#define ED_showboxes(e)
Definition: types.h:551
int rank(graph_t *g, int balance, int maxiter)
Definition: ns.c:681
Definition: types.h:251
void free()
int doSplines
Definition: pack.h:53
int i
Definition: gvdevice.c:448
unsigned int margin
Definition: pack.h:52
#define ND_shape(n)
Definition: types.h:495
Agraph_t * agsubg(Agraph_t *g, char *name, int cflag)
Definition: subg.c:52
#define ND_order(n)
Definition: types.h:481
EXTERN Agsym_t * E_showboxes
Definition: globals.h:116
#define GD_fontnames(g)
Definition: types.h:391
pack_mode getPackModeInfo(Agraph_t *g, pack_mode dflt, pack_info *pinfo)
Definition: pack.c:1364
#define VIRTUAL
Definition: const.h:28
#define GD_maxrank(g)
Definition: types.h:369
int n
Definition: types.h:203
Definition: types.h:215
Agraph_t * agroot(void *obj)
Definition: obj.c:169
void dot_rank(Agraph_t *, aspect_t *)
Definition: rank.c:573
#define ED_count(e)
Definition: types.h:538
int badGraph
Definition: aspect.h:24
Agnode_t * agnxtnode(Agraph_t *g, Agnode_t *n)
Definition: node.c:45
int agdelnode(Agraph_t *g, Agnode_t *arg_n)
Definition: node.c:192
EXTERN Agsym_t * N_group
Definition: globals.h:104
edge_t ** list
Definition: types.h:252
Agnode_t * agfstnode(Agraph_t *g)
Definition: node.c:38
int late_int(void *obj, attrsym_t *attr, int def, int low)
Definition: utils.c:69
#define GD_clust(g)
Definition: types.h:344
EXTERN Agsym_t * E_minlen
Definition: globals.h:116
#define GD_flip(g)
Definition: types.h:365
long agdelsubg(Agraph_t *g, Agraph_t *sub)
Definition: subg.c:93
Agobj_t base
Definition: cgraph.h:127
Agraph_t * dot_root(void *p)
Definition: dotinit.c:510
#define CL_OFFSET
Definition: const.h:155
Agraph_t * agraphof(void *obj)
Definition: obj.c:185
int packSubgraphs(int ng, Agraph_t **gs, Agraph_t *root, pack_info *info)
Definition: pack.c:1163
#define NULL
Definition: logic.h:50
node_t ** v
Definition: types.h:204
real cg(Operator Ax, Operator precond, int n, int dim, real *x0, real *rhs, real tol, int maxit, int *flag)
Definition: sparse_solve.c:227
void dot_cleanup(graph_t *g)
Definition: dotinit.c:179
Agedge_t * agnxtout(Agraph_t *g, Agedge_t *e)
Definition: edge.c:40
#define agfindgraphattr(g, a)
Definition: types.h:566
#define GD_charset(g)
Definition: types.h:351
EXTERN Agsym_t * E_weight
Definition: globals.h:116
#define ND_in(n)
Definition: types.h:468
#define GD_label_pos(g)
Definition: types.h:389
#define ND_coord(n)
Definition: types.h:457
void dot_init_node_edge(graph_t *g)
Definition: dotinit.c:75
#define streq(s, t)
Definition: cghdr.h:58
int getPack(Agraph_t *g, int not_def, int dflt)
Definition: pack.c:1381
#define ND_next(n)
Definition: types.h:478
#define GD_comp(g)
Definition: types.h:346
void dot_layout(Agraph_t *g)
Definition: dotinit.c:504
char * agnameof(void *)
Definition: id.c:143
Agraph_t * agfstsubg(Agraph_t *g)
boolean mapbool(char *p)
Definition: utils.c:470
Agrec_t * data
Definition: cgraph.h:96
Definition: pack.h:37
void dot_compoundEdges(graph_t *g)
Definition: compound.c:494
#define ND_out(n)
Definition: types.h:483
int size
Definition: types.h:253
#define ED_xpenalty(e)
Definition: types.h:558
#define ND_other(n)
Definition: types.h:482
int common_init_edge(edge_t *e)
Definition: utils.c:711
Definition: pack.h:37
void setEdgeType(graph_t *g, int dflt)
Definition: utils.c:1762
void gv_nodesize(node_t *n, boolean flip)
Definition: utils.c:1930
char * late_string(void *obj, attrsym_t *attr, char *def)
Definition: utils.c:120
#define GD_bb(g)
Definition: types.h:337
#define GD_nodesep(g)
Definition: types.h:382
#define GD_minrank(g)
Definition: types.h:371
#define ND_flat_out(n)
Definition: types.h:460
#define GD_rank(g)
Definition: types.h:384
Definition: types.h:202
#define GD_drawing(g)
Definition: types.h:336
void * agbindrec(void *obj, char *name, unsigned int size, int move_to_front)
Definition: rec.c:86
int agdelrec(void *obj, char *name)
Definition: rec.c:145
void dot_position(Agraph_t *, aspect_t *)
Definition: position.c:120
aspect_t * setAspect(Agraph_t *g, aspect_t *adata)
Definition: aspect.c:1978
#define free_list(L)
Definition: types.h:264
Agraph_t * mapClust(Agraph_t *cl)
Definition: ccomps.c:526
void dot_mincross(Agraph_t *, int)
Definition: mincross.c:331
#define ED_minlen(e)
Definition: types.h:549
Agraph_t * agnxtsubg(Agraph_t *subg)
Definition: subg.c:77
int nonconstraint_edge(edge_t *e)
Definition: class1.c:23
#define NEW(t)
Definition: memory.h:35
#define ag_xset(x, a, v)
Definition: dotinit.c:272
#define TRUE
Definition: cgraph.h:27