Use runtime asserts instead of error returns in desugar.c
The error paths are not tested and are mostly for NULL allocations so it makes more sense to use runtime asserts for now for simplicity's sake.
This commit is contained in:
parent
eb22abfb1b
commit
721d0a2b49
@ -9,16 +9,14 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static bool desugar_class(regex_term_t *term)
|
||||
static void desugar_class(regex_term_t *term)
|
||||
{
|
||||
if (term->class.negated)
|
||||
return false;
|
||||
assert(!term->class.negated);
|
||||
|
||||
const int count = term->class.count;
|
||||
regex_sequence_t *alternatives
|
||||
= malloc(count * sizeof(regex_sequence_t));
|
||||
if (NULL == alternatives)
|
||||
return false;
|
||||
assert(NULL != alternatives);
|
||||
|
||||
for (int i = 0; i < count; ++i) {
|
||||
regex_term_t *terms = malloc(sizeof(regex_term_t));
|
||||
@ -33,26 +31,21 @@ static bool desugar_class(regex_term_t *term)
|
||||
term->type = REGEX_TERM_SUBEXPR;
|
||||
term->subexpr.count = term->subexpr.capacity = count;
|
||||
term->subexpr.contents = alternatives;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool deep_copy_term(regex_term_t *dst, regex_term_t *src);
|
||||
static void deep_copy_term(regex_term_t *dst, regex_term_t *src);
|
||||
|
||||
static bool deep_copy_sequence(regex_sequence_t *dst, regex_sequence_t *src)
|
||||
static void deep_copy_sequence(regex_sequence_t *dst, regex_sequence_t *src)
|
||||
{
|
||||
dst->count = dst->capacity = src->count;
|
||||
dst->contents = malloc(dst->capacity * sizeof(regex_term_t));
|
||||
if (NULL == dst->contents)
|
||||
return false;
|
||||
assert(NULL != dst->contents);
|
||||
|
||||
for (int i = 0; i < dst->count; ++i)
|
||||
assert(deep_copy_term(&dst->contents[i], &src->contents[i]));
|
||||
|
||||
return true;
|
||||
deep_copy_term(&dst->contents[i], &src->contents[i]);
|
||||
}
|
||||
|
||||
static bool deep_copy_term(regex_term_t *dst, regex_term_t *src)
|
||||
static void deep_copy_term(regex_term_t *dst, regex_term_t *src)
|
||||
{
|
||||
assert(REGEX_TERM_WILDCARD != src->type);
|
||||
assert(REGEX_TERM_CLASS != src->type);
|
||||
@ -62,31 +55,26 @@ static bool deep_copy_term(regex_term_t *dst, regex_term_t *src)
|
||||
dst->subexpr.capacity = src->subexpr.count;
|
||||
dst->subexpr.contents
|
||||
= malloc(dst->subexpr.capacity * sizeof(regex_sequence_t));
|
||||
if (NULL == dst->subexpr.contents)
|
||||
return false;
|
||||
assert(NULL != dst->subexpr.contents);
|
||||
|
||||
for (int i = 0; i < dst->subexpr.count; ++i) {
|
||||
assert(deep_copy_sequence(
|
||||
&dst->subexpr.contents[i], &src->subexpr.contents[i]));
|
||||
deep_copy_sequence(
|
||||
&dst->subexpr.contents[i], &src->subexpr.contents[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool desugar_plus(regex_term_t *term)
|
||||
static void desugar_plus(regex_term_t *term)
|
||||
{
|
||||
regex_sequence_t *alternatives = malloc(sizeof(regex_sequence_t));
|
||||
if (NULL == alternatives)
|
||||
return false;
|
||||
assert(NULL != alternatives);
|
||||
|
||||
alternatives[0].count = alternatives[0].capacity = 2;
|
||||
alternatives[0].contents = malloc(2 * sizeof(regex_term_t));
|
||||
if (NULL == alternatives[0].contents)
|
||||
return false;
|
||||
assert(NULL != alternatives[0].contents);
|
||||
|
||||
memcpy(&alternatives[0].contents[0], term, sizeof(regex_term_t));
|
||||
if (!deep_copy_term(&alternatives[0].contents[1], term))
|
||||
return false;
|
||||
deep_copy_term(&alternatives[0].contents[1], term);
|
||||
alternatives[0].contents[0].quantifier = REGEX_QUANTIFIER_NONE;
|
||||
alternatives[0].contents[1].quantifier = REGEX_QUANTIFIER_STAR;
|
||||
|
||||
@ -94,27 +82,22 @@ static bool desugar_plus(regex_term_t *term)
|
||||
term->type = REGEX_TERM_SUBEXPR;
|
||||
term->subexpr.count = term->subexpr.capacity = 1;
|
||||
term->subexpr.contents = alternatives;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool desugar_qmark(regex_term_t *term)
|
||||
static void desugar_qmark(regex_term_t *term)
|
||||
{
|
||||
regex_sequence_t *alternatives = malloc(2 * sizeof(regex_sequence_t));
|
||||
if (NULL == alternatives)
|
||||
return false;
|
||||
assert(NULL != alternatives);
|
||||
|
||||
alternatives[0].count = alternatives[0].capacity = 1;
|
||||
alternatives[0].contents = malloc(sizeof(regex_term_t));
|
||||
if (NULL == alternatives[0].contents)
|
||||
return false;
|
||||
assert(NULL != alternatives[0].contents);
|
||||
alternatives[0].contents[0].quantifier = REGEX_QUANTIFIER_NONE;
|
||||
alternatives[0].contents[0].type = REGEX_TERM_EMPTY;
|
||||
|
||||
alternatives[1].count = alternatives[0].capacity = 1;
|
||||
alternatives[1].contents = malloc(sizeof(regex_term_t));
|
||||
if (NULL == alternatives[1].contents)
|
||||
return false;
|
||||
assert(NULL != alternatives[1].contents);
|
||||
memcpy(&alternatives[1].contents[0], term, sizeof(regex_term_t));
|
||||
alternatives[1].contents[0].quantifier = REGEX_QUANTIFIER_NONE;
|
||||
|
||||
@ -122,18 +105,16 @@ static bool desugar_qmark(regex_term_t *term)
|
||||
term->type = REGEX_TERM_SUBEXPR;
|
||||
term->subexpr.count = term->subexpr.capacity = 2;
|
||||
term->subexpr.contents = alternatives;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool desugar_term(regex_term_t *term)
|
||||
static void desugar_term(regex_term_t *term)
|
||||
{
|
||||
switch (term->type) {
|
||||
case REGEX_TERM_WILDCARD:
|
||||
return false;
|
||||
assert(false);
|
||||
break;
|
||||
case REGEX_TERM_CLASS:
|
||||
if (!desugar_class(term))
|
||||
return false;
|
||||
desugar_class(term);
|
||||
break;
|
||||
|
||||
case REGEX_TERM_LITERAL:
|
||||
@ -144,28 +125,23 @@ static bool desugar_term(regex_term_t *term)
|
||||
|
||||
switch (term->quantifier) {
|
||||
case REGEX_QUANTIFIER_PLUS:
|
||||
if (!desugar_plus(term))
|
||||
return false;
|
||||
desugar_plus(term);
|
||||
break;
|
||||
case REGEX_QUANTIFIER_QMARK:
|
||||
if (!desugar_qmark(term))
|
||||
return false;
|
||||
desugar_qmark(term);
|
||||
break;
|
||||
|
||||
case REGEX_QUANTIFIER_NONE:
|
||||
case REGEX_QUANTIFIER_STAR:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool desugar_regex(regex_t *regex)
|
||||
void desugar_regex(regex_t *regex)
|
||||
{
|
||||
for (int i = 0; i < regex->count; ++i) {
|
||||
for (int j = 0; j < regex->contents[i].count; ++j) {
|
||||
if (!desugar_term(®ex->contents[i].contents[j]))
|
||||
return false;
|
||||
desugar_term(®ex->contents[i].contents[j]);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -8,6 +8,6 @@
|
||||
|
||||
#include "regex.h"
|
||||
|
||||
bool desugar_regex(regex_t *regex);
|
||||
void desugar_regex(regex_t *regex);
|
||||
|
||||
#endif
|
||||
|
@ -19,8 +19,7 @@ static void a_is_unchanged(void)
|
||||
alternatives[0].contents = terms;
|
||||
regex_t t = { .count = 1, .capacity = 1, .contents = alternatives };
|
||||
|
||||
const bool success = desugar_regex(&t);
|
||||
ASSERT_TRUE(success);
|
||||
desugar_regex(&t);
|
||||
|
||||
ASSERT_EQ(1, t.count);
|
||||
ASSERT_NOT_NULL(t.contents);
|
||||
@ -47,8 +46,7 @@ static void abc_is_unchanged(void)
|
||||
alternatives[0].contents = terms;
|
||||
regex_t t = { .count = 1, .capacity = 1, .contents = alternatives };
|
||||
|
||||
const bool success = desugar_regex(&t);
|
||||
ASSERT_TRUE(success);
|
||||
desugar_regex(&t);
|
||||
|
||||
ASSERT_EQ(1, t.count);
|
||||
ASSERT_NOT_NULL(t.contents);
|
||||
@ -77,8 +75,7 @@ static void a_star_is_unchanged(void)
|
||||
alternatives[0].contents = terms;
|
||||
regex_t t = { .count = 1, .capacity = 1, .contents = alternatives };
|
||||
|
||||
const bool success = desugar_regex(&t);
|
||||
ASSERT_TRUE(success);
|
||||
desugar_regex(&t);
|
||||
|
||||
ASSERT_EQ(1, t.count);
|
||||
ASSERT_NOT_NULL(t.contents);
|
||||
@ -106,8 +103,7 @@ static void a_or_b_or_c_is_unchanged(void)
|
||||
}
|
||||
regex_t t = { .count = 3, .capacity = 3, .contents = alternatives };
|
||||
|
||||
const bool success = desugar_regex(&t);
|
||||
ASSERT_TRUE(success);
|
||||
desugar_regex(&t);
|
||||
|
||||
ASSERT_EQ(3, t.count);
|
||||
ASSERT_NOT_NULL(t.contents);
|
||||
@ -143,8 +139,7 @@ static void subexpr_a_is_unchanged(void)
|
||||
alternatives[0].contents = terms;
|
||||
regex_t t = { .count = 1, .capacity = 1, .contents = alternatives };
|
||||
|
||||
const bool success = desugar_regex(&t);
|
||||
ASSERT_TRUE(success);
|
||||
desugar_regex(&t);
|
||||
|
||||
ASSERT_EQ(1, t.count);
|
||||
ASSERT_NOT_NULL(t.contents);
|
||||
@ -177,8 +172,7 @@ static void a_plus_becomes_subexpr_aa_star(void)
|
||||
alternatives[0].contents = terms;
|
||||
regex_t t = { .count = 1, .capacity = 1, .contents = alternatives };
|
||||
|
||||
const bool success = desugar_regex(&t);
|
||||
ASSERT_TRUE(success);
|
||||
desugar_regex(&t);
|
||||
|
||||
ASSERT_EQ(1, t.count);
|
||||
ASSERT_NOT_NULL(t.contents);
|
||||
@ -215,8 +209,7 @@ static void a_qmark_becomes_subexpr_empty_or_a(void)
|
||||
alternatives[0].contents = terms;
|
||||
regex_t t = { .count = 1, .capacity = 1, .contents = alternatives };
|
||||
|
||||
const bool success = desugar_regex(&t);
|
||||
ASSERT_TRUE(success);
|
||||
desugar_regex(&t);
|
||||
|
||||
ASSERT_EQ(1, t.count);
|
||||
ASSERT_NOT_NULL(t.contents);
|
||||
@ -260,8 +253,7 @@ static void class_abc_becomes_subexpr_a_or_b_or_c(void)
|
||||
alternatives[0].contents = terms;
|
||||
regex_t t = { .count = 1, .capacity = 1, .contents = alternatives };
|
||||
|
||||
const bool success = desugar_regex(&t);
|
||||
ASSERT_TRUE(success);
|
||||
desugar_regex(&t);
|
||||
|
||||
ASSERT_EQ(1, t.count);
|
||||
ASSERT_NOT_NULL(t.contents);
|
||||
|
Loading…
x
Reference in New Issue
Block a user