⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcre_exec.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                NEXT_OPCODE;                            /* Negative assertion: all branches must fail to match */                            BEGIN_OPCODE(ASSERT_NOT):                do {                    RECURSIVE_MATCH_NEW_GROUP(7, stack.currentFrame->args.instructionPtr + 1 + LINK_SIZE, NULL);                    if (isMatch)                        RRETURN_NO_MATCH;                    stack.currentFrame->args.instructionPtr += getLinkValue(stack.currentFrame->args.instructionPtr + 1);                } while (*stack.currentFrame->args.instructionPtr == OP_ALT);                                stack.currentFrame->args.instructionPtr += 1 + LINK_SIZE;                NEXT_OPCODE;                            /* An alternation is the end of a branch; scan along to find the end of the             bracketed group and go to there. */                            BEGIN_OPCODE(ALT):                advanceToEndOfBracket(stack.currentFrame->args.instructionPtr);                NEXT_OPCODE;                            /* BRAZERO and BRAMINZERO occur just before a bracket group, indicating             that it may occur zero times. It may repeat infinitely, or not at all -             i.e. it could be ()* or ()? in the pattern. Brackets with fixed upper             repeat limits are compiled as a number of copies, with the optional ones             preceded by BRAZERO or BRAMINZERO. */                            BEGIN_OPCODE(BRAZERO): {                stack.currentFrame->locals.startOfRepeatingBracket = stack.currentFrame->args.instructionPtr + 1;                RECURSIVE_MATCH_NEW_GROUP(14, stack.currentFrame->locals.startOfRepeatingBracket, stack.currentFrame->args.bracketChain);                if (isMatch)                    RRETURN;                advanceToEndOfBracket(stack.currentFrame->locals.startOfRepeatingBracket);                stack.currentFrame->args.instructionPtr = stack.currentFrame->locals.startOfRepeatingBracket + 1 + LINK_SIZE;                NEXT_OPCODE;            }                            BEGIN_OPCODE(BRAMINZERO): {                stack.currentFrame->locals.startOfRepeatingBracket = stack.currentFrame->args.instructionPtr + 1;                advanceToEndOfBracket(stack.currentFrame->locals.startOfRepeatingBracket);                RECURSIVE_MATCH_NEW_GROUP(15, stack.currentFrame->locals.startOfRepeatingBracket + 1 + LINK_SIZE, stack.currentFrame->args.bracketChain);                if (isMatch)                    RRETURN;                stack.currentFrame->args.instructionPtr++;                NEXT_OPCODE;            }                            /* End of a group, repeated or non-repeating. If we are at the end of             an assertion "group", stop matching and return 1, but record the             current high water mark for use by positive assertions. Do this also             for the "once" (not-backup up) groups. */                            BEGIN_OPCODE(KET):            BEGIN_OPCODE(KETRMIN):            BEGIN_OPCODE(KETRMAX):                stack.currentFrame->locals.instructionPtrAtStartOfOnce = stack.currentFrame->args.instructionPtr - getLinkValue(stack.currentFrame->args.instructionPtr + 1);                stack.currentFrame->locals.subjectPtrAtStartOfInstruction = stack.currentFrame->args.bracketChain->bracketStart;                /* Back up the stack of bracket start pointers. */                stack.currentFrame->args.bracketChain = stack.currentFrame->args.bracketChain->previousBracket;                if (*stack.currentFrame->locals.instructionPtrAtStartOfOnce == OP_ASSERT || *stack.currentFrame->locals.instructionPtrAtStartOfOnce == OP_ASSERT_NOT) {                    md.endOffsetTop = stack.currentFrame->args.offsetTop;                    isMatch = true;                    RRETURN;                }                                /* In all other cases except a conditional group we have to check the                 group number back at the start and if necessary complete handling an                 extraction by setting the offsets and bumping the high water mark. */                                stack.currentFrame->locals.number = *stack.currentFrame->locals.instructionPtrAtStartOfOnce - OP_BRA;                                /* For extended extraction brackets (large number), we have to fish out                 the number from a dummy opcode at the start. */                                if (stack.currentFrame->locals.number > EXTRACT_BASIC_MAX)                    stack.currentFrame->locals.number = get2ByteValue(stack.currentFrame->locals.instructionPtrAtStartOfOnce + 2 + LINK_SIZE);                stack.currentFrame->locals.offset = stack.currentFrame->locals.number << 1;                #ifdef DEBUG                printf("end bracket %d", stack.currentFrame->locals.number);                printf("\n");#endif                                /* Test for a numbered group. This includes groups called as a result                 of recursion. Note that whole-pattern recursion is coded as a recurse                 into group 0, so it won't be picked up here. Instead, we catch it when                 the OP_END is reached. */                                if (stack.currentFrame->locals.number > 0) {                    if (stack.currentFrame->locals.offset >= md.offsetMax)                        md.offsetOverflow = true;                    else {                        md.offsetVector[stack.currentFrame->locals.offset] =                        md.offsetVector[md.offsetEnd - stack.currentFrame->locals.number];                        md.offsetVector[stack.currentFrame->locals.offset+1] = stack.currentFrame->args.subjectPtr - md.startSubject;                        if (stack.currentFrame->args.offsetTop <= stack.currentFrame->locals.offset)                            stack.currentFrame->args.offsetTop = stack.currentFrame->locals.offset + 2;                    }                }                                /* For a non-repeating ket, just continue at this level. This also                 happens for a repeating ket if no characters were matched in the group.                 This is the forcible breaking of infinite loops as implemented in Perl                 5.005. If there is an options reset, it will get obeyed in the normal                 course of events. */                                if (*stack.currentFrame->args.instructionPtr == OP_KET || stack.currentFrame->args.subjectPtr == stack.currentFrame->locals.subjectPtrAtStartOfInstruction) {                    stack.currentFrame->args.instructionPtr += 1 + LINK_SIZE;                    NEXT_OPCODE;                }                                /* The repeating kets try the rest of the pattern or restart from the                 preceding bracket, in the appropriate order. */                                if (*stack.currentFrame->args.instructionPtr == OP_KETRMIN) {                    RECURSIVE_MATCH(16, stack.currentFrame->args.instructionPtr + 1 + LINK_SIZE, stack.currentFrame->args.bracketChain);                    if (isMatch)                        RRETURN;                    RECURSIVE_MATCH_NEW_GROUP(17, stack.currentFrame->locals.instructionPtrAtStartOfOnce, stack.currentFrame->args.bracketChain);                    if (isMatch)                        RRETURN;                } else { /* OP_KETRMAX */                    RECURSIVE_MATCH_NEW_GROUP(18, stack.currentFrame->locals.instructionPtrAtStartOfOnce, stack.currentFrame->args.bracketChain);                    if (isMatch)                        RRETURN;                    RECURSIVE_MATCH(19, stack.currentFrame->args.instructionPtr + 1 + LINK_SIZE, stack.currentFrame->args.bracketChain);                    if (isMatch)                        RRETURN;                }                RRETURN;                            /* Start of subject. */            BEGIN_OPCODE(CIRC):                if (stack.currentFrame->args.subjectPtr != md.startSubject)                    RRETURN_NO_MATCH;                stack.currentFrame->args.instructionPtr++;                NEXT_OPCODE;            /* After internal newline if multiline. */            BEGIN_OPCODE(BOL):                if (stack.currentFrame->args.subjectPtr != md.startSubject && !isNewline(stack.currentFrame->args.subjectPtr[-1]))                    RRETURN_NO_MATCH;                stack.currentFrame->args.instructionPtr++;                NEXT_OPCODE;            /* End of subject. */            BEGIN_OPCODE(DOLL):                if (stack.currentFrame->args.subjectPtr < md.endSubject)                    RRETURN_NO_MATCH;                stack.currentFrame->args.instructionPtr++;                NEXT_OPCODE;            /* Before internal newline if multiline. */            BEGIN_OPCODE(EOL):                if (stack.currentFrame->args.subjectPtr < md.endSubject && !isNewline(*stack.currentFrame->args.subjectPtr))                    RRETURN_NO_MATCH;                stack.currentFrame->args.instructionPtr++;                NEXT_OPCODE;                            /* Word boundary assertions */                            BEGIN_OPCODE(NOT_WORD_BOUNDARY):            BEGIN_OPCODE(WORD_BOUNDARY): {                bool currentCharIsWordChar = false;                bool previousCharIsWordChar = false;                                if (stack.currentFrame->args.subjectPtr > md.startSubject)                    previousCharIsWordChar = isWordChar(stack.currentFrame->args.subjectPtr[-1]);                if (stack.currentFrame->args.subjectPtr < md.endSubject)                    currentCharIsWordChar = isWordChar(*stack.currentFrame->args.subjectPtr);                                /* Now see if the situation is what we want */                bool wordBoundaryDesired = (*stack.currentFrame->args.instructionPtr++ == OP_WORD_BOUNDARY);                if (wordBoundaryDesired ? currentCharIsWordChar == previousCharIsWordChar : currentCharIsWordChar != previousCharIsWordChar)                    RRETURN_NO_MATCH;                NEXT_OPCODE;            }                            /* Match a single character type; inline for speed */                            BEGIN_OPCODE(NOT_NEWLINE):                if (stack.currentFrame->args.subjectPtr >= md.endSubject)                    RRETURN_NO_MATCH;                if (isNewline(*stack.currentFrame->args.subjectPtr++))                    RRETURN_NO_MATCH;                stack.currentFrame->args.instructionPtr++;                NEXT_OPCODE;            BEGIN_OPCODE(NOT_DIGIT):                if (stack.currentFrame->args.subjectPtr >= md.endSubject)                    RRETURN_NO_MATCH;                if (isASCIIDigit(*stack.currentFrame->args.subjectPtr++))                    RRETURN_NO_MATCH;                stack.currentFrame->args.instructionPtr++;                NEXT_OPCODE;            BEGIN_OPCODE(DIGIT):                if (stack.currentFrame->args.subjectPtr >= md.endSubject)                    RRETURN_NO_MATCH;                if (!isASCIIDigit(*stack.currentFrame->args.subjectPtr++))                    RRETURN_NO_MATCH;                stack.currentFrame->args.instructionPtr++;                NEXT_OPCODE;            BEGIN_OPCODE(NOT_WHITESPACE):                if (stack.currentFrame->args.subjectPtr >= md.endSubject)                    RRETURN_NO_MATCH;                if (isSpaceChar(*stack.currentFrame->args.subjectPtr++))                    RRETURN_NO_MATCH;                stack.currentFrame->args.instructionPtr++;                NEXT_OPCODE;            BEGIN_OPCODE(WHITESPACE):                if (stack.currentFrame->args.subjectPtr >= md.endSubject)                    RRETURN_NO_MATCH;                if (!isSpaceChar(*stack.currentFrame->args.subjectPtr++))                    RRETURN_NO_MATCH;                stack.currentFrame->args.instructionPtr++;                NEXT_OPCODE;                            BEGIN_OPCODE(NOT_WORDCHAR):                if (stack.currentFrame->args.subjectPtr >= md.endSubject)                    RRETURN_NO_MATCH;                if (isWordChar(*stack.currentFrame->args.subjectPtr++))                    RRETURN_NO_MATCH;                stack.currentFrame->args.instructionPtr++;                NEXT_OPCODE;                            BEGIN_OPCODE(WORDCHAR):                if (stack.currentFrame->args.subjectPtr >= md.endSubject)                    RRETURN_NO_MATCH;                if (!isWordChar(*stack.currentFrame->args.subjectPtr++))                    RRETURN_NO_MATCH;                stack.currentFrame->args.instructionPtr++;                NEXT_OPCODE;                            /* Match a back reference, possibly repeatedly. Look past the end of the             item to see if there is repeat information following. The code is similar             to that for character classes, but repeated for efficiency. Then obey             similar code to character type repeats - written out again for speed.             However, if the referenced string is the empty string, always treat             it as matched, any number of times (otherwise there could be infinite             loops). */                            BEGIN_OPCODE(REF):                stack.currentFrame->locals.offset = get2ByteValue(stack.currentFrame->args.instructionPtr + 1) << 1;               /* Doubled ref number */                stack.currentFrame->args.instructionPtr += 3;                                 /* Advance past item */                                /* If the reference is unset, set the length to be longer than the amount                 of subject left; this ensures that every attempt at a match fails. We                 can't just fail here, because of the possibility of quantifiers with zero                 minima. */                                if (stack.currentFrame->locals.offset >= stack.currentFrame->args.offsetTop || md.offsetVector[stack.currentFrame->locals.offset] < 0)                    stack.currentFrame->locals.length = 0;                else                    stack.currentFrame->locals.length = md.offsetVector[stack.currentFrame->locals.offset+1] - md.offsetVector[stack.currentFrame->locals.offset];                                /* Set up for repetition, or handle the non-repeated case */                                switch (*stack.currentFrame->args.instructionPtr) {                    case OP_CRSTAR:                    case OP_CRMINSTAR:                    case OP_CRPLUS:                    case OP_CRMINPLUS:                    case OP_CRQUERY:                    case OP_CRMINQUERY:                        repeatInformationFromInstructionOffset(*stack.currentFrame->args.instructionPtr++ - OP_CRSTAR, minimize, min, stack.currentFrame->locals.max);                        break;                        

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -