Graphviz 13.0.0~dev.20250123.2027
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 <stdio.h>
20#include <stdlib.h>
21#include <util/agxbuf.h>
22#include <util/alloc.h>
23#include <util/streq.h>
24
25static void
27{
28 graph_t* subg;
29
30 if ((g != agroot(g)))
31 agbindrec(g, "Agraphinfo_t", sizeof(Agraphinfo_t), true);
32 if (g == droot)
33 GD_dotroot(agroot(g)) = droot;
34
35 for (subg = agfstsubg(g); subg; subg = agnxtsubg(subg)) {
36 dot_init_subg(subg, droot);
37 }
38}
39
40
41static void
43{
44 agbindrec(n, "Agnodeinfo_t", sizeof(Agnodeinfo_t), true); //graph custom data
47 alloc_elist(4, ND_in(n));
48 alloc_elist(4, ND_out(n));
51 alloc_elist(2, ND_other(n));
52 ND_UF_size(n) = 1;
53}
54
55static void
57{
58 char *tailgroup, *headgroup;
59 agbindrec(e, "Agedgeinfo_t", sizeof(Agedgeinfo_t), true); //graph custom data
61
62 ED_weight(e) = late_int(e, E_weight, 1, 0);
63 tailgroup = late_string(agtail(e), N_group, "");
64 headgroup = late_string(aghead(e), N_group, "");
65 ED_count(e) = ED_xpenalty(e) = 1;
66 if (tailgroup[0] && (tailgroup == headgroup)) {
68 ED_weight(e) *= 100;
69 }
70 if (nonconstraint_edge(e)) {
71 ED_xpenalty(e) = 0;
72 ED_weight(e) = 0;
73 }
74
75 {
76 int showboxes = late_int(e, E_showboxes, 0, 0);
77 if (showboxes > UCHAR_MAX) {
78 showboxes = UCHAR_MAX;
79 }
80 ED_showboxes(e) = (unsigned char)showboxes;
81 }
82 ED_minlen(e) = late_int(e, E_minlen, 1, 0);
83}
84
85void
87{
88 node_t *n;
89 edge_t *e;
90
91 for (n = agfstnode(g); n; n = agnxtnode(g, n))
93 for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
94 for (e = agfstout(g, n); e; e = agnxtout(g, e))
96 }
97}
98
99static void
101{
102 free_list(ND_in(n));
103 free_list(ND_out(n));
109 if (ND_shape(n))
110 ND_shape(n)->fns->freefn(n);
111 agdelrec(n, "Agnodeinfo_t");
112}
113
115{
116 edge_t *e;
117
118 for (size_t i = ND_in(n).size - 1; i != SIZE_MAX; i--) {
119 e = ND_in(n).list[i];
121 free(e->base.data);
122 free(e);
123 }
124 for (size_t i = ND_out(n).size - 1; i != SIZE_MAX; i--) {
125 e = ND_out(n).list[i];
127 free(e->base.data);
128 free(e);
129 }
130}
131
133{
134 node_t *next_vn;
135
136 while (vn) {
137 next_vn = ND_next(vn);
139 if (ND_node_type(vn) == VIRTUAL) {
140 free_list(ND_out(vn));
141 free_list(ND_in(vn));
142 free(vn->base.data);
143 free(vn);
144 }
145 vn = next_vn;
146 }
147}
148
149static void
151{
152 int i;
153 graph_t *subg;
154 for (subg = agfstsubg(g); subg; subg = agnxtsubg(subg)) {
155 dot_cleanup_graph(subg);
156 }
157 free(GD_drawing(g));
158 GD_drawing(g) = NULL;
159 if (! agbindrec(g, "Agraphinfo_t", 0, true)) return;
160 free (GD_clust(g));
161 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 }
175}
176
177/* delete the layout (but retain the underlying graph) */
179{
180 node_t *n;
181 edge_t *e;
182
184 for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
185 for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
187 }
189 }
191}
192
193#ifdef DEBUG
194int
195fastn (graph_t * g)
196{
197 node_t* u;
198 int cnt = 0;
199 for (u = GD_nlist(g); u; u = ND_next(u)) cnt++;
200 return cnt;
201}
202
203#if DEBUG > 1
204static void
205dumpRanks (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#endif
228
229
230static void
232{
233 Agnode_t* v = NULL;
234 int j, rk = ND_rank(n);
235
236 for (j = 0; j < GD_rank(g)[rk].n; j++) {
237 v = GD_rank(g)[rk].v[j];
238 if (v == n) {
239 for (j++; j < GD_rank(g)[rk].n; j++) {
240 GD_rank(g)[rk].v[j-1] = GD_rank(g)[rk].v[j];
241 }
242 GD_rank(g)[rk].n--;
243 break;
244 }
245 }
246 assert (v == n); /* if found */
247}
248
249/* removeFill:
250 * This removes all of the fill nodes added in mincross.
251 * It appears to be sufficient to remove them only from the
252 * rank array and fast node list of the root graph.
253 */
254static void
256{
257 Agnode_t* n;
258 Agnode_t* nxt;
259 Agraph_t* sg = agsubg (g, "_new_rank", 0);
260
261 if (!sg) return;
262 for (n = agfstnode(sg); n; n = nxt) {
263 nxt = agnxtnode(sg, n);
264 delete_fast_node (g, n);
265 remove_from_rank (g, n);
267 agdelnode(g, n);
268 }
269 agdelsubg (g, sg);
270
271}
272
273#define agnodeattr(g,n,v) agattr(g,AGNODE,n,v)
274
275static void
276attach_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 agxbuf buf = {0};
282
283 for (n = agfstnode(g); n; n = agnxtnode(g,n)) {
284 if (maxphase >= 1) {
285 agxbprint(&buf, "%d", ND_rank(n));
286 agxset(n, rk, agxbuse(&buf));
287 }
288 if (maxphase >= 2) {
289 agxbprint(&buf, "%d", ND_order(n));
290 agxset(n, order, agxbuse(&buf));
291 }
292 }
293 agxbfree(&buf);
294}
295
296static void dotLayout(Agraph_t * g)
297{
298 int maxphase = late_int(g, agfindgraphattr(g,"phase"), -1, 1);
299
301 setAspect(g);
302
303 dot_init_subg(g,g);
305
306 if (Verbose) {
307 fputs("Starting phase 1 [dot_rank]\n", stderr);
308 }
309 dot_rank(g);
310 if (maxphase == 1) {
311 attach_phase_attrs (g, 1);
312 return;
313 }
314 if (Verbose) {
315 fputs("Starting phase 2 [dot_mincross]\n", stderr);
316 }
317 dot_mincross(g);
318 if (maxphase == 2) {
319 attach_phase_attrs (g, 2);
320 return;
321 }
322 if (Verbose) {
323 fputs("Starting phase 3 [dot_position]\n", stderr);
324 }
325 dot_position(g);
326 if (maxphase == 3) {
327 attach_phase_attrs (g, 2); /* positions will be attached on output */
328 return;
329 }
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
338static void
340{
341 agbindrec(sg, "Agraphinfo_t", sizeof(Agraphinfo_t), true);
342 GD_drawing(sg) = gv_alloc(sizeof(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 */
357static void
359{
360 node_t* np;
361 double* ps = gv_calloc(2 * agnnodes(g), sizeof(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 */
375static void
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
391static void
393{
394 int nclust, j;
395 Agraph_t* cg;
396
397 agbindrec(cl, "Agraphinfo_t", sizeof(Agraphinfo_t), true);
398 GD_bb(cl) = GD_bb(scl);
399 GD_label_pos(cl) = GD_label_pos(scl);
400 memcpy(GD_border(cl), GD_border(scl), 4*sizeof(pointf));
401 nclust = GD_n_cluster(cl) = GD_n_cluster(scl);
402 GD_clust(cl) = gv_calloc(nclust + 1, sizeof(Agraph_t*));
403 for (j = 1; j <= nclust; j++) {
404 cg = mapClust(GD_clust(scl)[j]);
405 GD_clust(cl)[j] = cg;
406 copyCluster (GD_clust(scl)[j], cg);
407 }
408 /* transfer cluster label to original cluster */
409 GD_label(cl) = GD_label(scl);
410 GD_label(scl) = NULL;
411}
412
413/* copyClusterInfo:
414 * Copy cluster tree and info from components to main graph.
415 * Note that the original clusters have no Agraphinfo_t at this time.
416 */
417static void copyClusterInfo(size_t ncc, Agraph_t **ccs, Agraph_t *root) {
418 int j, nclust = 0;
419 Agraph_t* sg;
420 Agraph_t* cg;
421
422 for (size_t i = 0; i < ncc; i++)
423 nclust += GD_n_cluster(ccs[i]);
424
425 GD_n_cluster(root) = nclust;
426 GD_clust(root) = gv_calloc(nclust + 1, sizeof(Agraph_t*));
427 nclust = 1;
428 for (size_t i = 0; i < ncc; i++) {
429 sg = ccs[i];
430 for (j = 1; j <= GD_n_cluster(sg); j++) {
431 cg = mapClust(GD_clust(sg)[j]);
432 GD_clust(root)[nclust++] = cg;
433 copyCluster (GD_clust(sg)[j], cg);
434 }
435 }
436}
437
438/* doDot:
439 * Assume g has nodes.
440 */
441static void doDot (Agraph_t* g)
442{
443 Agraph_t **ccs;
444 Agraph_t *sg;
445 pack_info pinfo;
446 int Pack = getPack(g, -1, CL_OFFSET);
447 pack_mode mode = getPackModeInfo (g, l_undef, &pinfo);
448 getPackInfo(g, l_node, CL_OFFSET, &pinfo);
449
450 if (mode == l_undef && Pack < 0) {
451 /* No pack information; use old dot with components
452 * handled during layout
453 */
454 dotLayout(g);
455 } else {
456 /* fill in default values */
457 if (mode == l_undef)
458 pinfo.mode = l_graph;
459 else if (Pack < 0)
460 Pack = CL_OFFSET;
461 assert(Pack >= 0);
462 pinfo.margin = (unsigned)Pack;
463 pinfo.fixed = NULL;
464
465 /* components using clusters */
466 size_t ncc;
467 ccs = cccomps(g, &ncc, 0);
468 if (ncc == 1) {
469 dotLayout(g);
470 } else if (GD_drawing(g)->ratio_kind == R_NONE) {
471 pinfo.doSplines = true;
472
473 for (size_t i = 0; i < ncc; i++) {
474 sg = ccs[i];
475 initSubg (sg, g);
476 dotLayout (sg);
477 }
478 attachPos (g);
479 packSubgraphs(ncc, ccs, g, &pinfo);
480 resetCoord (g);
481 copyClusterInfo (ncc, ccs, g);
482 } else {
483 /* Not sure what semantics should be for non-trivial ratio
484 * attribute with multiple components.
485 * One possibility is to layout nodes, pack, then apply the ratio
486 * adjustment. We would then have to re-adjust all positions.
487 */
488 dotLayout(g);
489 }
490
491 for (size_t i = 0; i < ncc; i++) {
492 free (GD_drawing(ccs[i]));
493 dot_cleanup_graph(ccs[i]);
494 agdelete(g, ccs[i]);
495 }
496 free(ccs);
497 }
498}
499
501{
502 if (agnnodes(g)) doDot (g);
504}
505
507{
508 return GD_dotroot(agroot(p));
509}
510
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:337
void setEdgeType(graph_t *g, int defaultValue)
Definition utils.c:1434
char * late_string(void *obj, attrsym_t *attr, char *defaultValue)
Definition utils.c:80
int late_int(void *obj, attrsym_t *attr, int defaultValue, int minimum)
Definition utils.c:35
void common_init_node(node_t *n)
Definition utils.c:423
void common_init_edge(edge_t *e)
Definition utils.c:506
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:26
static void dotLayout(Agraph_t *g)
Definition dotinit.c:296
static void dot_cleanup_node(node_t *n)
Definition dotinit.c:100
Agraph_t * dot_root(void *p)
Definition dotinit.c:506
static void free_virtual_edge_list(node_t *n)
Definition dotinit.c:114
static void attach_phase_attrs(Agraph_t *g, int maxphase)
Definition dotinit.c:276
static void removeFill(Agraph_t *g)
Definition dotinit.c:255
static void dot_init_node(node_t *n)
Definition dotinit.c:42
static void copyClusterInfo(size_t ncc, Agraph_t **ccs, Agraph_t *root)
Definition dotinit.c:417
void dot_layout(Agraph_t *g)
Definition dotinit.c:500
void dot_init_node_edge(graph_t *g)
Definition dotinit.c:86
static void dot_cleanup_graph(graph_t *g)
Definition dotinit.c:150
static void resetCoord(Agraph_t *g)
Definition dotinit.c:376
static void free_virtual_node_list(node_t *vn)
Definition dotinit.c:132
static void doDot(Agraph_t *g)
Definition dotinit.c:441
void dot_cleanup(graph_t *g)
Definition dotinit.c:178
static void initSubg(Agraph_t *sg, Agraph_t *g)
Definition dotinit.c:339
static void copyCluster(Agraph_t *scl, Agraph_t *cl)
Definition dotinit.c:392
#define agnodeattr(g, n, v)
Definition dotinit.c:273
static void attachPos(Agraph_t *g)
Definition dotinit.c:358
static void dot_init_edge(edge_t *e)
Definition dotinit.c:56
static void remove_from_rank(Agraph_t *g, Agnode_t *n)
Definition dotinit.c:231
void delete_fast_node(Agraph_t *, Agnode_t *)
Definition fastgr.c:189
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:504
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:64
#define INCH2PS(a_inches)
Definition geom.h:63
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
static bool Verbose
Definition gml2gv.c:23
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:200
int agnnodes(Agraph_t *g)
Definition graph.c:159
int agxset(void *obj, Agsym_t *sym, const char *value)
Definition attr.c:532
char * agget(void *obj, char *name)
Definition attr.c:465
#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:883
#define ED_weight(e)
Definition types.h:603
#define aghead(e)
Definition cgraph.h:884
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:190
#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:143
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:75
Agraph_t * agnxtsubg(Agraph_t *subg)
Definition subg.c:80
Agraph_t * agsubg(Agraph_t *g, char *name, int cflag)
Definition subg.c:55
int agdelsubg(Agraph_t *g, Agraph_t *sub)
Definition subg.c:96
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:55
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:1254
int packSubgraphs(size_t ng, Agraph_t **gs, Agraph_t *root, pack_info *info)
Definition pack.c:1105
int getPack(Agraph_t *g, int not_def, int dflt)
Definition pack.c:1267
pack_mode getPackInfo(Agraph_t *g, pack_mode dflt, int dfltMargin, pack_info *pinfo)
Definition pack.c:1282
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:690
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:424
string attribute descriptor symbol in Agattr_s.dict
Definition cgraph.h:636
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