Removes the first n leading runes from the beginning of re. Edits re in place.
| 796 | // Removes the first n leading runes from the beginning of re. |
| 797 | // Edits re in place. |
| 798 | void Regexp::RemoveLeadingString(Regexp* re, int n) { |
| 799 | // Chase down concats to find first string. |
| 800 | // For regexps generated by parser, nested concats are |
| 801 | // flattened except when doing so would overflow the 16-bit |
| 802 | // limit on the size of a concatenation, so we should never |
| 803 | // see more than two here. |
| 804 | Regexp* stk[4]; |
| 805 | size_t d = 0; |
| 806 | while (re->op() == kRegexpConcat) { |
| 807 | if (d < arraysize(stk)) |
| 808 | stk[d++] = re; |
| 809 | re = re->sub()[0]; |
| 810 | } |
| 811 | |
| 812 | // Remove leading string from re. |
| 813 | if (re->op() == kRegexpLiteral) { |
| 814 | re->rune_ = 0; |
| 815 | re->op_ = kRegexpEmptyMatch; |
| 816 | } else if (re->op() == kRegexpLiteralString) { |
| 817 | if (n >= re->nrunes_) { |
| 818 | delete[] re->runes_; |
| 819 | re->runes_ = NULL; |
| 820 | re->nrunes_ = 0; |
| 821 | re->op_ = kRegexpEmptyMatch; |
| 822 | } else if (n == re->nrunes_ - 1) { |
| 823 | Rune rune = re->runes_[re->nrunes_ - 1]; |
| 824 | delete[] re->runes_; |
| 825 | re->runes_ = NULL; |
| 826 | re->nrunes_ = 0; |
| 827 | re->rune_ = rune; |
| 828 | re->op_ = kRegexpLiteral; |
| 829 | } else { |
| 830 | re->nrunes_ -= n; |
| 831 | memmove(re->runes_, re->runes_ + n, re->nrunes_ * sizeof re->runes_[0]); |
| 832 | } |
| 833 | } |
| 834 | |
| 835 | // If re is now empty, concatenations might simplify too. |
| 836 | while (d > 0) { |
| 837 | re = stk[--d]; |
| 838 | Regexp** sub = re->sub(); |
| 839 | if (sub[0]->op() == kRegexpEmptyMatch) { |
| 840 | sub[0]->Decref(); |
| 841 | sub[0] = NULL; |
| 842 | // Delete first element of concat. |
| 843 | switch (re->nsub()) { |
| 844 | case 0: |
| 845 | case 1: |
| 846 | // Impossible. |
| 847 | LOG(DFATAL) << "Concat of " << re->nsub(); |
| 848 | re->submany_ = NULL; |
| 849 | re->op_ = kRegexpEmptyMatch; |
| 850 | break; |
| 851 | |
| 852 | case 2: { |
| 853 | // Replace re with sub[1]. |
| 854 | Regexp* old = sub[1]; |
| 855 | sub[1] = NULL; |