Graphviz 14.0.3~dev.20251029.0425
Loading...
Searching...
No Matches
gv.cpp
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 "gv_channel.h"
12#include <cassert>
13#include <climits>
14#include <cstring>
15#include <gvc/gvc.h>
16#include <string>
17#include <util/agxbuf.h>
18#include <util/alloc.h>
19
20#define agfindattr(x, s) agattrsym(x, s)
21#define agraphattr(g, n, s) agattr_text(g, AGRAPH, n, s)
22
23static char emptystring[] = {'\0'};
24
25static GVC_t *gvc;
26
27static void gv_init(void) {
28 // list of builtins, enable demand loading
29 gvc = gvContextPlugins(lt_preloaded_symbols, DEMAND_LOADING);
30}
31
32Agraph_t *graph(char *name) {
33 if (!gvc)
34 gv_init();
35 return agopen(name, Agundirected, 0);
36}
37
38Agraph_t *digraph(char *name) {
39 if (!gvc)
40 gv_init();
41 return agopen(name, Agdirected, 0);
42}
43
44Agraph_t *strictgraph(char *name) {
45 if (!gvc)
46 gv_init();
47 return agopen(name, Agstrictundirected, 0);
48}
49
50Agraph_t *strictdigraph(char *name) {
51 if (!gvc)
52 gv_init();
53 return agopen(name, Agstrictdirected, 0);
54}
55
56Agraph_t *readstring(char *string) {
57 if (!gvc)
58 gv_init();
59 return agmemread(string);
60}
61
62Agraph_t *read(FILE *f) {
63 if (!gvc)
64 gv_init();
65 return agread(f, nullptr);
66}
67
68Agraph_t *read(const char *filename) {
69 FILE *f = fopen(filename, "r");
70 if (!f)
71 return nullptr;
72 if (!gvc)
73 gv_init();
74 Agraph_t *g = agread(f, nullptr);
75 fclose(f);
76 return g;
77}
78
79//-------------------------------------------------
80Agraph_t *graph(Agraph_t *g, char *name) {
81 if (!gvc)
82 gv_init();
83 return agsubg(g, name, 1);
84}
85
86Agnode_t *node(Agraph_t *g, char *name) {
87 if (!gvc)
88 return nullptr;
89 return agnode(g, name, 1);
90}
91
93 if (!gvc || !t || !h || !g)
94 return nullptr;
95 // edges from/to the protonode are not permitted
96 if (AGTYPE(t) == AGRAPH || AGTYPE(h) == AGRAPH)
97 return nullptr;
98 return agedge(g, t, h, nullptr, 1);
99}
100
101Agedge_t *edge(Agnode_t *t, Agnode_t *h) { return edge(agraphof(t), t, h); }
102
103// induce tail if necessary
104Agedge_t *edge(char *tname, Agnode_t *h) {
105 return edge(node(agraphof(h), tname), h);
106}
107
108// induce head if necessary
109Agedge_t *edge(Agnode_t *t, char *hname) {
110 return edge(t, node(agraphof(t), hname));
111}
112
113// induce tail/head if necessary
114Agedge_t *edge(Agraph_t *g, char *tname, char *hname) {
115 return edge(g, node(g, tname), node(g, hname));
116}
117
118//-------------------------------------------------
119static char *myagxget(void *obj, Agsym_t *a) {
120 if (!obj || !a)
121 return emptystring;
122 char *val = agxget(obj, a);
123 if (!val)
124 return emptystring;
125 if (strcmp(a->name, "label") == 0 && aghtmlstr(val)) {
126 const std::string buf = std::string("<") + val + ">";
127 return gv_strdup(buf.c_str());
128 }
129 return val;
130}
131char *getv(Agraph_t *g, Agsym_t *a) { return myagxget(g, a); }
132char *getv(Agraph_t *g, char *attr) {
133 if (!g || !attr)
134 return nullptr;
135 Agsym_t *a = agfindattr(agroot(g), attr);
136 return myagxget(g, a);
137}
138static void myagxset(void *obj, Agsym_t *a, char *val) {
139 if (strcmp(a->name, "label") == 0 && val[0] == '<') {
140 size_t len = strlen(val);
141 if (val[len - 1] == '>') {
142 std::string hs(val + 1, len - 2);
143 val = agstrdup_html(agraphof(obj), hs.c_str());
144 }
145 }
146 agxset(obj, a, val);
147}
148char *setv(Agraph_t *g, Agsym_t *a, char *val) {
149 if (!g || !a || !val)
150 return nullptr;
151 myagxset(g, a, val);
152 return val;
153}
154char *setv(Agraph_t *g, char *attr, char *val) {
155 if (!g || !attr || !val)
156 return nullptr;
157 Agsym_t *a = agfindattr(agroot(g), attr);
158 if (!a)
159 a = agraphattr(g->root, attr, emptystring);
160 myagxset(g, a, val);
161 return val;
162}
163//-------------------------------------------------
164char *getv(Agnode_t *n, Agsym_t *a) {
165 if (!n || !a)
166 return nullptr;
167 if (AGTYPE(n) == AGRAPH) // protonode
168 return nullptr; // FIXME ??
169 return myagxget(n, a);
170}
171char *getv(Agnode_t *n, char *attr) {
172 if (!n || !attr)
173 return nullptr;
174 if (AGTYPE(n) == AGRAPH) // protonode
175 return nullptr; // FIXME ??
176 Agraph_t *g = agroot(agraphof(n));
177 Agsym_t *a = agattr_text(g, AGNODE, attr, nullptr);
178 return myagxget(n, a);
179}
180char *setv(Agnode_t *n, Agsym_t *a, char *val) {
181 if (!n || !a || !val)
182 return nullptr;
183 if (AGTYPE(n) == AGRAPH) // protonode
184 return nullptr; // FIXME ??
185 myagxset(n, a, val);
186 return val;
187}
188char *setv(Agnode_t *n, char *attr, char *val) {
189
190 if (!n || !attr || !val)
191 return nullptr;
192 if (AGTYPE(n) == AGRAPH) { // protonode
193 auto g = reinterpret_cast<Agraph_t *>(n);
194 (void)agattr_text(g, AGNODE, attr,
195 val); // create default attribute in pseudo protonode
196 // FIXME? - deal with html in "label" attributes
197 return val;
198 }
199 Agraph_t *g = agroot(agraphof(n));
200 Agsym_t *a = agattr_text(g, AGNODE, attr, nullptr);
201 if (!a)
202 a = agattr_text(g, AGNODE, attr, emptystring);
203 myagxset(n, a, val);
204 return val;
205}
206//-------------------------------------------------
207char *getv(Agedge_t *e, Agsym_t *a) {
208 if (!e || !a)
209 return nullptr;
210 if (AGTYPE(e) == AGRAPH) // protoedge
211 return nullptr; // FIXME ??
212 return myagxget(e, a);
213}
214char *getv(Agedge_t *e, char *attr) {
215 if (!e || !attr)
216 return nullptr;
217 if (AGTYPE(e) == AGRAPH) // protoedge
218 return nullptr; // FIXME ??
219 Agraph_t *g = agraphof(agtail(e));
220 Agsym_t *a = agattr_text(g, AGEDGE, attr, nullptr);
221 return myagxget(e, a);
222}
223char *setv(Agedge_t *e, Agsym_t *a, char *val) {
224 if (!e || !a || !val)
225 return nullptr;
226 if (AGTYPE(e) == AGRAPH) // protoedge
227 return nullptr; // FIXME ??
228 myagxset(e, a, val);
229 return val;
230}
231char *setv(Agedge_t *e, char *attr, char *val) {
232 if (!e || !attr || !val)
233 return nullptr;
234 if (AGTYPE(e) == AGRAPH) { // protoedge
235 auto g = reinterpret_cast<Agraph_t *>(e);
236 (void)agattr_text(g, AGEDGE, attr,
237 val); // create default attribute in pseudo protoedge
238 // FIXME? - deal with html in "label" attributes
239 return val;
240 }
241 Agraph_t *g = agroot(agraphof(agtail(e)));
242 Agsym_t *a = agattr_text(g, AGEDGE, attr, nullptr);
243 if (!a)
244 a = agattr_text(g, AGEDGE, attr, emptystring);
245 myagxset(e, a, val);
246 return val;
247}
248//-------------------------------------------------
249Agraph_t *findsubg(Agraph_t *g, char *name) {
250 if (!g || !name)
251 return nullptr;
252 return agsubg(g, name, 0);
253}
254
255Agnode_t *findnode(Agraph_t *g, char *name) {
256 if (!g || !name)
257 return nullptr;
258 return agnode(g, name, 0);
259}
260
262 if (!t || !h)
263 return nullptr;
264 if (AGTYPE(t) == AGRAPH || AGTYPE(h) == AGRAPH)
265 return nullptr;
266 return agfindedge(agraphof(t), t, h);
267}
268
269Agsym_t *findattr(Agraph_t *g, char *name) {
270 if (!g || !name)
271 return nullptr;
272 return agfindattr(g, name);
273}
274
275Agsym_t *findattr(Agnode_t *n, char *name) {
276 if (!n || !name)
277 return nullptr;
278 return agfindattr(n, name);
279}
280
281Agsym_t *findattr(Agedge_t *e, char *name) {
282 if (!e || !name)
283 return nullptr;
284 return agfindattr(e, name);
285}
286
287//-------------------------------------------------
288
290 if (!e)
291 return nullptr;
292 if (AGTYPE(e) == AGRAPH)
293 return nullptr;
294 return aghead(e);
295}
296
298 if (!e)
299 return nullptr;
300 if (AGTYPE(e) == AGRAPH)
301 return nullptr;
302 return agtail(e);
303}
304
306 if (!g || g == g->root)
307 return nullptr;
308 return agroot(g);
309}
310
312 if (!e)
313 return nullptr;
314 if (AGTYPE(e) == AGRAPH)
315 return reinterpret_cast<Agraph_t *>(
316 e); // graph of protoedge is itself recast
317 return agraphof(agtail(e));
318}
319
321 if (!n)
322 return nullptr;
323 if (AGTYPE(n) == AGRAPH)
324 return reinterpret_cast<Agraph_t *>(
325 n); // graph of protonode is itself recast
326 return agraphof(n);
327}
328
330 if (!g)
331 return nullptr;
332 return agroot(g);
333}
334
335//-------------------------------------------------
337 return reinterpret_cast<Agnode_t *>(g); // gross abuse of the type system!
338}
339
341 return reinterpret_cast<Agedge_t *>(g); // gross abuse of the type system!
342}
343
344//-------------------------------------------------
345char *nameof(Agraph_t *g) {
346 if (!g)
347 return nullptr;
348 return agnameof(g);
349}
350char *nameof(Agnode_t *n) {
351 if (!n)
352 return nullptr;
353 if (AGTYPE(n) == AGRAPH)
354 return nullptr;
355 return agnameof(n);
356}
357char *nameof(Agsym_t *a) {
358 if (!a)
359 return nullptr;
360 return a->name;
361}
362
363//-------------------------------------------------
364bool ok(Agraph_t *g) { return g != nullptr; }
365bool ok(Agnode_t *n) { return n != nullptr; }
366bool ok(Agedge_t *e) { return e != nullptr; }
367bool ok(Agsym_t *a) { return a != nullptr; }
368//-------------------------------------------------
370 if (!g)
371 return nullptr;
372 return agfstsubg(g);
373}
374
376
377 if (!g || !sg)
378 return nullptr;
379 return agnxtsubg(sg);
380}
381
383
384Agraph_t *nextsupg(Agraph_t *, Agraph_t *) { return nullptr; }
385
387 if (!g)
388 return nullptr;
389 for (Agnode_t *n = agfstnode(g); n; n = agnxtnode(g, n)) {
390 Agedge_t *e = agfstout(g, n);
391 if (e)
392 return e;
393 }
394 return nullptr;
395}
396
398 if (!g || !e)
399 return nullptr;
400 Agedge_t *ne = agnxtout(g, e);
401 if (ne)
402 return ne;
403 for (Agnode_t *n = agnxtnode(g, agtail(e)); n; n = agnxtnode(g, n)) {
404 ne = agfstout(g, n);
405 if (ne)
406 return ne;
407 }
408 return nullptr;
409}
410
412
413Agedge_t *nextedge(Agraph_t *g, Agedge_t *e) { return nextout(g, e); }
414
416 if (!n)
417 return nullptr;
418 return agfstout(agraphof(n), n);
419}
420
422 if (!n || !e)
423 return nullptr;
424 return agnxtout(agraphof(n), e);
425}
426
428 if (!n)
429 return nullptr;
430 Agedge_t *e = agfstout(agraphof(n), n);
431 if (!e)
432 return nullptr;
433 return aghead(e);
434}
435
437 if (!n || !h)
438 return nullptr;
439 Agraph_t *g = agraphof(n);
440 Agedge_t *e = agfindedge(g, n, h);
441 if (!e)
442 return nullptr;
443 do {
444 e = agnxtout(g, AGMKOUT(e));
445 if (!e)
446 return nullptr;
447 } while (aghead(e) == h);
448 return aghead(e);
449}
450
452 if (!n)
453 return nullptr;
454 return agfstedge(agraphof(n), n);
455}
456
458 if (!n || !e)
459 return nullptr;
460 return agnxtedge(agraphof(n), e, n);
461}
462
464 if (!g)
465 return nullptr;
466 Agnode_t *n = agfstnode(g);
467 if (!n)
468 return nullptr;
469 return agfstin(g, n);
470}
471
473 if (!g || !e)
474 return nullptr;
475 Agedge_t *ne = agnxtin(g, e);
476 if (ne)
477 return ne;
478 Agnode_t *n = agnxtnode(g, aghead(e));
479 if (!n)
480 return nullptr;
481 return agfstin(g, n);
482}
483
485 if (!n)
486 return nullptr;
487 return agfstin(agraphof(n), n);
488}
489
491 if (!n || !e)
492 return nullptr;
493 return agnxtin(agraphof(n), e);
494}
495
497 if (!n)
498 return nullptr;
499 Agedge_t *e = agfstin(agraphof(n), n);
500 if (!e)
501 return nullptr;
502 return agtail(e);
503}
504
506 if (!n || !t)
507 return nullptr;
508 Agraph_t *g = agraphof(n);
509 Agedge_t *e = agfindedge(g, t, n);
510 if (!e)
511 return nullptr;
512 do {
513 e = agnxtin(g, AGMKIN(e));
514 if (!e)
515 return nullptr;
516 } while (agtail(e) == t);
517 return agtail(e);
518}
519
521 if (!g)
522 return nullptr;
523 return agfstnode(g);
524}
525
527 if (!g || !n)
528 return nullptr;
529 return agnxtnode(g, n);
530}
531
533 if (!e)
534 return nullptr;
535 return agtail(e);
536}
537
539 if (!e || n != agtail(e))
540 return nullptr;
541 return aghead(e);
542}
543
545 if (!g)
546 return nullptr;
547 g = agroot(g);
548 return agnxtattr(g, AGRAPH, nullptr);
549}
550
552 if (!g || !a)
553 return nullptr;
554 g = agroot(g);
555 return agnxtattr(g, AGRAPH, a);
556}
557
559 if (!n)
560 return nullptr;
561 Agraph_t *g = agraphof(n);
562 return agnxtattr(g, AGNODE, nullptr);
563}
564
566 if (!n || !a)
567 return nullptr;
568 Agraph_t *g = agraphof(n);
569 return agnxtattr(g, AGNODE, a);
570}
571
573 if (!e)
574 return nullptr;
575 Agraph_t *g = agraphof(agtail(e));
576 return agnxtattr(g, AGEDGE, nullptr);
577}
578
580 if (!e || !a)
581 return nullptr;
582 Agraph_t *g = agraphof(agtail(e));
583 return agnxtattr(g, AGEDGE, a);
584}
585
586bool rm(Agraph_t *g) {
587 if (!g)
588 return false;
589 // The rm function appears to have the semantics of agclose, so
590 // we should just do that, and let cgraph take care of all the
591 // details.
592 agclose(g);
593 return true;
594}
595
596bool rm(Agnode_t *n) {
597 if (!n)
598 return false;
599 // removal of the protonode is not permitted
600 if (strcmp(agnameof(n), "\001proto") == 0)
601 return false;
602 agdelete(agraphof(n), n);
603 return true;
604}
605
606bool rm(Agedge_t *e) {
607 if (!e)
608 return false;
609 // removal of the protoedge is not permitted
610 if (strcmp(agnameof(aghead(e)), "\001proto") == 0 ||
611 strcmp(agnameof(agtail(e)), "\001proto") == 0)
612 return false;
614 return true;
615}
616
617bool layout(Agraph_t *g, const char *engine) {
618 if (!g)
619 return false;
620 (void)gvFreeLayout(gvc, g); // ignore errors
621 int err = gvLayout(gvc, g, engine);
622 return err == 0;
623}
624
625// annotate the graph with layout information
626bool render(Agraph_t *g) {
627 if (!g)
628 return false;
629 attach_attrs(g);
630 return true;
631}
632
633// render to stdout
634bool render(Agraph_t *g, const char *format) {
635 if (!g)
636 return false;
637 int err = gvRender(gvc, g, format, stdout);
638 return err == 0;
639}
640
641// render to an open FILE
642bool render(Agraph_t *g, const char *format, FILE *f) {
643 if (!g)
644 return false;
645 int err = gvRender(gvc, g, format, f);
646 return err == 0;
647}
648
649// render to an open channel
650bool renderchannel(Agraph_t *g, const char *format, const char *channelname) {
651 if (!g)
652 return false;
654 int err = gvRender(gvc, g, format, (FILE *)channelname);
655 gv_writer_reset(gvc); // Reset to default
656 return err == 0;
657}
658
659// render to a filename
660bool render(Agraph_t *g, const char *format, const char *filename) {
661 if (!g)
662 return false;
663 int err = gvRenderFilename(gvc, g, format, filename);
664 return err == 0;
665}
666
667// render to string result, using binding-dependent gv_string_writer()
668char *renderresult(Agraph_t *g, const char *format) {
669 if (!g)
670 return nullptr;
671 if (!GD_alg(g))
672 return nullptr;
673 // must be freed by wrapper code
674 agxbuf buffer = {};
676 (void)gvRender(gvc, g, format, reinterpret_cast<FILE *>(&buffer));
677 gv_writer_reset(gvc); // Reset to default
678 const size_t len = agxblen(&buffer);
679 assert(len <= INT_MAX);
680 *reinterpret_cast<int *>(GD_alg(g)) = static_cast<int>(len);
681 return agxbdisown(&buffer);
682}
683
684// render to string result, using binding-dependent gv_string_writer()
685void renderresult(Agraph_t *g, const char *format, char *outdata) {
686 if (!g)
687 return;
689 (void)gvRender(gvc, g, format, reinterpret_cast<FILE *>(outdata));
690 gv_writer_reset(gvc); // Reset to default
691}
692
693// render to a malloc'ed data string, to be free'd by caller.
694char *renderdata(Agraph_t *g, const char *format) {
695 if (!g)
696 return nullptr;
697 char *data;
698 size_t length;
699 int err = gvRenderData(gvc, g, format, &data, &length);
700 if (err)
701 return nullptr;
702 return data;
703}
704
705bool write(Agraph_t *g, FILE *f) {
706 if (!g)
707 return false;
708 int err = agwrite(g, f);
709 return err == 0;
710}
711
712bool write(Agraph_t *g, const char *filename) {
713 if (!g)
714 return false;
715 FILE *f = fopen(filename, "w");
716 if (!f)
717 return false;
718 int err = agwrite(g, f);
719 fclose(f);
720 return err == 0;
721}
722
723bool tred(Agraph_t *g) {
724 if (!g)
725 return false;
726 int err = gvToolTred(g);
727 return err == 0;
728}
static size_t agxblen(const agxbuf *xb)
return number of characters currently stored
Definition agxbuf.h:88
static char * agxbdisown(agxbuf *xb)
Definition agxbuf.h:325
Memory allocation wrappers that exit on failure.
static char * gv_strdup(const char *original)
Definition alloc.h:101
static Extype_t length(Exid_t *rhs, Exdisc_t *disc)
Definition compile.c:1606
static char * err
Definition delaunay.c:538
lt_symlist_t lt_preloaded_symbols[]
static double len(glCompPoint p)
Definition glutils.c:136
edge
Definition gmlparse.y:244
Agsym_t * agattr_text(Agraph_t *g, int kind, char *name, const char *value)
creates or looks up text attributes of a graph
Definition attr.c:334
Agsym_t * agnxtattr(Agraph_t *g, int kind, Agsym_t *attr)
permits traversing the list of attributes of a given type
Definition attr.c:363
int agxset(void *obj, Agsym_t *sym, const char *value)
Definition attr.c:522
char * agxget(void *obj, Agsym_t *sym)
Definition attr.c:458
Agedge_t * agedge(Agraph_t *g, Agnode_t *t, Agnode_t *h, char *name, int createflag)
Definition edge.c:253
#define AGMKOUT(e)
Definition cgraph.h:971
Agedge_t * agnxtin(Agraph_t *g, Agedge_t *e)
Definition edge.c:71
Agedge_t * agfstout(Agraph_t *g, Agnode_t *n)
Definition edge.c:26
#define AGMKIN(e)
Definition cgraph.h:972
#define agtail(e)
Definition cgraph.h:977
#define agfindedge(g, t, h)
Definition types.h:609
Agedge_t * agnxtedge(Agraph_t *g, Agedge_t *e, Agnode_t *n)
Definition edge.c:96
#define aghead(e)
Definition cgraph.h:978
Agedge_t * agnxtout(Agraph_t *g, Agedge_t *e)
Definition edge.c:41
Agedge_t * agfstedge(Agraph_t *g, Agnode_t *n)
Definition edge.c:87
Agedge_t * agfstin(Agraph_t *g, Agnode_t *n)
Definition edge.c:57
Agdesc_t Agundirected
undirected
Definition graph.c:272
#define GD_alg(g)
Definition types.h:358
Agdesc_t Agstrictundirected
strict undirected
Definition graph.c:273
int agclose(Agraph_t *g)
deletes a graph, freeing its associated storage
Definition graph.c:95
Agdesc_t Agstrictdirected
strict directed. A strict graph cannot have multi-edges or self-arcs.
Definition graph.c:271
Agraph_t * agmemread(const char *cp)
reads a graph from the input string
Definition io.c:90
Agraph_t * agopen(char *name, Agdesc_t desc, Agdisc_t *disc)
creates a new graph with the given name and kind
Definition graph.c:42
int agwrite(Agraph_t *g, void *chan)
Return 0 on success, EOF on failure.
Definition write.c:669
Agraph_t * agread(void *chan, Agdisc_t *disc)
constructs a new graph
Definition grammar.c:2052
Agdesc_t Agdirected
directed
Definition graph.c:270
Agnode_t * agnode(Agraph_t *g, char *name, int createflag)
Definition node.c:141
Agnode_t * agnxtnode(Agraph_t *g, Agnode_t *n)
Definition node.c:48
Agnode_t * agfstnode(Agraph_t *g)
Definition node.c:41
Agraph_t * agraphof(void *obj)
Definition obj.c:185
char * agnameof(void *)
returns a string descriptor for the object.
Definition id.c:143
#define AGTYPE(obj)
returns AGRAPH, AGNODE, or AGEDGE depending on the type of the object
Definition cgraph.h:216
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
@ AGEDGE
Definition cgraph.h:207
@ AGNODE
Definition cgraph.h:207
@ AGRAPH
Definition cgraph.h:207
int aghtmlstr(const char *)
Definition refstr.c:438
char * agstrdup_html(Agraph_t *, const char *)
returns a pointer to a reference-counted HTML-like copy of the argument string, creating one if neces...
Definition refstr.c:395
Agraph_t * agfstsubg(Agraph_t *g)
Definition subg.c:73
Agraph_t * agnxtsubg(Agraph_t *subg)
Definition subg.c:78
Agraph_t * agsubg(Agraph_t *g, char *name, int cflag)
Definition subg.c:53
int gvFreeLayout(GVC_t *gvc, graph_t *g)
Definition gvlayout.c:105
int gvLayout(GVC_t *gvc, graph_t *g, const char *engine)
Definition gvc.c:52
int gvRender(GVC_t *gvc, graph_t *g, const char *format, FILE *out)
Definition gvc.c:84
int gvRenderData(GVC_t *gvc, graph_t *g, const char *format, char **result, size_t *length)
Definition gvc.c:175
GVC_t * gvContextPlugins(const lt_symlist_t *builtins, int demand_loading)
Definition gvc.c:35
int gvRenderFilename(GVC_t *gvc, graph_t *g, const char *format, const char *filename)
Definition gvc.c:114
void attach_attrs(graph_t *g)
Definition output.c:414
int gvToolTred(graph_t *g)
Definition gvtool_tred.c:70
static char emptystring[]
Definition gv.cpp:23
bool ok(Agraph_t *g)
Definition gv.cpp:364
bool tred(Agraph_t *g)
Definition gv.cpp:723
Agraph_t * firstsubg(Agraph_t *g)
Definition gv.cpp:369
Agraph_t * read(FILE *f)
Definition gv.cpp:62
Agraph_t * nextsubg(Agraph_t *g, Agraph_t *sg)
Definition gv.cpp:375
Agraph_t * readstring(char *string)
Definition gv.cpp:56
static char * myagxget(void *obj, Agsym_t *a)
Definition gv.cpp:119
Agraph_t * findsubg(Agraph_t *g, char *name)
Definition gv.cpp:249
static void gv_init(void)
Definition gv.cpp:27
Agraph_t * strictgraph(char *name)
Definition gv.cpp:44
Agedge_t * nextout(Agraph_t *g, Agedge_t *e)
Definition gv.cpp:397
bool write(Agraph_t *g, FILE *f)
Definition gv.cpp:705
Agraph_t * rootof(Agraph_t *g)
Definition gv.cpp:329
Agnode_t * headof(Agedge_t *e)
Definition gv.cpp:289
Agnode_t * firsttail(Agnode_t *n)
Definition gv.cpp:496
char * renderresult(Agraph_t *g, const char *format)
Definition gv.cpp:668
Agraph_t * strictdigraph(char *name)
Definition gv.cpp:50
bool renderchannel(Agraph_t *g, const char *format, const char *channelname)
Definition gv.cpp:650
char * getv(Agraph_t *g, Agsym_t *a)
Definition gv.cpp:131
Agedge_t * firstedge(Agraph_t *g)
Definition gv.cpp:411
Agraph_t * graphof(Agraph_t *g)
Definition gv.cpp:305
static GVC_t * gvc
Definition gv.cpp:25
char * nameof(Agraph_t *g)
Definition gv.cpp:345
Agnode_t * firstnode(Agraph_t *g)
Definition gv.cpp:520
Agedge_t * firstout(Agraph_t *g)
Definition gv.cpp:386
Agraph_t * nextsupg(Agraph_t *, Agraph_t *)
Definition gv.cpp:384
char * setv(Agraph_t *g, Agsym_t *a, char *val)
Definition gv.cpp:148
static void myagxset(void *obj, Agsym_t *a, char *val)
Definition gv.cpp:138
bool layout(Agraph_t *g, const char *engine)
Definition gv.cpp:617
Agsym_t * nextattr(Agraph_t *g, Agsym_t *a)
Definition gv.cpp:551
Agnode_t * tailof(Agedge_t *e)
Definition gv.cpp:297
char * renderdata(Agraph_t *g, const char *format)
Definition gv.cpp:694
Agnode_t * protonode(Agraph_t *g)
Definition gv.cpp:336
bool rm(Agraph_t *g)
Definition gv.cpp:586
Agnode_t * findnode(Agraph_t *g, char *name)
Definition gv.cpp:255
Agnode_t * nexttail(Agnode_t *n, Agnode_t *t)
Definition gv.cpp:505
Agraph_t * firstsupg(Agraph_t *g)
Definition gv.cpp:382
Agsym_t * findattr(Agraph_t *g, char *name)
Definition gv.cpp:269
Agraph_t * digraph(char *name)
Definition gv.cpp:38
Agedge_t * firstin(Agraph_t *g)
Definition gv.cpp:463
Agnode_t * nextnode(Agraph_t *g, Agnode_t *n)
Definition gv.cpp:526
Agraph_t * graph(char *name)
Definition gv.cpp:32
Agsym_t * firstattr(Agraph_t *g)
Definition gv.cpp:544
Agedge_t * nextin(Agraph_t *g, Agedge_t *e)
Definition gv.cpp:472
Agedge_t * nextedge(Agraph_t *g, Agedge_t *e)
Definition gv.cpp:413
Agedge_t * findedge(Agnode_t *t, Agnode_t *h)
Definition gv.cpp:261
#define agfindattr(x, s)
Definition gv.cpp:20
Agnode_t * firsthead(Agnode_t *n)
Definition gv.cpp:427
bool render(Agraph_t *g)
Definition gv.cpp:626
Agnode_t * nexthead(Agnode_t *n, Agnode_t *h)
Definition gv.cpp:436
#define agraphattr(g, n, s)
Definition gv.cpp:21
Agedge_t * protoedge(Agraph_t *g)
Definition gv.cpp:340
language-specific bindings API
void gv_channel_writer_init(GVC_t *gvc)
void gv_writer_reset(GVC_t *gvc)
void gv_string_writer_init(GVC_t *gvc)
Graphviz context library.
GVIO_API const char * format
Definition gvio.h:51
static gvloadimage_engine_t engine
graph or subgraph
Definition cgraph.h:424
Agraph_t * root
subgraphs - ancestors
Definition cgraph.h:433
Agraph_t * parent
Definition cgraph.h:433
string attribute descriptor symbol in Agattr_s.dict
Definition cgraph.h:640
char * name
Definition cgraph.h:642
Definition gvcint.h:81