From 484e1e33da7477b7278c9a3e9da878f0375dd75b Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Thu, 17 Dec 2020 16:27:23 -0800 Subject: Memory allocation failure checks, and a simpler new() function --- compiler.c | 14 +++++++------- file_loader.c | 13 +++++++------ grammar.c | 10 +++++----- types.h | 1 + utils.c | 8 ++++++++ utils.h | 4 ++++ viz.c | 5 +++-- vm.c | 32 ++++++++++++++++---------------- 8 files changed, 51 insertions(+), 36 deletions(-) diff --git a/compiler.c b/compiler.c index 4efecc6..34519b5 100644 --- a/compiler.c +++ b/compiler.c @@ -69,7 +69,7 @@ static vm_op_t *expand_choices(file_t *f, vm_op_t *first) if (!second) file_err(f, str, str, "There should be a pattern here after a '/'"); second = expand_choices(f, second); - vm_op_t *choice = calloc(sizeof(vm_op_t), 1); + vm_op_t *choice = new(vm_op_t); choice->op = VM_OTHERWISE; choice->start = first->start; if (first->len == second->len) @@ -85,7 +85,7 @@ static vm_op_t *chain_together(vm_op_t *first, vm_op_t *second) { if (first == NULL) return second; if (second == NULL) return first; - vm_op_t *chain = calloc(sizeof(vm_op_t), 1); + vm_op_t *chain = new(vm_op_t); chain->op = VM_CHAIN; chain->start = first->start; if (first->len >= 0 && second->len >= 0) @@ -104,7 +104,7 @@ vm_op_t *bpeg_simplepattern(file_t *f, const char *str) { str = after_spaces(str); if (!*str) return NULL; - vm_op_t *op = calloc(sizeof(vm_op_t), 1); + vm_op_t *op = new(vm_op_t); op->start = str; op->len = -1; char c = *str; @@ -464,7 +464,7 @@ vm_op_t *bpeg_simplepattern(file_t *f, const char *str) "These two patterns cannot possibly give the same result (different lengths: %ld != %ld)", first->len, second->len); } - op = calloc(sizeof(vm_op_t), 1); + op = new(vm_op_t); op->op = equal ? VM_EQUAL : VM_NOT_EQUAL; op->start = str; op->end = second->end; @@ -485,7 +485,7 @@ vm_op_t *bpeg_stringpattern(file_t *f, const char *str) { vm_op_t *ret = NULL; while (*str) { - vm_op_t *strop = calloc(sizeof(vm_op_t), 1); + vm_op_t *strop = new(vm_op_t); strop->start = str; strop->len = 0; strop->op = VM_STRING; @@ -497,7 +497,7 @@ vm_op_t *bpeg_stringpattern(file_t *f, const char *str) file_err(f, str, str, "There should be an escape sequence or pattern here after this backslash."); if (matchchar(&str, 'N')) { // \N (nodent) - interp = calloc(sizeof(vm_op_t), 1); + interp = new(vm_op_t); interp->op = VM_NODENT; break; } @@ -548,7 +548,7 @@ vm_op_t *bpeg_stringpattern(file_t *f, const char *str) */ vm_op_t *bpeg_replacement(file_t *f, vm_op_t *pat, const char *replacement) { - vm_op_t *op = calloc(sizeof(vm_op_t), 1); + vm_op_t *op = new(vm_op_t); op->op = VM_REPLACE; op->start = pat->start; op->len = pat->len; diff --git a/file_loader.c b/file_loader.c index 20ed253..9262d04 100644 --- a/file_loader.c +++ b/file_loader.c @@ -13,18 +13,19 @@ #include #include "file_loader.h" +#include "utils.h" static void populate_lines(file_t *f) { // Calculate line numbers: size_t linecap = 10; - f->lines = calloc(sizeof(const char*), linecap); + f->lines = xcalloc(sizeof(const char*), linecap); f->nlines = 0; char *p = f->contents; for (size_t n = 0; p && p < f->end; ++n) { ++f->nlines; if (n >= linecap) - f->lines = realloc(f->lines, sizeof(const char*)*(linecap *= 2)); + f->lines = xrealloc(f->lines, sizeof(const char*)*(linecap *= 2)); f->lines[n] = p; p = strchr(p, '\n'); if (p) ++p; @@ -39,7 +40,7 @@ file_t *load_file(const char *filename) if (filename == NULL) filename = "-"; int fd = strcmp(filename, "-") != 0 ? open(filename, O_RDONLY) : STDIN_FILENO; if (fd < 0) return NULL; - file_t *f = calloc(sizeof(file_t), 1); + file_t *f = new(file_t); f->filename = strdup(filename); struct stat sb; @@ -58,12 +59,12 @@ file_t *load_file(const char *filename) f->mmapped = 0; size_t capacity = 1000; f->length = 0; - f->contents = calloc(sizeof(char), capacity); + f->contents = xcalloc(sizeof(char), capacity); ssize_t just_read; while ((just_read=read(fd, &f->contents[f->length], capacity - f->length)) > 0) { f->length += (size_t)just_read; if (f->length >= capacity) - f->contents = realloc(f->contents, sizeof(char)*(capacity *= 2) + 1); + f->contents = xrealloc(f->contents, sizeof(char)*(capacity *= 2) + 1); } close(fd); @@ -79,7 +80,7 @@ file_t *load_file(const char *filename) file_t *spoof_file(const char *filename, char *text) { if (filename == NULL) filename = ""; - file_t *f = calloc(sizeof(file_t), 1); + file_t *f = new(file_t); f->filename = strdup(filename); f->contents = text; f->length = strlen(text); diff --git a/grammar.c b/grammar.c index 85a9610..5c9beee 100644 --- a/grammar.c +++ b/grammar.c @@ -12,15 +12,15 @@ grammar_t *new_grammar(void) { - grammar_t *g = calloc(sizeof(grammar_t), 1); - g->definitions = calloc(sizeof(def_t), (g->defcapacity = 128)); + grammar_t *g = new(grammar_t); + g->definitions = xcalloc(sizeof(def_t), (g->defcapacity = 128)); return g; } void add_def(grammar_t *g, file_t *f, const char *src, const char *name, vm_op_t *op) { if (g->defcount >= g->defcapacity) { - g->definitions = realloc(g->definitions, sizeof(&g->definitions[0])*(g->defcapacity += 32)); + g->definitions = xrealloc(g->definitions, sizeof(&g->definitions[0])*(g->defcapacity += 32)); } int i = g->defcount; g->definitions[i].file = f; @@ -84,12 +84,12 @@ vm_op_t *lookup(grammar_t *g, const char *name) void push_backref(grammar_t *g, const char *name, match_t *capture) { if (g->backrefcount >= g->backrefcapacity) { - g->backrefs = realloc(g->backrefs, sizeof(g->backrefs[0])*(g->backrefcapacity += 32)); + g->backrefs = xrealloc(g->backrefs, sizeof(g->backrefs[0])*(g->backrefcapacity += 32)); } size_t i = g->backrefcount++; g->backrefs[i].name = name; g->backrefs[i].capture = capture; - vm_op_t *op = calloc(sizeof(vm_op_t), 1); + vm_op_t *op = new(vm_op_t); op->op = VM_BACKREF; op->start = capture->start; op->end = capture->end; diff --git a/types.h b/types.h index b2939e0..aa61c38 100644 --- a/types.h +++ b/types.h @@ -13,6 +13,7 @@ enum BPEGFlag { BPEG_IGNORECASE = 1 << 1, BPEG_EXPLAIN = 1 << 2, BPEG_JSON = 1 << 3, + BPEG_LISTFILES = 1 << 4, }; /* diff --git a/utils.c b/utils.c index 2cc5258..16a53a3 100644 --- a/utils.c +++ b/utils.c @@ -172,5 +172,13 @@ size_t unescape_string(char *dest, const char *src, size_t bufsize) #undef PUT } +void *memcheck(void *p) +{ + if (p == NULL) { + fprintf(stderr, "memory allocation failure\n"); + _exit(1); + } + return p; +} // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1 diff --git a/utils.h b/utils.h index bd79e3f..61c817f 100644 --- a/utils.h +++ b/utils.h @@ -14,6 +14,9 @@ // TODO: better error reporting #define check(cond, ...) do { if (!(cond)) { fprintf(stderr, __VA_ARGS__); fwrite("\n", 1, 1, stderr); _exit(1); } } while(0) #define debug(...) do { if (verbose) fprintf(stderr, __VA_ARGS__); } while(0) +#define new(t) memcheck(calloc(sizeof(t), 1)) +#define xcalloc(a,b) memcheck(calloc(a,b)) +#define xrealloc(a,b) memcheck(realloc(a,b)) __attribute__((nonnull)) unsigned char unescapechar(const char *escaped, const char **end); @@ -25,6 +28,7 @@ __attribute__((nonnull)) int matchchar(const char **str, char c); __attribute__((nonnull)) size_t unescape_string(char *dest, const char *src, size_t bufsize); +void *memcheck(void *p); #endif // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1 diff --git a/viz.c b/viz.c index 8e80574..a7148f5 100644 --- a/viz.c +++ b/viz.c @@ -7,6 +7,7 @@ #include #include "types.h" +#include "utils.h" #include "viz.h" @@ -54,7 +55,7 @@ static void _visualize_matches(match_node_t *firstmatch, int depth, const char * if (RIGHT_TYPE(m)) { //if (m->m->op->op != VM_REF) { for (match_t *c = m->m->child; c; c = c->nextsibling) { - *nextchild = calloc(1, sizeof(match_node_t)); + *nextchild = new(match_node_t); (*nextchild)->m = c; nextchild = &((*nextchild)->next); } @@ -70,7 +71,7 @@ static void _visualize_matches(match_node_t *firstmatch, int depth, const char * } printf("\033[0;2m%s\033[0m", V); } else { - *nextchild = calloc(1, sizeof(match_node_t)); + *nextchild = new(match_node_t); (*nextchild)->m = m->m; nextchild = &((*nextchild)->next); printf("\033[%ldG\033[0;2m%s", 1+2*(m->m->start - text), V); diff --git a/vm.c b/vm.c index 2486264..d4ba826 100644 --- a/vm.c +++ b/vm.c @@ -107,7 +107,7 @@ static match_t *_match(grammar_t *g, file_t *f, const char *str, vm_op_t *op, un case VM_ANYCHAR: { if (str >= f->end || (!op->multiline && *str == '\n')) return NULL; - match_t *m = calloc(sizeof(match_t), 1); + match_t *m = new(match_t); m->op = op; m->start = str; m->end = next_char(f, str); @@ -118,7 +118,7 @@ static match_t *_match(grammar_t *g, file_t *f, const char *str, vm_op_t *op, un if ((flags & BPEG_IGNORECASE) ? strncasecmp(str, op->args.s, (size_t)op->len) != 0 : strncmp(str, op->args.s, (size_t)op->len) != 0) return NULL; - match_t *m = calloc(sizeof(match_t), 1); + match_t *m = new(match_t); m->op = op; m->start = str; m->end = str + op->len; @@ -127,7 +127,7 @@ static match_t *_match(grammar_t *g, file_t *f, const char *str, vm_op_t *op, un case VM_RANGE: { if ((unsigned char)*str < op->args.range.low || (unsigned char)*str > op->args.range.high) return NULL; - match_t *m = calloc(sizeof(match_t), 1); + match_t *m = new(match_t); m->op = op; m->start = str; m->end = str + 1; @@ -139,14 +139,14 @@ static match_t *_match(grammar_t *g, file_t *f, const char *str, vm_op_t *op, un destroy_match(&m); return NULL; } - m = calloc(sizeof(match_t), 1); + m = new(match_t); m->op = op; m->start = str; m->end = str; return m; } case VM_UPTO_AND: { - match_t *m = calloc(sizeof(match_t), 1); + match_t *m = new(match_t); m->start = str; m->op = op; if (!op->args.multiple.first && !op->args.multiple.second) { @@ -189,7 +189,7 @@ static match_t *_match(grammar_t *g, file_t *f, const char *str, vm_op_t *op, un return m; } case VM_REPEAT: { - match_t *m = calloc(sizeof(match_t), 1); + match_t *m = new(match_t); m->start = str; m->end = str; m->op = op; @@ -248,7 +248,7 @@ static match_t *_match(grammar_t *g, file_t *f, const char *str, vm_op_t *op, un if (str - backtrack < f->contents) return NULL; match_t *before = _match(g, f, str - backtrack, op->args.pat, flags, rec); if (before == NULL) return NULL; - match_t *m = calloc(sizeof(match_t), 1); + match_t *m = new(match_t); m->start = str; m->end = str; m->op = op; @@ -258,7 +258,7 @@ static match_t *_match(grammar_t *g, file_t *f, const char *str, vm_op_t *op, un case VM_BEFORE: { match_t *after = _match(g, f, str, op->args.pat, flags, rec); if (after == NULL) return NULL; - match_t *m = calloc(sizeof(match_t), 1); + match_t *m = new(match_t); m->start = str; m->end = str; m->op = op; @@ -268,7 +268,7 @@ static match_t *_match(grammar_t *g, file_t *f, const char *str, vm_op_t *op, un case VM_CAPTURE: { match_t *p = _match(g, f, str, op->args.pat, flags, rec); if (p == NULL) return NULL; - match_t *m = calloc(sizeof(match_t), 1); + match_t *m = new(match_t); m->start = str; m->end = p->end; m->op = op; @@ -280,7 +280,7 @@ static match_t *_match(grammar_t *g, file_t *f, const char *str, vm_op_t *op, un case VM_HIDE: { match_t *p = _match(g, f, str, op->args.pat, flags, rec); if (p == NULL) return NULL; - match_t *m = calloc(sizeof(match_t), 1); + match_t *m = new(match_t); m->start = str; m->end = p->end; m->op = op; @@ -303,7 +303,7 @@ static match_t *_match(grammar_t *g, file_t *f, const char *str, vm_op_t *op, un destroy_match(&m1); return NULL; } - match_t *m = calloc(sizeof(match_t), 1); + match_t *m = new(match_t); m->start = str; m->end = m2->end; m->op = op; @@ -331,7 +331,7 @@ static match_t *_match(grammar_t *g, file_t *f, const char *str, vm_op_t *op, un destroy_match(&m2); return NULL; } - match_t *m = calloc(sizeof(match_t), 1); + match_t *m = new(match_t); m->start = m1->start; m->end = m1->end; m->op = op; @@ -349,7 +349,7 @@ static match_t *_match(grammar_t *g, file_t *f, const char *str, vm_op_t *op, un p = _match(g, f, str, op->args.replace.replace_pat, flags, rec); if (p == NULL) return NULL; } - match_t *m = calloc(sizeof(match_t), 1); + match_t *m = new(match_t); m->start = str; m->op = op; if (p) { @@ -392,7 +392,7 @@ static match_t *_match(grammar_t *g, file_t *f, const char *str, vm_op_t *op, un } else if (best == NULL) { best = p; } - match_t *m = calloc(sizeof(match_t), 1); + match_t *m = new(match_t); m->start = best->start; m->end = best->end; m->op = op; @@ -424,7 +424,7 @@ static match_t *_match(grammar_t *g, file_t *f, const char *str, vm_op_t *op, un if (str[i] != denter || &str[i] >= f->end) return NULL; } - match_t *m = calloc(sizeof(match_t), 1); + match_t *m = new(match_t); m->start = start; m->end = &str[dents]; m->op = op; @@ -600,7 +600,7 @@ void print_match(file_t *f, match_t *m, print_options_t options) static match_t *match_backref(const char *str, vm_op_t *op, match_t *cap, unsigned int flags) { check(op->op == VM_BACKREF, "Attempt to match backref against something that's not a backref"); - match_t *ret = calloc(sizeof(match_t), 1); + match_t *ret = new(match_t); ret->start = str; ret->op = op; match_t **dest = &ret->child; -- cgit v1.2.3