diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2021-09-19 17:48:00 -0700 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2021-09-19 17:48:00 -0700 |
| commit | ae7f21b53149b52512dc4cb84aa20847c78526eb (patch) | |
| tree | 15fc805fb4ebd7c411cd1466c58b411d31177aac /print.c | |
| parent | 5fa09eb636892a36c4396308d4925077cf94ee3a (diff) | |
Moved capture retrieval logic into print.c
Diffstat (limited to 'print.c')
| -rw-r--r-- | print.c | 59 |
1 files changed, 59 insertions, 0 deletions
@@ -2,6 +2,7 @@ // print.c - Code for printing and visualizing matches. // +#include <ctype.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> @@ -114,6 +115,64 @@ static const char *context_after(printer_t *pr, const char *pos) } // +// Get a specific numbered pattern capture. +// +__attribute__((nonnull)) +static match_t *get_capture_by_num(match_t *m, int *n) +{ + if (*n == 0) return m; + if (m->pat->type == BP_CAPTURE && *n == 1) return m; + if (m->pat->type == BP_CAPTURE) --(*n); + if (m->children) { + for (int i = 0; m->children[i]; i++) { + match_t *cap = get_capture_by_num(m->children[i], n); + if (cap) return cap; + } + } + return NULL; +} + +// +// Get a capture with a specific name. +// +__attribute__((nonnull, pure)) +static match_t *get_capture_by_name(match_t *m, const char *name) +{ + if (m->pat->type == BP_CAPTURE && m->pat->args.capture.name + && strncmp(m->pat->args.capture.name, name, m->pat->args.capture.namelen) == 0) + return m; + if (m->children) { + for (int i = 0; m->children[i]; i++) { + match_t *cap = get_capture_by_name(m->children[i], name); + if (cap) return cap; + } + } + return NULL; +} + +// +// Get a capture by identifier (name or number). +// Update *id to point to after the identifier (if found). +// +__attribute__((nonnull)) +static match_t *get_capture(match_t *m, const char **id) +{ + if (isdigit(**id)) { + int n = (int)strtol(*id, (char**)id, 10); + return get_capture_by_num(m, &n); + } else { + const char *end = after_name(*id); + if (end == *id) return NULL; + char *name = strndup(*id, (size_t)(end-*id)); + match_t *cap = get_capture_by_name(m, name); + delete(&name); + *id = end; + if (**id == ';') ++(*id); + return cap; + } +} + +// // Print the text of a match (no context). // static void _print_match(FILE *out, printer_t *pr, match_t *m) |
