// Find matches in input. private void allMatches(MachineInput input, int n, DeliverFunc deliver) { int end = input.endPos(); if (n < 0) { n = end + 1; } for (int pos = 0, i = 0, prevMatchEnd = -1; i < n && pos <= end;) { int[] matches = doExecute(input, pos, UNANCHORED, prog.numCap); if (matches == null || matches.Length == 0) { break; } bool accept = true; if (matches[1] == pos) { // We've found an empty match. if (matches[0] == prevMatchEnd) { // We don't allow an empty match right // after a previous match, so ignore it. accept = false; } int r = input.step(pos); if (r < 0) { // EOF pos = end + 1; } else { pos += r & 0x7; } } else { pos = matches[1]; } prevMatchEnd = matches[1]; if (accept) { deliver(pad(matches)); i++; } } }
// match() runs the machine over the input |in| starting at |pos| with the // RE2 Anchor |anchor|. // It reports whether a match was found. // If so, matchcap holds the submatch information. public bool match(MachineInput @in, int pos, int anchor) { int startCond = re2.cond; if (startCond == Utils.EMPTY_ALL) { // impossible return(false); } if ((anchor == RE2.ANCHOR_START || anchor == RE2.ANCHOR_BOTH) && pos != 0) { return(false); } matched = false; for (int jj = 0; jj < prog.numCap; ++jj) { matchcap[jj] = -1; } Queue runq = q0, nextq = q1; int r = @in.step(pos); int rune = r >> 3; int width = r & 7; int rune1 = -1; int width1 = 0; if (r != MachineInput.EOF) { r = @in.step(pos + width); rune1 = r >> 3; width1 = r & 7; } int flag; // bitmask of EMPTY_* flags if (pos == 0) { flag = Utils.emptyOpContext(-1, rune); } else { flag = @in.context(pos); } for (;;) { if (runq.isEmpty()) { if ((startCond & Utils.EMPTY_BEGIN_TEXT) != 0 && pos != 0) { // Anchored match, past beginning of text. break; } if (matched) { // Have match; finished exploring alternatives. break; } if (re2.prefix.Length != 0 && rune1 != re2.prefixRune && @in.canCheckPrefix()) { // Match requires literal prefix; fast search for it. int advance = @in.index(re2, pos); if (advance < 0) { break; } pos += advance; r = @in.step(pos); rune = r >> 3; width = r & 7; r = @in.step(pos + width); rune1 = r >> 3; width1 = r & 7; } } if (!matched && (pos == 0 || anchor == RE2.UNANCHORED)) { // If we are anchoring at begin then only add threads that begin // at |pos| = 0. if (ncap > 0) { matchcap[0] = pos; } add(runq, prog.start, pos, matchcap, flag, null); } flag = Utils.emptyOpContext(rune, rune1); step(runq, nextq, pos, pos + width, rune, flag, anchor, pos == @in.endPos()); if (width == 0) { // EOF break; } if (ncap == 0 && matched) { // Found a match and not paying attention // to where it is, so any match will do. break; } pos += width; rune = rune1; width = width1; if (rune != -1) { r = @in.step(pos + width); rune1 = r >> 3; width1 = r & 7; } Queue tmpq = runq; runq = nextq; nextq = tmpq; } free(nextq); return(matched); }