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