ladybird/Tests/LibRegex/RegexLibC.cpp
Linus Groh 6e7459322d AK: Remove StringBuilder::build() in favor of to_deprecated_string()
Having an alias function that only wraps another one is silly, and
keeping the more obvious name should flush out more uses of deprecated
strings.
No behavior change.
2023-01-27 20:38:49 +00:00

1160 lines
46 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (c) 2020, Emanuel Sprung <emanuel.sprung@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibTest/TestCase.h>
#include <AK/StringBuilder.h>
#include <AK/Vector.h>
#include <regex.h>
#include <stdio.h>
TEST_CASE(catch_all)
{
DeprecatedString pattern = "^.*$";
regex_t regex;
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR);
EXPECT_EQ(regexec(&regex, "Hello World", 0, NULL, 0), REG_NOERR);
regfree(&regex);
}
TEST_CASE(simple_start)
{
DeprecatedString pattern = "^hello friends";
regex_t regex;
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR);
EXPECT_EQ(regexec(&regex, "Hello!", 0, NULL, 0), REG_NOMATCH);
EXPECT_EQ(regexec(&regex, "hello friends", 0, NULL, 0), REG_NOERR);
EXPECT_EQ(regexec(&regex, "Well, hello friends", 0, NULL, 0), REG_NOMATCH);
regfree(&regex);
}
TEST_CASE(simple_end)
{
DeprecatedString pattern = ".*hello\\.\\.\\. there$";
regex_t regex;
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR);
EXPECT_EQ(regexec(&regex, "Hallo", 0, NULL, 0), REG_NOMATCH);
EXPECT_EQ(regexec(&regex, "I said fyhello... there", 0, NULL, 0), REG_NOERR);
EXPECT_EQ(regexec(&regex, "ahello... therea", 0, NULL, 0), REG_NOMATCH);
EXPECT_EQ(regexec(&regex, "hello.. there", 0, NULL, 0), REG_NOMATCH);
regfree(&regex);
}
TEST_CASE(simple_period)
{
DeprecatedString pattern = "hello.";
regex_t regex;
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR);
EXPECT_EQ(regexec(&regex, "Hello1", 0, NULL, 0), REG_NOMATCH);
EXPECT_EQ(regexec(&regex, "hello1", 0, NULL, 0), REG_NOERR);
EXPECT_EQ(regexec(&regex, "hello2", 0, NULL, 0), REG_NOERR);
EXPECT_EQ(regexec(&regex, "hello?", 0, NULL, 0), REG_NOERR);
regfree(&regex);
}
TEST_CASE(simple_period_end)
{
DeprecatedString pattern = "hello.$";
regex_t regex;
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED | REG_NOSUB), REG_NOERR);
EXPECT_EQ(regexec(&regex, "Hello1", 0, NULL, REG_NOSUB), REG_NOMATCH);
EXPECT_EQ(regexec(&regex, "hello1hello1", 0, NULL, REG_GLOBAL), REG_NOERR);
EXPECT_EQ(regexec(&regex, "hello2hell", 0, NULL, REG_GLOBAL), REG_NOMATCH);
EXPECT_EQ(regexec(&regex, "hello?", 0, NULL, REG_NOSUB), REG_NOERR);
regfree(&regex);
}
TEST_CASE(simple_escaped)
{
DeprecatedString pattern = "hello\\.";
regex_t regex;
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR);
EXPECT_EQ(regexec(&regex, "hello", 0, NULL, 0), REG_NOMATCH);
EXPECT_EQ(regexec(&regex, "hello.", 0, NULL, 0), REG_NOERR);
regfree(&regex);
}
TEST_CASE(simple_period2_end)
{
DeprecatedString pattern = ".*hi... there$";
regex_t regex;
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR);
EXPECT_EQ(regexec(&regex, "Hello there", 0, NULL, REG_GLOBAL), REG_NOMATCH);
EXPECT_EQ(regexec(&regex, "I said fyhi... there", 0, NULL, REG_GLOBAL), REG_NOERR);
EXPECT_EQ(regexec(&regex, "....hi... ", 0, NULL, REG_GLOBAL), REG_NOMATCH);
EXPECT_EQ(regexec(&regex, "I said fyhihii there", 0, NULL, REG_GLOBAL), REG_NOERR);
EXPECT_EQ(regexec(&regex, "I said fyhihi there", 0, NULL, REG_GLOBAL), REG_NOMATCH);
regfree(&regex);
}
TEST_CASE(simple_plus)
{
DeprecatedString pattern = "a+";
regex_t regex;
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED | REG_NOSUB), REG_NOERR);
EXPECT_EQ(regexec(&regex, "b", 0, NULL, REG_NOSUB), REG_NOMATCH);
EXPECT_EQ(regexec(&regex, "a", 0, NULL, REG_NOSUB), REG_NOERR);
EXPECT_EQ(regexec(&regex, "aaaaaabbbbb", 0, NULL, REG_GLOBAL), REG_NOERR);
EXPECT_EQ(regexec(&regex, "aaaaaaaaaaa", 0, NULL, REG_GLOBAL), REG_NOERR);
regfree(&regex);
}
TEST_CASE(simple_questionmark)
{
DeprecatedString pattern = "da?d";
regex_t regex;
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR);
EXPECT_EQ(regexec(&regex, "a", 0, NULL, REG_GLOBAL), REG_NOMATCH);
EXPECT_EQ(regexec(&regex, "daa", 0, NULL, REG_GLOBAL), REG_NOMATCH);
EXPECT_EQ(regexec(&regex, "ddddd", 0, NULL, REG_GLOBAL), REG_NOERR);
EXPECT_EQ(regexec(&regex, "dd", 0, NULL, REG_GLOBAL), REG_NOERR);
EXPECT_EQ(regexec(&regex, "dad", 0, NULL, REG_GLOBAL), REG_NOERR);
EXPECT_EQ(regexec(&regex, "dada", 0, NULL, REG_GLOBAL), REG_NOERR);
EXPECT_EQ(regexec(&regex, "adadaa", 0, NULL, REG_GLOBAL), REG_NOERR);
regfree(&regex);
}
TEST_CASE(simple_questionmark_matchall)
{
DeprecatedString pattern = "da?d";
regex_t regex;
static constexpr int num_matches { 5 };
regmatch_t matches[num_matches];
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR);
EXPECT_EQ(regexec(&regex, "a", num_matches, matches, REG_GLOBAL), REG_NOMATCH);
EXPECT_EQ(matches[0].rm_cnt, 0);
EXPECT_EQ(regexec(&regex, "daa", num_matches, matches, REG_GLOBAL), REG_NOMATCH);
EXPECT_EQ(matches[0].rm_cnt, 0);
EXPECT_EQ(regexec(&regex, "ddddd", num_matches, matches, REG_GLOBAL), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 2);
EXPECT_EQ(matches[0].rm_so, 0);
EXPECT_EQ(matches[0].rm_eo, 2);
EXPECT_EQ(matches[1].rm_so, 2);
EXPECT_EQ(matches[1].rm_eo, 4);
EXPECT_EQ(regexec(&regex, "dd", num_matches, matches, REG_GLOBAL), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 1);
EXPECT_EQ(regexec(&regex, "dad", num_matches, matches, REG_GLOBAL), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 1);
EXPECT_EQ(regexec(&regex, "dada", num_matches, matches, REG_GLOBAL), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 1);
EXPECT_EQ(regexec(&regex, "adadaa", num_matches, matches, REG_GLOBAL), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 1);
regfree(&regex);
}
TEST_CASE(character_class)
{
DeprecatedString pattern = "[[:alpha:]]";
regex_t regex;
static constexpr int num_matches { 5 };
regmatch_t matches[num_matches];
DeprecatedString haystack = "[Window]\nOpacity=255\nAudibleBeep=0\n";
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR);
EXPECT_EQ(regexec(&regex, haystack.characters(), num_matches, matches, 0), REG_NOMATCH);
EXPECT_EQ(matches[0].rm_cnt, 0);
EXPECT_EQ(regexec(&regex, haystack.characters(), num_matches, matches, REG_GLOBAL), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 24);
EXPECT_EQ(haystack.substring_view(matches[0].rm_so, matches[0].rm_eo - matches[0].rm_so), "W");
EXPECT_EQ(haystack.substring_view(matches[1].rm_so, matches[1].rm_eo - matches[1].rm_so), "i");
regfree(&regex);
}
TEST_CASE(character_class2)
{
DeprecatedString pattern = "[[:alpha:]]*=([[:digit:]]*)|\\[(.*)\\]";
regex_t regex;
static constexpr int num_matches { 9 };
regmatch_t matches[num_matches];
DeprecatedString haystack = "[Window]\nOpacity=255\nAudibleBeep=0\n";
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED | REG_NEWLINE), REG_NOERR);
EXPECT_EQ(regexec(&regex, haystack.characters(), num_matches, matches, 0), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 3);
#if 0
for (int i = 0; i < num_matches; ++i) {
fprintf(stderr, "Matches[%i].rm_so: %li, .rm_eo: %li .rm_cnt: %li: ", i, matches[i].rm_so, matches[i].rm_eo, matches[i].rm_cnt);
fprintf(stderr, "haystack length: %lu\n", haystack.length());
if (matches[i].rm_so != -1)
fprintf(stderr, "%s\n", haystack.substring_view(matches[i].rm_so, matches[i].rm_eo - matches[i].rm_so).to_deprecated_string().characters());
}
#endif
EXPECT_EQ(haystack.substring_view(matches[0].rm_so, matches[0].rm_eo - matches[0].rm_so), "[Window]");
EXPECT_EQ(matches[1].rm_so, -1);
EXPECT_EQ(matches[1].rm_eo, -1);
EXPECT_EQ(matches[1].rm_cnt, 0);
EXPECT_EQ(haystack.substring_view(matches[2].rm_so, matches[2].rm_eo - matches[2].rm_so), "Window");
EXPECT_EQ(haystack.substring_view(matches[3].rm_so, matches[3].rm_eo - matches[3].rm_so), "Opacity=255");
EXPECT_EQ(haystack.substring_view(matches[4].rm_so, matches[4].rm_eo - matches[4].rm_so), "255");
EXPECT_EQ(matches[5].rm_so, -1);
EXPECT_EQ(matches[5].rm_eo, -1);
EXPECT_EQ(matches[5].rm_cnt, 0);
EXPECT_EQ(haystack.substring_view(matches[6].rm_so, matches[6].rm_eo - matches[6].rm_so), "AudibleBeep=0");
EXPECT_EQ(haystack.substring_view(matches[7].rm_so, matches[7].rm_eo - matches[7].rm_so), "0");
EXPECT_EQ(matches[8].rm_so, -1);
EXPECT_EQ(matches[8].rm_eo, -1);
EXPECT_EQ(matches[8].rm_cnt, 0);
regfree(&regex);
}
TEST_CASE(escaped_char_questionmark)
{
DeprecatedString pattern = "This\\.?And\\.?That";
regex_t regex;
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR);
EXPECT_EQ(regexec(&regex, "ThisAndThat", 0, NULL, 0), REG_NOERR);
EXPECT_EQ(regexec(&regex, "This.And.That", 0, NULL, 0), REG_NOERR);
EXPECT_EQ(regexec(&regex, "This And That", 0, NULL, 0), REG_NOMATCH);
EXPECT_EQ(regexec(&regex, "This..And..That", 0, NULL, 0), REG_NOMATCH);
regfree(&regex);
}
TEST_CASE(char_qualifier_asterisk)
{
DeprecatedString pattern = "regex*";
regex_t regex;
static constexpr int num_matches { 5 };
regmatch_t matches[num_matches];
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR);
EXPECT_EQ(regexec(&regex, "#include <regex.h>", num_matches, matches, REG_GLOBAL), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 1);
regfree(&regex);
}
TEST_CASE(char_utf8)
{
DeprecatedString pattern = "😀";
regex_t regex;
static constexpr int num_matches { 5 };
regmatch_t matches[num_matches];
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR);
EXPECT_EQ(regexec(&regex, "Привет, мир! 😀 γειά σου κόσμος 😀 こんにちは世界", num_matches, matches, REG_GLOBAL), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 2);
regfree(&regex);
}
TEST_CASE(parens)
{
DeprecatedString pattern = "test(hello)test";
regex_t regex;
static constexpr int num_matches { 5 };
regmatch_t matches[num_matches];
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR);
EXPECT_EQ(regexec(&regex, "testhellotest", num_matches, matches, 0), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 1);
EXPECT_EQ(matches[0].rm_so, 0);
EXPECT_EQ(matches[0].rm_eo, 13);
EXPECT_EQ(matches[1].rm_so, 4);
EXPECT_EQ(matches[1].rm_eo, 9);
regfree(&regex);
}
TEST_CASE(parser_error_parens)
{
DeprecatedString pattern = "test()test";
regex_t regex;
static constexpr int num_matches { 5 };
regmatch_t matches[num_matches];
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_EMPTY_EXPR);
EXPECT_EQ(regexec(&regex, "testhellotest", num_matches, matches, 0), REG_EMPTY_EXPR);
regfree(&regex);
}
TEST_CASE(parser_error_special_characters_used_at_wrong_place)
{
DeprecatedString pattern;
regex_t regex;
static constexpr int num_matches { 5 };
regmatch_t matches[num_matches];
Vector<char, 4> chars = { '*', '+', '?', '}' };
StringBuilder b;
for (auto& ch : chars) {
auto error_code_to_check = ch == '}' ? REG_EBRACE : REG_BADRPT;
// First in ere
b.clear();
b.append(ch);
pattern = b.to_deprecated_string();
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), error_code_to_check);
EXPECT_EQ(regexec(&regex, "test", num_matches, matches, 0), error_code_to_check);
regfree(&regex);
// After vertical line
b.clear();
b.append("a|"sv);
b.append(ch);
pattern = b.to_deprecated_string();
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), error_code_to_check);
EXPECT_EQ(regexec(&regex, "test", num_matches, matches, 0), error_code_to_check);
regfree(&regex);
// After circumflex
b.clear();
b.append('^');
b.append(ch);
pattern = b.to_deprecated_string();
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), error_code_to_check);
EXPECT_EQ(regexec(&regex, "test", num_matches, matches, 0), error_code_to_check);
regfree(&regex);
// After dollar
b.clear();
b.append('$');
b.append(ch);
pattern = b.to_deprecated_string();
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), error_code_to_check);
EXPECT_EQ(regexec(&regex, "test", num_matches, matches, 0), error_code_to_check);
regfree(&regex);
// After left parens
b.clear();
b.append('(');
b.append(ch);
b.append(')');
pattern = b.to_deprecated_string();
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), error_code_to_check);
EXPECT_EQ(regexec(&regex, "test", num_matches, matches, 0), error_code_to_check);
regfree(&regex);
}
}
TEST_CASE(parser_error_vertical_line_used_at_wrong_place)
{
DeprecatedString pattern;
regex_t regex;
static constexpr int num_matches { 5 };
regmatch_t matches[num_matches];
// First in ere
pattern = "|asdf";
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_EMPTY_EXPR);
EXPECT_EQ(regexec(&regex, "test", num_matches, matches, 0), REG_EMPTY_EXPR);
regfree(&regex);
// Last in ere
pattern = "asdf|";
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_EMPTY_EXPR);
EXPECT_EQ(regexec(&regex, "test", num_matches, matches, 0), REG_EMPTY_EXPR);
regfree(&regex);
// After left parens
pattern = "(|asdf)";
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_EMPTY_EXPR);
EXPECT_EQ(regexec(&regex, "test", num_matches, matches, 0), REG_EMPTY_EXPR);
regfree(&regex);
// Proceed right parens
pattern = "(asdf)|";
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_EMPTY_EXPR);
EXPECT_EQ(regexec(&regex, "test", num_matches, matches, 0), REG_EMPTY_EXPR);
regfree(&regex);
}
TEST_CASE(parens_qualifier_questionmark)
{
DeprecatedString pattern = "test(hello)?test";
regex_t regex;
static constexpr int num_matches { 5 };
regmatch_t matches[num_matches];
char const* match_str;
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR);
match_str = "testtest";
EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 1);
EXPECT_EQ(matches[0].rm_so, 0);
EXPECT_EQ(matches[0].rm_eo, 8);
EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "testtest");
match_str = "testhellotest";
EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 1);
EXPECT_EQ(matches[0].rm_so, 0);
EXPECT_EQ(matches[0].rm_eo, 13);
EXPECT_EQ(matches[1].rm_so, 4);
EXPECT_EQ(matches[1].rm_eo, 9);
EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "testhellotest");
EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "hello");
regfree(&regex);
}
TEST_CASE(parens_qualifier_asterisk)
{
DeprecatedString pattern = "test(hello)*test";
regex_t regex;
static constexpr int num_matches { 6 };
regmatch_t matches[num_matches];
char const* match_str;
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR);
match_str = "testtest";
EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 1);
EXPECT_EQ(matches[0].rm_so, 0);
EXPECT_EQ(matches[0].rm_eo, 8);
EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "testtest");
match_str = "testhellohellotest";
EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 1);
EXPECT_EQ(matches[0].rm_so, 0);
EXPECT_EQ(matches[0].rm_eo, 18);
EXPECT_EQ(matches[1].rm_so, 9);
EXPECT_EQ(matches[1].rm_eo, 14);
EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "testhellohellotest");
EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "hello");
match_str = "testhellohellotest, testhellotest";
EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, REG_GLOBAL), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 2);
EXPECT_EQ(matches[0].rm_so, 0);
EXPECT_EQ(matches[0].rm_eo, 18);
EXPECT_EQ(matches[1].rm_so, 9);
EXPECT_EQ(matches[1].rm_eo, 14);
EXPECT_EQ(matches[2].rm_so, 20);
EXPECT_EQ(matches[2].rm_eo, 33);
EXPECT_EQ(matches[3].rm_so, 24);
EXPECT_EQ(matches[3].rm_eo, 29);
EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "testhellohellotest");
EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "hello");
EXPECT_EQ(StringView(&match_str[matches[2].rm_so], matches[2].rm_eo - matches[2].rm_so), "testhellotest");
EXPECT_EQ(StringView(&match_str[matches[3].rm_so], matches[3].rm_eo - matches[3].rm_so), "hello");
regfree(&regex);
}
TEST_CASE(parens_qualifier_asterisk_2)
{
DeprecatedString pattern = "test(.*)test";
regex_t regex;
static constexpr int num_matches { 6 };
regmatch_t matches[num_matches];
char const* match_str;
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR);
match_str = "testasdftest";
EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 1);
EXPECT_EQ(matches[0].rm_so, 0);
EXPECT_EQ(matches[0].rm_eo, 12);
EXPECT_EQ(matches[1].rm_so, 4);
EXPECT_EQ(matches[1].rm_eo, 8);
EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "testasdftest");
EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "asdf");
match_str = "testasdfasdftest";
EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 1);
EXPECT_EQ(matches[0].rm_so, 0);
EXPECT_EQ(matches[0].rm_eo, 16);
EXPECT_EQ(matches[1].rm_so, 4);
EXPECT_EQ(matches[1].rm_eo, 12);
EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "testasdfasdftest");
EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "asdfasdf");
match_str = "testaaaatest, testbbbtest, testtest";
EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, REG_GLOBAL), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 1);
EXPECT_EQ(matches[0].rm_so, 0);
EXPECT_EQ(matches[0].rm_eo, 35);
EXPECT_EQ(matches[1].rm_so, 4);
EXPECT_EQ(matches[1].rm_eo, 31);
EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "testaaaatest, testbbbtest, testtest");
EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "aaaatest, testbbbtest, test");
regfree(&regex);
}
TEST_CASE(mulit_parens_qualifier_too_less_result_values)
{
DeprecatedString pattern = "test(a)?(b)?(c)?test";
regex_t regex;
static constexpr int num_matches { 4 };
regmatch_t matches[num_matches];
char const* match_str;
matches[3] = { -2, -2, 100 };
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR);
match_str = "testabtest";
EXPECT_EQ(regexec(&regex, match_str, num_matches - 1, matches, 0), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 1);
EXPECT_EQ(matches[0].rm_so, 0);
EXPECT_EQ(matches[0].rm_eo, 10);
EXPECT_EQ(matches[1].rm_so, 4);
EXPECT_EQ(matches[1].rm_eo, 5);
EXPECT_EQ(matches[2].rm_so, 5);
EXPECT_EQ(matches[2].rm_eo, 6);
EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "testabtest");
EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "a");
EXPECT_EQ(StringView(&match_str[matches[2].rm_so], matches[2].rm_eo - matches[2].rm_so), "b");
EXPECT_EQ(matches[3].rm_so, -2);
EXPECT_EQ(matches[3].rm_eo, -2);
EXPECT_EQ(matches[3].rm_cnt, 100);
match_str = "testabctest";
EXPECT_EQ(regexec(&regex, match_str, num_matches - 1, matches, 0), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 1);
EXPECT_EQ(matches[0].rm_so, 0);
EXPECT_EQ(matches[0].rm_eo, 11);
EXPECT_EQ(matches[1].rm_so, 4);
EXPECT_EQ(matches[1].rm_eo, 5);
EXPECT_EQ(matches[2].rm_so, 5);
EXPECT_EQ(matches[2].rm_eo, 6);
EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "testabctest");
EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "a");
EXPECT_EQ(StringView(&match_str[matches[2].rm_so], matches[2].rm_eo - matches[2].rm_so), "b");
EXPECT_EQ(matches[3].rm_so, -2);
EXPECT_EQ(matches[3].rm_eo, -2);
EXPECT_EQ(matches[3].rm_cnt, 100);
match_str = "testabctest, testabctest";
EXPECT_EQ(regexec(&regex, match_str, num_matches - 1, matches, REG_GLOBAL), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 2);
EXPECT_EQ(matches[0].rm_so, 0);
EXPECT_EQ(matches[0].rm_eo, 11);
EXPECT_EQ(matches[1].rm_so, 4);
EXPECT_EQ(matches[1].rm_eo, 5);
EXPECT_EQ(matches[2].rm_so, 5);
EXPECT_EQ(matches[2].rm_eo, 6);
EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "testabctest");
EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "a");
EXPECT_EQ(StringView(&match_str[matches[2].rm_so], matches[2].rm_eo - matches[2].rm_so), "b");
EXPECT_EQ(matches[3].rm_so, -2);
EXPECT_EQ(matches[3].rm_eo, -2);
EXPECT_EQ(matches[3].rm_cnt, 100);
regfree(&regex);
}
TEST_CASE(multi_parens_qualifier_questionmark)
{
DeprecatedString pattern = "test(a)?(b)?(c)?test";
regex_t regex;
static constexpr int num_matches { 8 };
regmatch_t matches[num_matches];
char const* match_str;
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR);
match_str = "testtest";
EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 1);
EXPECT_EQ(matches[0].rm_so, 0);
EXPECT_EQ(matches[0].rm_eo, 8);
EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "testtest");
match_str = "testabctest";
EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 1);
EXPECT_EQ(matches[0].rm_so, 0);
EXPECT_EQ(matches[0].rm_eo, 11);
EXPECT_EQ(matches[1].rm_so, 4);
EXPECT_EQ(matches[1].rm_eo, 5);
EXPECT_EQ(matches[2].rm_so, 5);
EXPECT_EQ(matches[2].rm_eo, 6);
EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "testabctest");
EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "a");
EXPECT_EQ(StringView(&match_str[matches[2].rm_so], matches[2].rm_eo - matches[2].rm_so), "b");
match_str = "testabctest, testactest";
EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, REG_GLOBAL), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 2);
EXPECT_EQ(matches[0].rm_so, 0);
EXPECT_EQ(matches[0].rm_eo, 11);
EXPECT_EQ(matches[1].rm_so, 4);
EXPECT_EQ(matches[1].rm_eo, 5);
EXPECT_EQ(matches[2].rm_so, 5);
EXPECT_EQ(matches[2].rm_eo, 6);
EXPECT_EQ(matches[3].rm_so, 6);
EXPECT_EQ(matches[3].rm_eo, 7);
EXPECT_EQ(matches[4].rm_so, 13);
EXPECT_EQ(matches[4].rm_eo, 23);
EXPECT_EQ(matches[5].rm_so, 17);
EXPECT_EQ(matches[5].rm_eo, 18);
EXPECT_EQ(matches[6].rm_so, -1);
EXPECT_EQ(matches[6].rm_eo, -1);
EXPECT_EQ(matches[7].rm_so, 18);
EXPECT_EQ(matches[7].rm_eo, 19);
EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "testabctest");
EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "a");
EXPECT_EQ(StringView(&match_str[matches[2].rm_so], matches[2].rm_eo - matches[2].rm_so), "b");
EXPECT_EQ(StringView(&match_str[matches[3].rm_so], matches[3].rm_eo - matches[3].rm_so), "c");
EXPECT_EQ(StringView(&match_str[matches[4].rm_so], matches[4].rm_eo - matches[4].rm_so), "testactest");
EXPECT_EQ(StringView(&match_str[matches[5].rm_so], matches[5].rm_eo - matches[5].rm_so), "a");
EXPECT_EQ(StringView(&match_str[matches[6].rm_so], matches[6].rm_eo - matches[6].rm_so), "");
EXPECT_EQ(StringView(&match_str[matches[7].rm_so], matches[7].rm_eo - matches[7].rm_so), "c");
regfree(&regex);
}
TEST_CASE(simple_alternative)
{
DeprecatedString pattern = "test|hello|friends";
regex_t regex;
static constexpr int num_matches { 1 };
regmatch_t matches[num_matches];
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR);
EXPECT_EQ(regexec(&regex, "test", num_matches, matches, 0), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 1);
EXPECT_EQ(matches[0].rm_so, 0);
EXPECT_EQ(matches[0].rm_eo, 4);
EXPECT_EQ(regexec(&regex, "hello", num_matches, matches, 0), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 1);
EXPECT_EQ(matches[0].rm_so, 0);
EXPECT_EQ(matches[0].rm_eo, 5);
EXPECT_EQ(regexec(&regex, "friends", num_matches, matches, 0), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 1);
EXPECT_EQ(matches[0].rm_so, 0);
EXPECT_EQ(matches[0].rm_eo, 7);
regfree(&regex);
}
TEST_CASE(alternative_match_groups)
{
DeprecatedString pattern = "test(a)?(b)?|hello ?(dear|my)? friends";
regex_t regex;
static constexpr int num_matches { 8 };
regmatch_t matches[num_matches];
char const* match_str;
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR);
match_str = "test";
EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 1);
EXPECT_EQ(matches[0].rm_so, 0);
EXPECT_EQ(matches[0].rm_eo, 4);
EXPECT_EQ(matches[1].rm_so, -1);
EXPECT_EQ(matches[1].rm_eo, -1);
EXPECT_EQ(matches[2].rm_so, -1);
EXPECT_EQ(matches[2].rm_eo, -1);
EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "test");
EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "");
EXPECT_EQ(StringView(&match_str[matches[2].rm_so], matches[2].rm_eo - matches[2].rm_so), "");
match_str = "testa";
EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 1);
EXPECT_EQ(matches[0].rm_so, 0);
EXPECT_EQ(matches[0].rm_eo, 5);
EXPECT_EQ(matches[1].rm_so, 4);
EXPECT_EQ(matches[1].rm_eo, 5);
EXPECT_EQ(matches[2].rm_so, -1);
EXPECT_EQ(matches[2].rm_eo, -1);
EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "testa");
EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "a");
EXPECT_EQ(StringView(&match_str[matches[2].rm_so], matches[2].rm_eo - matches[2].rm_so), "");
match_str = "testb";
EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 1);
EXPECT_EQ(matches[0].rm_so, 0);
EXPECT_EQ(matches[0].rm_eo, 5);
EXPECT_EQ(matches[1].rm_so, -1);
EXPECT_EQ(matches[1].rm_eo, -1);
EXPECT_EQ(matches[2].rm_so, 4);
EXPECT_EQ(matches[2].rm_eo, 5);
EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "testb");
EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "");
EXPECT_EQ(StringView(&match_str[matches[2].rm_so], matches[2].rm_eo - matches[2].rm_so), "b");
match_str = "hello friends";
EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 1);
EXPECT_EQ(matches[0].rm_so, 0);
EXPECT_EQ(matches[0].rm_eo, 13);
EXPECT_EQ(matches[1].rm_so, -1);
EXPECT_EQ(matches[1].rm_eo, -1);
EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "hello friends");
EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "");
match_str = "hello dear friends";
EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 1);
EXPECT_EQ(matches[0].rm_so, 0);
EXPECT_EQ(matches[0].rm_eo, 18);
EXPECT_EQ(matches[1].rm_so, -1);
EXPECT_EQ(matches[1].rm_eo, -1);
EXPECT_EQ(matches[2].rm_so, -1);
EXPECT_EQ(matches[2].rm_eo, -1);
EXPECT_EQ(matches[3].rm_so, 6);
EXPECT_EQ(matches[3].rm_eo, 10);
EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "hello dear friends");
EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "");
EXPECT_EQ(StringView(&match_str[matches[2].rm_so], matches[2].rm_eo - matches[2].rm_so), "");
EXPECT_EQ(StringView(&match_str[matches[3].rm_so], matches[3].rm_eo - matches[3].rm_so), "dear");
match_str = "hello my friends";
EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 1);
EXPECT_EQ(matches[0].rm_so, 0);
EXPECT_EQ(matches[0].rm_eo, 16);
EXPECT_EQ(matches[1].rm_so, -1);
EXPECT_EQ(matches[1].rm_eo, -1);
EXPECT_EQ(matches[2].rm_so, -1);
EXPECT_EQ(matches[2].rm_eo, -1);
EXPECT_EQ(matches[3].rm_so, 6);
EXPECT_EQ(matches[3].rm_eo, 8);
EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "hello my friends");
EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "");
EXPECT_EQ(StringView(&match_str[matches[2].rm_so], matches[2].rm_eo - matches[2].rm_so), "");
EXPECT_EQ(StringView(&match_str[matches[3].rm_so], matches[3].rm_eo - matches[3].rm_so), "my");
match_str = "testabc";
EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOMATCH);
EXPECT_EQ(matches[0].rm_cnt, 0);
EXPECT_EQ(matches[0].rm_so, -1);
EXPECT_EQ(matches[0].rm_eo, -1);
match_str = "hello test friends";
EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOMATCH);
EXPECT_EQ(matches[0].rm_cnt, 0);
EXPECT_EQ(matches[0].rm_so, -1);
EXPECT_EQ(matches[0].rm_eo, -1);
regfree(&regex);
}
TEST_CASE(parens_qualifier_exact)
{
DeprecatedString pattern = "(hello){3}";
regex_t regex;
static constexpr int num_matches { 5 };
regmatch_t matches[num_matches];
char const* match_str;
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR);
match_str = "hello";
EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOMATCH);
EXPECT_EQ(matches[0].rm_cnt, 0);
match_str = "hellohellohello";
EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 1);
EXPECT_EQ(matches[0].rm_so, 0);
EXPECT_EQ(matches[0].rm_eo, 15);
EXPECT_EQ(matches[1].rm_so, 10);
EXPECT_EQ(matches[1].rm_eo, 15);
EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "hellohellohello");
EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "hello");
match_str = "hellohellohellohello";
EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, REG_GLOBAL), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 1);
EXPECT_EQ(matches[0].rm_so, 0);
EXPECT_EQ(matches[0].rm_eo, 15);
EXPECT_EQ(matches[1].rm_so, 10);
EXPECT_EQ(matches[1].rm_eo, 15);
EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "hellohellohello");
EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "hello");
match_str = "test hellohellohello";
EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, REG_GLOBAL), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 1);
EXPECT_EQ(matches[0].rm_so, 5);
EXPECT_EQ(matches[0].rm_eo, 20);
EXPECT_EQ(matches[1].rm_so, 15);
EXPECT_EQ(matches[1].rm_eo, 20);
EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "hellohellohello");
EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "hello");
regfree(&regex);
}
TEST_CASE(parens_qualifier_minimum)
{
DeprecatedString pattern = "(hello){3,}";
regex_t regex;
static constexpr int num_matches { 5 };
regmatch_t matches[num_matches];
char const* match_str;
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR);
match_str = "hello";
EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOMATCH);
EXPECT_EQ(matches[0].rm_cnt, 0);
match_str = "hellohellohello";
EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 1);
EXPECT_EQ(matches[0].rm_so, 0);
EXPECT_EQ(matches[0].rm_eo, 15);
EXPECT_EQ(matches[1].rm_so, 10);
EXPECT_EQ(matches[1].rm_eo, 15);
EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "hellohellohello");
EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "hello");
match_str = "hellohellohellohello";
EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, REG_SEARCH), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 1);
EXPECT_EQ(matches[0].rm_so, 0);
EXPECT_EQ(matches[0].rm_eo, 20);
EXPECT_EQ(matches[1].rm_so, 15);
EXPECT_EQ(matches[1].rm_eo, 20);
EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "hellohellohellohello");
EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "hello");
match_str = "test hellohellohello";
EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, REG_GLOBAL), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 1);
EXPECT_EQ(matches[0].rm_so, 5);
EXPECT_EQ(matches[0].rm_eo, 20);
EXPECT_EQ(matches[1].rm_so, 15);
EXPECT_EQ(matches[1].rm_eo, 20);
EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "hellohellohello");
EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "hello");
match_str = "test hellohellohellohello";
EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, REG_GLOBAL), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 1);
EXPECT_EQ(matches[0].rm_so, 5);
EXPECT_EQ(matches[0].rm_eo, 25);
EXPECT_EQ(matches[1].rm_so, 20);
EXPECT_EQ(matches[1].rm_eo, 25);
EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "hellohellohellohello");
EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "hello");
regfree(&regex);
}
TEST_CASE(parens_qualifier_maximum)
{
DeprecatedString pattern = "(hello){2,3}";
regex_t regex;
static constexpr int num_matches { 5 };
regmatch_t matches[num_matches];
char const* match_str;
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR);
match_str = "hello";
EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOMATCH);
EXPECT_EQ(matches[0].rm_cnt, 0);
match_str = "hellohellohello";
EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 1);
EXPECT_EQ(matches[0].rm_so, 0);
EXPECT_EQ(matches[0].rm_eo, 15);
EXPECT_EQ(matches[1].rm_so, 10);
EXPECT_EQ(matches[1].rm_eo, 15);
EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "hellohellohello");
EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "hello");
match_str = "hellohellohellohello";
EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, REG_GLOBAL), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 1);
EXPECT_EQ(matches[0].rm_so, 0);
EXPECT_EQ(matches[0].rm_eo, 15);
EXPECT_EQ(matches[1].rm_so, 10);
EXPECT_EQ(matches[1].rm_eo, 15);
EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "hellohellohello");
EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "hello");
match_str = "test hellohellohello";
EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, REG_GLOBAL), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 1);
EXPECT_EQ(matches[0].rm_so, 5);
EXPECT_EQ(matches[0].rm_eo, 20);
EXPECT_EQ(matches[1].rm_so, 15);
EXPECT_EQ(matches[1].rm_eo, 20);
EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "hellohellohello");
EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "hello");
match_str = "test hellohellohellohello";
EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, REG_GLOBAL), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 1);
EXPECT_EQ(matches[0].rm_so, 5);
EXPECT_EQ(matches[0].rm_eo, 20);
EXPECT_EQ(matches[1].rm_so, 15);
EXPECT_EQ(matches[1].rm_eo, 20);
EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "hellohellohello");
EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "hello");
regfree(&regex);
}
TEST_CASE(char_qualifier_min_max)
{
DeprecatedString pattern = "c{3,30}";
regex_t regex;
static constexpr int num_matches { 5 };
regmatch_t matches[num_matches];
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR);
EXPECT_EQ(regexec(&regex, "cc", num_matches, matches, 0), REG_NOMATCH);
EXPECT_EQ(regexec(&regex, "ccc", num_matches, matches, 0), REG_NOERR);
EXPECT_EQ(regexec(&regex, "cccccccccccccccccccccccccccccc", num_matches, matches, 0), REG_NOERR);
EXPECT_EQ(matches[0].rm_cnt, 1);
EXPECT_EQ(regexec(&regex, "ccccccccccccccccccccccccccccccc", num_matches, matches, 0), REG_NOMATCH);
EXPECT_EQ(regexec(&regex, "ccccccccccccccccccccccccccccccc", num_matches, matches, REG_GLOBAL), REG_NOERR);
EXPECT_EQ(regexec(&regex, "cccccccccccccccccccccccccccccccc", num_matches, matches, 0), REG_NOMATCH);
regfree(&regex);
}
TEST_CASE(simple_bracket_chars)
{
DeprecatedString pattern = "[abc]";
regex_t regex;
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR);
EXPECT_EQ(regexec(&regex, "a", 0, NULL, 0), REG_NOERR);
EXPECT_EQ(regexec(&regex, "b", 0, NULL, 0), REG_NOERR);
EXPECT_EQ(regexec(&regex, "c", 0, NULL, 0), REG_NOERR);
EXPECT_EQ(regexec(&regex, "d", 0, NULL, 0), REG_NOMATCH);
EXPECT_EQ(regexec(&regex, "e", 0, NULL, 0), REG_NOMATCH);
regfree(&regex);
}
TEST_CASE(simple_bracket_chars_inverse)
{
DeprecatedString pattern = "[^abc]";
regex_t regex;
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR);
EXPECT_EQ(regexec(&regex, "a", 0, NULL, 0), REG_NOMATCH);
EXPECT_EQ(regexec(&regex, "b", 0, NULL, 0), REG_NOMATCH);
EXPECT_EQ(regexec(&regex, "c", 0, NULL, 0), REG_NOMATCH);
EXPECT_EQ(regexec(&regex, "d", 0, NULL, 0), REG_NOERR);
EXPECT_EQ(regexec(&regex, "e", 0, NULL, 0), REG_NOERR);
regfree(&regex);
}
TEST_CASE(simple_bracket_chars_range)
{
DeprecatedString pattern = "[a-d]";
regex_t regex;
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR);
EXPECT_EQ(regexec(&regex, "a", 0, NULL, 0), REG_NOERR);
EXPECT_EQ(regexec(&regex, "b", 0, NULL, 0), REG_NOERR);
EXPECT_EQ(regexec(&regex, "c", 0, NULL, 0), REG_NOERR);
EXPECT_EQ(regexec(&regex, "d", 0, NULL, 0), REG_NOERR);
EXPECT_EQ(regexec(&regex, "e", 0, NULL, 0), REG_NOMATCH);
regfree(&regex);
}
TEST_CASE(simple_bracket_chars_range_inverse)
{
DeprecatedString pattern = "[^a-df-z]";
regex_t regex;
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR);
EXPECT_EQ(regexec(&regex, "a", 0, NULL, 0), REG_NOMATCH);
EXPECT_EQ(regexec(&regex, "b", 0, NULL, 0), REG_NOMATCH);
EXPECT_EQ(regexec(&regex, "c", 0, NULL, 0), REG_NOMATCH);
EXPECT_EQ(regexec(&regex, "d", 0, NULL, 0), REG_NOMATCH);
EXPECT_EQ(regexec(&regex, "e", 0, NULL, 0), REG_NOERR);
EXPECT_EQ(regexec(&regex, "k", 0, NULL, 0), REG_NOMATCH);
EXPECT_EQ(regexec(&regex, "z", 0, NULL, 0), REG_NOMATCH);
regfree(&regex);
}
TEST_CASE(bracket_character_class_uuid)
{
DeprecatedString pattern = "^([[:xdigit:]]{8})-([[:xdigit:]]{4})-([[:xdigit:]]{4})-([[:xdigit:]]{4})-([[:xdigit:]]{12})$";
regex_t regex;
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR);
EXPECT_EQ(regexec(&regex, "fb9b62a2-1579-4e3a-afba-76239ccb6583", 0, NULL, 0), REG_NOERR);
EXPECT_EQ(regexec(&regex, "fb9b62a2", 0, NULL, 0), REG_NOMATCH);
regfree(&regex);
}
TEST_CASE(simple_bracket_character_class_inverse)
{
DeprecatedString pattern = "[^[:digit:]]";
regex_t regex;
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR);
EXPECT_EQ(regexec(&regex, "1", 0, NULL, 0), REG_NOMATCH);
EXPECT_EQ(regexec(&regex, "2", 0, NULL, 0), REG_NOMATCH);
EXPECT_EQ(regexec(&regex, "3", 0, NULL, 0), REG_NOMATCH);
EXPECT_EQ(regexec(&regex, "d", 0, NULL, 0), REG_NOERR);
EXPECT_EQ(regexec(&regex, "e", 0, NULL, 0), REG_NOERR);
regfree(&regex);
}
TEST_CASE(email_address)
{
DeprecatedString pattern = "^[A-Z0-9a-z._%+-]{1,64}@(?:[A-Za-z0-9-]{1,63}\\.){1,125}[A-Za-z]{2,63}$";
regex_t regex;
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR);
EXPECT_EQ(regexec(&regex, "emanuel.sprung@gmail.com", 0, NULL, 0), REG_NOERR);
EXPECT_EQ(regexec(&regex, "kling@serenityos.org", 0, NULL, 0), REG_NOERR);
regfree(&regex);
}
TEST_CASE(error_message)
{
DeprecatedString pattern = "^[A-Z0-9[a-z._%+-]{1,64}@[A-Za-z0-9-]{1,63}\\.{1,125}[A-Za-z]{2,63}$";
regex_t regex;
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_EBRACK);
EXPECT_EQ(regexec(&regex, "asdf@asdf.com", 0, NULL, 0), REG_EBRACK);
char buf[1024];
size_t buflen = 1024;
auto len = regerror(0, &regex, buf, buflen);
DeprecatedString expected = "Error during parsing of regular expression:\n ^[A-Z0-9[a-z._%+-]{1,64}@[A-Za-z0-9-]{1,63}\\.{1,125}[A-Za-z]{2,63}$\n ^---- [ ] imbalance.";
for (size_t i = 0; i < len; ++i) {
EXPECT_EQ(buf[i], expected[i]);
}
regfree(&regex);
}
TEST_CASE(simple_ignorecase)
{
DeprecatedString pattern = "^hello friends";
regex_t regex;
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED | REG_NOSUB | REG_ICASE), REG_NOERR);
EXPECT_EQ(regexec(&regex, "Hello Friends", 0, NULL, 0), REG_NOERR);
EXPECT_EQ(regexec(&regex, "hello Friends", 0, NULL, 0), REG_NOERR);
EXPECT_EQ(regexec(&regex, "hello Friends!", 0, NULL, 0), REG_NOMATCH);
EXPECT_EQ(regexec(&regex, "hello Friends!", 0, NULL, REG_GLOBAL), REG_NOERR);
EXPECT_EQ(regexec(&regex, "hell Friends", 0, NULL, 0), REG_NOMATCH);
EXPECT_EQ(regexec(&regex, "hell Friends", 0, NULL, REG_GLOBAL), REG_NOMATCH);
regfree(&regex);
}
TEST_CASE(simple_notbol_noteol)
{
DeprecatedString pattern = "^hello friends$";
DeprecatedString pattern2 = "hello friends";
regex_t regex, regex2;
EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED | REG_NOSUB | REG_ICASE), REG_NOERR);
EXPECT_EQ(regcomp(&regex2, pattern2.characters(), REG_EXTENDED | REG_NOSUB | REG_ICASE), REG_NOERR);
EXPECT_EQ(regexec(&regex, "hello friends", 0, NULL, REG_NOTBOL), REG_NOMATCH);
EXPECT_EQ(regexec(&regex, "hello friends", 0, NULL, REG_NOTEOL), REG_NOMATCH);
EXPECT_EQ(regexec(&regex, "hello friends", 0, NULL, REG_NOTBOL | REG_NOTEOL), REG_NOMATCH);
EXPECT_EQ(regexec(&regex, "a hello friends b", 0, NULL, REG_NOTBOL), REG_NOMATCH);
EXPECT_EQ(regexec(&regex, "a hello friends", 0, NULL, REG_NOTBOL), REG_NOMATCH);
EXPECT_EQ(regexec(&regex, "a hello friends", 0, NULL, REG_NOTBOL | REG_SEARCH), REG_NOERR);
EXPECT_EQ(regexec(&regex, "a hello friends b", 0, NULL, REG_NOTBOL | REG_SEARCH), REG_NOERR);
EXPECT_EQ(regexec(&regex, "a hello friends b", 0, NULL, REG_NOTEOL), REG_NOMATCH);
EXPECT_EQ(regexec(&regex, "hello friends b", 0, NULL, REG_NOTEOL), REG_NOMATCH);
EXPECT_EQ(regexec(&regex, "hello friends b", 0, NULL, REG_NOTEOL | REG_SEARCH), REG_NOERR);
EXPECT_EQ(regexec(&regex, "a hello friends b", 0, NULL, REG_NOTEOL | REG_SEARCH), REG_NOMATCH);
EXPECT_EQ(regexec(&regex, "a hello friends b", 0, NULL, REG_NOTBOL | REG_NOTEOL), REG_NOMATCH);
EXPECT_EQ(regexec(&regex, "a hello friends b", 0, NULL, REG_NOTBOL | REG_NOTEOL | REG_SEARCH), REG_NOMATCH);
EXPECT_EQ(regexec(&regex2, "hello friends", 0, NULL, REG_NOTBOL), REG_NOMATCH);
EXPECT_EQ(regexec(&regex2, "hello friends", 0, NULL, REG_NOTEOL), REG_NOMATCH);
regfree(&regex);
regfree(&regex2);
}
TEST_CASE(bre_basic)
{
regex_t regex;
EXPECT_EQ(regcomp(&regex, "hello friends", REG_NOSUB | REG_ICASE), REG_NOERR);
EXPECT_EQ(regexec(&regex, "hello friends", 0, NULL, 0), REG_NOERR);
regfree(&regex);
EXPECT_EQ(regcomp(&regex, "\\(15\\)\\1", REG_NOSUB | REG_ICASE), REG_NOERR);
EXPECT_EQ(regexec(&regex, "1515", 0, NULL, 0), REG_NOERR);
EXPECT_EQ(regexec(&regex, "55", 0, NULL, 0), REG_NOMATCH);
regfree(&regex);
EXPECT_EQ(regcomp(&regex, "15\\{1,2\\}", REG_NOSUB | REG_ICASE), REG_NOERR);
EXPECT_EQ(regexec(&regex, "15", 0, NULL, 0), REG_NOERR);
EXPECT_EQ(regexec(&regex, "1515", 0, NULL, 0), REG_NOMATCH);
EXPECT_EQ(regexec(&regex, "55", 0, NULL, 0), REG_NOMATCH);
regfree(&regex);
EXPECT_EQ(regcomp(&regex, "15{1,2}", REG_NOSUB | REG_ICASE), REG_NOERR);
EXPECT_EQ(regexec(&regex, "15{1,2}", 0, NULL, 0), REG_NOERR);
regfree(&regex);
EXPECT_EQ(regcomp(&regex, "1[56]", REG_NOSUB | REG_ICASE), REG_NOERR);
EXPECT_EQ(regexec(&regex, "15", 0, NULL, 0), REG_NOERR);
EXPECT_EQ(regexec(&regex, "16", 0, NULL, 0), REG_NOERR);
EXPECT_EQ(regexec(&regex, "17", 0, NULL, 0), REG_NOMATCH);
regfree(&regex);
}