Graphviz 14.1.3~dev.20260207.0611
Loading...
Searching...
No Matches
gmlparse.y
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%require "3.0"
12
13 /* By default, Bison emits a parser using symbols prefixed with "yy". Graphviz
14 * contains multiple Bison-generated parsers, so we alter this prefix to avoid
15 * symbol clashes.
16 */
17%define api.prefix {gml}
18
19%{
20#include <stdlib.h>
21#include <string.h>
22#include <arith.h>
23#include <gml2gv.h>
24#include <assert.h>
25#include <util/agxbuf.h>
26#include <util/alloc.h>
27#include <util/exit.h>
28#include <util/list.h>
29
30static gmlgraph* G;
31static gmlnode* N;
32static gmledge* E;
33
34static attrs_t *L;
35
36static void free_attrs(attrs_t *a) {
37 LIST_FREE(a);
38 free(a);
39}
40
41static LIST(attrs_t *) liststk = {.dtor = free_attrs};
42
43static char *sortToStr(unsigned short sort);
44
45static void free_node(gmlnode *p) {
46 if (!p) return;
48 free(p->id);
49 free (p);
50}
51
52static void free_edge(gmledge *p) {
53 if (!p) return;
55 free(p->target);
56 free(p->source);
57 free (p);
58}
59
60static void free_graph(gmlgraph *p) {
61 if (!p) return;
62 LIST_FREE(&p->nodelist);
63 LIST_FREE(&p->edgelist);
65 LIST_FREE(&p->graphlist);
66 free (p);
67}
68
69static void
70cleanup (void)
71{
72 LIST_CLEAR(&liststk);
73 if (L) {
75 L = NULL;
76 }
77 if (N) {
78 free_node(N);
79 N = NULL;
80 }
81 if (E) {
82 free_edge(E);
83 E = NULL;
84 }
85 if (G) {
87 G = NULL;
88 }
89}
90
91static void free_attr(gmlattr *p);
92
93static void
94pushAlist (void)
95{
96 attrs_t *const lp = gv_alloc(sizeof(attrs_t));
97 lp->dtor = free_attr;
98
99 if (L) {
100 LIST_PUSH_BACK(&liststk, L);
101 }
102 L = lp;
103}
104
105static attrs_t *popAlist(void) {
106 attrs_t *lp = L;
107
108 if (!LIST_IS_EMPTY(&liststk))
109 L = LIST_POP_BACK(&liststk);
110 else
111 L = NULL;
112
113 return lp;
114}
115
116static void
117popG (void)
118{
119 G = G->parent;
120}
121
122static void
123pushG (void)
124{
125 gmlgraph* g = gv_alloc(sizeof(gmlgraph));
126
127 g->attrlist.dtor = free_attr;
128 g->nodelist.dtor = free_node;
129 g->edgelist.dtor = free_edge;
130 g->graphlist.dtor = free_graph;
131 g->parent = G;
132 g->directed = -1;
133
134 if (G)
135 LIST_APPEND(&G->graphlist, g);
136
137 G = g;
138}
139
140static gmlnode*
141mkNode (void)
142{
143 gmlnode *const n = gv_alloc(sizeof(gmlnode));
144 n->attrlist.dtor = free_attr;
145 return n;
146}
147
148static gmledge*
149mkEdge (void)
150{
151 gmledge* ep = gv_alloc(sizeof(gmledge));
152 ep->attrlist.dtor = free_attr;
153 return ep;
154}
155
156static gmlattr *mkAttr(char* name, unsigned short sort, unsigned short kind,
157 char* str, attrs_t* list) {
158 gmlattr* gp = gv_alloc(sizeof(gmlattr));
159
160 assert (name || sort);
161 if (!name)
162 name = gv_strdup (sortToStr (sort));
163 gp->sort = sort;
164 gp->kind = kind;
165 gp->name = name;
166 if (str)
167 gp->u.value = str;
168 else {
169 if (list != NULL && LIST_IS_EMPTY(list)) {
170 free_attrs(list);
171 list = 0;
172 }
173 gp->u.lp = list;
174 }
175 return gp;
176}
177
178static int
179setDir (char* d)
180{
181 gmlgraph* g;
182 int dir = atoi (d);
183
184 free (d);
185 if (dir < 0) dir = -1;
186 else if (dir > 0) dir = 1;
187 else dir = 0;
188 G->directed = dir;
189
190 if (dir >= 0) {
191 for (g = G->parent; g; g = g->parent) {
192 if (g->directed < 0)
193 g->directed = dir;
194 else if (g->directed != dir)
195 return 1;
196 }
197 }
198
199 return 0;
200}
201
202%}
203%union {
204 int i;
205 char *str;
206 gmlnode* np;
207 gmledge* ep;
208 gmlattr* ap;
209 attrs_t *list;
210}
211
215%token STYLE LINE POINT
217%token <str> INTEGER REAL STRING ID NAME
218%token <list> GML_LIST
219
220%type <np> node
221%type <ep> edge
222%type <list> attrlist
223%type <ap> alistitem
224
225%%
226graph : optalist hdr body {gmllexeof(); if (G->parent) popG(); }
227 | error { cleanup(); YYABORT; }
228 |
229 ;
230
231hdr : GRAPH { pushG(); }
232 ;
233
234body : '[' optglist ']'
235 ;
236
237optglist : glist
238 | /* empty */
239 ;
240
241glist : glist glistitem
242 | glistitem
243 ;
244
245glistitem : node { LIST_APPEND(&G->nodelist, $1); }
246 | edge { LIST_APPEND(&G->edgelist, $1); }
247 | hdr body
249 if (setDir($2)) {
250 yyerror("mixed directed and undirected graphs");
251 cleanup ();
252 YYABORT;
253 }
254 }
255 | ID INTEGER { LIST_APPEND(&G->attrlist, mkAttr(gv_strdup("id"), 0, INTEGER, $2, 0)); }
256 | alistitem { LIST_APPEND(&G->attrlist, $1); }
257 ;
258
259node : NODE { N = mkNode(); } '[' nlist ']' { $$ = N; N = NULL; }
260 ;
261
262nlist : nlist nlistitem
263 | nlistitem
264 ;
265
266nlistitem : ID INTEGER { N->id = $2; }
267 | alistitem { LIST_APPEND(&N->attrlist, $1); }
268 ;
269
270edge : EDGE { E = mkEdge(); } '[' elist ']' { $$ = E; E = NULL; }
271 ;
272
273elist : elist elistitem
274 | elistitem
275 ;
276
277elistitem : SOURCE INTEGER { E->source = $2; }
278 | TARGET INTEGER { E->target = $2; }
279 | ID INTEGER { LIST_APPEND(&E->attrlist, mkAttr(gv_strdup("id"), 0, INTEGER, $2, 0)); }
280 | alistitem { LIST_APPEND(&E->attrlist, $1); }
281 ;
282
283attrlist : '[' {pushAlist(); } optalist ']' { $$ = popAlist(); }
284 ;
285
286optalist : alist
287 | /* empty */
288 ;
289
290alist : alist alistitem { LIST_APPEND(L, $2); }
291 | alistitem { LIST_APPEND(L, $1); }
292 ;
293
295 | NAME REAL { $$ = mkAttr ($1, 0, REAL, $2, 0); }
296 | NAME STRING { $$ = mkAttr ($1, 0, STRING, $2, 0); }
297 | NAME attrlist { $$ = mkAttr ($1, 0, GML_LIST, 0, $2); }
298 | XVAL REAL { $$ = mkAttr (0, XVAL, REAL, $2, 0); }
299 | XVAL INTEGER { $$ = mkAttr (0, XVAL, REAL, $2, 0); }
300 | YVAL REAL { $$ = mkAttr (0, YVAL, REAL, $2, 0); }
301 | WVAL REAL { $$ = mkAttr (0, WVAL, REAL, $2, 0); }
302 | HVAL REAL { $$ = mkAttr (0, HVAL, REAL, $2, 0); }
303 | LABEL STRING { $$ = mkAttr (0, LABEL, STRING, $2, 0); }
304 | GRAPHICS attrlist { $$ = mkAttr (0, GRAPHICS, GML_LIST, 0, $2); }
306 | TYPE STRING { $$ = mkAttr (0, TYPE, STRING, $2, 0); }
307 | FILL STRING { $$ = mkAttr (0, FILL, STRING, $2, 0); }
308 | OUTLINE STRING { $$ = mkAttr (0, OUTLINE, STRING, $2, 0); }
311 | WIDTH REAL { $$ = mkAttr (0, WIDTH, REAL, $2, 0); }
312 | WIDTH INTEGER { $$ = mkAttr (0, WIDTH, INTEGER, $2, 0); }
313 | STYLE STRING { $$ = mkAttr (0, STYLE, STRING, $2, 0); }
314 | STYLE attrlist { $$ = mkAttr (0, STYLE, GML_LIST, 0, $2); }
315 | LINE attrlist { $$ = mkAttr (0, LINE, GML_LIST, 0, $2); }
316 | POINT attrlist { $$ = mkAttr (0, POINT, GML_LIST, 0, $2); }
317 | TEXT STRING { $$ = mkAttr (0, TEXT, STRING, $2, 0); }
318 | FONTNAME STRING { $$ = mkAttr (0, FONTNAME, STRING, $2, 0); }
319 | FONTSIZE INTEGER { $$ = mkAttr (0, FONTNAME, INTEGER, $2, 0); }
320 | COLOR STRING { $$ = mkAttr (0, COLOR, STRING, $2, 0); }
321 ;
322
323%%
324
325static void free_attr(gmlattr *p) {
326 if (!p) return;
327 if (p->kind == GML_LIST && p->u.lp)
328 free_attrs(p->u.lp);
329 else
330 free (p->u.value);
331 free (p->name);
332 free (p);
333}
334
335static void deparseList(attrs_t *alist, agxbuf *xb);
336
337static void
339{
340 if (ap->kind == GML_LIST) {
341 agxbprint (xb, "%s ", ap->name);
342 deparseList (ap->u.lp, xb);
343 }
344 else if (ap->kind == STRING) {
345 agxbprint (xb, "%s \"%s\"", ap->name, ap->u.value);
346 }
347 else {
348 agxbprint (xb, "%s %s", ap->name, ap->u.value);
349 }
350}
351
352static void deparseList(attrs_t *alist, agxbuf *xb) {
353 agxbput (xb, "[ ");
354 for (size_t i = 0; alist != NULL && i < LIST_SIZE(alist); ++i) {
355 gmlattr *const ap = LIST_GET(alist, i);
356 deparseAttr (ap, xb);
357 agxbputc (xb, ' ');
358 }
359 agxbput (xb, "]");
360
361}
362
363static void
365{
366 char* str;
367
368 if (ap->kind == GML_LIST) {
369 deparseList (ap->u.lp, xb);
370 str = agxbuse (xb);
371 }
372 else
373 str = ap->u.value;
374
375 agsafeset (obj, ap->name, str, "");
376}
377
378static void addNodeLabelGraphics(Agnode_t *np, attrs_t *alist, agxbuf *unk) {
379 int cnt = 0;
380
381 if (!alist)
382 return;
383
384 for (size_t i = 0; i < LIST_SIZE(alist); ++i) {
385 gmlattr *const ap = LIST_GET(alist, i);
386 if (ap->sort == TEXT) {
387 agsafeset (np, "label", ap->u.value, "");
388 }
389 else if (ap->sort == COLOR) {
390 agsafeset (np, "fontcolor", ap->u.value, "");
391 }
392 else if (ap->sort == FONTSIZE) {
393 agsafeset (np, "fontsize", ap->u.value, "");
394 }
395 else if (ap->sort == FONTNAME) {
396 agsafeset (np, "fontname", ap->u.value, "");
397 }
398 else {
399 if (cnt)
400 agxbputc (unk, ' ');
401 else {
402 agxbput (unk, "[ ");
403 }
404 deparseAttr (ap, unk);
405 cnt++;
406 }
407 }
408
409 if (cnt) {
410 agxbput (unk, " ]");
411 agsafeset (np, "LabelGraphics", agxbuse (unk), "");
412 }
413 else
414 agxbclear (unk);
415}
416
417static void addEdgeLabelGraphics(Agedge_t *ep, attrs_t *alist, agxbuf *xb,
418 agxbuf *unk) {
419 char* x = "0";
420 char* y = "0";
421 int cnt = 0;
422
423 if (!alist)
424 return;
425
426 for (size_t i = 0; i < LIST_SIZE(alist); ++i) {
427 gmlattr *const ap = LIST_GET(alist, i);
428 if (ap->sort == TEXT) {
429 agsafeset (ep, "label", ap->u.value, "");
430 }
431 else if (ap->sort == COLOR) {
432 agsafeset (ep, "fontcolor", ap->u.value, "");
433 }
434 else if (ap->sort == FONTSIZE) {
435 agsafeset (ep, "fontsize", ap->u.value, "");
436 }
437 else if (ap->sort == FONTNAME) {
438 agsafeset (ep, "fontname", ap->u.value, "");
439 }
440 else if (ap->sort == XVAL) {
441 x = ap->u.value;
442 }
443 else if (ap->sort == YVAL) {
444 y = ap->u.value;
445 }
446 else {
447 if (cnt)
448 agxbputc (unk, ' ');
449 else {
450 agxbput (unk, "[ ");
451 }
452 deparseAttr (ap, unk);
453 cnt++;
454 }
455 }
456
457 agxbprint (xb, "%s,%s", x, y);
458 agsafeset (ep, "lp", agxbuse (xb), "");
459
460 if (cnt) {
461 agxbput (unk, " ]");
462 agsafeset (ep, "LabelGraphics", agxbuse (unk), "");
463 }
464 else
465 agxbclear (unk);
466}
467
468static void addNodeGraphics(Agnode_t *np, attrs_t *alist, agxbuf *xb,
469 agxbuf *unk) {
470 char* x = "0";
471 char* y = "0";
472 char buf[BUFSIZ];
473 double d;
474 int cnt = 0;
475
476 for (size_t i = 0; alist != NULL && i < LIST_SIZE(alist); ++i) {
477 gmlattr *const ap = LIST_GET(alist, i);
478 if (ap->sort == XVAL) {
479 x = ap->u.value;
480 }
481 else if (ap->sort == YVAL) {
482 y = ap->u.value;
483 }
484 else if (ap->sort == WVAL) {
485 d = atof (ap->u.value);
486 snprintf(buf, sizeof(buf), "%.04f", d/72.0);
487 agsafeset (np, "width", buf, "");
488 }
489 else if (ap->sort == HVAL) {
490 d = atof (ap->u.value);
491 snprintf(buf, sizeof(buf), "%.04f", d/72.0);
492 agsafeset (np, "height", buf, "");
493 }
494 else if (ap->sort == TYPE) {
495 agsafeset (np, "shape", ap->u.value, "");
496 }
497 else if (ap->sort == FILL) {
498 agsafeset (np, "color", ap->u.value, "");
499 }
500 else if (ap->sort == OUTLINE) {
501 agsafeset (np, "pencolor", ap->u.value, "");
502 }
503 else if (ap->sort == WIDTH || ap->sort == OUTLINEWIDTH) {
504 agsafeset (np, "penwidth", ap->u.value, "");
505 }
506 else if (ap->sort == STYLE || ap->sort == OUTLINESTYLE) {
507 agsafeset (np, "style", ap->u.value, "");
508 }
509 else {
510 if (cnt)
511 agxbputc (unk, ' ');
512 else {
513 agxbput (unk, "[ ");
514 }
515 deparseAttr (ap, unk);
516 cnt++;
517 }
518 }
519
520 agxbprint (xb, "%s,%s", x, y);
521 agsafeset (np, "pos", agxbuse (xb), "");
522
523 if (cnt) {
524 agxbput (unk, " ]");
525 agsafeset (np, "graphics", agxbuse (unk), "");
526 }
527 else
528 agxbclear (unk);
529}
530
531static void addEdgePoint(Agedge_t *ep, attrs_t *alist, agxbuf *xb) {
532 char* x = "0";
533 char* y = "0";
534
535 for (size_t i = 0; alist != NULL && i < LIST_SIZE(alist); ++i) {
536 gmlattr *const ap = LIST_GET(alist, i);
537 if (ap->sort == XVAL) {
538 x = ap->u.value;
539 }
540 else if (ap->sort == YVAL) {
541 y = ap->u.value;
542 }
543 else {
544 fprintf (stderr, "non-X/Y field in point attribute");
545 unknown ((Agobj_t*)ep, ap, xb);
546 }
547 }
548
549 if (agxblen(xb)) agxbputc (xb, ' ');
550 agxbprint (xb, "%s,%s", x, y);
551}
552
553static void addEdgePos(Agedge_t *ep, attrs_t *alist, agxbuf *xb) {
554 if (!alist) return;
555 for (size_t i = 0; i < LIST_SIZE(alist); ++i) {
556 gmlattr *const ap = LIST_GET(alist, i);
557 if (ap->sort == POINT) {
558 addEdgePoint (ep, ap->u.lp, xb);
559 }
560 else {
561 fprintf (stderr, "non-point field in line attribute");
562 unknown(&ep->base, ap, xb);
563 }
564 }
565 agsafeset (ep, "pos", agxbuse (xb), "");
566}
567
568static void addEdgeGraphics(Agedge_t *ep, attrs_t *alist, agxbuf *xb,
569 agxbuf *unk) {
570 int cnt = 0;
571
572 for (size_t i = 0; alist != NULL && i < LIST_SIZE(alist); ++i) {
573 gmlattr *const ap = LIST_GET(alist, i);
574 if (ap->sort == WIDTH) {
575 agsafeset (ep, "penwidth", ap->u.value, "");
576 }
577 else if (ap->sort == STYLE) {
578 agsafeset (ep, "style", ap->u.value, "");
579 }
580 else if (ap->sort == FILL) {
581 agsafeset (ep, "color", ap->u.value, "");
582 }
583 else if (ap->sort == LINE) {
584 addEdgePos (ep, ap->u.lp, xb);
585 }
586 else {
587 if (cnt)
588 agxbputc (unk, ' ');
589 else {
590 agxbput (unk, "[ ");
591 }
592 deparseAttr (ap, unk);
593 cnt++;
594 }
595 }
596
597 if (cnt) {
598 agxbput (unk, " ]");
599 agsafeset (ep, "graphics", agxbuse (unk), "");
600 }
601 else
602 agxbclear(unk);
603}
604
605static void addAttrs(Agobj_t *obj, attrs_t *alist, agxbuf *xb, agxbuf *unk) {
606 for (size_t i = 0; i < LIST_SIZE(alist); ++i) {
607 gmlattr *const ap = LIST_GET(alist, i);
608 if (ap->sort == GRAPHICS) {
609 if (AGTYPE(obj) == AGNODE)
610 addNodeGraphics ((Agnode_t*)obj, ap->u.lp, xb, unk);
611 else if (AGTYPE(obj) == AGEDGE)
612 addEdgeGraphics ((Agedge_t*)obj, ap->u.lp, xb, unk);
613 else
614 unknown (obj, ap, xb);
615 }
616 else if (ap->sort == LABELGRAPHICS) {
617 if (AGTYPE(obj) == AGNODE)
618 addNodeLabelGraphics ((Agnode_t*)obj, ap->u.lp, unk);
619 else if (AGTYPE(obj) == AGEDGE)
620 addEdgeLabelGraphics ((Agedge_t*)obj, ap->u.lp, xb, unk);
621 else
622 unknown (obj, ap, xb);
623 }
624 else
625 unknown (obj, ap, xb);
626 }
627}
628
630 agxbuf *xb, agxbuf *unk) {
631 Agraph_t* g;
632 Agnode_t* n;
633 Agnode_t* h;
634 Agedge_t* e;
635
636 if (parent) {
637 g = agsubg (parent, NULL, 1);
638 }
639 else if (graph->directed >= 1)
640 g = agopen (name, Agdirected, 0);
641 else
642 g = agopen (name, Agundirected, 0);
643
644 if (!parent && L) {
645 addAttrs(&g->base, L, xb, unk);
646 }
647 for (size_t i = 0; i < LIST_SIZE(&graph->nodelist); ++i) {
648 gmlnode *const np = LIST_GET(&graph->nodelist, i);
649 if (!np->id) {
650 fprintf (stderr, "node without an id attribute");
651 graphviz_exit (1);
652 }
653 n = agnode (g, np->id, 1);
654 addAttrs(&n->base, &np->attrlist, xb, unk);
655 }
656
657 for (size_t i = 0; i < LIST_SIZE(&graph->edgelist); ++i) {
658 gmledge *ep = LIST_GET(&graph->edgelist, i);
659 if (!ep->source) {
660 fprintf (stderr, "edge without an source attribute");
661 graphviz_exit (1);
662 }
663 if (!ep->target) {
664 fprintf (stderr, "node without an target attribute");
665 graphviz_exit (1);
666 }
667 n = agnode (g, ep->source, 1);
668 h = agnode (g, ep->target, 1);
669 e = agedge (g, n, h, NULL, 1);
670 addAttrs(&e->base, &ep->attrlist, xb, unk);
671 }
672 for (size_t i = 0; i < LIST_SIZE(&graph->graphlist); ++i) {
673 gmlgraph *const gp = LIST_GET(&graph->graphlist, i);
674 mkGraph (gp, g, NULL, xb, unk);
675 }
676
677 addAttrs(&g->base, &graph->attrlist, xb, unk);
678
679 return g;
680}
681
683gml_to_gv (char* name, FILE* fp, int cnt, int* errors)
684{
685 Agraph_t* g;
686 int error;
687
688 if (cnt == 0)
689 initgmlscan(fp);
690 else
691 initgmlscan(0);
692
693 L = NULL;
694 pushAlist ();
695 gmlparse ();
696
697 error = gmlerrors();
698 *errors |= error;
699 if (!G || error)
700 g = NULL;
701 else {
702 agxbuf xb = {0};
703 agxbuf unk = {0};
704 g = mkGraph (G, NULL, name, &xb, &unk);
705 agxbfree (&xb);
706 agxbfree(&unk);
707 }
708
709 cleanup ();
710
711 return g;
712}
713
714static char *sortToStr(unsigned short sort) {
715 char* s;
716
717 switch (sort) {
718 case GRAPH :
719 s = "graph"; break;
720 case NODE :
721 s = "node"; break;
722 case EDGE :
723 s = "edge"; break;
724 case DIRECTED :
725 s = "directed"; break;
726 case ID :
727 s = "id"; break;
728 case SOURCE :
729 s = "source"; break;
730 case TARGET :
731 s = "target"; break;
732 case XVAL :
733 s = "xval"; break;
734 case YVAL :
735 s = "yval"; break;
736 case WVAL :
737 s = "wval"; break;
738 case HVAL :
739 s = "hval"; break;
740 case LABEL :
741 s = "label"; break;
742 case GRAPHICS :
743 s = "graphics"; break;
744 case LABELGRAPHICS :
745 s = "labelGraphics"; break;
746 case TYPE :
747 s = "type"; break;
748 case FILL :
749 s = "fill"; break;
750 case OUTLINE :
751 s = "outline"; break;
752 case OUTLINESTYLE :
753 s = "outlineStyle"; break;
754 case OUTLINEWIDTH :
755 s = "outlineWidth"; break;
756 case WIDTH :
757 s = "width"; break;
758 case STYLE :
759 s = "style"; break;
760 case LINE :
761 s = "line"; break;
762 case POINT :
763 s = "point"; break;
764 case TEXT :
765 s = "text"; break;
766 case FONTSIZE :
767 s = "fontSize"; break;
768 case FONTNAME :
769 s = "fontName"; break;
770 case COLOR :
771 s = "color"; break;
772 case INTEGER :
773 s = "integer"; break;
774 case REAL :
775 s = "real"; break;
776 case STRING :
777 s = "string"; break;
778 case NAME :
779 s = "name"; break;
780 case GML_LIST :
781 s = "list"; break;
782 case '[' :
783 s = "["; break;
784 case ']' :
785 s = "]"; break;
786 default :
787 s = NULL;break;
788 }
789
790 return s;
791}
Dynamically expanding string buffers.
static void agxbfree(agxbuf *xb)
free any malloced resources
Definition agxbuf.h:97
static int agxbprint(agxbuf *xb, const char *fmt,...)
Printf-style output to an agxbuf.
Definition agxbuf.h:252
static void agxbclear(agxbuf *xb)
resets pointer to data
Definition agxbuf.h:312
static WUR char * agxbuse(agxbuf *xb)
Definition agxbuf.h:325
static size_t agxblen(const agxbuf *xb)
return number of characters currently stored
Definition agxbuf.h:108
static int agxbputc(agxbuf *xb, char c)
add character to buffer
Definition agxbuf.h:295
Memory allocation wrappers that exit on failure.
static char * gv_strdup(const char *original)
Definition alloc.h:101
static void * gv_alloc(size_t size)
Definition alloc.h:47
#define parent(i)
Definition closest.c:75
static NORETURN void graphviz_exit(int status)
Definition exit.h:23
#define DIRECTED
Definition gc.c:50
#define G
Definition gdefs.h:7
GML-DOT converter
int gmlerrors(void)
Definition gmlscan.l:121
void initgmlscan(FILE *)
Definition gmlscan.c:850
void gmllexeof(void)
Definition gmlscan.l:126
static void free_attrs(attrs_t *a)
Definition gmlparse.c:96
#define YYABORT
Definition gmlparse.c:940
static attrs_t * L
Definition gmlparse.c:94
static void cleanup(void)
Definition gmlparse.c:130
static gmlnode * mkNode(void)
Definition gmlparse.c:201
static int setDir(char *d)
Definition gmlparse.c:239
static void free_edge(gmledge *p)
Definition gmlparse.c:112
static void free_node(gmlnode *p)
Definition gmlparse.c:105
static gmledge * mkEdge(void)
Definition gmlparse.c:209
static void pushAlist(void)
Definition gmlparse.c:154
static void free_graph(gmlgraph *p)
Definition gmlparse.c:120
static void popG(void)
Definition gmlparse.c:177
static gmlattr * mkAttr(char *name, unsigned short sort, unsigned short kind, char *str, attrs_t *list)
Definition gmlparse.c:216
void free(void *)
static void pushG(void)
Definition gmlparse.c:183
#define yyerror
Definition gmlparse.c:71
static attrs_t * popAlist(void)
Definition gmlparse.c:165
#define LABEL
Definition gmlparse.h:115
#define OUTLINESTYLE
Definition gmlparse.h:121
#define WIDTH
Definition gmlparse.h:123
#define GRAPHICS
Definition gmlparse.h:116
#define POINT
Definition gmlparse.h:126
#define NAME
Definition gmlparse.h:135
#define COLOR
Definition gmlparse.h:130
#define TEXT
Definition gmlparse.h:127
#define TYPE
Definition gmlparse.h:118
#define FONTSIZE
Definition gmlparse.h:128
#define GML_LIST
Definition gmlparse.h:136
#define FILL
Definition gmlparse.h:119
#define ID
Definition gmlparse.h:134
#define OUTLINEWIDTH
Definition gmlparse.h:122
#define SOURCE
Definition gmlparse.h:109
int gmlparse(void)
#define NODE
Definition gmlparse.h:106
#define TARGET
Definition gmlparse.h:110
#define WVAL
Definition gmlparse.h:113
#define EDGE
Definition gmlparse.h:107
#define STYLE
Definition gmlparse.h:124
#define HVAL
Definition gmlparse.h:114
#define YVAL
Definition gmlparse.h:112
#define FONTNAME
Definition gmlparse.h:129
#define LABELGRAPHICS
Definition gmlparse.h:117
#define XVAL
Definition gmlparse.h:111
#define LINE
Definition gmlparse.h:125
#define OUTLINE
Definition gmlparse.h:120
#define GRAPH
Definition gmlparse.h:105
static char * sortToStr(unsigned short sort)
Definition gmlparse.y:714
static void addEdgeGraphics(Agedge_t *ep, attrs_t *alist, agxbuf *xb, agxbuf *unk)
Definition gmlparse.y:568
static void addAttrs(Agobj_t *obj, attrs_t *alist, agxbuf *xb, agxbuf *unk)
Definition gmlparse.y:605
static void deparseAttr(gmlattr *ap, agxbuf *xb)
Definition gmlparse.y:338
alist $2
Definition gmlparse.y:290
static void addEdgeLabelGraphics(Agedge_t *ep, attrs_t *alist, agxbuf *xb, agxbuf *unk)
Definition gmlparse.y:417
glistitem $1
Definition gmlparse.y:245
alistitem NAME REAL
Definition gmlparse.y:295
static void addNodeLabelGraphics(Agnode_t *np, attrs_t *alist, agxbuf *unk)
Definition gmlparse.y:378
edge
Definition gmlparse.y:246
static Agraph_t * mkGraph(gmlgraph *graph, Agraph_t *parent, char *name, agxbuf *xb, agxbuf *unk)
Definition gmlparse.y:629
static void addNodeGraphics(Agnode_t *np, attrs_t *alist, agxbuf *xb, agxbuf *unk)
Definition gmlparse.y:468
static void addEdgePoint(Agedge_t *ep, attrs_t *alist, agxbuf *xb)
Definition gmlparse.y:531
static void addEdgePos(Agedge_t *ep, attrs_t *alist, agxbuf *xb)
Definition gmlparse.y:553
N
Definition gmlparse.y:259
static void free_attr(gmlattr *p)
Definition gmlparse.y:325
E
Definition gmlparse.y:270
NAME STRING
Definition gmlparse.y:296
hdr body DIRECTED INTEGER
Definition gmlparse.y:248
static void deparseList(attrs_t *alist, agxbuf *xb)
Definition gmlparse.y:352
alistitem
Definition gmlparse.y:267
optalist
Definition gmlparse.y:283
NAME attrlist
Definition gmlparse.y:297
Agraph_t * gml_to_gv(char *name, FILE *fp, int cnt, int *errors)
Definition gmlparse.y:683
static int errors
Definition gmlscan.c:847
body
Definition grammar.y:215
node NULL
Definition grammar.y:181
static int cnt(Dict_t *d, Dtlink_t **set)
Definition graph.c:198
int agsafeset(void *obj, char *name, const char *value, const char *def)
set an attribute’s value and default, ensuring it is declared before setting it locally
Definition attr.c:562
Agedge_t * agedge(Agraph_t *g, Agnode_t *t, Agnode_t *h, char *name, int createflag)
Definition edge.c:255
Agdesc_t Agundirected
undirected
Definition graph.c:274
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
Agdesc_t Agdirected
directed
Definition graph.c:272
Agnode_t * agnode(Agraph_t *g, char *name, int createflag)
Definition node.c:143
#define AGTYPE(obj)
returns AGRAPH, AGNODE, or AGEDGE depending on the type of the object
Definition cgraph.h:216
@ AGEDGE
Definition cgraph.h:207
@ AGNODE
Definition cgraph.h:207
Agraph_t * agsubg(Agraph_t *g, char *name, int cflag)
Definition subg.c:55
Agraph_t * graph(char *name)
Definition gv.cpp:34
agxbput(xb, staging)
@ unknown
Definition gvgen.c:34
textitem scanner parser str
Definition htmlparse.y:218
table Syntax error
Definition htmlparse.y:288
$$
Definition htmlparse.y:321
type-generic dynamically expanding list
#define LIST(type)
Definition list.h:55
#define LIST_SIZE(list)
Definition list.h:80
#define LIST_CLEAR(list)
Definition list.h:240
#define LIST_APPEND(list, item)
Definition list.h:120
#define LIST_FREE(list)
Definition list.h:370
#define LIST_POP_BACK(list)
Definition list.h:407
#define LIST_IS_EMPTY(list)
Definition list.h:90
#define LIST_PUSH_BACK(list, item)
Definition list.h:384
#define LIST_GET(list, index)
Definition list.h:155
Agobj_t base
Definition cgraph.h:269
Agobj_t base
Definition cgraph.h:260
a generic header of Agraph_s, Agnode_s and Agedge_s
Definition cgraph.h:210
graph or subgraph
Definition cgraph.h:424
Agobj_t base
Definition cgraph.h:425
Definition types.h:251
void * lp
actually an attrs_t *
Definition gml2gv.h:16
char * value
Definition gml2gv.h:15
unsigned short kind
Definition gml2gv.h:11
unsigned short sort
Definition gml2gv.h:12
union gmlattr::@25 u
char * name
Definition gml2gv.h:13
char * source
Definition gml2gv.h:28
attrs_t attrlist
Definition gml2gv.h:30
char * target
Definition gml2gv.h:29
int directed
Definition gml2gv.h:35
struct gmlgraph * parent
Definition gml2gv.h:34
attrs_t attrlist
Definition gml2gv.h:36
attrs_t attrlist
Definition gml2gv.h:24
char * id
Definition gml2gv.h:23
Definition grammar.c:90