Memory allocation failure checks, and a simpler new() function
This commit is contained in:
parent
40be243004
commit
484e1e33da
14
compiler.c
14
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;
|
||||
|
@ -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);
|
||||
|
10
grammar.c
10
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;
|
||||
|
1
types.h
1
types.h
@ -13,6 +13,7 @@ enum BPEGFlag {
|
||||
BPEG_IGNORECASE = 1 << 1,
|
||||
BPEG_EXPLAIN = 1 << 2,
|
||||
BPEG_JSON = 1 << 3,
|
||||
BPEG_LISTFILES = 1 << 4,
|
||||
};
|
||||
|
||||
/*
|
||||
|
8
utils.c
8
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
|
||||
|
4
utils.h
4
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
|
||||
|
5
viz.c
5
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);
|
||||
|
32
vm.c
32
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;
|
||||
|
Loading…
Reference in New Issue
Block a user