]> granicus.if.org Git - graphviz/commitdiff
add a test program for proving jsonXDot
authorMatthew Fernandez <matthew.fernandez@gmail.com>
Sat, 27 Feb 2021 02:52:10 +0000 (18:52 -0800)
committerMatthew Fernandez <matthew.fernandez@gmail.com>
Sat, 6 Mar 2021 01:30:19 +0000 (17:30 -0800)
Related to #1958.

rtest/xdot2json.c [new file with mode: 0644]

diff --git a/rtest/xdot2json.c b/rtest/xdot2json.c
new file mode 100644 (file)
index 0000000..e6f7e56
--- /dev/null
@@ -0,0 +1,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;
+}