From 5db008dbd2084d90631b567ed5320566aa76b41c Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Sun, 23 Oct 2022 00:15:49 -0400 Subject: Better JSON printing and fixed issue with numbered captures --- json.c | 49 ++++++++++++++++++++++++++++++++++++------------- match.c | 21 ++++++++++++++++----- match.h | 2 +- 3 files changed, 53 insertions(+), 19 deletions(-) diff --git a/json.c b/json.c index 297aa30..e3731d5 100644 --- a/json.c +++ b/json.c @@ -16,24 +16,47 @@ static int _json_match(const char *text, match_t *m, int comma, bool verbose); // static int _json_match(const char *text, match_t *m, int comma, bool verbose) { - if (comma) printf(",\n"); - comma = 0; - printf("{\"rule\":\""); - for (const char *c = m->pat->start; c < m->pat->end; c++) { - switch (*c) { - case '"': printf("\\\""); break; - case '\\': printf("\\\\"); break; - case '\t': printf("\\t"); break; - case '\n': printf("↵"); break; - default: printf("%c", *c); break; + if (!verbose && m->pat->type != BP_TAGGED) { + if (m->children) { + for (int i = 0; m->children && m->children[i]; i++) + comma |= _json_match(text, m->children[i], comma, verbose); } + return comma; } - printf("\",\"range\":[%ld,%ld]", m->start - text, m->end - text); + if (comma) printf(",\n"); + comma = 0; + printf("{"); if (m->pat->type == BP_TAGGED) - printf(",\"tag\":\"%.*s\"", (int)m->pat->args.capture.namelen, m->pat->args.capture.name); + printf("\"tag\":\"%.*s\"", (int)m->pat->args.capture.namelen, m->pat->args.capture.name); + if (verbose) { + printf(",\"rule\":\""); + for (const char *c = m->pat->start; c < m->pat->end; c++) { + switch (*c) { + case '"': printf("\\\""); break; + case '\\': printf("\\\\"); break; + case '\t': printf("\\t"); break; + case '\n': printf("↵"); break; + default: printf("%c", *c); break; + } + } + printf("\","); + printf("\"range\":[%ld,%ld]", m->start - text, m->end - text); + } else { + printf(",\"text\":\""); + for (const char *c = m->start; c < m->end; c++) { + switch (*c) { + case '"': printf("\\\""); break; + case '\\': printf("\\\\"); break; + case '\t': printf("\\t"); break; + case '\n': printf("↵"); break; + default: printf("%c", *c); break; + } + } + printf("\""); + } - if (m->children && (verbose || m->pat->type != BP_REF)) { + if (m->children) { printf(",\"children\":["); for (int i = 0; m->children && m->children[i]; i++) comma |= _json_match(text, m->children[i], comma, verbose); diff --git a/match.c b/match.c index cb7918c..4eca7cb 100644 --- a/match.c +++ b/match.c @@ -886,10 +886,13 @@ bool next_match_safe(match_t **m, const char *start, const char *end, pat_t *pat __attribute__((nonnull)) static match_t *_get_numbered_capture(match_t *m, int *n) { - if (*n == 0) return m; - if (m->pat->type == BP_CAPTURE && m->pat->args.capture.namelen == 0) { + if (m->pat->type == BP_CAPTURE && m->pat->args.capture.namelen > 0) + return NULL; + + if ((m->pat->type == BP_CAPTURE && m->pat->args.capture.namelen == 0) || m->pat->type == BP_TAGGED) { if (*n == 1) return m; - --(*n); + else return NULL; + // --(*n); } if (m->children) { for (int i = 0; m->children[i]; i++) { @@ -905,14 +908,22 @@ static match_t *_get_numbered_capture(match_t *m, int *n) // match_t *get_numbered_capture(match_t *m, int n) { - return _get_numbered_capture(m, &n); + if (n <= 0) return m; + if (m->children) { + for (int i = 0; m->children[i]; i++) { + match_t *cap = _get_numbered_capture(m->children[i], &n); + if (cap) return cap; + } + } + return NULL; } // // Get a capture with a specific name. // -match_t *get_named_capture(match_t *m, const char *name, size_t namelen) +match_t *get_named_capture(match_t *m, const char *name, ssize_t _namelen) { + size_t namelen = _namelen < 0 ? strlen(name) : (size_t)_namelen; if (m->pat->type == BP_CAPTURE && m->pat->args.capture.name && m->pat->args.capture.namelen == namelen && strncmp(m->pat->args.capture.name, name, m->pat->args.capture.namelen) == 0) diff --git a/match.h b/match.h index 64ae84c..cf4f977 100644 --- a/match.h +++ b/match.h @@ -37,7 +37,7 @@ bool next_match_safe(match_t **m, const char *start, const char *end, pat_t *pat __attribute__((nonnull)) match_t *get_numbered_capture(match_t *m, int n); __attribute__((nonnull, pure)) -match_t *get_named_capture(match_t *m, const char *name, size_t namelen); +match_t *get_named_capture(match_t *m, const char *name, ssize_t namelen); #endif // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 -- cgit v1.2.3