| 212 | } |
| 213 | |
| 214 | bool Prog::SearchOnePass(const StringPiece& text, |
| 215 | const StringPiece& const_context, |
| 216 | Anchor anchor, MatchKind kind, |
| 217 | StringPiece* match, int nmatch) { |
| 218 | if (anchor != kAnchored && kind != kFullMatch) { |
| 219 | LOG(DFATAL) << "Cannot use SearchOnePass for unanchored matches."; |
| 220 | return false; |
| 221 | } |
| 222 | |
| 223 | // Make sure we have at least cap[1], |
| 224 | // because we use it to tell if we matched. |
| 225 | int ncap = 2*nmatch; |
| 226 | if (ncap < 2) |
| 227 | ncap = 2; |
| 228 | |
| 229 | const char* cap[kMaxCap]; |
| 230 | for (int i = 0; i < ncap; i++) |
| 231 | cap[i] = NULL; |
| 232 | |
| 233 | const char* matchcap[kMaxCap]; |
| 234 | for (int i = 0; i < ncap; i++) |
| 235 | matchcap[i] = NULL; |
| 236 | |
| 237 | StringPiece context = const_context; |
| 238 | if (context.data() == NULL) |
| 239 | context = text; |
| 240 | if (anchor_start() && context.begin() != text.begin()) |
| 241 | return false; |
| 242 | if (anchor_end() && context.end() != text.end()) |
| 243 | return false; |
| 244 | if (anchor_end()) |
| 245 | kind = kFullMatch; |
| 246 | |
| 247 | uint8_t* nodes = onepass_nodes_.data(); |
| 248 | int statesize = sizeof(OneState) + bytemap_range()*sizeof(uint32_t); |
| 249 | // start() is always mapped to the zeroth OneState. |
| 250 | OneState* state = IndexToNode(nodes, statesize, 0); |
| 251 | uint8_t* bytemap = bytemap_; |
| 252 | const char* bp = text.data(); |
| 253 | const char* ep = text.data() + text.size(); |
| 254 | const char* p; |
| 255 | bool matched = false; |
| 256 | matchcap[0] = bp; |
| 257 | cap[0] = bp; |
| 258 | uint32_t nextmatchcond = state->matchcond; |
| 259 | for (p = bp; p < ep; p++) { |
| 260 | int c = bytemap[*p & 0xFF]; |
| 261 | uint32_t matchcond = nextmatchcond; |
| 262 | uint32_t cond = state->action[c]; |
| 263 | |
| 264 | // Determine whether we can reach act->next. |
| 265 | // If so, advance state and nextmatchcond. |
| 266 | if ((cond & kEmptyAllFlags) == 0 || Satisfy(cond, context, p)) { |
| 267 | uint32_t nextindex = cond >> kIndexShift; |
| 268 | state = IndexToNode(nodes, statesize, nextindex); |
| 269 | nextmatchcond = state->matchcond; |
| 270 | } else { |
| 271 | state = NULL; |