M Include/check.h => Include/check.h +2 -0
@@ 1,3 1,5 @@
#pragma once
#define CHECK(x) { int _impl_check_result; if ((_impl_check_result = (x))) { return _impl_check_result; } }
+
+#define CHECK_(x, code) { if (!(x)) { return (code); } }
A Include/errors.h => Include/errors.h +10 -0
@@ 0,0 1,10 @@
+#pragma once
+
+enum {
+ E_UNIMPLEMENTED = -1,
+ E_UNEXPECTED = -2,
+ E_LOGIC = -3,
+ E_UNINITIALIZED = -4,
+ E_ALREADY = -5,
+ E_NIL = -6
+};
M Src/ast.c => Src/ast.c +9 -10
@@ 9,6 9,7 @@
#include <set.h>
#include <check.h>
+#include <errors.h>
enum ast_store ast_store_type(struct ast* a) {
switch (a->type) {
@@ 32,7 33,7 @@ int ast_get_children(struct ast* a, struct ast** begin, struct ast** end) {
*end = a->store.child + 1;
break;
default:
- assert(0 && "ast_store_type: unhandled type");
+ return E_UNEXPECTED;
}
return 0;
}
@@ 43,19 44,17 @@ int ast_new(struct ast* a, int tag) {
a->max_repetitions = 1;
a->next = NULL;
switch (ast_store_type(a)) {
- case AST_STORE_NODE: a->store.child = NULL; return 0;
- case AST_STORE_CHAR: a->store.glyph = '\0'; return 0;
+ case AST_STORE_NONE: break;
+ case AST_STORE_NODE: a->store.child = NULL; break;
+ case AST_STORE_CHAR: a->store.glyph = '\0'; break;
+ case AST_STORE_SET: a->store.set = NULL; break;
case AST_STORE_LIST:
a->store.children.first = NULL;
a->store.children.last = NULL;
return 0;
- case AST_STORE_SET:
- a->store.set = NULL;
- return 0;
- case AST_STORE_NONE: return 0;
+ default: return E_UNEXPECTED;
}
- assert(0 && "ast_new: unknown type");
- return -1;
+ return 0;
}
int ast_setup_repetition(struct ast* a, char repetition) {
@@ 63,7 62,7 @@ int ast_setup_repetition(struct ast* a, char repetition) {
case '?': a->min_repetitions = 0; a->max_repetitions = 1; break;
case '*': a->min_repetitions = 0; a->max_repetitions = UINT_MAX; break;
case '+': a->min_repetitions = 1; a->max_repetitions = UINT_MAX; break;
- default: return -1;
+ default: return E_UNEXPECTED;
}
return 0;
}
M Src/ast_normalize.c => Src/ast_normalize.c +4 -4
@@ 1,10 1,10 @@
#include <ast_normalize.h>
-#include <assert.h>
#include <limits.h>
#include <string.h>
#include <check.h>
+#include <errors.h>
static inline int ast_free(struct ast* a, struct mem_mgr* m) {
(void)a;
@@ 22,7 22,7 @@ static void safe_sum(unsigned* a, unsigned b) {
}
static int merge_equivalent_entries(struct ast* a, struct mem_mgr* mgr) {
- assert(a->type == AST_TYPE_SEQ);
+ CHECK_(a->type == AST_TYPE_SEQ, E_UNEXPECTED);
struct ast* current = a->store.children.first;
@@ 79,7 79,7 @@ static int merge_equivalent_entries(struct ast* a, struct mem_mgr* mgr) {
static int remove_equivalent_branches(struct ast* a, struct mem_mgr* mgr) {
// OR should be at least 1 elements long
- assert(a);
+ CHECK_(a, E_NIL);
if (!a->next) {
return 0;
}
@@ 132,7 132,7 @@ int ast_normalize(struct ast* a, struct mem_mgr* mgr) {
}
case AST_TYPE_SEQ:
{
- assert(a->store.children.first && a->store.children.first->next);
+ CHECK_(a->store.children.first && a->store.children.first->next, E_LOGIC);
FOR_AST(a, a1, CHECK(ast_normalize(a1, mgr)));
CHECK(merge_equivalent_entries(a, mgr));
break;
M Src/dump_tree.c => Src/dump_tree.c +0 -1
@@ 1,5 1,4 @@
-#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <dump_tree.h>
M Src/main.c => Src/main.c +0 -1
@@ 1,5 1,4 @@
-#include <assert.h>
#include <locale.h>
#include <stdlib.h>
#include <stdio.h>
M Src/memory_manager.c => Src/memory_manager.c +5 -4
@@ 5,6 5,7 @@
#include <memory_manager.h>
#include <check.h>
+#include <errors.h>
static inline void* ext_alloc(struct mem_mgr_config* cfg, size_t size) {
return cfg->ext_alloc(size, cfg->data);
@@ 84,10 85,10 @@ static inline int block_owns_ptr(struct block* b, void* ptr) {
static int pool_free(struct pool* p, void* ptr) {
struct block* b = p->list;
- assert(b && "ast_mem_mgr: mgr is not initialized");
+ CHECK_(b, E_UNINITIALIZED);
if (block_owns_ptr(b, ptr)) {
- assert(b->ref_count && "ast_mem_mgr: double-free");
+ CHECK_(b->ref_count, E_ALREADY);
--b->ref_count;
if (!b->ref_count) {
// no reason to push it into free blocks -- it's first & already clean
@@ 96,7 97,7 @@ static int pool_free(struct pool* p, void* ptr) {
return 0;
}
- assert(b->next && "ast_mem_mgr: tried to free ptr that was not alloc'd here");
+ CHECK_(b->next, E_UNEXPECTED);
struct block* bn = b->next;
while (bn && (ptr < (void*)bn->begin || ptr >= (void*)bn->end)) {
@@ 107,7 108,7 @@ static int pool_free(struct pool* p, void* ptr) {
return -1;
}
- assert(bn->ref_count);
+ CHECK_(bn->ref_count, E_LOGIC);
--bn->ref_count;
if (bn->ref_count == 0) {
M Src/transitions.c => Src/transitions.c +6 -2
@@ 5,6 5,7 @@
#include <transitions.h>
#include <check.h>
+#include <errors.h>
static inline int is_leaf(struct ast* a) {
switch (a->type) {
@@ 86,7 87,7 @@ static int to_graph_impl_or(struct transition_vec* ts, struct ast* a, struct con
CHECK(to_graph_impl(ts, a1, &newctx))
size_t new_len = transition_vec_len(ts);
- assert(old_len + leafs == new_len);
+ CHECK_(old_len + leafs == new_len, E_LOGIC);
// the last transition in a subexpression should jump to the end of OR
// rather than passing control to the next subexpr
@@ 136,7 137,10 @@ static int to_graph_impl(struct transition_vec* ts, struct ast* a, struct contex
CHECK(to_graph_impl(ts, a->store.child, ctx));
t_prev = transition_vec_at(ts, transition_vec_len(ts) - 1);
- assert(t_prev->on_ok == SIZE_MAX || t_prev->on_ok == transition_vec_len(ts));
+ CHECK_(
+ (t_prev->on_ok == SIZE_MAX || t_prev->on_ok == transition_vec_len(ts)),
+ E_LOGIC
+ );
on_ok_(t_prev, transition_vec_len(ts));
struct transition* t2 = transition_vec_alloc(ts);