aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2020-12-17 16:27:23 -0800
committerBruce Hill <bruce@bruce-hill.com>2020-12-17 16:27:23 -0800
commit484e1e33da7477b7278c9a3e9da878f0375dd75b (patch)
tree892979f8bf65fd9a1366c040fa4a090968fcaecf
parent40be243004b095fe15bb2ece176692f8354cdf45 (diff)
Memory allocation failure checks, and a simpler new() function
-rw-r--r--compiler.c14
-rw-r--r--file_loader.c13
-rw-r--r--grammar.c10
-rw-r--r--types.h1
-rw-r--r--utils.c8
-rw-r--r--utils.h4
-rw-r--r--viz.c5
-rw-r--r--vm.c32
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 <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);
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 <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);
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;