Tests equality of all top-level structure but not subregexps.
| 345 | |
| 346 | // Tests equality of all top-level structure but not subregexps. |
| 347 | static bool TopEqual(Regexp* a, Regexp* b) { |
| 348 | if (a->op() != b->op()) |
| 349 | return false; |
| 350 | |
| 351 | switch (a->op()) { |
| 352 | case kRegexpNoMatch: |
| 353 | case kRegexpEmptyMatch: |
| 354 | case kRegexpAnyChar: |
| 355 | case kRegexpAnyByte: |
| 356 | case kRegexpBeginLine: |
| 357 | case kRegexpEndLine: |
| 358 | case kRegexpWordBoundary: |
| 359 | case kRegexpNoWordBoundary: |
| 360 | case kRegexpBeginText: |
| 361 | return true; |
| 362 | |
| 363 | case kRegexpEndText: |
| 364 | // The parse flags remember whether it's \z or (?-m:$), |
| 365 | // which matters when testing against PCRE. |
| 366 | return ((a->parse_flags() ^ b->parse_flags()) & Regexp::WasDollar) == 0; |
| 367 | |
| 368 | case kRegexpLiteral: |
| 369 | return a->rune() == b->rune() && |
| 370 | ((a->parse_flags() ^ b->parse_flags()) & Regexp::FoldCase) == 0; |
| 371 | |
| 372 | case kRegexpLiteralString: |
| 373 | return a->nrunes() == b->nrunes() && |
| 374 | ((a->parse_flags() ^ b->parse_flags()) & Regexp::FoldCase) == 0 && |
| 375 | memcmp(a->runes(), b->runes(), |
| 376 | a->nrunes() * sizeof a->runes()[0]) == 0; |
| 377 | |
| 378 | case kRegexpAlternate: |
| 379 | case kRegexpConcat: |
| 380 | return a->nsub() == b->nsub(); |
| 381 | |
| 382 | case kRegexpStar: |
| 383 | case kRegexpPlus: |
| 384 | case kRegexpQuest: |
| 385 | return ((a->parse_flags() ^ b->parse_flags()) & Regexp::NonGreedy) == 0; |
| 386 | |
| 387 | case kRegexpRepeat: |
| 388 | return ((a->parse_flags() ^ b->parse_flags()) & Regexp::NonGreedy) == 0 && |
| 389 | a->min() == b->min() && |
| 390 | a->max() == b->max(); |
| 391 | |
| 392 | case kRegexpCapture: |
| 393 | return a->cap() == b->cap() && a->name() == b->name(); |
| 394 | |
| 395 | case kRegexpHaveMatch: |
| 396 | return a->match_id() == b->match_id(); |
| 397 | |
| 398 | case kRegexpCharClass: { |
| 399 | CharClass* acc = a->cc(); |
| 400 | CharClass* bcc = b->cc(); |
| 401 | return acc->size() == bcc->size() && |
| 402 | acc->end() - acc->begin() == bcc->end() - bcc->begin() && |
| 403 | memcmp(acc->begin(), bcc->begin(), |
| 404 | (acc->end() - acc->begin()) * sizeof acc->begin()[0]) == 0; |