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