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