diff --git a/Meta/Lagom/CMakeLists.txt b/Meta/Lagom/CMakeLists.txt index 20a8f85ec5d..e744a685fd6 100644 --- a/Meta/Lagom/CMakeLists.txt +++ b/Meta/Lagom/CMakeLists.txt @@ -483,6 +483,7 @@ if (BUILD_TESTING) LibCore LibDNS LibGC + LibRegex LibTest LibTextCodec LibThreading @@ -511,10 +512,6 @@ if (BUILD_TESTING) # LibTLS needs a special working directory to find cacert.pem lagom_test(../../Tests/LibTLS/TestTLSHandshake.cpp LibTLS LIBS LibTLS LibCrypto) lagom_test(../../Tests/LibTLS/TestTLSCertificateParser.cpp LibTLS LIBS LibTLS LibCrypto) - - # RegexLibC test POSIX and contains many Serenity extensions - # It is therefore not reasonable to run it on Lagom, and we only run the Regex test - lagom_test(../../Tests/LibRegex/Regex.cpp LIBS LibRegex WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../../Tests/LibRegex) # JavaScriptTestRunner + LibTest tests # test-js diff --git a/Tests/LibRegex/CMakeLists.txt b/Tests/LibRegex/CMakeLists.txt index 5d7d1f1efe5..cfccc90d8ad 100644 --- a/Tests/LibRegex/CMakeLists.txt +++ b/Tests/LibRegex/CMakeLists.txt @@ -1,6 +1,5 @@ set(TEST_SOURCES - Regex.cpp - RegexLibC.cpp + TestRegex.cpp ) foreach(source IN LISTS TEST_SOURCES) diff --git a/Tests/LibRegex/RegexLibC.cpp b/Tests/LibRegex/RegexLibC.cpp deleted file mode 100644 index ed50912a6d3..00000000000 --- a/Tests/LibRegex/RegexLibC.cpp +++ /dev/null @@ -1,1159 +0,0 @@ -/* - * Copyright (c) 2020, Emanuel Sprung - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#include - -#include -#include -#include -#include - -TEST_CASE(catch_all) -{ - ByteString pattern = "^.*$"; - regex_t regex; - - EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED), REG_NOERR); - EXPECT_EQ(regexec(®ex, "Hello World", 0, NULL, 0), REG_NOERR); - - regfree(®ex); -} - -TEST_CASE(simple_start) -{ - ByteString pattern = "^hello friends"; - regex_t regex; - - EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED), REG_NOERR); - EXPECT_EQ(regexec(®ex, "Hello!", 0, NULL, 0), REG_NOMATCH); - EXPECT_EQ(regexec(®ex, "hello friends", 0, NULL, 0), REG_NOERR); - EXPECT_EQ(regexec(®ex, "Well, hello friends", 0, NULL, 0), REG_NOMATCH); - - regfree(®ex); -} - -TEST_CASE(simple_end) -{ - ByteString pattern = ".*hello\\.\\.\\. there$"; - regex_t regex; - - EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED), REG_NOERR); - EXPECT_EQ(regexec(®ex, "Hallo", 0, NULL, 0), REG_NOMATCH); - EXPECT_EQ(regexec(®ex, "I said fyhello... there", 0, NULL, 0), REG_NOERR); - EXPECT_EQ(regexec(®ex, "ahello... therea", 0, NULL, 0), REG_NOMATCH); - EXPECT_EQ(regexec(®ex, "hello.. there", 0, NULL, 0), REG_NOMATCH); - - regfree(®ex); -} - -TEST_CASE(simple_period) -{ - ByteString pattern = "hello."; - regex_t regex; - - EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED), REG_NOERR); - EXPECT_EQ(regexec(®ex, "Hello1", 0, NULL, 0), REG_NOMATCH); - EXPECT_EQ(regexec(®ex, "hello1", 0, NULL, 0), REG_NOERR); - EXPECT_EQ(regexec(®ex, "hello2", 0, NULL, 0), REG_NOERR); - EXPECT_EQ(regexec(®ex, "hello?", 0, NULL, 0), REG_NOERR); - - regfree(®ex); -} - -TEST_CASE(simple_period_end) -{ - ByteString pattern = "hello.$"; - regex_t regex; - - EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED | REG_NOSUB), REG_NOERR); - EXPECT_EQ(regexec(®ex, "Hello1", 0, NULL, REG_NOSUB), REG_NOMATCH); - EXPECT_EQ(regexec(®ex, "hello1hello1", 0, NULL, REG_GLOBAL), REG_NOERR); - EXPECT_EQ(regexec(®ex, "hello2hell", 0, NULL, REG_GLOBAL), REG_NOMATCH); - EXPECT_EQ(regexec(®ex, "hello?", 0, NULL, REG_NOSUB), REG_NOERR); - - regfree(®ex); -} - -TEST_CASE(simple_escaped) -{ - ByteString pattern = "hello\\."; - regex_t regex; - - EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED), REG_NOERR); - EXPECT_EQ(regexec(®ex, "hello", 0, NULL, 0), REG_NOMATCH); - EXPECT_EQ(regexec(®ex, "hello.", 0, NULL, 0), REG_NOERR); - - regfree(®ex); -} - -TEST_CASE(simple_period2_end) -{ - ByteString pattern = ".*hi... there$"; - regex_t regex; - - EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED), REG_NOERR); - EXPECT_EQ(regexec(®ex, "Hello there", 0, NULL, REG_GLOBAL), REG_NOMATCH); - EXPECT_EQ(regexec(®ex, "I said fyhi... there", 0, NULL, REG_GLOBAL), REG_NOERR); - EXPECT_EQ(regexec(®ex, "....hi... ", 0, NULL, REG_GLOBAL), REG_NOMATCH); - EXPECT_EQ(regexec(®ex, "I said fyhihii there", 0, NULL, REG_GLOBAL), REG_NOERR); - EXPECT_EQ(regexec(®ex, "I said fyhihi there", 0, NULL, REG_GLOBAL), REG_NOMATCH); - - regfree(®ex); -} - -TEST_CASE(simple_plus) -{ - ByteString pattern = "a+"; - regex_t regex; - - EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED | REG_NOSUB), REG_NOERR); - EXPECT_EQ(regexec(®ex, "b", 0, NULL, REG_NOSUB), REG_NOMATCH); - EXPECT_EQ(regexec(®ex, "a", 0, NULL, REG_NOSUB), REG_NOERR); - EXPECT_EQ(regexec(®ex, "aaaaaabbbbb", 0, NULL, REG_GLOBAL), REG_NOERR); - EXPECT_EQ(regexec(®ex, "aaaaaaaaaaa", 0, NULL, REG_GLOBAL), REG_NOERR); - - regfree(®ex); -} - -TEST_CASE(simple_questionmark) -{ - ByteString pattern = "da?d"; - regex_t regex; - - EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED), REG_NOERR); - EXPECT_EQ(regexec(®ex, "a", 0, NULL, REG_GLOBAL), REG_NOMATCH); - EXPECT_EQ(regexec(®ex, "daa", 0, NULL, REG_GLOBAL), REG_NOMATCH); - EXPECT_EQ(regexec(®ex, "ddddd", 0, NULL, REG_GLOBAL), REG_NOERR); - EXPECT_EQ(regexec(®ex, "dd", 0, NULL, REG_GLOBAL), REG_NOERR); - EXPECT_EQ(regexec(®ex, "dad", 0, NULL, REG_GLOBAL), REG_NOERR); - EXPECT_EQ(regexec(®ex, "dada", 0, NULL, REG_GLOBAL), REG_NOERR); - EXPECT_EQ(regexec(®ex, "adadaa", 0, NULL, REG_GLOBAL), REG_NOERR); - - regfree(®ex); -} - -TEST_CASE(simple_questionmark_matchall) -{ - ByteString pattern = "da?d"; - regex_t regex; - static constexpr int num_matches { 5 }; - regmatch_t matches[num_matches]; - - EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED), REG_NOERR); - EXPECT_EQ(regexec(®ex, "a", num_matches, matches, REG_GLOBAL), REG_NOMATCH); - EXPECT_EQ(matches[0].rm_cnt, 0); - EXPECT_EQ(regexec(®ex, "daa", num_matches, matches, REG_GLOBAL), REG_NOMATCH); - EXPECT_EQ(matches[0].rm_cnt, 0); - - EXPECT_EQ(regexec(®ex, "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(®ex, "dd", num_matches, matches, REG_GLOBAL), REG_NOERR); - EXPECT_EQ(matches[0].rm_cnt, 1); - EXPECT_EQ(regexec(®ex, "dad", num_matches, matches, REG_GLOBAL), REG_NOERR); - EXPECT_EQ(matches[0].rm_cnt, 1); - EXPECT_EQ(regexec(®ex, "dada", num_matches, matches, REG_GLOBAL), REG_NOERR); - EXPECT_EQ(matches[0].rm_cnt, 1); - EXPECT_EQ(regexec(®ex, "adadaa", num_matches, matches, REG_GLOBAL), REG_NOERR); - EXPECT_EQ(matches[0].rm_cnt, 1); - - regfree(®ex); -} - -TEST_CASE(character_class) -{ - ByteString pattern = "[[:alpha:]]"; - regex_t regex; - static constexpr int num_matches { 5 }; - regmatch_t matches[num_matches]; - - ByteString haystack = "[Window]\nOpacity=255\nAudibleBeep=0\n"; - EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED), REG_NOERR); - EXPECT_EQ(regexec(®ex, haystack.characters(), num_matches, matches, 0), REG_NOMATCH); - EXPECT_EQ(matches[0].rm_cnt, 0); - EXPECT_EQ(regexec(®ex, 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(®ex); -} - -TEST_CASE(character_class2) -{ - ByteString pattern = "[[:alpha:]]*=([[:digit:]]*)|\\[(.*)\\]"; - regex_t regex; - static constexpr int num_matches { 9 }; - regmatch_t matches[num_matches]; - - ByteString haystack = "[Window]\nOpacity=255\nAudibleBeep=0\n"; - EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED | REG_NEWLINE), REG_NOERR); - EXPECT_EQ(regexec(®ex, 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_byte_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(®ex); -} - -TEST_CASE(escaped_char_questionmark) -{ - ByteString pattern = "This\\.?And\\.?That"; - regex_t regex; - - EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED), REG_NOERR); - EXPECT_EQ(regexec(®ex, "ThisAndThat", 0, NULL, 0), REG_NOERR); - EXPECT_EQ(regexec(®ex, "This.And.That", 0, NULL, 0), REG_NOERR); - EXPECT_EQ(regexec(®ex, "This And That", 0, NULL, 0), REG_NOMATCH); - EXPECT_EQ(regexec(®ex, "This..And..That", 0, NULL, 0), REG_NOMATCH); - - regfree(®ex); -} - -TEST_CASE(char_qualifier_asterisk) -{ - ByteString pattern = "regex*"; - regex_t regex; - static constexpr int num_matches { 5 }; - regmatch_t matches[num_matches]; - - EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED), REG_NOERR); - EXPECT_EQ(regexec(®ex, "#include ", num_matches, matches, REG_GLOBAL), REG_NOERR); - EXPECT_EQ(matches[0].rm_cnt, 1); - - regfree(®ex); -} - -TEST_CASE(char_utf8) -{ - ByteString pattern = "😀"; - regex_t regex; - static constexpr int num_matches { 5 }; - regmatch_t matches[num_matches]; - - EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED), REG_NOERR); - EXPECT_EQ(regexec(®ex, "Привет, мир! 😀 γειά σου κόσμος 😀 こんにちは世界", num_matches, matches, REG_GLOBAL), REG_NOERR); - EXPECT_EQ(matches[0].rm_cnt, 2); - - regfree(®ex); -} - -TEST_CASE(parens) -{ - ByteString pattern = "test(hello)test"; - regex_t regex; - static constexpr int num_matches { 5 }; - regmatch_t matches[num_matches]; - - EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED), REG_NOERR); - - EXPECT_EQ(regexec(®ex, "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(®ex); -} - -TEST_CASE(parser_error_parens) -{ - ByteString pattern = "test()test"; - regex_t regex; - static constexpr int num_matches { 5 }; - regmatch_t matches[num_matches]; - - EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED), REG_EMPTY_EXPR); - EXPECT_EQ(regexec(®ex, "testhellotest", num_matches, matches, 0), REG_EMPTY_EXPR); - - regfree(®ex); -} - -TEST_CASE(parser_error_special_characters_used_at_wrong_place) -{ - ByteString pattern; - regex_t regex; - static constexpr int num_matches { 5 }; - regmatch_t matches[num_matches]; - - Vector 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_byte_string(); - EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED), error_code_to_check); - EXPECT_EQ(regexec(®ex, "test", num_matches, matches, 0), error_code_to_check); - regfree(®ex); - - // After vertical line - b.clear(); - b.append("a|"sv); - b.append(ch); - pattern = b.to_byte_string(); - EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED), error_code_to_check); - EXPECT_EQ(regexec(®ex, "test", num_matches, matches, 0), error_code_to_check); - regfree(®ex); - - // After circumflex - b.clear(); - b.append('^'); - b.append(ch); - pattern = b.to_byte_string(); - EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED), error_code_to_check); - EXPECT_EQ(regexec(®ex, "test", num_matches, matches, 0), error_code_to_check); - regfree(®ex); - - // After dollar - b.clear(); - b.append('$'); - b.append(ch); - pattern = b.to_byte_string(); - EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED), error_code_to_check); - EXPECT_EQ(regexec(®ex, "test", num_matches, matches, 0), error_code_to_check); - regfree(®ex); - - // After left parens - b.clear(); - b.append('('); - b.append(ch); - b.append(')'); - pattern = b.to_byte_string(); - EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED), error_code_to_check); - EXPECT_EQ(regexec(®ex, "test", num_matches, matches, 0), error_code_to_check); - regfree(®ex); - } -} - -TEST_CASE(parser_error_vertical_line_used_at_wrong_place) -{ - ByteString pattern; - regex_t regex; - static constexpr int num_matches { 5 }; - regmatch_t matches[num_matches]; - - // First in ere - pattern = "|asdf"; - EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED), REG_EMPTY_EXPR); - EXPECT_EQ(regexec(®ex, "test", num_matches, matches, 0), REG_EMPTY_EXPR); - regfree(®ex); - - // Last in ere - pattern = "asdf|"; - EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED), REG_EMPTY_EXPR); - EXPECT_EQ(regexec(®ex, "test", num_matches, matches, 0), REG_EMPTY_EXPR); - regfree(®ex); - - // After left parens - pattern = "(|asdf)"; - EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED), REG_EMPTY_EXPR); - EXPECT_EQ(regexec(®ex, "test", num_matches, matches, 0), REG_EMPTY_EXPR); - regfree(®ex); - - // Proceed right parens - pattern = "(asdf)|"; - EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED), REG_EMPTY_EXPR); - EXPECT_EQ(regexec(®ex, "test", num_matches, matches, 0), REG_EMPTY_EXPR); - regfree(®ex); -} - -TEST_CASE(parens_qualifier_questionmark) -{ - ByteString 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(®ex, pattern.characters(), REG_EXTENDED), REG_NOERR); - - match_str = "testtest"; - EXPECT_EQ(regexec(®ex, 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(®ex, 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(®ex); -} - -TEST_CASE(parens_qualifier_asterisk) -{ - ByteString 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(®ex, pattern.characters(), REG_EXTENDED), REG_NOERR); - - match_str = "testtest"; - EXPECT_EQ(regexec(®ex, 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(®ex, 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(®ex, 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(®ex); -} - -TEST_CASE(parens_qualifier_asterisk_2) -{ - ByteString pattern = "test(.*)test"; - regex_t regex; - static constexpr int num_matches { 6 }; - regmatch_t matches[num_matches]; - char const* match_str; - - EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED), REG_NOERR); - - match_str = "testasdftest"; - EXPECT_EQ(regexec(®ex, 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(®ex, 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(®ex, 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(®ex); -} - -TEST_CASE(mulit_parens_qualifier_too_less_result_values) -{ - ByteString 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(®ex, pattern.characters(), REG_EXTENDED), REG_NOERR); - - match_str = "testabtest"; - EXPECT_EQ(regexec(®ex, 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(®ex, 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(®ex, 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(®ex); -} - -TEST_CASE(multi_parens_qualifier_questionmark) -{ - ByteString 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(®ex, pattern.characters(), REG_EXTENDED), REG_NOERR); - - match_str = "testtest"; - EXPECT_EQ(regexec(®ex, 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(®ex, 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(®ex, 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(®ex); -} - -TEST_CASE(simple_alternative) -{ - ByteString pattern = "test|hello|friends"; - regex_t regex; - static constexpr int num_matches { 1 }; - regmatch_t matches[num_matches]; - - EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED), REG_NOERR); - - EXPECT_EQ(regexec(®ex, "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(®ex, "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(®ex, "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(®ex); -} - -TEST_CASE(alternative_match_groups) -{ - ByteString 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(®ex, pattern.characters(), REG_EXTENDED), REG_NOERR); - - match_str = "test"; - EXPECT_EQ(regexec(®ex, 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(®ex, 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(®ex, 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(®ex, 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(®ex, 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(®ex, 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(®ex, 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(®ex, 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(®ex); -} - -TEST_CASE(parens_qualifier_exact) -{ - ByteString pattern = "(hello){3}"; - regex_t regex; - static constexpr int num_matches { 5 }; - regmatch_t matches[num_matches]; - char const* match_str; - - EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED), REG_NOERR); - - match_str = "hello"; - EXPECT_EQ(regexec(®ex, match_str, num_matches, matches, 0), REG_NOMATCH); - EXPECT_EQ(matches[0].rm_cnt, 0); - - match_str = "hellohellohello"; - EXPECT_EQ(regexec(®ex, 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(®ex, 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(®ex, 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(®ex); -} - -TEST_CASE(parens_qualifier_minimum) -{ - ByteString pattern = "(hello){3,}"; - regex_t regex; - static constexpr int num_matches { 5 }; - regmatch_t matches[num_matches]; - char const* match_str; - - EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED), REG_NOERR); - - match_str = "hello"; - EXPECT_EQ(regexec(®ex, match_str, num_matches, matches, 0), REG_NOMATCH); - EXPECT_EQ(matches[0].rm_cnt, 0); - - match_str = "hellohellohello"; - EXPECT_EQ(regexec(®ex, 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(®ex, 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(®ex, 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(®ex, 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(®ex); -} - -TEST_CASE(parens_qualifier_maximum) -{ - ByteString 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(®ex, pattern.characters(), REG_EXTENDED), REG_NOERR); - - match_str = "hello"; - EXPECT_EQ(regexec(®ex, match_str, num_matches, matches, 0), REG_NOMATCH); - EXPECT_EQ(matches[0].rm_cnt, 0); - - match_str = "hellohellohello"; - EXPECT_EQ(regexec(®ex, 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(®ex, 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(®ex, 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(®ex, 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(®ex); -} - -TEST_CASE(char_qualifier_min_max) -{ - ByteString pattern = "c{3,30}"; - regex_t regex; - static constexpr int num_matches { 5 }; - regmatch_t matches[num_matches]; - - EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED), REG_NOERR); - - EXPECT_EQ(regexec(®ex, "cc", num_matches, matches, 0), REG_NOMATCH); - EXPECT_EQ(regexec(®ex, "ccc", num_matches, matches, 0), REG_NOERR); - EXPECT_EQ(regexec(®ex, "cccccccccccccccccccccccccccccc", num_matches, matches, 0), REG_NOERR); - EXPECT_EQ(matches[0].rm_cnt, 1); - EXPECT_EQ(regexec(®ex, "ccccccccccccccccccccccccccccccc", num_matches, matches, 0), REG_NOMATCH); - EXPECT_EQ(regexec(®ex, "ccccccccccccccccccccccccccccccc", num_matches, matches, REG_GLOBAL), REG_NOERR); - EXPECT_EQ(regexec(®ex, "cccccccccccccccccccccccccccccccc", num_matches, matches, 0), REG_NOMATCH); - - regfree(®ex); -} - -TEST_CASE(simple_bracket_chars) -{ - ByteString pattern = "[abc]"; - regex_t regex; - - EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED), REG_NOERR); - EXPECT_EQ(regexec(®ex, "a", 0, NULL, 0), REG_NOERR); - EXPECT_EQ(regexec(®ex, "b", 0, NULL, 0), REG_NOERR); - EXPECT_EQ(regexec(®ex, "c", 0, NULL, 0), REG_NOERR); - EXPECT_EQ(regexec(®ex, "d", 0, NULL, 0), REG_NOMATCH); - EXPECT_EQ(regexec(®ex, "e", 0, NULL, 0), REG_NOMATCH); - regfree(®ex); -} - -TEST_CASE(simple_bracket_chars_inverse) -{ - ByteString pattern = "[^abc]"; - regex_t regex; - - EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED), REG_NOERR); - EXPECT_EQ(regexec(®ex, "a", 0, NULL, 0), REG_NOMATCH); - EXPECT_EQ(regexec(®ex, "b", 0, NULL, 0), REG_NOMATCH); - EXPECT_EQ(regexec(®ex, "c", 0, NULL, 0), REG_NOMATCH); - EXPECT_EQ(regexec(®ex, "d", 0, NULL, 0), REG_NOERR); - EXPECT_EQ(regexec(®ex, "e", 0, NULL, 0), REG_NOERR); - regfree(®ex); -} - -TEST_CASE(simple_bracket_chars_range) -{ - ByteString pattern = "[a-d]"; - regex_t regex; - - EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED), REG_NOERR); - EXPECT_EQ(regexec(®ex, "a", 0, NULL, 0), REG_NOERR); - EXPECT_EQ(regexec(®ex, "b", 0, NULL, 0), REG_NOERR); - EXPECT_EQ(regexec(®ex, "c", 0, NULL, 0), REG_NOERR); - EXPECT_EQ(regexec(®ex, "d", 0, NULL, 0), REG_NOERR); - EXPECT_EQ(regexec(®ex, "e", 0, NULL, 0), REG_NOMATCH); - regfree(®ex); -} - -TEST_CASE(simple_bracket_chars_range_inverse) -{ - ByteString pattern = "[^a-df-z]"; - regex_t regex; - - EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED), REG_NOERR); - EXPECT_EQ(regexec(®ex, "a", 0, NULL, 0), REG_NOMATCH); - EXPECT_EQ(regexec(®ex, "b", 0, NULL, 0), REG_NOMATCH); - EXPECT_EQ(regexec(®ex, "c", 0, NULL, 0), REG_NOMATCH); - EXPECT_EQ(regexec(®ex, "d", 0, NULL, 0), REG_NOMATCH); - EXPECT_EQ(regexec(®ex, "e", 0, NULL, 0), REG_NOERR); - EXPECT_EQ(regexec(®ex, "k", 0, NULL, 0), REG_NOMATCH); - EXPECT_EQ(regexec(®ex, "z", 0, NULL, 0), REG_NOMATCH); - regfree(®ex); -} - -TEST_CASE(bracket_character_class_uuid) -{ - ByteString pattern = "^([[:xdigit:]]{8})-([[:xdigit:]]{4})-([[:xdigit:]]{4})-([[:xdigit:]]{4})-([[:xdigit:]]{12})$"; - regex_t regex; - - EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED), REG_NOERR); - EXPECT_EQ(regexec(®ex, "fb9b62a2-1579-4e3a-afba-76239ccb6583", 0, NULL, 0), REG_NOERR); - EXPECT_EQ(regexec(®ex, "fb9b62a2", 0, NULL, 0), REG_NOMATCH); - - regfree(®ex); -} - -TEST_CASE(simple_bracket_character_class_inverse) -{ - ByteString pattern = "[^[:digit:]]"; - regex_t regex; - - EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED), REG_NOERR); - EXPECT_EQ(regexec(®ex, "1", 0, NULL, 0), REG_NOMATCH); - EXPECT_EQ(regexec(®ex, "2", 0, NULL, 0), REG_NOMATCH); - EXPECT_EQ(regexec(®ex, "3", 0, NULL, 0), REG_NOMATCH); - EXPECT_EQ(regexec(®ex, "d", 0, NULL, 0), REG_NOERR); - EXPECT_EQ(regexec(®ex, "e", 0, NULL, 0), REG_NOERR); - regfree(®ex); -} - -TEST_CASE(email_address) -{ - ByteString 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(®ex, pattern.characters(), REG_EXTENDED), REG_NOERR); - EXPECT_EQ(regexec(®ex, "emanuel.sprung@gmail.com", 0, NULL, 0), REG_NOERR); - EXPECT_EQ(regexec(®ex, "andreas@ladybird.org", 0, NULL, 0), REG_NOERR); - - regfree(®ex); -} - -TEST_CASE(error_message) -{ - ByteString 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(®ex, pattern.characters(), REG_EXTENDED), REG_EBRACK); - EXPECT_EQ(regexec(®ex, "asdf@asdf.com", 0, NULL, 0), REG_EBRACK); - char buf[1024]; - size_t buflen = 1024; - auto len = regerror(0, ®ex, buf, buflen); - ByteString 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(®ex); -} - -TEST_CASE(simple_ignorecase) -{ - ByteString pattern = "^hello friends"; - regex_t regex; - - EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED | REG_NOSUB | REG_ICASE), REG_NOERR); - EXPECT_EQ(regexec(®ex, "Hello Friends", 0, NULL, 0), REG_NOERR); - EXPECT_EQ(regexec(®ex, "hello Friends", 0, NULL, 0), REG_NOERR); - - EXPECT_EQ(regexec(®ex, "hello Friends!", 0, NULL, 0), REG_NOMATCH); - EXPECT_EQ(regexec(®ex, "hello Friends!", 0, NULL, REG_GLOBAL), REG_NOERR); - - EXPECT_EQ(regexec(®ex, "hell Friends", 0, NULL, 0), REG_NOMATCH); - EXPECT_EQ(regexec(®ex, "hell Friends", 0, NULL, REG_GLOBAL), REG_NOMATCH); - - regfree(®ex); -} - -TEST_CASE(simple_notbol_noteol) -{ - ByteString pattern = "^hello friends$"; - ByteString pattern2 = "hello friends"; - regex_t regex, regex2; - - EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED | REG_NOSUB | REG_ICASE), REG_NOERR); - EXPECT_EQ(regcomp(®ex2, pattern2.characters(), REG_EXTENDED | REG_NOSUB | REG_ICASE), REG_NOERR); - - EXPECT_EQ(regexec(®ex, "hello friends", 0, NULL, REG_NOTBOL), REG_NOMATCH); - EXPECT_EQ(regexec(®ex, "hello friends", 0, NULL, REG_NOTEOL), REG_NOMATCH); - EXPECT_EQ(regexec(®ex, "hello friends", 0, NULL, REG_NOTBOL | REG_NOTEOL), REG_NOMATCH); - - EXPECT_EQ(regexec(®ex, "a hello friends b", 0, NULL, REG_NOTBOL), REG_NOMATCH); - EXPECT_EQ(regexec(®ex, "a hello friends", 0, NULL, REG_NOTBOL), REG_NOMATCH); - EXPECT_EQ(regexec(®ex, "a hello friends", 0, NULL, REG_NOTBOL | REG_SEARCH), REG_NOERR); - EXPECT_EQ(regexec(®ex, "a hello friends b", 0, NULL, REG_NOTBOL | REG_SEARCH), REG_NOERR); - - EXPECT_EQ(regexec(®ex, "a hello friends b", 0, NULL, REG_NOTEOL), REG_NOMATCH); - EXPECT_EQ(regexec(®ex, "hello friends b", 0, NULL, REG_NOTEOL), REG_NOMATCH); - EXPECT_EQ(regexec(®ex, "hello friends b", 0, NULL, REG_NOTEOL | REG_SEARCH), REG_NOERR); - EXPECT_EQ(regexec(®ex, "a hello friends b", 0, NULL, REG_NOTEOL | REG_SEARCH), REG_NOMATCH); - - EXPECT_EQ(regexec(®ex, "a hello friends b", 0, NULL, REG_NOTBOL | REG_NOTEOL), REG_NOMATCH); - EXPECT_EQ(regexec(®ex, "a hello friends b", 0, NULL, REG_NOTBOL | REG_NOTEOL | REG_SEARCH), REG_NOMATCH); - - EXPECT_EQ(regexec(®ex2, "hello friends", 0, NULL, REG_NOTBOL), REG_NOMATCH); - EXPECT_EQ(regexec(®ex2, "hello friends", 0, NULL, REG_NOTEOL), REG_NOMATCH); - - regfree(®ex); - regfree(®ex2); -} - -TEST_CASE(bre_basic) -{ - regex_t regex; - EXPECT_EQ(regcomp(®ex, "hello friends", REG_NOSUB | REG_ICASE), REG_NOERR); - EXPECT_EQ(regexec(®ex, "hello friends", 0, NULL, 0), REG_NOERR); - regfree(®ex); - - EXPECT_EQ(regcomp(®ex, "\\(15\\)\\1", REG_NOSUB | REG_ICASE), REG_NOERR); - EXPECT_EQ(regexec(®ex, "1515", 0, NULL, 0), REG_NOERR); - EXPECT_EQ(regexec(®ex, "55", 0, NULL, 0), REG_NOMATCH); - regfree(®ex); - - EXPECT_EQ(regcomp(®ex, "15\\{1,2\\}", REG_NOSUB | REG_ICASE), REG_NOERR); - EXPECT_EQ(regexec(®ex, "15", 0, NULL, 0), REG_NOERR); - EXPECT_EQ(regexec(®ex, "1515", 0, NULL, 0), REG_NOMATCH); - EXPECT_EQ(regexec(®ex, "55", 0, NULL, 0), REG_NOMATCH); - regfree(®ex); - - EXPECT_EQ(regcomp(®ex, "15{1,2}", REG_NOSUB | REG_ICASE), REG_NOERR); - EXPECT_EQ(regexec(®ex, "15{1,2}", 0, NULL, 0), REG_NOERR); - regfree(®ex); - - EXPECT_EQ(regcomp(®ex, "1[56]", REG_NOSUB | REG_ICASE), REG_NOERR); - EXPECT_EQ(regexec(®ex, "15", 0, NULL, 0), REG_NOERR); - EXPECT_EQ(regexec(®ex, "16", 0, NULL, 0), REG_NOERR); - EXPECT_EQ(regexec(®ex, "17", 0, NULL, 0), REG_NOMATCH); - regfree(®ex); -} diff --git a/Tests/LibRegex/Regex.cpp b/Tests/LibRegex/TestRegex.cpp similarity index 100% rename from Tests/LibRegex/Regex.cpp rename to Tests/LibRegex/TestRegex.cpp