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
|
// utility for translating xdot to JSON via the xdot API
#include <errno.h>
#include <graphviz/xdot.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv) {
if (argc > 3 || (argc > 1 && strcmp(argv[1], "--help") == 0)) {
fprintf(stderr, "usage: %s [input_file [output_file]]\n", argv[0]);
return EXIT_FAILURE;
}
// setup input source
FILE *input = stdin;
if (argc > 1) {
input = fopen(argv[1], "r");
if (input == NULL) {
fprintf(stderr, "failed to open %s: %s", argv[1], strerror(errno));
return EXIT_FAILURE;
}
}
// there is no API for parsing from a file handle, so read the entire file
// into a string buffer
char *in = NULL;
size_t off = 0;
size_t sz = 0;
do {
char buf[BUFSIZ];
size_t r = fread(buf, 1, sizeof(buf), input);
if (r == 0) {
if (ferror(input)) {
fprintf(stderr, "failed while reading %s\n", argv[1]);
free(in);
fclose(input);
return EXIT_FAILURE;
}
} else {
// do we need to expand our buffer?
if (sz < r || sz - r < off) {
size_t s = sz == 0 ? BUFSIZ : 2 * sz;
char *i = realloc(in, s);
if (i == NULL) {
fprintf(stderr, "out of memory\n");
free(in);
fclose(input);
return EXIT_FAILURE;
}
in = i;
sz = s;
}
memcpy(in + off, buf, r);
off += r;
}
} while (!feof(input));
// we no longer need the input file
fclose(input);
// NUL-terminate the read input
if (off == sz) {
char *i = realloc(in, sz + 1);
if (i == NULL) {
fprintf(stderr, "out of memory\n");
free(in);
return EXIT_FAILURE;
}
in = i;
++sz;
}
in[off] = '\0';
// parse input into an xdot object
xdot *x = parseXDot(in);
free(in);
if (x == NULL) {
fprintf(stderr, "failed to parse input into xdot\n");
return EXIT_FAILURE;
}
// setup output sink
FILE *output = stdout;
if (argc > 2) {
output = fopen(argv[2], "w");
if (output == NULL) {
fprintf(stderr, "failed to open %s: %s", argv[2], strerror(errno));
freeXDot(x);
return EXIT_FAILURE;
}
}
// turn that into JSON
jsonXDot(output, x);
// clean up
freeXDot(x);
fclose(output);
return EXIT_SUCCESS;
}
|