diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2021-01-12 22:22:38 -0800 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2021-01-12 22:22:38 -0800 |
| commit | 2d109f974b6a03a79db3dd8a5ffe5c2aff76659e (patch) | |
| tree | 082415222af72e0ac17eac9260a5e5a1ce59221a | |
| parent | 5811ff4554da3d980ff32a83efa35ea1a4512484 (diff) | |
Some general cleanup, adding comments, adding more __attribute__s where
applicable
| -rw-r--r-- | bp.c | 34 | ||||
| -rw-r--r-- | compiler.c | 13 | ||||
| -rw-r--r-- | file_loader.c | 1 | ||||
| -rw-r--r-- | file_loader.h | 3 | ||||
| -rw-r--r-- | grammar.c | 1 | ||||
| -rw-r--r-- | grammar.h | 2 | ||||
| -rw-r--r-- | json.c | 1 | ||||
| -rw-r--r-- | printing.c | 31 | ||||
| -rw-r--r-- | printing.h | 2 | ||||
| -rw-r--r-- | vm.c | 26 | ||||
| -rw-r--r-- | vm.h | 4 |
11 files changed, 76 insertions, 42 deletions
@@ -41,6 +41,11 @@ static const char *usage = ( static print_options_t print_options = 0; +// +// Return a pointer to the value part of a flag, if present, otherwise NULL. +// This works for --foo=value or --foo value +// +__attribute__((nonnull)) static char *getflag(const char *flag, char *argv[], int *i) { size_t n = strlen(flag); @@ -57,22 +62,11 @@ static char *getflag(const char *flag, char *argv[], int *i) return NULL; } -static int print_errors(file_t *f, match_t *m) -{ - int ret = 0; - if (m->op->type == VM_CAPTURE && m->op->args.capture.name && streq(m->op->args.capture.name, "!")) { - printf("\033[31;1m"); - print_match(stdout, f, m, print_options); - printf("\033[0m\n"); - fprint_line(stdout, f, m->start, m->end, " "); - return 1; - } - if (m->child) ret += print_errors(f, m->child); - if (m->nextsibling) ret += print_errors(f, m->nextsibling); - return ret; -} - -static int run_match(def_t *defs, const char *filename, vm_op_t *pattern, unsigned int flags) +// +// For a given filename, open the file and attempt to match the given pattern +// against it, printing any results according to the flags. +// +static int process_file(def_t *defs, const char *filename, vm_op_t *pattern, unsigned int flags) { static int printed_matches = 0; int success = 0; @@ -81,7 +75,7 @@ static int run_match(def_t *defs, const char *filename, vm_op_t *pattern, unsign if (flags & BP_INPLACE) // Need to do this before matching intern_file(f); match_t *m = match(defs, f, f->contents, pattern, flags); - if (m && print_errors(f, m) > 0) + if (m && print_errors(f, m, print_options) > 0) _exit(1); if (m != NULL && m->end > m->start + 1) { success = 1; @@ -271,7 +265,7 @@ int main(int argc, char *argv[]) if (i < argc) { // Files pass in as command line args: for (int nfiles = 0; i < argc; nfiles++, i++) { - found += run_match(defs, argv[i], pattern, flags); + found += process_file(defs, argv[i], pattern, flags); } } else if (isatty(STDIN_FILENO)) { // No files, no piped in input, so use * **/*: @@ -279,12 +273,12 @@ int main(int argc, char *argv[]) glob("*", 0, NULL, &globbuf); glob("**/*", GLOB_APPEND, NULL, &globbuf); for (size_t i = 0; i < globbuf.gl_pathc; i++) { - found += run_match(defs, globbuf.gl_pathv[i], pattern, flags); + found += process_file(defs, globbuf.gl_pathv[i], pattern, flags); } globfree(&globbuf); } else { // Piped in input: - found += run_match(defs, NULL, pattern, flags); + found += process_file(defs, NULL, pattern, flags); } if (flags & BP_JSON) printf("]\n"); @@ -12,10 +12,13 @@ #define file_err(f, ...) do { fprint_line(stderr, f, __VA_ARGS__); _exit(1); } while(0) -__attribute__((nonnull)) static vm_op_t *expand_chain(file_t *f, vm_op_t *first); -__attribute__((nonnull)) static vm_op_t *expand_choices(file_t *f, vm_op_t *first); +__attribute__((nonnull)) +static vm_op_t *expand_chain(file_t *f, vm_op_t *first); +__attribute__((nonnull)) +static vm_op_t *expand_choices(file_t *f, vm_op_t *first); static vm_op_t *chain_together(vm_op_t *first, vm_op_t *second); -__attribute__((nonnull(1,4))) static void set_range(vm_op_t *op, ssize_t min, ssize_t max, vm_op_t *pat, vm_op_t *sep); +__attribute__((nonnull(1,4))) +static void set_range(vm_op_t *op, ssize_t min, ssize_t max, vm_op_t *pat, vm_op_t *sep); // // Helper function to initialize a range object. @@ -113,6 +116,10 @@ static vm_op_t *expand_choices(file_t *f, vm_op_t *first) return choice; } +// +// Given two patterns, return a new opcode for the first pattern followed by +// the second. If either pattern is NULL, return the other. +// static vm_op_t *chain_together(vm_op_t *first, vm_op_t *second) { if (first == NULL) return second; diff --git a/file_loader.c b/file_loader.c index 1452907..a7ce56d 100644 --- a/file_loader.c +++ b/file_loader.c @@ -19,6 +19,7 @@ // In the file object, populate the `lines` array with pointers to the // beginning of each line. // +__attribute__((nonnull)) static void populate_lines(file_t *f) { // Calculate line numbers: diff --git a/file_loader.h b/file_loader.h index b4e7938..3b0f15b 100644 --- a/file_loader.h +++ b/file_loader.h @@ -14,6 +14,7 @@ typedef struct { } file_t; file_t *load_file(const char *filename); +__attribute__((nonnull(2), returns_nonnull)) file_t *spoof_file(const char *filename, char *text); __attribute__((nonnull)) void intern_file(file_t *f); @@ -25,7 +26,7 @@ __attribute__((pure, nonnull)) size_t get_char_number(file_t *f, const char *p); __attribute__((pure, nonnull)) const char *get_line(file_t *f, size_t line_number); -__attribute__((format (printf, 5, 6))) +__attribute__((nonnull(1,2,3,4), format(printf, 5, 6))) void fprint_line(FILE *dest, file_t *f, const char *start, const char *end, const char *fmt, ...); #endif @@ -67,6 +67,7 @@ vm_op_t *lookup(def_t *defs, const char *name) // // Push a backreference onto the backreference stack // +__attribute__((nonnull)) static def_t *with_backref(def_t *defs, file_t *f, const char *name, match_t *m) { vm_op_t *op = new(vm_op_t); @@ -7,7 +7,7 @@ #include "file_loader.h" #include "types.h" -__attribute__((nonnull(2,3,4))) +__attribute__((nonnull(2,3,4), returns_nonnull)) def_t *with_def(def_t *defs, file_t *f, const char *name, vm_op_t *op); __attribute__((nonnull(2,3))) def_t *with_backrefs(def_t *defs, file_t *f, match_t *m); @@ -11,6 +11,7 @@ // `comma` is used to track whether a comma will need to be printed before the // next object or not. // +__attribute__((nonnull)) static int _json_match(const char *text, match_t *m, int comma, int verbose) { if (!verbose) { @@ -25,11 +25,12 @@ typedef struct { // Return the height of a match object (i.e. the number of descendents of the // structure). // -static int match_height(match_t *m) +__attribute__((nonnull, pure)) +static int height_of_match(match_t *m) { int height = 0; for (match_t *c = m->child; c; c = c->nextsibling) { - int childheight = match_height(c); + int childheight = height_of_match(c); if (childheight > height) height = childheight; } return 1 + height; @@ -38,10 +39,9 @@ static int match_height(match_t *m) // // Print a visual explanation for the as-yet-unprinted matches provided. // +__attribute__((nonnull)) static void _visualize_matches(match_node_t *firstmatch, int depth, const char *text, size_t textlen) { - if (!firstmatch) return; - const char *V = "│"; // Vertical bar const char *H = "─"; // Horizontal bar const char *color = (depth % 2 == 0) ? "34" : "33"; @@ -54,7 +54,7 @@ static void _visualize_matches(match_node_t *firstmatch, int depth, const char * // while also printing earlier matches first when it doesn't affect overall // output height. for (match_node_t *p = firstmatch; p; p = p->next) - if (match_height(p->m) > match_height(viz)) + if (height_of_match(p->m) > height_of_match(viz)) viz = p->m; const char *viz_type = viz->op->start; size_t viz_typelen = (size_t)(viz->op->end - viz->op->start); @@ -164,6 +164,7 @@ static void _visualize_matches(match_node_t *firstmatch, int depth, const char * // Recursively look for references to a rule called "pattern" and print an // explanation for each one. // +__attribute__((nonnull)) static void _visualize_patterns(match_t *m) { if (m->op->type == VM_REF && streq(m->op->args.s, "pattern")) { @@ -190,6 +191,7 @@ void visualize_match(match_t *m) // // Print a line number. // +__attribute__((nonnull)) static void print_line_number(FILE *out, print_state_t *state, print_options_t options) { state->printed_line = state->line; @@ -203,6 +205,7 @@ static void print_line_number(FILE *out, print_state_t *state, print_options_t o // // Helper function for print_match(), using a struct to keep track of some state. // +__attribute__((nonnull)) static void _print_match(FILE *out, file_t *f, match_t *m, print_state_t *state, print_options_t options) { static const char *hl = "\033[0;31;1m"; @@ -300,4 +303,22 @@ void print_match(FILE *out, file_t *f, match_t *m, print_options_t options) _print_match(out, f, m, &state, options); } +// +// Print any errors that are present in the given match object. +// +int print_errors(file_t *f, match_t *m, print_options_t options) +{ + int ret = 0; + if (m->op->type == VM_CAPTURE && m->op->args.capture.name && streq(m->op->args.capture.name, "!")) { + printf("\033[31;1m"); + print_match(stdout, f, m, options); + printf("\033[0m\n"); + fprint_line(stdout, f, m->start, m->end, " "); + return 1; + } + if (m->child) ret += print_errors(f, m->child, options); + if (m->nextsibling) ret += print_errors(f, m->nextsibling, options); + return ret; +} + // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1 @@ -15,6 +15,8 @@ __attribute__((nonnull)) void visualize_match(match_t *m); __attribute__((nonnull)) void print_match(FILE *out, file_t *f, match_t *m, print_options_t options); +__attribute__((nonnull)) +int print_errors(file_t *f, match_t *m, print_options_t options); #endif // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1 @@ -16,6 +16,7 @@ // // UTF8-compliant char iteration // +__attribute__((nonnull, pure)) static inline const char *next_char(file_t *f, const char *str) { char c = *str; @@ -55,6 +56,7 @@ typedef struct recursive_ref_s { // Attempt to match text against a previously captured value. // Return the character position after the backref has matched, or NULL if no match has occurred. // +__attribute__((nonnull)) static const char *match_backref(const char *str, vm_op_t *op, match_t *cap, unsigned int flags) { check(op->type == VM_BACKREF, "Attempt to match backref against something that's not a backref"); @@ -100,7 +102,7 @@ static const char *match_backref(const char *str, vm_op_t *op, match_t *cap, uns if (cap->end > prev) { size_t len = (size_t)(cap->end - prev); if ((flags & BP_IGNORECASE) ? memicmp(str, prev, len) != 0 - : memcmp(str, prev, len) != 0) { + : memcmp(str, prev, len) != 0) { return NULL; } str += len; @@ -115,6 +117,7 @@ static const char *match_backref(const char *str, vm_op_t *op, match_t *cap, uns // a match struct, or NULL if no match is found. // The returned value should be free()'d to avoid memory leaking. // +__attribute__((hot, nonnull(2,3,4))) static match_t *_match(def_t *defs, file_t *f, const char *str, vm_op_t *op, unsigned int flags, recursive_ref_t *rec) { switch (op->type) { @@ -474,6 +477,7 @@ static match_t *_match(def_t *defs, file_t *f, const char *str, vm_op_t *op, uns // // 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; @@ -489,6 +493,7 @@ static match_t *get_capture_by_num(match_t *m, int *n) // // 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->op->type == VM_CAPTURE && m->op->args.capture.name @@ -502,21 +507,22 @@ static match_t *get_capture_by_name(match_t *m, const char *name) } // -// Get a capture by name. +// Get a capture by identifier (name or number). +// Update *id to point to after the identifier (if found). // -match_t *get_capture(match_t *m, const char **r) +match_t *get_capture(match_t *m, const char **id) { - if (isdigit(**r)) { - int n = (int)strtol(*r, (char**)r, 10); + if (isdigit(**id)) { + int n = (int)strtol(*id, (char**)id, 10); return get_capture_by_num(m->child, &n); } else { - const char *end = after_name(*r); - if (end == *r) return NULL; - char *name = strndup(*r, (size_t)(end-*r)); + 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); xfree(&name); - *r = end; - if (**r == ';') ++(*r); + *id = end; + if (**id == ';') ++(*id); return cap; } return NULL; @@ -8,12 +8,12 @@ #include "types.h" -__attribute__((hot, nonnull(2,3,4))) +__attribute__((nonnull(2,3,4))) match_t *match(def_t *defs, file_t *f, const char *str, vm_op_t *op, unsigned int flags); __attribute__((nonnull)) void destroy_match(match_t **m); __attribute__((nonnull)) -match_t *get_capture(match_t *m, const char **r); +match_t *get_capture(match_t *m, const char **id); #endif // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1 |
