-
Notifications
You must be signed in to change notification settings - Fork 194
/
Copy pathjgf2dot.c
144 lines (132 loc) · 3.68 KB
/
jgf2dot.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/* Copyright (c) 2020, 2021 International Business Machines Corporation
Prepared by: Geert Janssen <geert@us.ibm.com>
Convert JSON-Graph to GraphViz Dot.
Simple-minded approach: using a third-party JSON parser (JSMN) that
produces an array of tokens from an input character array.
(https://github.com/zserge/jsmn)
The expected schema is hard-coded into the program logic.
First constructs a graph from the input and afterwards traverses
the graph to produce the dot formatted output.
The input is assumed to be valid JSON and moreover must comply with the
IBM AI4Code JSON-Graph schema. Even in its strict mode, the JSMN parser
seems to be lenient and/or not follow the JSON standard.
For instance, the primitives false, true and null are only checked
for their first character.
All checks immediately cause a program exit upon error.
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define JSMN_HEADER
#include "jgflib.h"
/* Output graph in GraphViz dot format. */
static void graph_show_list_dot(Graph g, FILE *fp)
{
fprintf(fp, "%sgraph ", g->directed ? "di" : "");
if (g->label)
show(fp, g->label, 1);
else
fputs("\"jgf2dot\"", fp);
fputs(" {\n", fp);
/* graph atributes: */
int attrs = g->version || g->root || g->type || g->label || g->attrs;
if (attrs) {
int need_comma = 0;
fputs(" graph [", fp);
/* Predefined attributes: */
if (g->version) {
fputs("version=", fp);
show(fp, g->version, 1);
need_comma = 1;
}
if (g->root) {
if (need_comma) fputc(',', fp);
fputs("root=", fp);
show(fp, g->root, 1);
need_comma = 1;
}
if (g->type) {
if (need_comma) fputc(',', fp);
fputs("type=", fp);
show(fp, g->type, 1);
need_comma = 1;
}
if (g->label) {
if (need_comma) fputc(',', fp);
fputs("label=", fp);
show(fp, g->label, 1);
need_comma = 1;
}
/* Any other attributes: */
show_attrs(fp, g->attrs, need_comma);
fputs("];\n", fp);
}
Node n;
for (n = g->nodes; n; n = n->next) {
fputs(" ", fp);
show(fp, n->id, 0);
int attrs = n->label || n->attrs;
if (attrs) {
int need_comma = 0;
fputs(" [", fp);
if (n->label) {
fputs("label=", fp);
show(fp, n->label, 1);
need_comma = 1;
}
/* Any other attributes: */
show_attrs(fp, n->attrs, need_comma);
fputc(']', fp);
}
fputs(";\n", fp);
}
Edge e;
for (e = g->edges; e; e = e->next) {
fputs(" ", fp);
show(fp, e->between[0], 0);
fprintf(fp, " -%c ", g->directed ? '>' : '-');
show(fp, e->between[1], 0);
/* edge atributes: */
int attrs = e->label || e->attrs;
if (attrs) {
int need_comma = 0;
fputs(" [", fp);
if (e->label) {
fputs("label=", fp);
show(fp, e->label, 1);
need_comma = 1;
}
/* Any other attributes: */
show_attrs(fp, e->attrs, need_comma);
fputc(']', fp);
}
fputs(";\n", fp);
}
fputs("}\n", fp);
}
int main(int argc, char *argv[])
{
/* Read from a file argument or stdin: */
if (argc > 1 && argv[1]) {
if (!strcmp(argv[1], "-d")) {
debug = 1;
/*shift*/
argc--; argv[1] = argv[2];
}
}
if (argc > 1 && argv[1]) {
if (!freopen (argv[1], "rb", stdin)) {
fprintf (stderr, "(E): Cannot read file %s.\n", argv[1]);
exit(4);
}
if (debug) fprintf(stderr, "(D): Processing file %s.\n", argv[1]);
}
if (debug)
fprintf(stderr, "(D): Converting JSON to GraphViz Dot...\n");
Graph graph = jgf_parse();
graph_show_list_dot(graph, stdout);
/*graph_free(graph); */
return 0;
}