Graphviz 13.0.0~dev.20250402.0402
Loading...
Searching...
No Matches
gv2gml.c
Go to the documentation of this file.
1
6/**********************************************************
7* This software is part of the graphviz package *
8* https://graphviz.org *
9* *
10* Copyright (c) 1994-2004 AT&T Corp. *
11* and is licensed under the *
12* Common Public License, Version 1.0 *
13* by AT&T Corp. *
14* *
15* Information and Software Systems Research *
16* AT&T Research, Florham Park NJ *
17**********************************************************/
18
19#include <stdbool.h>
20#include <stdio.h>
21#include <stdlib.h>
22#include <inttypes.h>
23
24#include <getopt.h>
25
26#include <cgraph/cgraph.h>
27#include <cgraph/ingraphs.h>
28#include <common/types.h>
29#include <common/utils.h>
30#include <util/exit.h>
31#include <util/gv_ctype.h>
32#include <util/streq.h>
33#include <util/strview.h>
34#include <util/tokenize.h>
35#include <util/unreachable.h>
36#include "openFile.h"
37
38static FILE *outFile;
39static char *CmdName;
40static char **Files;
41static uint64_t id;
42static bool yworks;
43
44#define POS_SET (1<<0)
45#define W_SET (1<<1)
46#define H_SET (1<<2)
47#define INVIS (1<<3)
48#define FILL (1<<4)
49#define LINE (1<<5)
50#define DASH (1<<6)
51#define DOT (1<<7)
52#define BOLD (1<<8)
53
54typedef struct {
55 unsigned int flags;
56/* graphics */
57 double x;
58 double y;
59 double w;
60 double h;
61 char* type; /* shape */
62 char* image;
63 char* fill; /* fillcolor */
64 char* outline; /* pencolor */
65 char* width; /* penwidth */
67/* label graphics */
68 char* fontColor;
69 char* fontSize;
70 char* fontName;
72
73typedef struct {
74 unsigned int flags;
75/* graphics */
76 char* width; /* penwidth */
77 char* fill; /* pencolor */
78 char* arrow; /* dir */
79 char* arrowhead; /* arrowhead */
80 char* arrowtail; /* arrowtail */
81 char* pos;
82/* label graphics */
83 char* fontColor;
84 char* fontSize;
85 char* fontName;
87
88typedef struct {
90 uint64_t id;
92
93#define ID(n) (((Local_Agnodeinfo_t*)(n->base.data))->id)
94
95static void indent(int ix) {
96 while (ix--)
97 fprintf (outFile, " ");
98}
99
101static bool isNumber(char* s) {
102 char* ep = s;
103 strtod(s, &ep);
104 if (s != ep) {
105 while (gv_isspace(*ep)) ep++;
106 if (*ep) return false;
107 return true;
108 }
109 return false;
110}
111
113static int
115{
116 int flags = 0;
117 char* sep = " \t,";
118
119 for (tok_t t = tok(s, sep); !tok_end(&t); tok_next(&t)) {
120 strview_t ip = tok_get(&t);
121 if (strview_str_eq(ip, "invis")) flags |= INVIS;
122 else if (strview_str_eq(ip, "filled")) flags |= FILL;
123 else if (strview_str_eq(ip, "dashed")) flags |= DASH;
124 else if (strview_str_eq(ip, "dotted")) flags |= DOT;
125 else if (strview_str_eq(ip, "solid")) flags |= LINE;
126 else if (strview_str_eq(ip, "bold")) flags |= BOLD;
127 }
128
129 return flags;
130}
131
132static void emitInt(char *name, int value, int ix) {
133 indent(ix);
134 fprintf (outFile, "%s %d\n", name, value);
135}
136
137static void emitReal(char *name, double value, int ix) {
138 indent(ix);
139 fprintf (outFile, "%s %g\n", name, value);
140}
141
142static void emitPoint(double x, double y, int ix) {
143 indent(ix);
144 fprintf (outFile, "point [ x %g y %g ]\n", x, y);
145}
146
147static char*
148skipWS (char* s)
149{
150 while (gv_isspace(*s)) s++;
151 return s;
152}
153
154/* Return NULL if unsuccessful
155 */
156static char*
157readPoint (char* s, double* xp, double* yp)
158{
159 char* endp;
160
161 s = skipWS(s);
162 *xp = strtod (s, &endp);
163 if (s == endp) return NULL;
164 endp++; /* skip comma */
165 s = endp;
166 *yp = strtod (s, &endp);
167 if (s == endp) return NULL;
168 else return endp;
169}
170
171static char*
172arrowEnd (char* s0, char* pfx, int* fp, double* xp, double* yp)
173{
174 char* s = skipWS(s0);
175
176 if (strncmp(s,pfx,2)) return s;
177 s += 2; /* skip prefix */
178 s = readPoint (s, xp, yp);
179 if (s == NULL) {
180 fprintf (stderr, "Illegal spline end: %s\n", s0);
181 graphviz_exit(1);
182 }
183 *fp = 1;
184 return s;
185}
186
187static void emitSpline(char *s, int ix) {
188 double sx, sy, ex, ey;
189 int sarrow = 0;
190 int earrow = 0;
191
192 s = arrowEnd (s, "e,", &earrow, &ex, &ey);
193 s = arrowEnd (s, "s,", &sarrow, &sx, &sy);
194 indent(ix);
195 fprintf (outFile, "Line [\n");
196 if (sarrow)
197 emitPoint(sx, sy, ix+1);
198 while ((s = readPoint (s, &sx, &sy)))
199 emitPoint(sx, sy, ix+1);
200 if (earrow)
201 emitPoint(ex, ey, ix+1);
202 indent(ix);
203 fprintf (outFile, "]\n");
204
205}
206
207// `fputs` wrapper to handle the difference in calling convention to what
208// `xml_escape`’s `cb` expects
209static inline int put(void *stream, const char *s) {
210 return fputs(s, stream);
211}
212
213// write a string to the given file, XML-escaping the input
214static inline int xml_puts(FILE *stream, const char *s) {
215 const xml_flags_t flags = {.dash = 1, .nbsp = 1};
216 return xml_escape(s, flags, put, stream);
217}
218
219static void emitAttr(char *name, char *value, int ix) {
220 indent(ix);
221 if (isNumber (value))
222 fprintf (outFile, "%s %s\n", name, value);
223 else {
224 fprintf(outFile, "%s \"", name);
225 xml_puts(outFile, value);
226 fputs("\"\n", outFile);
227 }
228}
229
230/* node attributes:
231 * label
232 * graphics
233 * LabelGraphics
234 */
235static void emitNodeAttrs(Agraph_t *G, Agnode_t *np, int ix) {
236 Agsym_t* s;
237 char* v;
238 node_attrs attrs = {0};
239 int doGraphics = 0;
240 int doLabelGraphics = 0;
241 char* label = 0;
242 int style;
243 double x, y;
244
245 /* First, process the attributes, saving the graphics attributes */
246 for (s = agnxtattr (G, AGNODE, NULL); s; s = agnxtattr (G, AGNODE, s)) {
247 if (streq(s->name, "style")) { /* hasFill outlineStyle invis */
248 if (*(v = agxget (np, s))) {
249 style = parseStyle (v);
250 if (style & INVIS)
251 attrs.flags |= INVIS;
252 if (style & FILL)
253 attrs.flags |= FILL;
254 if (style & LINE)
255 attrs.outlineStyle = "line";
256 if (style & DASH)
257 attrs.outlineStyle = "dashed";
258 if (style & DOT)
259 attrs.outlineStyle = "dotted";
260 doGraphics = 1;
261 }
262 }
263 else if (streq(s->name, "label")) {
264 v = agxget (np, s);
265 if (streq("\\N", v)) {
266 label = agnameof(np);
267 emitAttr(s->name, label, ix);
268 doLabelGraphics = 1;
269 }
270 else if (*v) {
271 label = v;
272 emitAttr(s->name, label, ix);
273 doLabelGraphics = 1;
274 }
275 }
276 else if (streq(s->name, "penwidth")) {
277 if (*(v = agxget (np, s))) {
278 attrs.width = v;
279 doGraphics = 1;
280 }
281 }
282 else if (streq(s->name, "width")) {
283 v = agxget (np, s);
284 if (*v) {
285 attrs.w = 72.0*atof (v);
286 attrs.flags |= W_SET;
287 doGraphics = 1;
288 }
289 }
290 else if (streq(s->name, "height")) {
291 v = agxget (np, s);
292 if (*v) {
293 attrs.h = 72.0*atof (v);
294 attrs.flags |= H_SET;
295 doGraphics = 1;
296 }
297 }
298 else if (streq(s->name, "pos")) {
299 v = agxget (np, s);
300 if (sscanf (v, "%lf,%lf", &x, &y) == 2) {
301 doGraphics = 1;
302 attrs.x = x;
303 attrs.y = y;
304 attrs.flags |= POS_SET;
305 }
306 }
307 else if (streq(s->name, "shape")) { /* type */
308 if (*(v = agxget (np, s))) {
309 attrs.type = v;
310 doGraphics = 1;
311 }
312 }
313 else if (streq(s->name, "color")) {
314 if (*(v = agxget (np, s))) {
315 attrs.fill = v;
316 attrs.outline = v;
317 doGraphics = 1;
318 }
319 }
320 else if (streq(s->name, "fillcolor")) {
321 if (*(v = agxget (np, s))) {
322 attrs.fill = v;
323 doGraphics = 1;
324 }
325 }
326 else if (streq(s->name, "pencolor")) {
327 if (*(v = agxget (np, s))) {
328 attrs.outline = v;
329 doGraphics = 1;
330 }
331 }
332 else if (streq(s->name, "fontname")) { /* fontName */
333 if (*(v = agxget (np, s))) {
334 attrs.fontName = v;
335 doLabelGraphics = 1;
336 }
337 }
338 else if (streq(s->name, "fontsize")) { /* fontSize */
339 if (*(v = agxget (np, s))) {
340 attrs.fontSize = v;
341 doLabelGraphics = 1;
342 }
343 }
344 else if (streq(s->name, "fontcolor")) { /* fontColor */
345 if (*(v = agxget (np, s))) {
346 attrs.fontColor = v;
347 doLabelGraphics = 1;
348 }
349 }
350 else {
351 v = agxget (np, s);
352 emitAttr(s->name, v, ix);
353 }
354 }
355
356 /* Then, print them, if any */
357 if (doGraphics) {
358 fprintf (outFile, " graphics [\n");
359 if (attrs.flags & POS_SET) {
360 emitReal("x", attrs.x, ix+1);
361 emitReal("y", attrs.y, ix+1);
362 }
363 if (attrs.flags & W_SET) {
364 emitReal("w", attrs.w, ix+1);
365 }
366 if (attrs.flags & H_SET) {
367 emitReal("H", attrs.h, ix+1);
368 }
369 if (attrs.flags & INVIS) {
370 emitInt("visible", 0, ix+1);
371 }
372 if (attrs.flags & FILL) {
373 emitInt("hasFill", 1, ix+1);
374 }
375 if (attrs.type) {
376 emitAttr("type", attrs.type, ix+1);
377 }
378 if (attrs.image) {
379 emitAttr("image", attrs.image, ix+1);
380 }
381 if (attrs.fill) {
382 emitAttr("fill", attrs.fill, ix+1);
383 }
384 if (attrs.outline) {
385 emitAttr("outline", attrs.outline, ix+1);
386 }
387 if (attrs.width) {
388 emitAttr("width", attrs.width, ix+1);
389 }
390 if (attrs.outlineStyle) {
391 emitAttr("outlineStyle", attrs.outlineStyle, ix+1);
392 }
393 fprintf (outFile, " ]\n");
394 }
395
396 if (doLabelGraphics) {
397 fprintf (outFile, " LabelGraphics [\n");
398 if (label) emitAttr("text", label, ix+1);
399 if (attrs.fontColor) {
400 emitAttr(yworks ? "color" : "fontColor", attrs.fontColor, ix+1);
401 }
402 if (attrs.fontSize) {
403 emitAttr("fontSize", attrs.fontSize, ix+1);
404 }
405 if (attrs.fontName) {
406 emitAttr("fontName", attrs.fontName, ix+1);
407 }
408 fprintf (outFile, " ]\n");
409 }
410}
411
412/* emitNode:
413 * set node id
414 * label, width height, x, y, type fillcolor
415 */
416static void emitNode(Agraph_t *G, Agnode_t *n) {
417 agbindrec(n, "nodeinfo", sizeof(Local_Agnodeinfo_t), true);
418 fprintf(outFile, " node [\n id %" PRIu64 "\n name \"%s\"\n", id,
419 agnameof(n));
420 ID(n) = id++;
421 emitNodeAttrs(G, n, 2);
422 fprintf (outFile, " ]\n");
423
424}
425
426/* edge attributes:
427 * label
428 * graphics
429 * LabelGraphics
430 */
431static void emitEdgeAttrs(Agraph_t *G, Agedge_t *ep, int ix) {
432 Agsym_t* s;
433 char* v;
434 edge_attrs attrs = {0};
435 int doGraphics = 0;
436 int doLabelGraphics = 0;
437 char* label = 0;
438 int style;
439
440 /* First, process the attributes, saving the graphics attributes */
441 for (s = agnxtattr (G, AGEDGE, NULL); s; s = agnxtattr (G, AGEDGE, s)) {
442 if (streq(s->name, "style")) { /* hasFill outlineStyle invis */
443 if (*(v = agxget (ep, s))) {
444 style = parseStyle (v);
445 if (style & INVIS)
446 attrs.flags |= INVIS;
447 if (style & LINE)
448 attrs.flags |= LINE;
449 if (style & DASH)
450 attrs.flags |= DASH;
451 if (style & DOT)
452 attrs.flags |= DOT;
453 if (style & BOLD)
454 attrs.width = "2";
455 doGraphics = 1;
456 }
457 }
458 else if (streq(s->name, "label")) {
459 if (*(v = agxget (ep, s))) {
460 label = v;
461 emitAttr(s->name, label, ix);
462 doLabelGraphics = 1;
463 }
464 }
465 else if (streq(s->name, "penwidth")) {
466 if (*(v = agxget (ep, s))) {
467 attrs.width = v;
468 doGraphics = 1;
469 }
470 }
471 else if (streq(s->name, "pos")) {
472 if (*(v = agxget (ep, s))) {
473 doGraphics = 1;
474 attrs.pos = v;
475 }
476 }
477 else if (streq(s->name, "dir")) {
478 if (*(v = agxget (ep, s))) {
479 doGraphics = 1;
480 attrs.arrow = v;
481 }
482 }
483 else if (streq(s->name, "color")) {
484 if (*(v = agxget (ep, s))) {
485 attrs.fill = v;
486 doGraphics = 1;
487 }
488 }
489 else if (streq(s->name, "pencolor")) {
490 if (*(v = agxget (ep, s))) {
491 attrs.fill = v;
492 doGraphics = 1;
493 }
494 }
495 else if (streq(s->name, "arrowhead")) {
496 if (*(v = agxget (ep, s))) {
497 attrs.arrowhead = v;
498 doGraphics = 1;
499 }
500 }
501 else if (streq(s->name, "arrowtail")) {
502 if (*(v = agxget (ep, s))) {
503 attrs.arrowtail = v;
504 doGraphics = 1;
505 }
506 }
507 else if (streq(s->name, "fontname")) { /* fontName */
508 if (*(v = agxget (ep, s))) {
509 attrs.fontName = v;
510 doLabelGraphics = 1;
511 }
512 }
513 else if (streq(s->name, "fontsize")) { /* fontSize */
514 if (*(v = agxget (ep, s))) {
515 attrs.fontSize = v;
516 doLabelGraphics = 1;
517 }
518 }
519 else if (streq(s->name, "fontcolor")) { /* fontColor */
520 if (*(v = agxget (ep, s))) {
521 attrs.fontColor = v;
522 doLabelGraphics = 1;
523 }
524 }
525 else {
526 v = agxget (ep, s);
527 emitAttr(s->name, v, ix);
528 }
529 }
530
531 /* Then, print them, if any */
532 if (doGraphics) {
533 fprintf (outFile, " graphics [\n");
534 if (attrs.pos) {
535 emitSpline(attrs.pos, ix+1);
536 }
537 if (attrs.flags & INVIS) {
538 emitInt("visible", 0, ix+1);
539 }
540 if (attrs.fill) {
541 emitAttr("fill", attrs.fill, ix+1);
542 }
543 if (attrs.width) {
544 emitAttr("width", attrs.width, ix+1);
545 }
546 if (attrs.arrowhead) {
547 emitAttr("targetArrow", attrs.arrowhead, ix+1);
548 }
549 if (attrs.arrowtail) {
550 emitAttr("sourceArrow", attrs.arrowtail, ix+1);
551 }
552 if (attrs.flags & DASH) {
553 emitAttr("style", "dashed", ix+1);
554 }
555 else if (attrs.flags & DOT) {
556 emitAttr("style", "dotted", ix+1);
557 }
558 else if (attrs.flags & LINE) {
559 emitAttr("style", "line", ix+1);
560 }
561 if (attrs.arrow) {
562 if (streq(attrs.arrow,"forward"))
563 emitAttr("arrow", "first", ix+1);
564 else if (streq(attrs.arrow,"back"))
565 emitAttr("arrow", "last", ix+1);
566 else if (streq(attrs.arrow,"both"))
567 emitAttr("arrow", "both", ix+1);
568 else if (streq(attrs.arrow,"none"))
569 emitAttr("arrow", "none", ix+1);
570 }
571 fprintf (outFile, " ]\n");
572 }
573
574 if (doLabelGraphics) {
575 fprintf (outFile, " LabelGraphics [\n");
576 if (label) emitAttr("text", label, ix+1);
577 if (attrs.fontColor) {
578 emitAttr(yworks ? "color" : "fontColor", attrs.fontColor, ix+1);
579 }
580 if (attrs.fontSize) {
581 emitAttr("fontSize", attrs.fontSize, ix+1);
582 }
583 if (attrs.fontName) {
584 emitAttr("fontName", attrs.fontName, ix+1);
585 }
586 fprintf (outFile, " ]\n");
587 }
588}
589
590static void emitEdge(Agraph_t *G, Agedge_t *e) {
591 fprintf(outFile, " edge [\n id %" PRIu64 "\n", (uint64_t)AGSEQ(e));
592 fprintf(outFile, " source %" PRIu64 "\n", ID(agtail(e)));
593 fprintf(outFile, " target %" PRIu64 "\n", ID(aghead(e)));
594 emitEdgeAttrs(G, e, 2);
595 fprintf (outFile, " ]\n");
596}
597
598static void emitGraphAttrs(Agraph_t *G) {
599 Agsym_t* s;
600 char* v;
601
602 for (s = agnxtattr (G, AGRAPH, NULL); s; s = agnxtattr (G, AGRAPH, s)) {
603 if (*(v = agxget (G, s))) {
604 emitAttr(s->name, v, 1);
605 }
606 }
607}
608
609static void gv_to_gml(Agraph_t *G) {
610 Agnode_t* n;
611 Agedge_t* e;
612
613 fprintf (outFile, "graph [\n version 2\n");
614 if (agisdirected(G))
615 fprintf (outFile, " directed 1\n");
616 else
617 fprintf (outFile, " directed 0\n");
618
620
621 /* FIX: Not sure how to handle default attributes or subgraphs */
622
623 for (n = agfstnode(G); n; n = agnxtnode (G, n)) {
624 emitNode(G, n);
625 }
626
627 for (n = agfstnode(G); n; n = agnxtnode (G, n)) {
628 for (e = agfstout(G, n); e; e = agnxtout (G, e)) {
629 emitEdge(G, e);
630 }
631 }
632 fprintf (outFile, "]\n");
633}
634
635static char *useString = "Usage: %s [-y] [-?] <files>\n\
636 -o<file> : output to <file> (stdout)\n\
637 -y : output yWorks.com GML variant\n\
638 -? - print usage\n\
639If no files are specified, stdin is used\n";
640
641static void usage(int v)
642{
643 printf(useString, CmdName);
644 graphviz_exit(v);
645}
646
647static char *cmdName(char *cmd)
648{
649 char *sp;
650
651 sp = strrchr(cmd, '/');
652 if (sp)
653 sp++;
654 else
655 sp = cmd;
656 return sp;
657}
658
659static void initargs(int argc, char **argv)
660{
661 int c;
662
663 CmdName = cmdName(argv[0]);
664 opterr = 0;
665 while ((c = getopt(argc, argv, ":o:y")) != -1) {
666 switch (c) {
667 case 'o':
668 if (outFile != NULL)
669 fclose(outFile);
670 outFile = openFile(CmdName, optarg, "w");
671 break;
672 case 'y':
673 yworks = true;
674 break;
675 case ':':
676 fprintf(stderr, "%s: option -%c missing parameter\n", CmdName, optopt);
677 usage(1);
678 break;
679 case '?':
680 if (optopt == '?')
681 usage(0);
682 else {
683 fprintf(stderr, "%s: option -%c unrecognized\n", CmdName,
684 optopt);
685 usage(1);
686 }
687 break;
688 default:
689 UNREACHABLE();
690 }
691 }
692
693 argv += optind;
694 argc -= optind;
695
696 if (argc)
697 Files = argv;
698 if (!outFile)
699 outFile = stdout;
700}
701
702int main(int argc, char **argv)
703{
704 Agraph_t *G;
705 Agraph_t *prev = 0;
706 int rv;
707 ingraph_state ig;
708
709 rv = 0;
710 initargs(argc, argv);
711 newIngraph(&ig, Files);
712
713 while ((G = nextGraph(&ig))) {
714 if (prev) {
715 id = 0;
716 agclose(prev);
717 }
718 prev = G;
719 gv_to_gml(G);
720 fflush(outFile);
721 }
722 graphviz_exit(rv);
723}
abstract graph C library, Cgraph API
static char * cmd
Definition acyclic.c:40
static NORETURN void graphviz_exit(int status)
Definition exit.h:23
static int flags
Definition gc.c:61
#define G
Definition gdefs.h:7
node NULL
Definition grammar.y:163
Agsym_t * agnxtattr(Agraph_t *g, int kind, Agsym_t *attr)
permits traversing the list of attributes of a given type
Definition attr.c:386
char * agxget(void *obj, Agsym_t *sym)
Definition attr.c:482
Agedge_t * agfstout(Agraph_t *g, Agnode_t *n)
Definition edge.c:24
#define agtail(e)
Definition cgraph.h:992
#define aghead(e)
Definition cgraph.h:993
Agedge_t * agnxtout(Agraph_t *g, Agedge_t *e)
Definition edge.c:39
int agisdirected(Agraph_t *g)
Definition graph.c:180
int agclose(Agraph_t *g)
deletes a graph, freeing its associated storage
Definition graph.c:97
Agnode_t * agnxtnode(Agraph_t *g, Agnode_t *n)
Definition node.c:47
Agnode_t * agfstnode(Agraph_t *g)
Definition node.c:40
char * agnameof(void *)
returns a string descriptor for the object.
Definition id.c:143
#define AGSEQ(obj)
Definition cgraph.h:225
@ AGEDGE
Definition cgraph.h:207
@ AGNODE
Definition cgraph.h:207
@ AGRAPH
Definition cgraph.h:207
void * agbindrec(void *obj, const char *name, unsigned int recsize, int move_to_front)
attaches a new record of the given size to the object
Definition rec.c:89
static void emitNode(Agraph_t *G, Agnode_t *n)
Definition gv2gml.c:416
#define BOLD
Definition gv2gml.c:52
#define POS_SET
Definition gv2gml.c:44
static void emitSpline(char *s, int ix)
Definition gv2gml.c:187
static char * readPoint(char *s, double *xp, double *yp)
Definition gv2gml.c:157
static void emitEdgeAttrs(Agraph_t *G, Agedge_t *ep, int ix)
Definition gv2gml.c:431
#define W_SET
Definition gv2gml.c:45
static void emitInt(char *name, int value, int ix)
Definition gv2gml.c:132
static void emitGraphAttrs(Agraph_t *G)
Definition gv2gml.c:598
#define INVIS
Definition gv2gml.c:47
#define ID(n)
Definition gv2gml.c:93
static void emitReal(char *name, double value, int ix)
Definition gv2gml.c:137
static char * arrowEnd(char *s0, char *pfx, int *fp, double *xp, double *yp)
Definition gv2gml.c:172
static FILE * outFile
Definition gv2gml.c:38
static int xml_puts(FILE *stream, const char *s)
Definition gv2gml.c:214
static void initargs(int argc, char **argv)
Definition gv2gml.c:659
#define DASH
Definition gv2gml.c:50
static void emitNodeAttrs(Agraph_t *G, Agnode_t *np, int ix)
Definition gv2gml.c:235
#define FILL
Definition gv2gml.c:48
static int put(void *stream, const char *s)
Definition gv2gml.c:209
static uint64_t id
Definition gv2gml.c:41
static char * skipWS(char *s)
Definition gv2gml.c:148
#define DOT
Definition gv2gml.c:51
static void emitEdge(Agraph_t *G, Agedge_t *e)
Definition gv2gml.c:590
#define H_SET
Definition gv2gml.c:46
static bool yworks
use yWorks.com variant of GML?
Definition gv2gml.c:42
static void emitAttr(char *name, char *value, int ix)
Definition gv2gml.c:219
static void indent(int ix)
Definition gv2gml.c:95
static char * useString
Definition gv2gml.c:635
static void gv_to_gml(Agraph_t *G)
Definition gv2gml.c:609
static char ** Files
Definition gv2gml.c:40
static int parseStyle(char *s)
Simple implementation for parsing style attribute.
Definition gv2gml.c:114
static bool isNumber(char *s)
Return true if input string is number.
Definition gv2gml.c:101
static char * CmdName
Definition gv2gml.c:39
#define LINE
Definition gv2gml.c:49
static char * cmdName(char *cmd)
Definition gv2gml.c:647
static void emitPoint(double x, double y, int ix)
Definition gv2gml.c:142
replacements for ctype.h functions
static bool gv_isspace(int c)
Definition gv_ctype.h:55
static const char * usage
Definition gvpr.c:47
$2 u p prev
Definition htmlparse.y:297
Agraph_t * nextGraph(ingraph_state *sp)
Definition ingraphs.c:61
ingraph_state * newIngraph(ingraph_state *sp, char **files)
Definition ingraphs.c:140
supports user-supplied data
static FILE * openFile(const char *argv0, const char *name, const char *mode)
Definition openFile.h:8
static int label(Agnode_t *n, int nodecnt, int *edgecnt)
Definition sccmap.c:161
static bool streq(const char *a, const char *b)
are a and b equal?
Definition streq.h:11
graph or subgraph
Definition cgraph.h:424
implementation of Agrec_t
Definition cgraph.h:172
string attribute descriptor symbol in Agattr_s.dict
Definition cgraph.h:651
uint64_t id
Definition gv2gml.c:90
char * fill
Definition gv2gml.c:77
char * width
Definition gv2gml.c:76
unsigned int flags
Definition gv2gml.c:74
char * fontName
Definition gv2gml.c:85
char * fontColor
Definition gv2gml.c:83
char * arrowhead
Definition gv2gml.c:79
char * arrow
Definition gv2gml.c:78
char * fontSize
Definition gv2gml.c:84
char * pos
Definition gv2gml.c:81
char * arrowtail
Definition gv2gml.c:80
char * outline
Definition gv2gml.c:64
double x
Definition gv2gml.c:57
double w
Definition gv2gml.c:59
double y
Definition gv2gml.c:58
char * type
Definition gv2gml.c:61
char * fontColor
Definition gv2gml.c:68
unsigned int flags
Definition gv2gml.c:55
double h
Definition gv2gml.c:60
char * fill
Definition gv2gml.c:63
char * fontSize
Definition gv2gml.c:69
char * outlineStyle
Definition gv2gml.c:66
char * fontName
Definition gv2gml.c:70
char * image
Definition gv2gml.c:62
char * width
Definition gv2gml.c:65
a non-owning string reference
Definition strview.h:20
state for an in-progress string tokenization
Definition tokenize.h:36
unsigned dash
Definition utils.h:42
Non-owning string references.
static bool strview_str_eq(strview_t a, const char *b)
compare a string reference to a string for equality
Definition strview.h:98
int main()
String tokenization.
static strview_t tok_get(const tok_t *t)
get the current token
Definition tokenize.h:76
static tok_t tok(const char *input, const char *separators)
begin tokenization of a new string
Definition tokenize.h:43
static bool tok_end(const tok_t *t)
is this tokenizer exhausted?
Definition tokenize.h:68
static void tok_next(tok_t *t)
advance to the next token in the string being scanned
Definition tokenize.h:85
graphs, nodes and edges info: Agraphinfo_t, Agnodeinfo_t and Agedgeinfo_t
Definition grammar.c:93
char * name
Definition grammar.c:98
#define UNREACHABLE()
Definition unreachable.h:30
int xml_escape(const char *s, xml_flags_t flags, int(*cb)(void *state, const char *s), void *state)
Definition xml.c:179