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