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