📄 pcre_exec.cpp.svn-base
字号:
BEGIN_OPCODE(BRAZERO): { stack.currentFrame->locals.startOfRepeatingBracket = stack.currentFrame->args.instructionPtr + 1; RECURSIVE_MATCH_STARTNG_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_STARTNG_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_STARTNG_NEW_GROUP(17, stack.currentFrame->locals.instructionPtrAtStartOfOnce, stack.currentFrame->args.bracketChain); if (isMatch) RRETURN; } else { /* OP_KETRMAX */ RECURSIVE_MATCH_STARTNG_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; case OP_CRRANGE: case OP_CRMINRANGE: minimize = (*stack.currentFrame->args.instructionPtr == OP_CRMINRANGE); min = get2ByteValue(stack.currentFrame->args.instructionPtr + 1); stack.currentFrame->locals.max = get2ByteValue(stack.currentFrame->args.instructionPtr + 3); if (stack.currentFrame->locals.max == 0) stack.currentFrame->locals.max = INT_MAX; stack.currentFrame->args.instructionPtr += 5; break; default: /* No repeat follows */ if (!matchRef(stack.currentFrame->locals.offset, stack.currentFrame->args.subjectPtr, stack.currentFrame->locals.length, md)) RRETURN_NO_MATCH; stack.currentFrame->args.subjectPtr += stack.currentFrame->locals.length; NEXT_OPCODE; } /* If the length of the reference is zero, just continue with the main loop. */ if (stack.currentFrame->locals.length == 0) NEXT_OPCODE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -