Runs the work queue, processing the single byte c followed by any empty strings indicated by flag. For example, c == 'a' and flag == kEmptyEndLine, means to match c$. Sets the bool *ismatch to true if the end of the regular expression program has been reached (the regexp has matched).
| 924 | // means to match c$. Sets the bool *ismatch to true if the end of the |
| 925 | // regular expression program has been reached (the regexp has matched). |
| 926 | void DFA::RunWorkqOnByte(Workq* oldq, Workq* newq, |
| 927 | int c, uint32_t flag, bool* ismatch) { |
| 928 | //mutex_.AssertHeld(); |
| 929 | |
| 930 | newq->clear(); |
| 931 | for (Workq::iterator i = oldq->begin(); i != oldq->end(); ++i) { |
| 932 | if (oldq->is_mark(*i)) { |
| 933 | if (*ismatch) |
| 934 | return; |
| 935 | newq->mark(); |
| 936 | continue; |
| 937 | } |
| 938 | int id = *i; |
| 939 | Prog::Inst* ip = prog_->inst(id); |
| 940 | switch (ip->opcode()) { |
| 941 | default: |
| 942 | LOG(DFATAL) << "unhandled opcode: " << ip->opcode(); |
| 943 | break; |
| 944 | |
| 945 | case kInstFail: // never succeeds |
| 946 | case kInstCapture: // already followed |
| 947 | case kInstNop: // already followed |
| 948 | case kInstAltMatch: // already followed |
| 949 | case kInstEmptyWidth: // already followed |
| 950 | break; |
| 951 | |
| 952 | case kInstByteRange: // can follow if c is in range |
| 953 | if (!ip->Matches(c)) |
| 954 | break; |
| 955 | AddToQueue(newq, ip->out(), flag); |
| 956 | if (ip->hint() != 0) { |
| 957 | // We have a hint, but we must cancel out the |
| 958 | // increment that will occur after the break. |
| 959 | i += ip->hint() - 1; |
| 960 | } else { |
| 961 | // We have no hint, so we must find the end |
| 962 | // of the current list and then skip to it. |
| 963 | Prog::Inst* ip0 = ip; |
| 964 | while (!ip->last()) |
| 965 | ++ip; |
| 966 | i += ip - ip0; |
| 967 | } |
| 968 | break; |
| 969 | |
| 970 | case kInstMatch: |
| 971 | if (prog_->anchor_end() && c != kByteEndText && |
| 972 | kind_ != Prog::kManyMatch) |
| 973 | break; |
| 974 | *ismatch = true; |
| 975 | if (kind_ == Prog::kFirstMatch) { |
| 976 | // Can stop processing work queue since we found a match. |
| 977 | return; |
| 978 | } |
| 979 | break; |
| 980 | } |
| 981 | } |
| 982 | |
| 983 | if (ExtraDebug) |
nothing calls this directly
no test coverage detected