private static int simpleMatch()

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;
    }