Memory allocation failure checks, and a simpler new() function

This commit is contained in:
Bruce Hill 2020-12-17 16:27:23 -08:00
parent 40be243004
commit 484e1e33da
8 changed files with 51 additions and 36 deletions

View File

@ -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;

View File

@ -13,18 +13,19 @@
#include <unistd.h>
#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);

View File

@ -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;

View File

@ -13,6 +13,7 @@ enum BPEGFlag {
BPEG_IGNORECASE = 1 << 1,
BPEG_EXPLAIN = 1 << 2,
BPEG_JSON = 1 << 3,
BPEG_LISTFILES = 1 << 4,
};
/*

View File

@ -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

View File

@ -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

5
viz.c
View File

@ -7,6 +7,7 @@
#include <string.h>
#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);

32
vm.c
View File

@ -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;