aboutsummaryrefslogtreecommitdiff
path: root/json.c
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2020-12-14 22:01:50 -0800
committerBruce Hill <bruce@bruce-hill.com>2020-12-14 22:01:50 -0800
commit2fb68fa97f096e5bd0f3ff81d31c3bc61719ae8a (patch)
tree5fc08368fed465d88b115b7dd75f309cec010806 /json.c
parente638a517bfe60af1975d793bfbfda4d64428d15f (diff)
Moved json code into its own file
Diffstat (limited to 'json.c')
-rw-r--r--json.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/json.c b/json.c
new file mode 100644
index 0000000..d45e79c
--- /dev/null
+++ b/json.c
@@ -0,0 +1,44 @@
+/*
+ * json.c - Code for printing JSON output of matches.
+ */
+#include "types.h"
+
+/*
+ * Print a match as JSON
+ */
+static int _json_match(FILE *f, const char *text, match_t *m, int comma, int verbose)
+{
+ if (!verbose) {
+ if (m->op->op != VM_REF) {
+ for (match_t *child = m->child; child; child = child->nextsibling) {
+ comma |= _json_match(f, text, child, comma, verbose);
+ }
+ return comma;
+ }
+ }
+
+ if (comma) fprintf(f, ",\n");
+ comma = 0;
+ fprintf(f, "{\"rule\":\"");
+ for (const char *c = m->op->start; c < m->op->end; c++) {
+ switch (*c) {
+ case '"': fprintf(f, "\\\""); break;
+ case '\\': fprintf(f, "\\\\"); break;
+ case '\t': fprintf(f, "\\t"); break;
+ case '\n': fprintf(f, "↵"); break;
+ default: fprintf(f, "%c", *c); break;
+ }
+ }
+ fprintf(f, "\",\"start\":%ld,\"end\":%ld,\"children\":[",
+ m->start - text, m->end - text);
+ for (match_t *child = m->child; child; child = child->nextsibling) {
+ comma |= _json_match(f, text, child, comma, verbose);
+ }
+ fprintf(f, "]}");
+ return 1;
+}
+
+void json_match(FILE *f, const char *text, match_t *m, int verbose)
+{
+ _json_match(f, text, m, 0, verbose);
+}