in rhino/src/main/java/org/mozilla/javascript/regexp/NativeRegExp.java [2145:2364]
private static int simpleMatch(
REGlobalData gData,
String input,
int op,
byte[] program,
int pc,
int end,
boolean updatecp,
boolean matchBackward) {
boolean result = false;
char matchCh;
int parenIndex;
int offset, length, index;
int startcp = gData.cp;
int cpDelta = matchBackward ? -1 : 1;
final int cpToMatch = gData.cp + (matchBackward ? -1 : 0);
final boolean cpInBounds = cpToMatch >= 0 && cpToMatch < end;
switch (op) {
case REOP_EMPTY:
result = true;
break;
// We just use gData.cp and not cpToMatch in the BOL, EOL, WBDRY, WNONBDRY cases
// since their behaviour is identical in both forward and backward matching
case REOP_BOL:
if (gData.cp != 0) {
if (!gData.multiline || !isLineTerm(input.charAt(gData.cp - 1))) {
break;
}
}
result = true;
break;
case REOP_EOL:
if (gData.cp != end) {
if (!gData.multiline || !isLineTerm(input.charAt(gData.cp))) {
break;
}
}
result = true;
break;
case REOP_WBDRY:
result =
((gData.cp == 0 || !isWord(input.charAt(gData.cp - 1)))
^ !((gData.cp < end) && isWord(input.charAt(gData.cp))));
break;
case REOP_WNONBDRY:
result =
((gData.cp == 0 || !isWord(input.charAt(gData.cp - 1)))
^ ((gData.cp < end) && isWord(input.charAt(gData.cp))));
break;
case REOP_DOT:
if (cpInBounds
&& ((gData.regexp.flags & JSREG_DOTALL) != 0
|| !isLineTerm(input.charAt(cpToMatch)))) {
result = true;
gData.cp += cpDelta;
}
break;
case REOP_DIGIT:
if (cpInBounds && isDigit(input.charAt(cpToMatch))) {
result = true;
gData.cp += cpDelta;
}
break;
case REOP_NONDIGIT:
if (cpInBounds && !isDigit(input.charAt(cpToMatch))) {
result = true;
gData.cp += cpDelta;
}
break;
case REOP_ALNUM:
if (cpInBounds && isWord(input.charAt(cpToMatch))) {
result = true;
gData.cp += cpDelta;
}
break;
case REOP_NONALNUM:
if (cpInBounds && !isWord(input.charAt(cpToMatch))) {
result = true;
gData.cp += cpDelta;
}
break;
case REOP_SPACE:
if (cpInBounds && isREWhiteSpace(input.charAt(cpToMatch))) {
result = true;
gData.cp += cpDelta;
}
break;
case REOP_NONSPACE:
if (cpInBounds && !isREWhiteSpace(input.charAt(cpToMatch))) {
result = true;
gData.cp += cpDelta;
}
break;
case REOP_BACKREF:
{
parenIndex = getIndex(program, pc);
pc += INDEX_LEN;
result = backrefMatcher(gData, parenIndex, input, end, matchBackward);
}
break;
case REOP_NAMED_BACKREF:
{
int groupNameIndex = getIndex(program, pc);
pc += INDEX_LEN;
int groupNameLength = getIndex(program, pc);
pc += INDEX_LEN;
if (gData.parens == null) {
break;
}
String backRefName =
new String(gData.regexp.source, groupNameIndex, groupNameLength);
List<Integer> indices = gData.regexp.namedCaptureGroups.get(backRefName);
boolean failed = false;
for (int i : indices) {
if (gData.parensIndex(i) == -1) continue;
result = backrefMatcher(gData, i, input, end, matchBackward);
if (result) {
break;
} else failed = true;
}
if (!failed) result = true;
break;
}
case REOP_FLAT:
{
offset = getIndex(program, pc);
pc += INDEX_LEN;
length = getIndex(program, pc);
pc += INDEX_LEN;
if (matchBackward) result = flatNMatcherBackward(gData, offset, length, input);
else result = flatNMatcher(gData, offset, length, input, end);
}
break;
case REOP_FLAT1:
{
matchCh = (char) (program[pc++] & 0xFF);
if (cpInBounds && input.charAt(cpToMatch) == matchCh) {
result = true;
gData.cp += cpDelta;
}
}
break;
case REOP_FLATi:
{
offset = getIndex(program, pc);
pc += INDEX_LEN;
length = getIndex(program, pc);
pc += INDEX_LEN;
if (matchBackward) result = flatNIMatcherBackward(gData, offset, length, input);
else result = flatNIMatcher(gData, offset, length, input, end);
}
break;
case REOP_FLAT1i:
{
matchCh = (char) (program[pc++] & 0xFF);
if (cpInBounds) {
char c = input.charAt(cpToMatch);
if (matchCh == c || upcase(matchCh) == upcase(c)) {
result = true;
gData.cp += cpDelta;
}
}
}
break;
case REOP_UCFLAT1:
{
matchCh = (char) getIndex(program, pc);
pc += INDEX_LEN;
if (cpInBounds && input.charAt(cpToMatch) == matchCh) {
result = true;
gData.cp += cpDelta;
}
}
break;
case REOP_UCFLAT1i:
{
matchCh = (char) getIndex(program, pc);
pc += INDEX_LEN;
if (cpInBounds) {
char c = input.charAt(cpToMatch);
if (matchCh == c || upcase(matchCh) == upcase(c)) {
result = true;
gData.cp += cpDelta;
}
}
}
break;
case REOP_CLASS:
case REOP_NCLASS:
{
index = getIndex(program, pc);
pc += INDEX_LEN;
if (cpInBounds) {
if (classMatcher(
gData, gData.regexp.classList[index], input.charAt(cpToMatch))) {
gData.cp += cpDelta;
result = true;
break;
}
}
}
break;
default:
throw Kit.codeBug();
}
if (result) {
if (!updatecp) gData.cp = startcp;
return pc;
}
gData.cp = startcp;
return -1;
}