/* * Copyright (c) Camden Dixie O'Brien * SPDX-License-Identifier: AGPL-3.0-only */ #include "parser.h" #include "testing.h" #define PARSE_REGEX_STRING(s, r) parse_regex(s, strlen(s), r) static void a_has_no_alternative(void) { regex_t r = { 0 }; const int result = PARSE_REGEX_STRING("a", &r); ASSERT_NE(-1, result); ASSERT_NULL(r.alternative); regex_free_children(&r); } static void a_pipe_b_has_alternative(void) { regex_t r = { 0 }; const int result = PARSE_REGEX_STRING("a|b", &r); ASSERT_NE(-1, result); ASSERT_NOT_NULL(r.alternative); regex_free_children(&r); } static void a_pipe_b_pipe_c_result_alternative_has_alternative(void) { regex_t r = { 0 }; const int result = PARSE_REGEX_STRING("a|b|c", &r); ASSERT_NE(-1, result); ASSERT_NOT_NULL(r.alternative); ASSERT_NOT_NULL(r.alternative->alternative); regex_free_children(&r); } static void a_is_parsed_as_unquantified_literal(void) { regex_t r = { 0 }; const int result = PARSE_REGEX_STRING("a", &r); ASSERT_NE(-1, result); ASSERT_EQ(1, 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); regex_free_children(&r); } static void b_is_parsed_as_unquantified_literal(void) { regex_t r = { 0 }; const int result = PARSE_REGEX_STRING("b", &r); ASSERT_NE(-1, result); ASSERT_EQ(1, r.sequence.len); ASSERT_EQ(QUANTIFIER_NONE, r.sequence.contents[0].quantifier); ASSERT_EQ(TERM_TYPE_LITERAL, r.sequence.contents[0].type); ASSERT_EQ('b', r.sequence.contents[0].literal); 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); } static void dot_is_parsed_as_unquantified_wildcard_term(void) { regex_t r = { 0 }; const int result = PARSE_REGEX_STRING(".", &r); ASSERT_NE(-1, result); ASSERT_EQ(1, r.sequence.len); ASSERT_EQ(QUANTIFIER_NONE, r.sequence.contents[0].quantifier); ASSERT_EQ(TERM_TYPE_WILDCARD, r.sequence.contents[0].type); regex_free_children(&r); } static void backslash_dot_is_parsed_as_unquantified_literal(void) { regex_t r = { 0 }; const int result = PARSE_REGEX_STRING("\\.", &r); ASSERT_NE(-1, result); ASSERT_EQ(1, r.sequence.len); ASSERT_EQ(QUANTIFIER_NONE, r.sequence.contents[0].quantifier); ASSERT_EQ(TERM_TYPE_LITERAL, r.sequence.contents[0].type); ASSERT_EQ('.', r.sequence.contents[0].literal); regex_free_children(&r); } static void backslash_backslash_is_parsed_as_unquantified_literal(void) { regex_t r = { 0 }; const int result = PARSE_REGEX_STRING("\\\\", &r); ASSERT_NE(-1, result); ASSERT_EQ(1, r.sequence.len); ASSERT_EQ(QUANTIFIER_NONE, r.sequence.contents[0].quantifier); ASSERT_EQ(TERM_TYPE_LITERAL, r.sequence.contents[0].type); ASSERT_EQ('\\', r.sequence.contents[0].literal); regex_free_children(&r); } static void a_pipe_b_in_parens_is_parsed_as_regex_term(void) { regex_t r = { 0 }; const int result = PARSE_REGEX_STRING("(a|b)", &r); ASSERT_NE(-1, result); ASSERT_EQ(1, r.sequence.len); ASSERT_EQ(QUANTIFIER_NONE, r.sequence.contents[0].quantifier); ASSERT_EQ(TERM_TYPE_REGEX, r.sequence.contents[0].type); const regex_t *inner = &r.sequence.contents[0].regex; ASSERT_EQ(1, inner->sequence.len); ASSERT_EQ(QUANTIFIER_NONE, inner->sequence.contents[0].quantifier); ASSERT_EQ(TERM_TYPE_LITERAL, inner->sequence.contents[0].type); ASSERT_EQ('a', inner->sequence.contents[0].literal); const regex_t *inner_alt = inner->alternative; ASSERT_EQ(1, inner->sequence.len); ASSERT_EQ(QUANTIFIER_NONE, inner_alt->sequence.contents[0].quantifier); ASSERT_EQ(TERM_TYPE_LITERAL, inner_alt->sequence.contents[0].type); ASSERT_EQ('b', inner_alt->sequence.contents[0].literal); regex_free_children(&r); } static void a_in_parens_b_is_parsed_as_sequence_with_regex_term(void) { regex_t r = { 0 }; const int result = PARSE_REGEX_STRING("(a)b", &r); ASSERT_NE(-1, result); ASSERT_EQ(2, r.sequence.len); ASSERT_EQ(QUANTIFIER_NONE, r.sequence.contents[0].quantifier); ASSERT_EQ(TERM_TYPE_REGEX, r.sequence.contents[0].type); 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); const regex_t *inner = &r.sequence.contents[0].regex; ASSERT_EQ(1, inner->sequence.len); ASSERT_EQ(QUANTIFIER_NONE, inner->sequence.contents[0].quantifier); ASSERT_EQ(TERM_TYPE_LITERAL, inner->sequence.contents[0].type); ASSERT_EQ('a', inner->sequence.contents[0].literal); regex_free_children(&r); } int main(void) { TESTING_BEGIN(); a_has_no_alternative(); a_pipe_b_has_alternative(); 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(); dot_is_parsed_as_unquantified_wildcard_term(); backslash_dot_is_parsed_as_unquantified_literal(); backslash_backslash_is_parsed_as_unquantified_literal(); a_pipe_b_in_parens_is_parsed_as_regex_term(); a_in_parens_b_is_parsed_as_sequence_with_regex_term(); return TESTING_END(); }