Graphviz 13.0.0~dev.20241220.2304
Loading...
Searching...
No Matches
dotinit.c
Go to the documentation of this file.
1/*************************************************************************
2 * Copyright (c) 2011 AT&T Intellectual Property
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * https://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors: Details at https://graphviz.org
9 *************************************************************************/
10
11#include <assert.h>
12#include <limits.h>
13#include <time.h>
14#include <dotgen/dot.h>
15#include <pack/pack.h>
16#include <dotgen/aspect.h>
17#include <stdbool.h>
18#include <stdint.h>
19#include <stdlib.h>
20#include <util/agxbuf.h>
21#include <util/alloc.h>
22#include <util/streq.h>
23
24static void
26{
27 graph_t* subg;
28
29 if ((g != agroot(g)))
30 agbindrec(g, "Agraphinfo_t", sizeof(Agraphinfo_t), true);
31 if (g == droot)
32 GD_dotroot(agroot(g)) = droot;
33
34 for (subg = agfstsubg(g); subg; subg = agnxtsubg(subg)) {
35 dot_init_subg(subg, droot);
36 }
37}
38
39
40static void
42{
43 agbindrec(n, "Agnodeinfo_t", sizeof(Agnodeinfo_t), true); //graph custom data
46 alloc_elist(4, ND_in(n));
47 alloc_elist(4, ND_out(n));
50 alloc_elist(2, ND_other(n));
51 ND_UF_size(n) = 1;
52}
53
54static void
56{
57 char *tailgroup, *headgroup;
58 agbindrec(e, "Agedgeinfo_t", sizeof(Agedgeinfo_t), true); //graph custom data
60
61 ED_weight(e) = late_int(e, E_weight, 1, 0);
62 tailgroup = late_string(agtail(e), N_group, "");
63 headgroup = late_string(aghead(e), N_group, "");
64 ED_count(e) = ED_xpenalty(e) = 1;
65 if (tailgroup[0] && (tailgroup == headgroup)) {
67 ED_weight(e) *= 100;
68 }
69 if (nonconstraint_edge(e)) {
70 ED_xpenalty(e) = 0;
71 ED_weight(e) = 0;
72 }
73
74 {
75 int showboxes = late_int(e, E_showboxes, 0, 0);
76 if (showboxes > UCHAR_MAX) {
77 showboxes = UCHAR_MAX;
78 }
79 ED_showboxes(e) = (unsigned char)showboxes;
80 }
81 ED_minlen(e) = late_int(e, E_minlen, 1, 0);
82}
83
84void
86{
87 node_t *n;
88 edge_t *e;
89
90 for (n = agfstnode(g); n; n = agnxtnode(g, n))
92 for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
93 for (e = agfstout(g, n); e; e = agnxtout(g, e))
95 }
96}
97
98static void
100{
101 free_list(ND_in(n));
102 free_list(ND_out(n));
108 if (ND_shape(n))
109 ND_shape(n)->fns->freefn(n);
110 agdelrec(n, "Agnodeinfo_t");
111}
112
114{
115 edge_t *e;
116
117 for (size_t i = ND_in(n).size - 1; i != SIZE_MAX; i--) {
118 e = ND_in(n).list[i];
120 free(e->base.data);
121 free(e);
122 }
123 for (size_t i = ND_out(n).size - 1; i != SIZE_MAX; i--) {
124 e = ND_out(n).list[i];
126 free(e->base.data);
127 free(e);
128 }
129}
130
132{
133 node_t *next_vn;
134
135 while (vn) {
136 next_vn = ND_next(vn);
138 if (ND_node_type(vn) == VIRTUAL) {
139 free_list(ND_out(vn));
140 free_list(ND_in(vn));
141 free(vn->base.data);
142 free(vn);
143 }
144 vn = next_vn;
145 }
146}
147
148static void
150{
151 int i;
152 graph_t *subg;
153 for (subg = agfstsubg(g); subg; subg = agnxtsubg(subg)) {
154 dot_cleanup_graph(subg);
155 }
156 free(GD_drawing(g));
157 GD_drawing(g) = NULL;
158 if (! agbindrec(g, "Agraphinfo_t", 0, true)) return;
159 free (GD_clust(g));
160 free (GD_rankleader(g));
161
162 free_list(GD_comp(g));
163 if (GD_rank(g)) {
164 for (i = GD_minrank(g); i <= GD_maxrank(g); i++)
165 free(GD_rank(g)[i].av);
166 if (GD_minrank(g) == -1)
167 free(GD_rank(g)-1);
168 else
169 free(GD_rank(g));
170 }
171 if (g != agroot(g)) {
172 free_label (GD_label(g));
173 }
174}
175
176/* delete the layout (but retain the underlying graph) */
178{
179 node_t *n;
180 edge_t *e;
181
183 for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
184 for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
186 }
188 }
190}
191
192#ifdef DEBUG
193int
194fastn (graph_t * g)
195{
196 node_t* u;
197 int cnt = 0;
198 for (u = GD_nlist(g); u; u = ND_next(u)) cnt++;
199 return cnt;
200}
201
202#if DEBUG > 1
203static void
204dumpRanks (graph_t * g)
205{
206 int i, j;
207 node_t* u;
208 rank_t *rank = GD_rank(g);
209 int rcnt = 0;
210 for (i = GD_minrank(g); i <= GD_maxrank(g); i++) {
211 fprintf (stderr, "[%d] :", i);
212 for (j = 0; j < rank[i].n; j++) {
213 u = rank[i].v[j];
214 rcnt++;
215 if (streq(agnameof(u),"virtual"))
216 fprintf (stderr, " %x", u);
217 else
218 fprintf (stderr, " %s", agnameof(u));
219
220 }
221 fprintf (stderr, "\n");
222 }
223 fprintf (stderr, "count %d rank count = %d\n", fastn(g), rcnt);
224}
225#endif
226#endif
227
228
229static void
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 */
253static void
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);
266 agdelnode(g, n);
267 }
268 agdelsubg (g, sg);
269
270}
271
272#define agnodeattr(g,n,v) agattr(g,AGNODE,n,v)
273
274static void
275attach_phase_attrs (Agraph_t * g, int maxphase)
276{
277 Agsym_t* rk = agnodeattr(g,"rank","");
278 Agsym_t* order = agnodeattr(g,"order","");
279 Agnode_t* n;
280 agxbuf buf = {0};
281
282 for (n = agfstnode(g); n; n = agnxtnode(g,n)) {
283 if (maxphase >= 1) {
284 agxbprint(&buf, "%d", ND_rank(n));
285 agxset(n, rk, agxbuse(&buf));
286 }
287 if (maxphase >= 2) {
288 agxbprint(&buf, "%d", ND_order(n));
289 agxset(n, order, agxbuse(&buf));
290 }
291 }
292 agxbfree(&buf);
293}
294
295static void dotLayout(Agraph_t * g)
296{
297 int maxphase = late_int(g, agfindgraphattr(g,"phase"), -1, 1);
298
300 setAspect(g);
301
302 dot_init_subg(g,g);
304
305 dot_rank(g);
306 if (maxphase == 1) {
307 attach_phase_attrs (g, 1);
308 return;
309 }
310 dot_mincross(g);
311 if (maxphase == 2) {
312 attach_phase_attrs (g, 2);
313 return;
314 }
315 dot_position(g);
316 if (maxphase == 3) {
317 attach_phase_attrs (g, 2); /* positions will be attached on output */
318 return;
319 }
320 if (GD_flags(g) & NEW_RANK)
321 removeFill (g);
322 dot_sameports(g);
323 dot_splines(g);
324 if (mapbool(agget(g, "compound")))
326}
327
328static void
330{
331 agbindrec(sg, "Agraphinfo_t", sizeof(Agraphinfo_t), true);
332 GD_drawing(sg) = gv_alloc(sizeof(layout_t));
333 GD_drawing(sg)->quantum = GD_drawing(g)->quantum;
334 GD_drawing(sg)->dpi = GD_drawing(g)->dpi;
335 GD_gvc(sg) = GD_gvc (g);
336 GD_charset(sg) = GD_charset (g);
337 GD_rankdir2(sg) = GD_rankdir2 (g);
338 GD_nodesep(sg) = GD_nodesep(g);
339 GD_ranksep(sg) = GD_ranksep(g);
340 GD_fontnames(sg) = GD_fontnames(g);
341}
342
343/* attachPos:
344 * the packing library assumes all units are in inches stored in ND_pos, so we
345 * have to copy the position info there.
346 */
347static void
349{
350 node_t* np;
351 double* ps = gv_calloc(2 * agnnodes(g), sizeof(double));
352
353 for (np = agfstnode(g); np; np = agnxtnode(g, np)) {
354 ND_pos(np) = ps;
355 ps[0] = PS2INCH(ND_coord(np).x);
356 ps[1] = PS2INCH(ND_coord(np).y);
357 ps += 2;
358 }
359}
360
361/* resetCoord:
362 * Store new position info from pack library call, stored in ND_pos in inches,
363 * back to ND_coord in points.
364 */
365static void
367{
368 node_t* np = agfstnode(g);
369 double* sp = ND_pos(np);
370 double* ps = sp;
371
372 for (np = agfstnode(g); np; np = agnxtnode(g, np)) {
373 ND_pos(np) = 0;
374 ND_coord(np).x = INCH2PS(ps[0]);
375 ND_coord(np).y = INCH2PS(ps[1]);
376 ps += 2;
377 }
378 free (sp);
379}
380
381static void
383{
384 int nclust, j;
385 Agraph_t* cg;
386
387 agbindrec(cl, "Agraphinfo_t", sizeof(Agraphinfo_t), true);
388 GD_bb(cl) = GD_bb(scl);
389 GD_label_pos(cl) = GD_label_pos(scl);
390 memcpy(GD_border(cl), GD_border(scl), 4*sizeof(pointf));
391 nclust = GD_n_cluster(cl) = GD_n_cluster(scl);
392 GD_clust(cl) = gv_calloc(nclust + 1, sizeof(Agraph_t*));
393 for (j = 1; j <= nclust; j++) {
394 cg = mapClust(GD_clust(scl)[j]);
395 GD_clust(cl)[j] = cg;
396 copyCluster (GD_clust(scl)[j], cg);
397 }
398 /* transfer cluster label to original cluster */
399 GD_label(cl) = GD_label(scl);
400 GD_label(scl) = NULL;
401}
402
403/* copyClusterInfo:
404 * Copy cluster tree and info from components to main graph.
405 * Note that the original clusters have no Agraphinfo_t at this time.
406 */
407static void copyClusterInfo(size_t ncc, Agraph_t **ccs, Agraph_t *root) {
408 int j, nclust = 0;
409 Agraph_t* sg;
410 Agraph_t* cg;
411
412 for (size_t i = 0; i < ncc; i++)
413 nclust += GD_n_cluster(ccs[i]);
414
415 GD_n_cluster(root) = nclust;
416 GD_clust(root) = gv_calloc(nclust + 1, sizeof(Agraph_t*));
417 nclust = 1;
418 for (size_t i = 0; i < ncc; i++) {
419 sg = ccs[i];
420 for (j = 1; j <= GD_n_cluster(sg); j++) {
421 cg = mapClust(GD_clust(sg)[j]);
422 GD_clust(root)[nclust++] = cg;
423 copyCluster (GD_clust(sg)[j], cg);
424 }
425 }
426}
427
428/* doDot:
429 * Assume g has nodes.
430 */
431static void doDot (Agraph_t* g)
432{
433 Agraph_t **ccs;
434 Agraph_t *sg;
435 pack_info pinfo;
436 int Pack = getPack(g, -1, CL_OFFSET);
437 pack_mode mode = getPackModeInfo (g, l_undef, &pinfo);
438 getPackInfo(g, l_node, CL_OFFSET, &pinfo);
439
440 if (mode == l_undef && Pack < 0) {
441 /* No pack information; use old dot with components
442 * handled during layout
443 */
444 dotLayout(g);
445 } else {
446 /* fill in default values */
447 if (mode == l_undef)
448 pinfo.mode = l_graph;
449 else if (Pack < 0)
450 Pack = CL_OFFSET;
451 assert(Pack >= 0);
452 pinfo.margin = (unsigned)Pack;
453 pinfo.fixed = NULL;
454
455 /* components using clusters */
456 size_t ncc;
457 ccs = cccomps(g, &ncc, 0);
458 if (ncc == 1) {
459 dotLayout(g);
460 } else if (GD_drawing(g)->ratio_kind == R_NONE) {
461 pinfo.doSplines = true;
462
463 for (size_t i = 0; i < ncc; i++) {
464 sg = ccs[i];
465 initSubg (sg, g);
466 dotLayout (sg);
467 }
468 attachPos (g);
469 packSubgraphs(ncc, ccs, g, &pinfo);
470 resetCoord (g);
471 copyClusterInfo (ncc, ccs, g);
472 } else {
473 /* Not sure what semantics should be for non-trivial ratio
474 * attribute with multiple components.
475 * One possibility is to layout nodes, pack, then apply the ratio
476 * adjustment. We would then have to re-adjust all positions.
477 */
478 dotLayout(g);
479 }
480
481 for (size_t i = 0; i < ncc; i++) {
482 free (GD_drawing(ccs[i]));
483 dot_cleanup_graph(ccs[i]);
484 agdelete(g, ccs[i]);
485 }
486 free(ccs);
487 }
488}
489
491{
492 if (agnnodes(g)) doDot (g);
494}
495
497{
498 return GD_dotroot(agroot(p));
499}
500
static void agxbfree(agxbuf *xb)
free any malloced resources
Definition agxbuf.h:78
static int agxbprint(agxbuf *xb, const char *fmt,...)
Printf-style output to an agxbuf.
Definition agxbuf.h:234
static WUR char * agxbuse(agxbuf *xb)
Definition agxbuf.h:307
Memory allocation wrappers that exit on failure.
static void * gv_calloc(size_t nmemb, size_t size)
Definition alloc.h:26
static void * gv_alloc(size_t size)
Definition alloc.h:47
void setAspect(Agraph_t *g)
Definition aspect.c:30
bool nonconstraint_edge(edge_t *e)
Definition class1.c:20
bool mapbool(const char *p)
Definition utils.c:335
void setEdgeType(graph_t *g, int defaultValue)
Definition utils.c:1434
char * late_string(void *obj, attrsym_t *attr, char *defaultValue)
Definition utils.c:78
int late_int(void *obj, attrsym_t *attr, int defaultValue, int minimum)
Definition utils.c:33
void common_init_node(node_t *n)
Definition utils.c:421
void common_init_edge(edge_t *e)
Definition utils.c:504
void gv_nodesize(node_t *n, bool flip)
Definition utils.c:1547
void dot_compoundEdges(graph_t *g)
Definition compound.c:458
#define EDGETYPE_SPLINE
Definition const.h:253
#define CL_OFFSET
Definition const.h:151
#define NEW_RANK
Definition const.h:257
#define VIRTUAL
Definition const.h:25
#define CL_CROSS
Definition const.h:153
mode
Definition cvtgxl.c:33
static void dot_init_subg(graph_t *g, graph_t *droot)
Definition dotinit.c:25
static void dotLayout(Agraph_t *g)
Definition dotinit.c:295
static void dot_cleanup_node(node_t *n)
Definition dotinit.c:99
Agraph_t * dot_root(void *p)
Definition dotinit.c:496
static void free_virtual_edge_list(node_t *n)
Definition dotinit.c:113
static void attach_phase_attrs(Agraph_t *g, int maxphase)
Definition dotinit.c:275
static void removeFill(Agraph_t *g)
Definition dotinit.c:254
static void dot_init_node(node_t *n)
Definition dotinit.c:41
static void copyClusterInfo(size_t ncc, Agraph_t **ccs, Agraph_t *root)
Definition dotinit.c:407
void dot_layout(Agraph_t *g)
Definition dotinit.c:490
void dot_init_node_edge(graph_t *g)
Definition dotinit.c:85
static void dot_cleanup_graph(graph_t *g)
Definition dotinit.c:149
static void resetCoord(Agraph_t *g)
Definition dotinit.c:366
static void free_virtual_node_list(node_t *vn)
Definition dotinit.c:131
static void doDot(Agraph_t *g)
Definition dotinit.c:431
void dot_cleanup(graph_t *g)
Definition dotinit.c:177
static void initSubg(Agraph_t *sg, Agraph_t *g)
Definition dotinit.c:329
static void copyCluster(Agraph_t *scl, Agraph_t *cl)
Definition dotinit.c:382
#define agnodeattr(g, n, v)
Definition dotinit.c:272
static void attachPos(Agraph_t *g)
Definition dotinit.c:348
static void dot_init_edge(edge_t *e)
Definition dotinit.c:55
static void remove_from_rank(Agraph_t *g, Agnode_t *n)
Definition dotinit.c:230
void delete_fast_node(Agraph_t *, Agnode_t *)
Definition fastgr.c:191
void dot_mincross(Agraph_t *)
Definition mincross.c:351
void dot_sameports(Agraph_t *)
Definition sameport.c:39
void dot_splines(Agraph_t *)
Definition dotsplines.c:503
void dot_rank(Agraph_t *)
Definition rank.c:449
void delete_fast_edge(Agedge_t *)
Definition fastgr.c:108
void dot_position(Agraph_t *)
Definition position.c:125
#define PS2INCH(a_points)
Definition geom.h:70
#define INCH2PS(a_inches)
Definition geom.h:69
Agsym_t * N_group
Definition globals.h:78
Agsym_t * E_weight
Definition globals.h:81
Agsym_t * E_minlen
Definition globals.h:81
Agsym_t * E_showboxes
Definition globals.h:84
void free(void *)
#define SIZE_MAX
Definition gmlscan.c:347
node NULL
Definition grammar.y:163
static int cnt(Dict_t *d, Dtlink_t **set)
Definition graph.c:210
int agnnodes(Agraph_t *g)
Definition graph.c:169
int agxset(void *obj, Agsym_t *sym, const char *value)
Definition attr.c:478
char * agget(void *obj, char *name)
Definition attr.c:439
#define ED_minlen(e)
Definition types.h:592
#define ED_showboxes(e)
Definition types.h:594
#define ED_xpenalty(e)
Definition types.h:601
Agedge_t * agfstout(Agraph_t *g, Agnode_t *n)
Definition edge.c:24
#define ED_count(e)
Definition types.h:580
#define agtail(e)
Definition cgraph.h:880
#define ED_weight(e)
Definition types.h:603
#define aghead(e)
Definition cgraph.h:881
Agedge_t * agnxtout(Agraph_t *g, Agedge_t *e)
Definition edge.c:39
#define GD_minrank(g)
Definition types.h:384
#define agfindgraphattr(g, a)
Definition types.h:613
#define GD_rankdir2(g)
Definition types.h:376
#define GD_maxrank(g)
Definition types.h:382
#define GD_fontnames(g)
Definition types.h:402
#define GD_drawing(g)
Definition types.h:353
#define GD_border(g)
Definition types.h:359
#define GD_clust(g)
Definition types.h:360
#define GD_flags(g)
Definition types.h:365
#define GD_rank(g)
Definition types.h:395
#define GD_bb(g)
Definition types.h:354
#define GD_nlist(g)
Definition types.h:393
#define GD_label_pos(g)
Definition types.h:400
#define GD_n_cluster(g)
Definition types.h:389
#define GD_dotroot(g)
Definition types.h:361
#define GD_comp(g)
Definition types.h:362
#define GD_label(g)
Definition types.h:374
#define GD_nodesep(g)
Definition types.h:394
#define GD_charset(g)
Definition types.h:367
#define GD_gvc(g)
Definition types.h:355
#define GD_flip(g)
Definition types.h:378
#define GD_rankleader(g)
Definition types.h:396
#define GD_ranksep(g)
Definition types.h:397
#define ND_rank(n)
Definition types.h:523
Agnode_t * agnxtnode(Agraph_t *g, Agnode_t *n)
Definition node.c:47
Agnode_t * agfstnode(Agraph_t *g)
Definition node.c:40
#define ND_next(n)
Definition types.h:510
#define ND_other(n)
Definition types.h:514
#define ND_label(n)
Definition types.h:502
#define ND_flat_out(n)
Definition types.h:493
#define ND_node_type(n)
Definition types.h:511
int agdelnode(Agraph_t *g, Agnode_t *arg_n)
removes a node from a graph or subgraph.
Definition node.c:195
#define ND_order(n)
Definition types.h:513
#define ND_xlabel(n)
Definition types.h:503
#define ND_UF_size(n)
Definition types.h:487
#define ND_pos(n)
Definition types.h:520
#define ND_flat_in(n)
Definition types.h:492
#define ND_coord(n)
Definition types.h:490
#define ND_in(n)
Definition types.h:501
#define ND_shape(n)
Definition types.h:528
#define ND_out(n)
Definition types.h:515
Agraph_t * agraphof(void *obj)
Definition obj.c:185
char * agnameof(void *)
returns a string descriptor for the object.
Definition id.c:158
int agdelete(Agraph_t *g, void *obj)
deletes object. Equivalent to agclose, agdelnode, and agdeledge for obj being a graph,...
Definition obj.c:20
Agraph_t * agroot(void *obj)
Definition obj.c:168
void * agbindrec(void *obj, const char *name, unsigned int recsize, int move_to_front)
attaches a new record of the given size to the object
Definition rec.c:89
int agdelrec(void *obj, const char *name)
deletes a named record from one object
Definition rec.c:137
Agraph_t * agfstsubg(Agraph_t *g)
Definition subg.c:78
Agraph_t * agnxtsubg(Agraph_t *subg)
Definition subg.c:83
Agraph_t * agsubg(Agraph_t *g, char *name, int cflag)
Definition subg.c:58
int agdelsubg(Agraph_t *g, Agraph_t *sub)
Definition subg.c:99
void free_label(textlabel_t *p)
Definition labels.c:199
Agraph_t ** cccomps(Agraph_t *g, size_t *ncc, char *pfx)
Definition ccomps.c:439
Agraph_t * mapClust(Agraph_t *cl)
Definition ccomps.c:366
static int * ps
Definition lu.c:51
static int Pack
Definition neatoinit.c:54
int rank(graph_t *g, int balance, int maxiter)
Definition ns.c:1001
pack_mode getPackModeInfo(Agraph_t *g, pack_mode dflt, pack_info *pinfo)
Definition pack.c:1253
int packSubgraphs(size_t ng, Agraph_t **gs, Agraph_t *root, pack_info *info)
Definition pack.c:1104
int getPack(Agraph_t *g, int not_def, int dflt)
Definition pack.c:1266
pack_mode getPackInfo(Agraph_t *g, pack_mode dflt, int dfltMargin, pack_info *pinfo)
Definition pack.c:1281
support for connected components
pack_mode
Definition pack.h:55
@ l_undef
Definition pack.h:55
@ l_graph
Definition pack.h:55
@ l_node
Definition pack.h:55
void dotneato_postprocess(Agraph_t *g)
Definition postproc.c:689
void gv_cleanup_edge(Agedge_t *e)
Definition utils.c:1524
static double cg(SparseMatrix A, const double *precond, int n, int dim, double *x0, double *rhs, double tol, double maxit)
static bool streq(const char *a, const char *b)
are a and b equal?
Definition streq.h:11
Agobj_t base
Definition cgraph.h:269
Agobj_t base
Definition cgraph.h:260
Agrec_t * data
stores programmer-defined data, access with AGDATA
Definition cgraph.h:212
graph or subgraph
Definition cgraph.h:425
string attribute descriptor symbol in Agattr_s.dict
Definition cgraph.h:637
pack_mode mode
Definition pack.h:72
bool doSplines
use splines in constructing graph shape
Definition pack.h:71
bool * fixed
Definition pack.h:73
unsigned int margin
Definition pack.h:70
#define free_list(L)
Definition types.h:272
#define alloc_elist(n, L)
Definition types.h:267
@ R_NONE
Definition types.h:215