Serenity Operating System
at master 1159 lines 47 kB view raw
1/* 2 * Copyright (c) 2020, Emanuel Sprung <emanuel.sprung@gmail.com> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <LibTest/TestCase.h> 8 9#include <AK/StringBuilder.h> 10#include <AK/Vector.h> 11#include <regex.h> 12#include <stdio.h> 13 14TEST_CASE(catch_all) 15{ 16 DeprecatedString pattern = "^.*$"; 17 regex_t regex; 18 19 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR); 20 EXPECT_EQ(regexec(&regex, "Hello World", 0, NULL, 0), REG_NOERR); 21 22 regfree(&regex); 23} 24 25TEST_CASE(simple_start) 26{ 27 DeprecatedString pattern = "^hello friends"; 28 regex_t regex; 29 30 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR); 31 EXPECT_EQ(regexec(&regex, "Hello!", 0, NULL, 0), REG_NOMATCH); 32 EXPECT_EQ(regexec(&regex, "hello friends", 0, NULL, 0), REG_NOERR); 33 EXPECT_EQ(regexec(&regex, "Well, hello friends", 0, NULL, 0), REG_NOMATCH); 34 35 regfree(&regex); 36} 37 38TEST_CASE(simple_end) 39{ 40 DeprecatedString pattern = ".*hello\\.\\.\\. there$"; 41 regex_t regex; 42 43 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR); 44 EXPECT_EQ(regexec(&regex, "Hallo", 0, NULL, 0), REG_NOMATCH); 45 EXPECT_EQ(regexec(&regex, "I said fyhello... there", 0, NULL, 0), REG_NOERR); 46 EXPECT_EQ(regexec(&regex, "ahello... therea", 0, NULL, 0), REG_NOMATCH); 47 EXPECT_EQ(regexec(&regex, "hello.. there", 0, NULL, 0), REG_NOMATCH); 48 49 regfree(&regex); 50} 51 52TEST_CASE(simple_period) 53{ 54 DeprecatedString pattern = "hello."; 55 regex_t regex; 56 57 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR); 58 EXPECT_EQ(regexec(&regex, "Hello1", 0, NULL, 0), REG_NOMATCH); 59 EXPECT_EQ(regexec(&regex, "hello1", 0, NULL, 0), REG_NOERR); 60 EXPECT_EQ(regexec(&regex, "hello2", 0, NULL, 0), REG_NOERR); 61 EXPECT_EQ(regexec(&regex, "hello?", 0, NULL, 0), REG_NOERR); 62 63 regfree(&regex); 64} 65 66TEST_CASE(simple_period_end) 67{ 68 DeprecatedString pattern = "hello.$"; 69 regex_t regex; 70 71 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED | REG_NOSUB), REG_NOERR); 72 EXPECT_EQ(regexec(&regex, "Hello1", 0, NULL, REG_NOSUB), REG_NOMATCH); 73 EXPECT_EQ(regexec(&regex, "hello1hello1", 0, NULL, REG_GLOBAL), REG_NOERR); 74 EXPECT_EQ(regexec(&regex, "hello2hell", 0, NULL, REG_GLOBAL), REG_NOMATCH); 75 EXPECT_EQ(regexec(&regex, "hello?", 0, NULL, REG_NOSUB), REG_NOERR); 76 77 regfree(&regex); 78} 79 80TEST_CASE(simple_escaped) 81{ 82 DeprecatedString pattern = "hello\\."; 83 regex_t regex; 84 85 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR); 86 EXPECT_EQ(regexec(&regex, "hello", 0, NULL, 0), REG_NOMATCH); 87 EXPECT_EQ(regexec(&regex, "hello.", 0, NULL, 0), REG_NOERR); 88 89 regfree(&regex); 90} 91 92TEST_CASE(simple_period2_end) 93{ 94 DeprecatedString pattern = ".*hi... there$"; 95 regex_t regex; 96 97 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR); 98 EXPECT_EQ(regexec(&regex, "Hello there", 0, NULL, REG_GLOBAL), REG_NOMATCH); 99 EXPECT_EQ(regexec(&regex, "I said fyhi... there", 0, NULL, REG_GLOBAL), REG_NOERR); 100 EXPECT_EQ(regexec(&regex, "....hi... ", 0, NULL, REG_GLOBAL), REG_NOMATCH); 101 EXPECT_EQ(regexec(&regex, "I said fyhihii there", 0, NULL, REG_GLOBAL), REG_NOERR); 102 EXPECT_EQ(regexec(&regex, "I said fyhihi there", 0, NULL, REG_GLOBAL), REG_NOMATCH); 103 104 regfree(&regex); 105} 106 107TEST_CASE(simple_plus) 108{ 109 DeprecatedString pattern = "a+"; 110 regex_t regex; 111 112 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED | REG_NOSUB), REG_NOERR); 113 EXPECT_EQ(regexec(&regex, "b", 0, NULL, REG_NOSUB), REG_NOMATCH); 114 EXPECT_EQ(regexec(&regex, "a", 0, NULL, REG_NOSUB), REG_NOERR); 115 EXPECT_EQ(regexec(&regex, "aaaaaabbbbb", 0, NULL, REG_GLOBAL), REG_NOERR); 116 EXPECT_EQ(regexec(&regex, "aaaaaaaaaaa", 0, NULL, REG_GLOBAL), REG_NOERR); 117 118 regfree(&regex); 119} 120 121TEST_CASE(simple_questionmark) 122{ 123 DeprecatedString pattern = "da?d"; 124 regex_t regex; 125 126 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR); 127 EXPECT_EQ(regexec(&regex, "a", 0, NULL, REG_GLOBAL), REG_NOMATCH); 128 EXPECT_EQ(regexec(&regex, "daa", 0, NULL, REG_GLOBAL), REG_NOMATCH); 129 EXPECT_EQ(regexec(&regex, "ddddd", 0, NULL, REG_GLOBAL), REG_NOERR); 130 EXPECT_EQ(regexec(&regex, "dd", 0, NULL, REG_GLOBAL), REG_NOERR); 131 EXPECT_EQ(regexec(&regex, "dad", 0, NULL, REG_GLOBAL), REG_NOERR); 132 EXPECT_EQ(regexec(&regex, "dada", 0, NULL, REG_GLOBAL), REG_NOERR); 133 EXPECT_EQ(regexec(&regex, "adadaa", 0, NULL, REG_GLOBAL), REG_NOERR); 134 135 regfree(&regex); 136} 137 138TEST_CASE(simple_questionmark_matchall) 139{ 140 DeprecatedString pattern = "da?d"; 141 regex_t regex; 142 static constexpr int num_matches { 5 }; 143 regmatch_t matches[num_matches]; 144 145 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR); 146 EXPECT_EQ(regexec(&regex, "a", num_matches, matches, REG_GLOBAL), REG_NOMATCH); 147 EXPECT_EQ(matches[0].rm_cnt, 0); 148 EXPECT_EQ(regexec(&regex, "daa", num_matches, matches, REG_GLOBAL), REG_NOMATCH); 149 EXPECT_EQ(matches[0].rm_cnt, 0); 150 151 EXPECT_EQ(regexec(&regex, "ddddd", num_matches, matches, REG_GLOBAL), REG_NOERR); 152 EXPECT_EQ(matches[0].rm_cnt, 2); 153 154 EXPECT_EQ(matches[0].rm_so, 0); 155 EXPECT_EQ(matches[0].rm_eo, 2); 156 EXPECT_EQ(matches[1].rm_so, 2); 157 EXPECT_EQ(matches[1].rm_eo, 4); 158 159 EXPECT_EQ(regexec(&regex, "dd", num_matches, matches, REG_GLOBAL), REG_NOERR); 160 EXPECT_EQ(matches[0].rm_cnt, 1); 161 EXPECT_EQ(regexec(&regex, "dad", num_matches, matches, REG_GLOBAL), REG_NOERR); 162 EXPECT_EQ(matches[0].rm_cnt, 1); 163 EXPECT_EQ(regexec(&regex, "dada", num_matches, matches, REG_GLOBAL), REG_NOERR); 164 EXPECT_EQ(matches[0].rm_cnt, 1); 165 EXPECT_EQ(regexec(&regex, "adadaa", num_matches, matches, REG_GLOBAL), REG_NOERR); 166 EXPECT_EQ(matches[0].rm_cnt, 1); 167 168 regfree(&regex); 169} 170 171TEST_CASE(character_class) 172{ 173 DeprecatedString pattern = "[[:alpha:]]"; 174 regex_t regex; 175 static constexpr int num_matches { 5 }; 176 regmatch_t matches[num_matches]; 177 178 DeprecatedString haystack = "[Window]\nOpacity=255\nAudibleBeep=0\n"; 179 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR); 180 EXPECT_EQ(regexec(&regex, haystack.characters(), num_matches, matches, 0), REG_NOMATCH); 181 EXPECT_EQ(matches[0].rm_cnt, 0); 182 EXPECT_EQ(regexec(&regex, haystack.characters(), num_matches, matches, REG_GLOBAL), REG_NOERR); 183 EXPECT_EQ(matches[0].rm_cnt, 24); 184 EXPECT_EQ(haystack.substring_view(matches[0].rm_so, matches[0].rm_eo - matches[0].rm_so), "W"); 185 EXPECT_EQ(haystack.substring_view(matches[1].rm_so, matches[1].rm_eo - matches[1].rm_so), "i"); 186 187 regfree(&regex); 188} 189 190TEST_CASE(character_class2) 191{ 192 DeprecatedString pattern = "[[:alpha:]]*=([[:digit:]]*)|\\[(.*)\\]"; 193 regex_t regex; 194 static constexpr int num_matches { 9 }; 195 regmatch_t matches[num_matches]; 196 197 DeprecatedString haystack = "[Window]\nOpacity=255\nAudibleBeep=0\n"; 198 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED | REG_NEWLINE), REG_NOERR); 199 EXPECT_EQ(regexec(&regex, haystack.characters(), num_matches, matches, 0), REG_NOERR); 200 201 EXPECT_EQ(matches[0].rm_cnt, 3); 202#if 0 203 for (int i = 0; i < num_matches; ++i) { 204 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); 205 fprintf(stderr, "haystack length: %lu\n", haystack.length()); 206 if (matches[i].rm_so != -1) 207 fprintf(stderr, "%s\n", haystack.substring_view(matches[i].rm_so, matches[i].rm_eo - matches[i].rm_so).to_deprecated_string().characters()); 208 } 209#endif 210 211 EXPECT_EQ(haystack.substring_view(matches[0].rm_so, matches[0].rm_eo - matches[0].rm_so), "[Window]"); 212 213 EXPECT_EQ(matches[1].rm_so, -1); 214 EXPECT_EQ(matches[1].rm_eo, -1); 215 EXPECT_EQ(matches[1].rm_cnt, 0); 216 217 EXPECT_EQ(haystack.substring_view(matches[2].rm_so, matches[2].rm_eo - matches[2].rm_so), "Window"); 218 EXPECT_EQ(haystack.substring_view(matches[3].rm_so, matches[3].rm_eo - matches[3].rm_so), "Opacity=255"); 219 220 EXPECT_EQ(haystack.substring_view(matches[4].rm_so, matches[4].rm_eo - matches[4].rm_so), "255"); 221 222 EXPECT_EQ(matches[5].rm_so, -1); 223 EXPECT_EQ(matches[5].rm_eo, -1); 224 EXPECT_EQ(matches[5].rm_cnt, 0); 225 226 EXPECT_EQ(haystack.substring_view(matches[6].rm_so, matches[6].rm_eo - matches[6].rm_so), "AudibleBeep=0"); 227 EXPECT_EQ(haystack.substring_view(matches[7].rm_so, matches[7].rm_eo - matches[7].rm_so), "0"); 228 229 EXPECT_EQ(matches[8].rm_so, -1); 230 EXPECT_EQ(matches[8].rm_eo, -1); 231 EXPECT_EQ(matches[8].rm_cnt, 0); 232 233 regfree(&regex); 234} 235 236TEST_CASE(escaped_char_questionmark) 237{ 238 DeprecatedString pattern = "This\\.?And\\.?That"; 239 regex_t regex; 240 241 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR); 242 EXPECT_EQ(regexec(&regex, "ThisAndThat", 0, NULL, 0), REG_NOERR); 243 EXPECT_EQ(regexec(&regex, "This.And.That", 0, NULL, 0), REG_NOERR); 244 EXPECT_EQ(regexec(&regex, "This And That", 0, NULL, 0), REG_NOMATCH); 245 EXPECT_EQ(regexec(&regex, "This..And..That", 0, NULL, 0), REG_NOMATCH); 246 247 regfree(&regex); 248} 249 250TEST_CASE(char_qualifier_asterisk) 251{ 252 DeprecatedString pattern = "regex*"; 253 regex_t regex; 254 static constexpr int num_matches { 5 }; 255 regmatch_t matches[num_matches]; 256 257 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR); 258 EXPECT_EQ(regexec(&regex, "#include <regex.h>", num_matches, matches, REG_GLOBAL), REG_NOERR); 259 EXPECT_EQ(matches[0].rm_cnt, 1); 260 261 regfree(&regex); 262} 263 264TEST_CASE(char_utf8) 265{ 266 DeprecatedString pattern = "😀"; 267 regex_t regex; 268 static constexpr int num_matches { 5 }; 269 regmatch_t matches[num_matches]; 270 271 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR); 272 EXPECT_EQ(regexec(&regex, "Привет, мир! 😀 γειά σου κόσμος 😀 こんにちは世界", num_matches, matches, REG_GLOBAL), REG_NOERR); 273 EXPECT_EQ(matches[0].rm_cnt, 2); 274 275 regfree(&regex); 276} 277 278TEST_CASE(parens) 279{ 280 DeprecatedString pattern = "test(hello)test"; 281 regex_t regex; 282 static constexpr int num_matches { 5 }; 283 regmatch_t matches[num_matches]; 284 285 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR); 286 287 EXPECT_EQ(regexec(&regex, "testhellotest", num_matches, matches, 0), REG_NOERR); 288 EXPECT_EQ(matches[0].rm_cnt, 1); 289 290 EXPECT_EQ(matches[0].rm_so, 0); 291 EXPECT_EQ(matches[0].rm_eo, 13); 292 EXPECT_EQ(matches[1].rm_so, 4); 293 EXPECT_EQ(matches[1].rm_eo, 9); 294 295 regfree(&regex); 296} 297 298TEST_CASE(parser_error_parens) 299{ 300 DeprecatedString pattern = "test()test"; 301 regex_t regex; 302 static constexpr int num_matches { 5 }; 303 regmatch_t matches[num_matches]; 304 305 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_EMPTY_EXPR); 306 EXPECT_EQ(regexec(&regex, "testhellotest", num_matches, matches, 0), REG_EMPTY_EXPR); 307 308 regfree(&regex); 309} 310 311TEST_CASE(parser_error_special_characters_used_at_wrong_place) 312{ 313 DeprecatedString pattern; 314 regex_t regex; 315 static constexpr int num_matches { 5 }; 316 regmatch_t matches[num_matches]; 317 318 Vector<char, 4> chars = { '*', '+', '?', '}' }; 319 StringBuilder b; 320 321 for (auto& ch : chars) { 322 323 auto error_code_to_check = ch == '}' ? REG_EBRACE : REG_BADRPT; 324 325 // First in ere 326 b.clear(); 327 b.append(ch); 328 pattern = b.to_deprecated_string(); 329 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), error_code_to_check); 330 EXPECT_EQ(regexec(&regex, "test", num_matches, matches, 0), error_code_to_check); 331 regfree(&regex); 332 333 // After vertical line 334 b.clear(); 335 b.append("a|"sv); 336 b.append(ch); 337 pattern = b.to_deprecated_string(); 338 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), error_code_to_check); 339 EXPECT_EQ(regexec(&regex, "test", num_matches, matches, 0), error_code_to_check); 340 regfree(&regex); 341 342 // After circumflex 343 b.clear(); 344 b.append('^'); 345 b.append(ch); 346 pattern = b.to_deprecated_string(); 347 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), error_code_to_check); 348 EXPECT_EQ(regexec(&regex, "test", num_matches, matches, 0), error_code_to_check); 349 regfree(&regex); 350 351 // After dollar 352 b.clear(); 353 b.append('$'); 354 b.append(ch); 355 pattern = b.to_deprecated_string(); 356 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), error_code_to_check); 357 EXPECT_EQ(regexec(&regex, "test", num_matches, matches, 0), error_code_to_check); 358 regfree(&regex); 359 360 // After left parens 361 b.clear(); 362 b.append('('); 363 b.append(ch); 364 b.append(')'); 365 pattern = b.to_deprecated_string(); 366 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), error_code_to_check); 367 EXPECT_EQ(regexec(&regex, "test", num_matches, matches, 0), error_code_to_check); 368 regfree(&regex); 369 } 370} 371 372TEST_CASE(parser_error_vertical_line_used_at_wrong_place) 373{ 374 DeprecatedString pattern; 375 regex_t regex; 376 static constexpr int num_matches { 5 }; 377 regmatch_t matches[num_matches]; 378 379 // First in ere 380 pattern = "|asdf"; 381 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_EMPTY_EXPR); 382 EXPECT_EQ(regexec(&regex, "test", num_matches, matches, 0), REG_EMPTY_EXPR); 383 regfree(&regex); 384 385 // Last in ere 386 pattern = "asdf|"; 387 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_EMPTY_EXPR); 388 EXPECT_EQ(regexec(&regex, "test", num_matches, matches, 0), REG_EMPTY_EXPR); 389 regfree(&regex); 390 391 // After left parens 392 pattern = "(|asdf)"; 393 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_EMPTY_EXPR); 394 EXPECT_EQ(regexec(&regex, "test", num_matches, matches, 0), REG_EMPTY_EXPR); 395 regfree(&regex); 396 397 // Proceed right parens 398 pattern = "(asdf)|"; 399 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_EMPTY_EXPR); 400 EXPECT_EQ(regexec(&regex, "test", num_matches, matches, 0), REG_EMPTY_EXPR); 401 regfree(&regex); 402} 403 404TEST_CASE(parens_qualifier_questionmark) 405{ 406 DeprecatedString pattern = "test(hello)?test"; 407 regex_t regex; 408 static constexpr int num_matches { 5 }; 409 regmatch_t matches[num_matches]; 410 char const* match_str; 411 412 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR); 413 414 match_str = "testtest"; 415 EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOERR); 416 EXPECT_EQ(matches[0].rm_cnt, 1); 417 EXPECT_EQ(matches[0].rm_so, 0); 418 EXPECT_EQ(matches[0].rm_eo, 8); 419 EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "testtest"); 420 421 match_str = "testhellotest"; 422 EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOERR); 423 EXPECT_EQ(matches[0].rm_cnt, 1); 424 EXPECT_EQ(matches[0].rm_so, 0); 425 EXPECT_EQ(matches[0].rm_eo, 13); 426 EXPECT_EQ(matches[1].rm_so, 4); 427 EXPECT_EQ(matches[1].rm_eo, 9); 428 EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "testhellotest"); 429 EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "hello"); 430 431 regfree(&regex); 432} 433 434TEST_CASE(parens_qualifier_asterisk) 435{ 436 DeprecatedString pattern = "test(hello)*test"; 437 regex_t regex; 438 static constexpr int num_matches { 6 }; 439 regmatch_t matches[num_matches]; 440 char const* match_str; 441 442 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR); 443 444 match_str = "testtest"; 445 EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOERR); 446 EXPECT_EQ(matches[0].rm_cnt, 1); 447 EXPECT_EQ(matches[0].rm_so, 0); 448 EXPECT_EQ(matches[0].rm_eo, 8); 449 EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "testtest"); 450 451 match_str = "testhellohellotest"; 452 EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOERR); 453 EXPECT_EQ(matches[0].rm_cnt, 1); 454 EXPECT_EQ(matches[0].rm_so, 0); 455 EXPECT_EQ(matches[0].rm_eo, 18); 456 EXPECT_EQ(matches[1].rm_so, 9); 457 EXPECT_EQ(matches[1].rm_eo, 14); 458 EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "testhellohellotest"); 459 EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "hello"); 460 461 match_str = "testhellohellotest, testhellotest"; 462 EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, REG_GLOBAL), REG_NOERR); 463 EXPECT_EQ(matches[0].rm_cnt, 2); 464 EXPECT_EQ(matches[0].rm_so, 0); 465 EXPECT_EQ(matches[0].rm_eo, 18); 466 EXPECT_EQ(matches[1].rm_so, 9); 467 EXPECT_EQ(matches[1].rm_eo, 14); 468 EXPECT_EQ(matches[2].rm_so, 20); 469 EXPECT_EQ(matches[2].rm_eo, 33); 470 EXPECT_EQ(matches[3].rm_so, 24); 471 EXPECT_EQ(matches[3].rm_eo, 29); 472 EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "testhellohellotest"); 473 EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "hello"); 474 EXPECT_EQ(StringView(&match_str[matches[2].rm_so], matches[2].rm_eo - matches[2].rm_so), "testhellotest"); 475 EXPECT_EQ(StringView(&match_str[matches[3].rm_so], matches[3].rm_eo - matches[3].rm_so), "hello"); 476 477 regfree(&regex); 478} 479 480TEST_CASE(parens_qualifier_asterisk_2) 481{ 482 DeprecatedString pattern = "test(.*)test"; 483 regex_t regex; 484 static constexpr int num_matches { 6 }; 485 regmatch_t matches[num_matches]; 486 char const* match_str; 487 488 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR); 489 490 match_str = "testasdftest"; 491 EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOERR); 492 EXPECT_EQ(matches[0].rm_cnt, 1); 493 EXPECT_EQ(matches[0].rm_so, 0); 494 EXPECT_EQ(matches[0].rm_eo, 12); 495 EXPECT_EQ(matches[1].rm_so, 4); 496 EXPECT_EQ(matches[1].rm_eo, 8); 497 EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "testasdftest"); 498 EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "asdf"); 499 500 match_str = "testasdfasdftest"; 501 EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOERR); 502 EXPECT_EQ(matches[0].rm_cnt, 1); 503 EXPECT_EQ(matches[0].rm_so, 0); 504 EXPECT_EQ(matches[0].rm_eo, 16); 505 EXPECT_EQ(matches[1].rm_so, 4); 506 EXPECT_EQ(matches[1].rm_eo, 12); 507 EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "testasdfasdftest"); 508 EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "asdfasdf"); 509 510 match_str = "testaaaatest, testbbbtest, testtest"; 511 EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, REG_GLOBAL), REG_NOERR); 512 EXPECT_EQ(matches[0].rm_cnt, 1); 513 EXPECT_EQ(matches[0].rm_so, 0); 514 EXPECT_EQ(matches[0].rm_eo, 35); 515 EXPECT_EQ(matches[1].rm_so, 4); 516 EXPECT_EQ(matches[1].rm_eo, 31); 517 518 EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "testaaaatest, testbbbtest, testtest"); 519 EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "aaaatest, testbbbtest, test"); 520 521 regfree(&regex); 522} 523 524TEST_CASE(mulit_parens_qualifier_too_less_result_values) 525{ 526 DeprecatedString pattern = "test(a)?(b)?(c)?test"; 527 regex_t regex; 528 static constexpr int num_matches { 4 }; 529 regmatch_t matches[num_matches]; 530 char const* match_str; 531 532 matches[3] = { -2, -2, 100 }; 533 534 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR); 535 536 match_str = "testabtest"; 537 EXPECT_EQ(regexec(&regex, match_str, num_matches - 1, matches, 0), REG_NOERR); 538 EXPECT_EQ(matches[0].rm_cnt, 1); 539 EXPECT_EQ(matches[0].rm_so, 0); 540 EXPECT_EQ(matches[0].rm_eo, 10); 541 EXPECT_EQ(matches[1].rm_so, 4); 542 EXPECT_EQ(matches[1].rm_eo, 5); 543 EXPECT_EQ(matches[2].rm_so, 5); 544 EXPECT_EQ(matches[2].rm_eo, 6); 545 EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "testabtest"); 546 EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "a"); 547 EXPECT_EQ(StringView(&match_str[matches[2].rm_so], matches[2].rm_eo - matches[2].rm_so), "b"); 548 EXPECT_EQ(matches[3].rm_so, -2); 549 EXPECT_EQ(matches[3].rm_eo, -2); 550 EXPECT_EQ(matches[3].rm_cnt, 100); 551 552 match_str = "testabctest"; 553 EXPECT_EQ(regexec(&regex, match_str, num_matches - 1, matches, 0), REG_NOERR); 554 EXPECT_EQ(matches[0].rm_cnt, 1); 555 EXPECT_EQ(matches[0].rm_so, 0); 556 EXPECT_EQ(matches[0].rm_eo, 11); 557 EXPECT_EQ(matches[1].rm_so, 4); 558 EXPECT_EQ(matches[1].rm_eo, 5); 559 EXPECT_EQ(matches[2].rm_so, 5); 560 EXPECT_EQ(matches[2].rm_eo, 6); 561 EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "testabctest"); 562 EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "a"); 563 EXPECT_EQ(StringView(&match_str[matches[2].rm_so], matches[2].rm_eo - matches[2].rm_so), "b"); 564 EXPECT_EQ(matches[3].rm_so, -2); 565 EXPECT_EQ(matches[3].rm_eo, -2); 566 EXPECT_EQ(matches[3].rm_cnt, 100); 567 568 match_str = "testabctest, testabctest"; 569 570 EXPECT_EQ(regexec(&regex, match_str, num_matches - 1, matches, REG_GLOBAL), REG_NOERR); 571 EXPECT_EQ(matches[0].rm_cnt, 2); 572 EXPECT_EQ(matches[0].rm_so, 0); 573 EXPECT_EQ(matches[0].rm_eo, 11); 574 EXPECT_EQ(matches[1].rm_so, 4); 575 EXPECT_EQ(matches[1].rm_eo, 5); 576 EXPECT_EQ(matches[2].rm_so, 5); 577 EXPECT_EQ(matches[2].rm_eo, 6); 578 EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "testabctest"); 579 EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "a"); 580 EXPECT_EQ(StringView(&match_str[matches[2].rm_so], matches[2].rm_eo - matches[2].rm_so), "b"); 581 EXPECT_EQ(matches[3].rm_so, -2); 582 EXPECT_EQ(matches[3].rm_eo, -2); 583 EXPECT_EQ(matches[3].rm_cnt, 100); 584 585 regfree(&regex); 586} 587 588TEST_CASE(multi_parens_qualifier_questionmark) 589{ 590 DeprecatedString pattern = "test(a)?(b)?(c)?test"; 591 regex_t regex; 592 static constexpr int num_matches { 8 }; 593 regmatch_t matches[num_matches]; 594 char const* match_str; 595 596 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR); 597 598 match_str = "testtest"; 599 EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOERR); 600 EXPECT_EQ(matches[0].rm_cnt, 1); 601 EXPECT_EQ(matches[0].rm_so, 0); 602 EXPECT_EQ(matches[0].rm_eo, 8); 603 EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "testtest"); 604 605 match_str = "testabctest"; 606 EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOERR); 607 EXPECT_EQ(matches[0].rm_cnt, 1); 608 EXPECT_EQ(matches[0].rm_so, 0); 609 EXPECT_EQ(matches[0].rm_eo, 11); 610 EXPECT_EQ(matches[1].rm_so, 4); 611 EXPECT_EQ(matches[1].rm_eo, 5); 612 EXPECT_EQ(matches[2].rm_so, 5); 613 EXPECT_EQ(matches[2].rm_eo, 6); 614 EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "testabctest"); 615 EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "a"); 616 EXPECT_EQ(StringView(&match_str[matches[2].rm_so], matches[2].rm_eo - matches[2].rm_so), "b"); 617 618 match_str = "testabctest, testactest"; 619 620 EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, REG_GLOBAL), REG_NOERR); 621 EXPECT_EQ(matches[0].rm_cnt, 2); 622 EXPECT_EQ(matches[0].rm_so, 0); 623 EXPECT_EQ(matches[0].rm_eo, 11); 624 EXPECT_EQ(matches[1].rm_so, 4); 625 EXPECT_EQ(matches[1].rm_eo, 5); 626 EXPECT_EQ(matches[2].rm_so, 5); 627 EXPECT_EQ(matches[2].rm_eo, 6); 628 EXPECT_EQ(matches[3].rm_so, 6); 629 EXPECT_EQ(matches[3].rm_eo, 7); 630 631 EXPECT_EQ(matches[4].rm_so, 13); 632 EXPECT_EQ(matches[4].rm_eo, 23); 633 EXPECT_EQ(matches[5].rm_so, 17); 634 EXPECT_EQ(matches[5].rm_eo, 18); 635 EXPECT_EQ(matches[6].rm_so, -1); 636 EXPECT_EQ(matches[6].rm_eo, -1); 637 EXPECT_EQ(matches[7].rm_so, 18); 638 EXPECT_EQ(matches[7].rm_eo, 19); 639 640 EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "testabctest"); 641 EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "a"); 642 EXPECT_EQ(StringView(&match_str[matches[2].rm_so], matches[2].rm_eo - matches[2].rm_so), "b"); 643 EXPECT_EQ(StringView(&match_str[matches[3].rm_so], matches[3].rm_eo - matches[3].rm_so), "c"); 644 EXPECT_EQ(StringView(&match_str[matches[4].rm_so], matches[4].rm_eo - matches[4].rm_so), "testactest"); 645 EXPECT_EQ(StringView(&match_str[matches[5].rm_so], matches[5].rm_eo - matches[5].rm_so), "a"); 646 EXPECT_EQ(StringView(&match_str[matches[6].rm_so], matches[6].rm_eo - matches[6].rm_so), ""); 647 EXPECT_EQ(StringView(&match_str[matches[7].rm_so], matches[7].rm_eo - matches[7].rm_so), "c"); 648 649 regfree(&regex); 650} 651 652TEST_CASE(simple_alternative) 653{ 654 DeprecatedString pattern = "test|hello|friends"; 655 regex_t regex; 656 static constexpr int num_matches { 1 }; 657 regmatch_t matches[num_matches]; 658 659 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR); 660 661 EXPECT_EQ(regexec(&regex, "test", num_matches, matches, 0), REG_NOERR); 662 EXPECT_EQ(matches[0].rm_cnt, 1); 663 EXPECT_EQ(matches[0].rm_so, 0); 664 EXPECT_EQ(matches[0].rm_eo, 4); 665 666 EXPECT_EQ(regexec(&regex, "hello", num_matches, matches, 0), REG_NOERR); 667 EXPECT_EQ(matches[0].rm_cnt, 1); 668 EXPECT_EQ(matches[0].rm_so, 0); 669 EXPECT_EQ(matches[0].rm_eo, 5); 670 671 EXPECT_EQ(regexec(&regex, "friends", num_matches, matches, 0), REG_NOERR); 672 EXPECT_EQ(matches[0].rm_cnt, 1); 673 EXPECT_EQ(matches[0].rm_so, 0); 674 EXPECT_EQ(matches[0].rm_eo, 7); 675 676 regfree(&regex); 677} 678 679TEST_CASE(alternative_match_groups) 680{ 681 DeprecatedString pattern = "test(a)?(b)?|hello ?(dear|my)? friends"; 682 regex_t regex; 683 static constexpr int num_matches { 8 }; 684 regmatch_t matches[num_matches]; 685 char const* match_str; 686 687 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR); 688 689 match_str = "test"; 690 EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOERR); 691 EXPECT_EQ(matches[0].rm_cnt, 1); 692 EXPECT_EQ(matches[0].rm_so, 0); 693 EXPECT_EQ(matches[0].rm_eo, 4); 694 EXPECT_EQ(matches[1].rm_so, -1); 695 EXPECT_EQ(matches[1].rm_eo, -1); 696 EXPECT_EQ(matches[2].rm_so, -1); 697 EXPECT_EQ(matches[2].rm_eo, -1); 698 EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "test"); 699 EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), ""); 700 EXPECT_EQ(StringView(&match_str[matches[2].rm_so], matches[2].rm_eo - matches[2].rm_so), ""); 701 702 match_str = "testa"; 703 EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOERR); 704 EXPECT_EQ(matches[0].rm_cnt, 1); 705 EXPECT_EQ(matches[0].rm_so, 0); 706 EXPECT_EQ(matches[0].rm_eo, 5); 707 EXPECT_EQ(matches[1].rm_so, 4); 708 EXPECT_EQ(matches[1].rm_eo, 5); 709 EXPECT_EQ(matches[2].rm_so, -1); 710 EXPECT_EQ(matches[2].rm_eo, -1); 711 EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "testa"); 712 EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "a"); 713 EXPECT_EQ(StringView(&match_str[matches[2].rm_so], matches[2].rm_eo - matches[2].rm_so), ""); 714 715 match_str = "testb"; 716 EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOERR); 717 EXPECT_EQ(matches[0].rm_cnt, 1); 718 EXPECT_EQ(matches[0].rm_so, 0); 719 EXPECT_EQ(matches[0].rm_eo, 5); 720 EXPECT_EQ(matches[1].rm_so, -1); 721 EXPECT_EQ(matches[1].rm_eo, -1); 722 EXPECT_EQ(matches[2].rm_so, 4); 723 EXPECT_EQ(matches[2].rm_eo, 5); 724 EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "testb"); 725 EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), ""); 726 EXPECT_EQ(StringView(&match_str[matches[2].rm_so], matches[2].rm_eo - matches[2].rm_so), "b"); 727 728 match_str = "hello friends"; 729 EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOERR); 730 EXPECT_EQ(matches[0].rm_cnt, 1); 731 EXPECT_EQ(matches[0].rm_so, 0); 732 EXPECT_EQ(matches[0].rm_eo, 13); 733 EXPECT_EQ(matches[1].rm_so, -1); 734 EXPECT_EQ(matches[1].rm_eo, -1); 735 EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "hello friends"); 736 EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), ""); 737 738 match_str = "hello dear friends"; 739 EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOERR); 740 EXPECT_EQ(matches[0].rm_cnt, 1); 741 EXPECT_EQ(matches[0].rm_so, 0); 742 EXPECT_EQ(matches[0].rm_eo, 18); 743 EXPECT_EQ(matches[1].rm_so, -1); 744 EXPECT_EQ(matches[1].rm_eo, -1); 745 EXPECT_EQ(matches[2].rm_so, -1); 746 EXPECT_EQ(matches[2].rm_eo, -1); 747 EXPECT_EQ(matches[3].rm_so, 6); 748 EXPECT_EQ(matches[3].rm_eo, 10); 749 EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "hello dear friends"); 750 EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), ""); 751 EXPECT_EQ(StringView(&match_str[matches[2].rm_so], matches[2].rm_eo - matches[2].rm_so), ""); 752 EXPECT_EQ(StringView(&match_str[matches[3].rm_so], matches[3].rm_eo - matches[3].rm_so), "dear"); 753 754 match_str = "hello my friends"; 755 EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOERR); 756 EXPECT_EQ(matches[0].rm_cnt, 1); 757 EXPECT_EQ(matches[0].rm_so, 0); 758 EXPECT_EQ(matches[0].rm_eo, 16); 759 EXPECT_EQ(matches[1].rm_so, -1); 760 EXPECT_EQ(matches[1].rm_eo, -1); 761 EXPECT_EQ(matches[2].rm_so, -1); 762 EXPECT_EQ(matches[2].rm_eo, -1); 763 EXPECT_EQ(matches[3].rm_so, 6); 764 EXPECT_EQ(matches[3].rm_eo, 8); 765 EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "hello my friends"); 766 EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), ""); 767 EXPECT_EQ(StringView(&match_str[matches[2].rm_so], matches[2].rm_eo - matches[2].rm_so), ""); 768 EXPECT_EQ(StringView(&match_str[matches[3].rm_so], matches[3].rm_eo - matches[3].rm_so), "my"); 769 770 match_str = "testabc"; 771 EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOMATCH); 772 EXPECT_EQ(matches[0].rm_cnt, 0); 773 EXPECT_EQ(matches[0].rm_so, -1); 774 EXPECT_EQ(matches[0].rm_eo, -1); 775 776 match_str = "hello test friends"; 777 EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOMATCH); 778 EXPECT_EQ(matches[0].rm_cnt, 0); 779 EXPECT_EQ(matches[0].rm_so, -1); 780 EXPECT_EQ(matches[0].rm_eo, -1); 781 782 regfree(&regex); 783} 784 785TEST_CASE(parens_qualifier_exact) 786{ 787 DeprecatedString pattern = "(hello){3}"; 788 regex_t regex; 789 static constexpr int num_matches { 5 }; 790 regmatch_t matches[num_matches]; 791 char const* match_str; 792 793 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR); 794 795 match_str = "hello"; 796 EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOMATCH); 797 EXPECT_EQ(matches[0].rm_cnt, 0); 798 799 match_str = "hellohellohello"; 800 EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOERR); 801 EXPECT_EQ(matches[0].rm_cnt, 1); 802 EXPECT_EQ(matches[0].rm_so, 0); 803 EXPECT_EQ(matches[0].rm_eo, 15); 804 EXPECT_EQ(matches[1].rm_so, 10); 805 EXPECT_EQ(matches[1].rm_eo, 15); 806 EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "hellohellohello"); 807 EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "hello"); 808 809 match_str = "hellohellohellohello"; 810 EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, REG_GLOBAL), REG_NOERR); 811 EXPECT_EQ(matches[0].rm_cnt, 1); 812 EXPECT_EQ(matches[0].rm_so, 0); 813 EXPECT_EQ(matches[0].rm_eo, 15); 814 EXPECT_EQ(matches[1].rm_so, 10); 815 EXPECT_EQ(matches[1].rm_eo, 15); 816 EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "hellohellohello"); 817 EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "hello"); 818 819 match_str = "test hellohellohello"; 820 EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, REG_GLOBAL), REG_NOERR); 821 EXPECT_EQ(matches[0].rm_cnt, 1); 822 EXPECT_EQ(matches[0].rm_so, 5); 823 EXPECT_EQ(matches[0].rm_eo, 20); 824 EXPECT_EQ(matches[1].rm_so, 15); 825 EXPECT_EQ(matches[1].rm_eo, 20); 826 EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "hellohellohello"); 827 EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "hello"); 828 829 regfree(&regex); 830} 831 832TEST_CASE(parens_qualifier_minimum) 833{ 834 DeprecatedString pattern = "(hello){3,}"; 835 regex_t regex; 836 static constexpr int num_matches { 5 }; 837 regmatch_t matches[num_matches]; 838 char const* match_str; 839 840 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR); 841 842 match_str = "hello"; 843 EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOMATCH); 844 EXPECT_EQ(matches[0].rm_cnt, 0); 845 846 match_str = "hellohellohello"; 847 EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOERR); 848 EXPECT_EQ(matches[0].rm_cnt, 1); 849 EXPECT_EQ(matches[0].rm_so, 0); 850 EXPECT_EQ(matches[0].rm_eo, 15); 851 EXPECT_EQ(matches[1].rm_so, 10); 852 EXPECT_EQ(matches[1].rm_eo, 15); 853 EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "hellohellohello"); 854 EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "hello"); 855 856 match_str = "hellohellohellohello"; 857 858 EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, REG_SEARCH), REG_NOERR); 859 EXPECT_EQ(matches[0].rm_cnt, 1); 860 EXPECT_EQ(matches[0].rm_so, 0); 861 EXPECT_EQ(matches[0].rm_eo, 20); 862 EXPECT_EQ(matches[1].rm_so, 15); 863 EXPECT_EQ(matches[1].rm_eo, 20); 864 EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "hellohellohellohello"); 865 EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "hello"); 866 867 match_str = "test hellohellohello"; 868 EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, REG_GLOBAL), REG_NOERR); 869 EXPECT_EQ(matches[0].rm_cnt, 1); 870 EXPECT_EQ(matches[0].rm_so, 5); 871 EXPECT_EQ(matches[0].rm_eo, 20); 872 EXPECT_EQ(matches[1].rm_so, 15); 873 EXPECT_EQ(matches[1].rm_eo, 20); 874 EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "hellohellohello"); 875 EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "hello"); 876 877 match_str = "test hellohellohellohello"; 878 EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, REG_GLOBAL), REG_NOERR); 879 EXPECT_EQ(matches[0].rm_cnt, 1); 880 EXPECT_EQ(matches[0].rm_so, 5); 881 EXPECT_EQ(matches[0].rm_eo, 25); 882 EXPECT_EQ(matches[1].rm_so, 20); 883 EXPECT_EQ(matches[1].rm_eo, 25); 884 EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "hellohellohellohello"); 885 EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "hello"); 886 887 regfree(&regex); 888} 889 890TEST_CASE(parens_qualifier_maximum) 891{ 892 DeprecatedString pattern = "(hello){2,3}"; 893 regex_t regex; 894 static constexpr int num_matches { 5 }; 895 regmatch_t matches[num_matches]; 896 char const* match_str; 897 898 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR); 899 900 match_str = "hello"; 901 EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOMATCH); 902 EXPECT_EQ(matches[0].rm_cnt, 0); 903 904 match_str = "hellohellohello"; 905 EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, 0), REG_NOERR); 906 EXPECT_EQ(matches[0].rm_cnt, 1); 907 EXPECT_EQ(matches[0].rm_so, 0); 908 EXPECT_EQ(matches[0].rm_eo, 15); 909 EXPECT_EQ(matches[1].rm_so, 10); 910 EXPECT_EQ(matches[1].rm_eo, 15); 911 EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "hellohellohello"); 912 EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "hello"); 913 914 match_str = "hellohellohellohello"; 915 EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, REG_GLOBAL), REG_NOERR); 916 EXPECT_EQ(matches[0].rm_cnt, 1); 917 EXPECT_EQ(matches[0].rm_so, 0); 918 EXPECT_EQ(matches[0].rm_eo, 15); 919 EXPECT_EQ(matches[1].rm_so, 10); 920 EXPECT_EQ(matches[1].rm_eo, 15); 921 EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "hellohellohello"); 922 EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "hello"); 923 924 match_str = "test hellohellohello"; 925 EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, REG_GLOBAL), REG_NOERR); 926 EXPECT_EQ(matches[0].rm_cnt, 1); 927 EXPECT_EQ(matches[0].rm_so, 5); 928 EXPECT_EQ(matches[0].rm_eo, 20); 929 EXPECT_EQ(matches[1].rm_so, 15); 930 EXPECT_EQ(matches[1].rm_eo, 20); 931 EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "hellohellohello"); 932 EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "hello"); 933 934 match_str = "test hellohellohellohello"; 935 EXPECT_EQ(regexec(&regex, match_str, num_matches, matches, REG_GLOBAL), REG_NOERR); 936 EXPECT_EQ(matches[0].rm_cnt, 1); 937 EXPECT_EQ(matches[0].rm_so, 5); 938 EXPECT_EQ(matches[0].rm_eo, 20); 939 EXPECT_EQ(matches[1].rm_so, 15); 940 EXPECT_EQ(matches[1].rm_eo, 20); 941 EXPECT_EQ(StringView(&match_str[matches[0].rm_so], matches[0].rm_eo - matches[0].rm_so), "hellohellohello"); 942 EXPECT_EQ(StringView(&match_str[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so), "hello"); 943 944 regfree(&regex); 945} 946 947TEST_CASE(char_qualifier_min_max) 948{ 949 DeprecatedString pattern = "c{3,30}"; 950 regex_t regex; 951 static constexpr int num_matches { 5 }; 952 regmatch_t matches[num_matches]; 953 954 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR); 955 956 EXPECT_EQ(regexec(&regex, "cc", num_matches, matches, 0), REG_NOMATCH); 957 EXPECT_EQ(regexec(&regex, "ccc", num_matches, matches, 0), REG_NOERR); 958 EXPECT_EQ(regexec(&regex, "cccccccccccccccccccccccccccccc", num_matches, matches, 0), REG_NOERR); 959 EXPECT_EQ(matches[0].rm_cnt, 1); 960 EXPECT_EQ(regexec(&regex, "ccccccccccccccccccccccccccccccc", num_matches, matches, 0), REG_NOMATCH); 961 EXPECT_EQ(regexec(&regex, "ccccccccccccccccccccccccccccccc", num_matches, matches, REG_GLOBAL), REG_NOERR); 962 EXPECT_EQ(regexec(&regex, "cccccccccccccccccccccccccccccccc", num_matches, matches, 0), REG_NOMATCH); 963 964 regfree(&regex); 965} 966 967TEST_CASE(simple_bracket_chars) 968{ 969 DeprecatedString pattern = "[abc]"; 970 regex_t regex; 971 972 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR); 973 EXPECT_EQ(regexec(&regex, "a", 0, NULL, 0), REG_NOERR); 974 EXPECT_EQ(regexec(&regex, "b", 0, NULL, 0), REG_NOERR); 975 EXPECT_EQ(regexec(&regex, "c", 0, NULL, 0), REG_NOERR); 976 EXPECT_EQ(regexec(&regex, "d", 0, NULL, 0), REG_NOMATCH); 977 EXPECT_EQ(regexec(&regex, "e", 0, NULL, 0), REG_NOMATCH); 978 regfree(&regex); 979} 980 981TEST_CASE(simple_bracket_chars_inverse) 982{ 983 DeprecatedString pattern = "[^abc]"; 984 regex_t regex; 985 986 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR); 987 EXPECT_EQ(regexec(&regex, "a", 0, NULL, 0), REG_NOMATCH); 988 EXPECT_EQ(regexec(&regex, "b", 0, NULL, 0), REG_NOMATCH); 989 EXPECT_EQ(regexec(&regex, "c", 0, NULL, 0), REG_NOMATCH); 990 EXPECT_EQ(regexec(&regex, "d", 0, NULL, 0), REG_NOERR); 991 EXPECT_EQ(regexec(&regex, "e", 0, NULL, 0), REG_NOERR); 992 regfree(&regex); 993} 994 995TEST_CASE(simple_bracket_chars_range) 996{ 997 DeprecatedString pattern = "[a-d]"; 998 regex_t regex; 999 1000 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR); 1001 EXPECT_EQ(regexec(&regex, "a", 0, NULL, 0), REG_NOERR); 1002 EXPECT_EQ(regexec(&regex, "b", 0, NULL, 0), REG_NOERR); 1003 EXPECT_EQ(regexec(&regex, "c", 0, NULL, 0), REG_NOERR); 1004 EXPECT_EQ(regexec(&regex, "d", 0, NULL, 0), REG_NOERR); 1005 EXPECT_EQ(regexec(&regex, "e", 0, NULL, 0), REG_NOMATCH); 1006 regfree(&regex); 1007} 1008 1009TEST_CASE(simple_bracket_chars_range_inverse) 1010{ 1011 DeprecatedString pattern = "[^a-df-z]"; 1012 regex_t regex; 1013 1014 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR); 1015 EXPECT_EQ(regexec(&regex, "a", 0, NULL, 0), REG_NOMATCH); 1016 EXPECT_EQ(regexec(&regex, "b", 0, NULL, 0), REG_NOMATCH); 1017 EXPECT_EQ(regexec(&regex, "c", 0, NULL, 0), REG_NOMATCH); 1018 EXPECT_EQ(regexec(&regex, "d", 0, NULL, 0), REG_NOMATCH); 1019 EXPECT_EQ(regexec(&regex, "e", 0, NULL, 0), REG_NOERR); 1020 EXPECT_EQ(regexec(&regex, "k", 0, NULL, 0), REG_NOMATCH); 1021 EXPECT_EQ(regexec(&regex, "z", 0, NULL, 0), REG_NOMATCH); 1022 regfree(&regex); 1023} 1024 1025TEST_CASE(bracket_character_class_uuid) 1026{ 1027 DeprecatedString pattern = "^([[:xdigit:]]{8})-([[:xdigit:]]{4})-([[:xdigit:]]{4})-([[:xdigit:]]{4})-([[:xdigit:]]{12})$"; 1028 regex_t regex; 1029 1030 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR); 1031 EXPECT_EQ(regexec(&regex, "fb9b62a2-1579-4e3a-afba-76239ccb6583", 0, NULL, 0), REG_NOERR); 1032 EXPECT_EQ(regexec(&regex, "fb9b62a2", 0, NULL, 0), REG_NOMATCH); 1033 1034 regfree(&regex); 1035} 1036 1037TEST_CASE(simple_bracket_character_class_inverse) 1038{ 1039 DeprecatedString pattern = "[^[:digit:]]"; 1040 regex_t regex; 1041 1042 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR); 1043 EXPECT_EQ(regexec(&regex, "1", 0, NULL, 0), REG_NOMATCH); 1044 EXPECT_EQ(regexec(&regex, "2", 0, NULL, 0), REG_NOMATCH); 1045 EXPECT_EQ(regexec(&regex, "3", 0, NULL, 0), REG_NOMATCH); 1046 EXPECT_EQ(regexec(&regex, "d", 0, NULL, 0), REG_NOERR); 1047 EXPECT_EQ(regexec(&regex, "e", 0, NULL, 0), REG_NOERR); 1048 regfree(&regex); 1049} 1050 1051TEST_CASE(email_address) 1052{ 1053 DeprecatedString pattern = "^[A-Z0-9a-z._%+-]{1,64}@(?:[A-Za-z0-9-]{1,63}\\.){1,125}[A-Za-z]{2,63}$"; 1054 regex_t regex; 1055 1056 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_NOERR); 1057 EXPECT_EQ(regexec(&regex, "emanuel.sprung@gmail.com", 0, NULL, 0), REG_NOERR); 1058 EXPECT_EQ(regexec(&regex, "kling@serenityos.org", 0, NULL, 0), REG_NOERR); 1059 1060 regfree(&regex); 1061} 1062 1063TEST_CASE(error_message) 1064{ 1065 DeprecatedString pattern = "^[A-Z0-9[a-z._%+-]{1,64}@[A-Za-z0-9-]{1,63}\\.{1,125}[A-Za-z]{2,63}$"; 1066 regex_t regex; 1067 1068 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED), REG_EBRACK); 1069 EXPECT_EQ(regexec(&regex, "asdf@asdf.com", 0, NULL, 0), REG_EBRACK); 1070 char buf[1024]; 1071 size_t buflen = 1024; 1072 auto len = regerror(0, &regex, buf, buflen); 1073 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."; 1074 for (size_t i = 0; i < len; ++i) { 1075 EXPECT_EQ(buf[i], expected[i]); 1076 } 1077 1078 regfree(&regex); 1079} 1080 1081TEST_CASE(simple_ignorecase) 1082{ 1083 DeprecatedString pattern = "^hello friends"; 1084 regex_t regex; 1085 1086 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED | REG_NOSUB | REG_ICASE), REG_NOERR); 1087 EXPECT_EQ(regexec(&regex, "Hello Friends", 0, NULL, 0), REG_NOERR); 1088 EXPECT_EQ(regexec(&regex, "hello Friends", 0, NULL, 0), REG_NOERR); 1089 1090 EXPECT_EQ(regexec(&regex, "hello Friends!", 0, NULL, 0), REG_NOMATCH); 1091 EXPECT_EQ(regexec(&regex, "hello Friends!", 0, NULL, REG_GLOBAL), REG_NOERR); 1092 1093 EXPECT_EQ(regexec(&regex, "hell Friends", 0, NULL, 0), REG_NOMATCH); 1094 EXPECT_EQ(regexec(&regex, "hell Friends", 0, NULL, REG_GLOBAL), REG_NOMATCH); 1095 1096 regfree(&regex); 1097} 1098 1099TEST_CASE(simple_notbol_noteol) 1100{ 1101 DeprecatedString pattern = "^hello friends$"; 1102 DeprecatedString pattern2 = "hello friends"; 1103 regex_t regex, regex2; 1104 1105 EXPECT_EQ(regcomp(&regex, pattern.characters(), REG_EXTENDED | REG_NOSUB | REG_ICASE), REG_NOERR); 1106 EXPECT_EQ(regcomp(&regex2, pattern2.characters(), REG_EXTENDED | REG_NOSUB | REG_ICASE), REG_NOERR); 1107 1108 EXPECT_EQ(regexec(&regex, "hello friends", 0, NULL, REG_NOTBOL), REG_NOMATCH); 1109 EXPECT_EQ(regexec(&regex, "hello friends", 0, NULL, REG_NOTEOL), REG_NOMATCH); 1110 EXPECT_EQ(regexec(&regex, "hello friends", 0, NULL, REG_NOTBOL | REG_NOTEOL), REG_NOMATCH); 1111 1112 EXPECT_EQ(regexec(&regex, "a hello friends b", 0, NULL, REG_NOTBOL), REG_NOMATCH); 1113 EXPECT_EQ(regexec(&regex, "a hello friends", 0, NULL, REG_NOTBOL), REG_NOMATCH); 1114 EXPECT_EQ(regexec(&regex, "a hello friends", 0, NULL, REG_NOTBOL | REG_SEARCH), REG_NOERR); 1115 EXPECT_EQ(regexec(&regex, "a hello friends b", 0, NULL, REG_NOTBOL | REG_SEARCH), REG_NOERR); 1116 1117 EXPECT_EQ(regexec(&regex, "a hello friends b", 0, NULL, REG_NOTEOL), REG_NOMATCH); 1118 EXPECT_EQ(regexec(&regex, "hello friends b", 0, NULL, REG_NOTEOL), REG_NOMATCH); 1119 EXPECT_EQ(regexec(&regex, "hello friends b", 0, NULL, REG_NOTEOL | REG_SEARCH), REG_NOERR); 1120 EXPECT_EQ(regexec(&regex, "a hello friends b", 0, NULL, REG_NOTEOL | REG_SEARCH), REG_NOMATCH); 1121 1122 EXPECT_EQ(regexec(&regex, "a hello friends b", 0, NULL, REG_NOTBOL | REG_NOTEOL), REG_NOMATCH); 1123 EXPECT_EQ(regexec(&regex, "a hello friends b", 0, NULL, REG_NOTBOL | REG_NOTEOL | REG_SEARCH), REG_NOMATCH); 1124 1125 EXPECT_EQ(regexec(&regex2, "hello friends", 0, NULL, REG_NOTBOL), REG_NOMATCH); 1126 EXPECT_EQ(regexec(&regex2, "hello friends", 0, NULL, REG_NOTEOL), REG_NOMATCH); 1127 1128 regfree(&regex); 1129 regfree(&regex2); 1130} 1131 1132TEST_CASE(bre_basic) 1133{ 1134 regex_t regex; 1135 EXPECT_EQ(regcomp(&regex, "hello friends", REG_NOSUB | REG_ICASE), REG_NOERR); 1136 EXPECT_EQ(regexec(&regex, "hello friends", 0, NULL, 0), REG_NOERR); 1137 regfree(&regex); 1138 1139 EXPECT_EQ(regcomp(&regex, "\\(15\\)\\1", REG_NOSUB | REG_ICASE), REG_NOERR); 1140 EXPECT_EQ(regexec(&regex, "1515", 0, NULL, 0), REG_NOERR); 1141 EXPECT_EQ(regexec(&regex, "55", 0, NULL, 0), REG_NOMATCH); 1142 regfree(&regex); 1143 1144 EXPECT_EQ(regcomp(&regex, "15\\{1,2\\}", REG_NOSUB | REG_ICASE), REG_NOERR); 1145 EXPECT_EQ(regexec(&regex, "15", 0, NULL, 0), REG_NOERR); 1146 EXPECT_EQ(regexec(&regex, "1515", 0, NULL, 0), REG_NOMATCH); 1147 EXPECT_EQ(regexec(&regex, "55", 0, NULL, 0), REG_NOMATCH); 1148 regfree(&regex); 1149 1150 EXPECT_EQ(regcomp(&regex, "15{1,2}", REG_NOSUB | REG_ICASE), REG_NOERR); 1151 EXPECT_EQ(regexec(&regex, "15{1,2}", 0, NULL, 0), REG_NOERR); 1152 regfree(&regex); 1153 1154 EXPECT_EQ(regcomp(&regex, "1[56]", REG_NOSUB | REG_ICASE), REG_NOERR); 1155 EXPECT_EQ(regexec(&regex, "15", 0, NULL, 0), REG_NOERR); 1156 EXPECT_EQ(regexec(&regex, "16", 0, NULL, 0), REG_NOERR); 1157 EXPECT_EQ(regexec(&regex, "17", 0, NULL, 0), REG_NOMATCH); 1158 regfree(&regex); 1159}