diff --git a/lib/parser.c b/lib/parser.c index fa1783a..f4b7b0f 100644 --- a/lib/parser.c +++ b/lib/parser.c @@ -8,6 +8,8 @@ #include #include +#define SEQUENCE_START_CAPACITY 8 + static bool is_special(char c) { switch (c) { @@ -20,7 +22,7 @@ static bool is_special(char c) static int parse_literal(const char *input, int rem, char *out) { - if (rem > 0 || !is_special(input[0])) { + if (rem > 0 && !is_special(input[0])) { *out = input[0]; return 1; } else { @@ -46,17 +48,30 @@ static int parse_sequence(const char *input, int rem, sequence_t *out) { int result, used = 0; - out->contents = calloc(1, sizeof(term_t)); out->len = 0; - out->capacity = 1; - - result = parse_term(input + used, rem - used, &out->contents[0]); - if (result < 0) + out->capacity = SEQUENCE_START_CAPACITY; + out->contents = calloc(out->capacity, sizeof(term_t)); + if (NULL == out->contents) return -1; - ++out->len; - used += result; - return used; + while (used < rem) { + if (out->len >= out->capacity) { + out->capacity *= 2; + out->contents + = realloc(out->contents, out->capacity * sizeof(term_t)); + if (NULL == out->contents) + return -1; + } + + result + = parse_term(input + used, rem - used, &out->contents[out->len]); + if (result < 0) + break; + ++out->len; + used += result; + } + + return out->len > 0 ? used : -1; } int parse_regex(const char *input, int rem, regex_t *out) @@ -74,6 +89,8 @@ int parse_regex(const char *input, int rem, regex_t *out) ++used; out->alternative = calloc(1, sizeof(regex_t)); + if (NULL == out->alternative) + return -1; result = parse_regex(input + used, rem - used, out->alternative); if (result < 0) return -1; diff --git a/tests/parser_tests.c b/tests/parser_tests.c index d641e9c..35554c9 100644 --- a/tests/parser_tests.c +++ b/tests/parser_tests.c @@ -64,6 +64,26 @@ static void b_is_parsed_as_unquantified_literal(void) regex_free_children(&r); } +static void abc_is_parsed_as_sequence_of_unquantified_literals(void) +{ + regex_t r = { 0 }; + const int result = PARSE_REGEX_STRING("abc", &r); + ASSERT_NE(-1, result); + + ASSERT_EQ(3, r.sequence.len); + ASSERT_EQ(QUANTIFIER_NONE, r.sequence.contents[0].quantifier); + ASSERT_EQ(TERM_TYPE_LITERAL, r.sequence.contents[0].type); + ASSERT_EQ('a', r.sequence.contents[0].literal); + ASSERT_EQ(QUANTIFIER_NONE, r.sequence.contents[1].quantifier); + ASSERT_EQ(TERM_TYPE_LITERAL, r.sequence.contents[1].type); + ASSERT_EQ('b', r.sequence.contents[1].literal); + ASSERT_EQ(QUANTIFIER_NONE, r.sequence.contents[2].quantifier); + ASSERT_EQ(TERM_TYPE_LITERAL, r.sequence.contents[2].type); + ASSERT_EQ('c', r.sequence.contents[2].literal); + + regex_free_children(&r); +} + int main(void) { TESTING_BEGIN(); @@ -72,5 +92,6 @@ int main(void) a_pipe_b_pipe_c_result_alternative_has_alternative(); a_is_parsed_as_unquantified_literal(); b_is_parsed_as_unquantified_literal(); + abc_is_parsed_as_sequence_of_unquantified_literals(); return TESTING_END(); }