| Index: third_party/re2/re2/nfa.cc
|
| diff --git a/third_party/re2/re2/nfa.cc b/third_party/re2/re2/nfa.cc
|
| index 8c4f76136d51fbbfbeb9372b61dad0438c2d9886..bc8996c420f3b709dd4ea539a303a69a2eca8ee2 100644
|
| --- a/third_party/re2/re2/nfa.cc
|
| +++ b/third_party/re2/re2/nfa.cc
|
| @@ -122,7 +122,7 @@ class NFA {
|
|
|
| Thread* free_threads_; // free list
|
|
|
| - DISALLOW_EVIL_CONSTRUCTORS(NFA);
|
| + DISALLOW_COPY_AND_ASSIGN(NFA);
|
| };
|
|
|
| NFA::NFA(Prog* prog) {
|
| @@ -468,7 +468,7 @@ bool NFA::Search(const StringPiece& text, const StringPiece& const_context,
|
|
|
| if (text.begin() > context.begin()) {
|
| c = text.begin()[-1] & 0xFF;
|
| - wasword = Prog::IsWordChar(c);
|
| + wasword = Prog::IsWordChar(static_cast<uint8>(c));
|
| }
|
|
|
| // Loop over the text, stepping the machine.
|
| @@ -529,7 +529,8 @@ bool NFA::Search(const StringPiece& text, const StringPiece& const_context,
|
| break;
|
|
|
| case kInstCapture:
|
| - match_[ip->cap()] = p;
|
| + if (ip->cap() < ncapture_)
|
| + match_[ip->cap()] = p;
|
| id = ip->out();
|
| continue;
|
|
|
| @@ -607,7 +608,8 @@ bool NFA::Search(const StringPiece& text, const StringPiece& const_context,
|
|
|
| if (matched_) {
|
| for (int i = 0; i < nsubmatch; i++)
|
| - submatch[i].set(match_[2*i], match_[2*i+1] - match_[2*i]);
|
| + submatch[i].set(match_[2*i],
|
| + static_cast<int>(match_[2*i+1] - match_[2*i]));
|
| if (Debug)
|
| fprintf(stderr, "match (%d,%d)\n",
|
| static_cast<int>(match_[0] - btext_),
|
| @@ -705,5 +707,52 @@ Prog::SearchNFA(const StringPiece& text, const StringPiece& context,
|
| return true;
|
| }
|
|
|
| -} // namespace re2
|
| +// For each instruction i in the program reachable from the start, compute the
|
| +// number of instructions reachable from i by following only empty transitions
|
| +// and record that count as fanout[i].
|
| +//
|
| +// fanout holds the results and is also the work queue for the outer iteration.
|
| +// reachable holds the reached nodes for the inner iteration.
|
| +void Prog::Fanout(SparseArray<int>* fanout) {
|
| + DCHECK_EQ(fanout->max_size(), size());
|
| + SparseSet reachable(size());
|
| + fanout->clear();
|
| + fanout->set_new(start(), 0);
|
| + for (SparseArray<int>::iterator i = fanout->begin(); i != fanout->end(); ++i) {
|
| + int* count = &i->second;
|
| + reachable.clear();
|
| + reachable.insert(i->index());
|
| + for (SparseSet::iterator j = reachable.begin(); j != reachable.end(); ++j) {
|
| + Prog::Inst* ip = inst(*j);
|
| + switch (ip->opcode()) {
|
| + default:
|
| + LOG(DFATAL) << "unhandled " << ip->opcode() << " in Prog::Fanout()";
|
| + break;
|
| +
|
| + case kInstByteRange:
|
| + (*count)++;
|
| + if (!fanout->has_index(ip->out())) {
|
| + fanout->set_new(ip->out(), 0);
|
| + }
|
| + break;
|
| +
|
| + case kInstAlt:
|
| + case kInstAltMatch:
|
| + reachable.insert(ip->out1());
|
| + // fall through
|
| +
|
| + case kInstCapture:
|
| + case kInstEmptyWidth:
|
| + case kInstNop:
|
| + reachable.insert(ip->out());
|
| + break;
|
|
|
| + case kInstMatch:
|
| + case kInstFail:
|
| + break;
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| +} // namespace re2
|
|
|