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