📄 pcre_exec.cpp.svn-base
字号:
/* Match a single ASCII character. */ BEGIN_OPCODE(ASCII_CHAR): if (md.endSubject == stack.currentFrame->args.subjectPtr) RRETURN_NO_MATCH; if (*stack.currentFrame->args.subjectPtr != stack.currentFrame->args.instructionPtr[1]) RRETURN_NO_MATCH; ++stack.currentFrame->args.subjectPtr; stack.currentFrame->args.instructionPtr += 2; NEXT_OPCODE; /* Match one of two cases of an ASCII letter. */ BEGIN_OPCODE(ASCII_LETTER_IGNORING_CASE): if (md.endSubject == stack.currentFrame->args.subjectPtr) RRETURN_NO_MATCH; if ((*stack.currentFrame->args.subjectPtr | 0x20) != stack.currentFrame->args.instructionPtr[1]) RRETURN_NO_MATCH; ++stack.currentFrame->args.subjectPtr; stack.currentFrame->args.instructionPtr += 2; NEXT_OPCODE; /* Match a single character repeatedly; different opcodes share code. */ BEGIN_OPCODE(EXACT): min = stack.currentFrame->locals.max = get2ByteValue(stack.currentFrame->args.instructionPtr + 1); minimize = false; stack.currentFrame->args.instructionPtr += 3; goto REPEATCHAR; BEGIN_OPCODE(UPTO): BEGIN_OPCODE(MINUPTO): min = 0; stack.currentFrame->locals.max = get2ByteValue(stack.currentFrame->args.instructionPtr + 1); minimize = *stack.currentFrame->args.instructionPtr == OP_MINUPTO; stack.currentFrame->args.instructionPtr += 3; goto REPEATCHAR; BEGIN_OPCODE(STAR): BEGIN_OPCODE(MINSTAR): BEGIN_OPCODE(PLUS): BEGIN_OPCODE(MINPLUS): BEGIN_OPCODE(QUERY): BEGIN_OPCODE(MINQUERY): repeatInformationFromInstructionOffset(*stack.currentFrame->args.instructionPtr++ - OP_STAR, minimize, min, stack.currentFrame->locals.max); /* Common code for all repeated single-character matches. We can give up quickly if there are fewer than the minimum number of characters left in the subject. */ REPEATCHAR: stack.currentFrame->locals.length = 1; getUTF8CharAndIncrementLength(stack.currentFrame->locals.fc, stack.currentFrame->args.instructionPtr, stack.currentFrame->locals.length); if (min * (stack.currentFrame->locals.fc > 0xFFFF ? 2 : 1) > md.endSubject - stack.currentFrame->args.subjectPtr) RRETURN_NO_MATCH; stack.currentFrame->args.instructionPtr += stack.currentFrame->locals.length; if (stack.currentFrame->locals.fc <= 0xFFFF) { int othercase = md.ignoreCase ? kjs_pcre_ucp_othercase(stack.currentFrame->locals.fc) : -1; for (int i = 1; i <= min; i++) { if (*stack.currentFrame->args.subjectPtr != stack.currentFrame->locals.fc && *stack.currentFrame->args.subjectPtr != othercase) RRETURN_NO_MATCH; ++stack.currentFrame->args.subjectPtr; } if (min == stack.currentFrame->locals.max) NEXT_OPCODE; if (minimize) { stack.currentFrame->locals.repeatOthercase = othercase; for (stack.currentFrame->locals.fi = min;; stack.currentFrame->locals.fi++) { RECURSIVE_MATCH(28, stack.currentFrame->args.instructionPtr, stack.currentFrame->args.bracketChain); if (isMatch) RRETURN; if (stack.currentFrame->locals.fi >= stack.currentFrame->locals.max || stack.currentFrame->args.subjectPtr >= md.endSubject) RRETURN; if (*stack.currentFrame->args.subjectPtr != stack.currentFrame->locals.fc && *stack.currentFrame->args.subjectPtr != stack.currentFrame->locals.repeatOthercase) RRETURN; ++stack.currentFrame->args.subjectPtr; } /* Control never reaches here */ } else { stack.currentFrame->locals.subjectPtrAtStartOfInstruction = stack.currentFrame->args.subjectPtr; for (int i = min; i < stack.currentFrame->locals.max; i++) { if (stack.currentFrame->args.subjectPtr >= md.endSubject) break; if (*stack.currentFrame->args.subjectPtr != stack.currentFrame->locals.fc && *stack.currentFrame->args.subjectPtr != othercase) break; ++stack.currentFrame->args.subjectPtr; } while (stack.currentFrame->args.subjectPtr >= stack.currentFrame->locals.subjectPtrAtStartOfInstruction) { RECURSIVE_MATCH(29, stack.currentFrame->args.instructionPtr, stack.currentFrame->args.bracketChain); if (isMatch) RRETURN; --stack.currentFrame->args.subjectPtr; } RRETURN_NO_MATCH; } /* Control never reaches here */ } else { /* No case on surrogate pairs, so no need to bother with "othercase". */ for (int i = 1; i <= min; i++) { if (*stack.currentFrame->args.subjectPtr != stack.currentFrame->locals.fc) RRETURN_NO_MATCH; stack.currentFrame->args.subjectPtr += 2; } if (min == stack.currentFrame->locals.max) NEXT_OPCODE; if (minimize) { for (stack.currentFrame->locals.fi = min;; stack.currentFrame->locals.fi++) { RECURSIVE_MATCH(30, stack.currentFrame->args.instructionPtr, stack.currentFrame->args.bracketChain); if (isMatch) RRETURN; if (stack.currentFrame->locals.fi >= stack.currentFrame->locals.max || stack.currentFrame->args.subjectPtr >= md.endSubject) RRETURN; if (*stack.currentFrame->args.subjectPtr != stack.currentFrame->locals.fc) RRETURN; stack.currentFrame->args.subjectPtr += 2; } /* Control never reaches here */ } else { stack.currentFrame->locals.subjectPtrAtStartOfInstruction = stack.currentFrame->args.subjectPtr; for (int i = min; i < stack.currentFrame->locals.max; i++) { if (stack.currentFrame->args.subjectPtr > md.endSubject - 2) break; if (*stack.currentFrame->args.subjectPtr != stack.currentFrame->locals.fc) break; stack.currentFrame->args.subjectPtr += 2; } while (stack.currentFrame->args.subjectPtr >= stack.currentFrame->locals.subjectPtrAtStartOfInstruction) { RECURSIVE_MATCH(31, stack.currentFrame->args.instructionPtr, stack.currentFrame->args.bracketChain); if (isMatch) RRETURN; stack.currentFrame->args.subjectPtr -= 2; } RRETURN_NO_MATCH; } /* Control never reaches here */ } /* Control never reaches here */ /* Match a negated single one-byte character. */ BEGIN_OPCODE(NOT): { if (stack.currentFrame->args.subjectPtr >= md.endSubject) RRETURN_NO_MATCH; stack.currentFrame->args.instructionPtr++; int c = *stack.currentFrame->args.subjectPtr++; if (md.ignoreCase) { if (c < 128) c = toLowerCase(c); if (toLowerCase(*stack.currentFrame->args.instructionPtr++) == c) RRETURN_NO_MATCH; } else { if (*stack.currentFrame->args.instructionPtr++ == c) RRETURN_NO_MATCH; } NEXT_OPCODE; } /* Match a negated single one-byte character repeatedly. This is almost a repeat of the code for a repeated single character, but I haven't found a nice way of commoning these up that doesn't require a test of the positive/negative option for each character match. Maybe that wouldn't add very much to the time taken, but character matching *is* what this is all about... */ BEGIN_OPCODE(NOTEXACT): min = stack.currentFrame->locals.max = get2ByteValue(stack.currentFrame->args.instructionPtr + 1); minimize = false; stack.currentFrame->args.instructionPtr += 3; goto REPEATNOTCHAR; BEGIN_OPCODE(NOTUPTO): BEGIN_OPCODE(NOTMINUPTO): min = 0; stack.currentFrame->locals.max = get2ByteValue(stack.currentFrame->args.instructionPtr + 1); minimize = *stack.currentFrame->args.instructionPtr == OP_NOTMINUPTO; stack.currentFrame->args.instructionPtr += 3; goto REPEATNOTCHAR; BEGIN_OPCODE(NOTSTAR): BEGIN_OPCODE(NOTMINSTAR): BEGIN_OPCODE(NOTPLUS): BEGIN_OPCODE(NOTMINPLUS): BEGIN_OPCODE(NOTQUERY): BEGIN_OPCODE(NOTMINQUERY): repeatInformationFromInstructionOffset(*stack.currentFrame->args.instructionPtr++ - OP_NOTSTAR, minimize, min, stack.currentFrame->locals.max); /* Common code for all repeated single-byte matches. We can give up quickly if there are fewer than the minimum number of bytes left in the subject. */ REPEATNOTCHAR: if (min > md.endSubject - stack.currentFrame->args.subjectPtr) RRETURN_NO_MATCH; stack.currentFrame->locals.fc = *stack.currentFrame->args.instructionPtr++; /* The code is duplicated for the caseless and caseful cases, for speed, since matching characters is likely to be quite common. First, ensure the minimum number of matches are present. If min = max, continue at the same level without recursing. Otherwise, if minimizing, keep trying the rest of the expression and advancing one matching character if failing, up to the maximum. Alternatively, if maximizing, find the maximum number of characters and work backwards. */ DPRINTF(("negative matching %c{%d,%d}\n", stack.currentFrame->locals.fc, min, stack.currentFrame->locals.max)); if (md.ignoreCase) { if (stack.currentFrame->locals.fc < 128) stack.currentFrame->locals.fc = toLowerCase(stack.currentFrame->locals.fc); for (int i = 1; i <= min; i++) { int d = *stack.currentFrame->args.subjectPtr++; if (d < 128) d = toLowerCase(d); if (stack.currentFrame->locals.fc == d) RRETURN_NO_MATCH; } if (min == stack.currentFrame->locals.max) NEXT_OPCODE; if (minimize) { for (stack.currentFrame->locals.fi = min;; stack.currentFrame->locals.fi++) { RECURSIVE_MATCH(38, stack.currentFrame->args.instructionPtr, stack.currentFrame->args.bracketChain); if (isMatch) RRETURN; int d = *stack.currentFrame->args.subjectPtr++; if (d < 128) d = toLowerCase(d); if (stack.currentFrame->locals.fi >= stack.currentFrame->locals.max || stack.currentFrame->args.subjectPtr >= md.endSubject || stack.currentFrame->locals.fc == d) RRETURN; } /* Control never reaches here */ } /* Maximize case */ else { stack.currentFrame->locals.subjectPtrAtStartOfInstruction = stack.currentFrame->args.subjectPtr; for (int i = min; i < stack.currentFrame->locals.max; i++) { if (stack.currentFrame->args.subjectPtr >= md.endSubject) break; int d = *stack.currentFrame->args.subjectPtr; if (d < 128) d = toLowerCase(d); if (stack.currentFrame->locals.fc == d) break; ++stack.currentFrame->args.subjectPtr; } for (;;) { RECURSIVE_MATCH(40, stack.currentFrame->args.instructionPtr, stack.currentFrame->args.bracketChain); if (isMatch) RRETURN; if (stack.currentFrame->args.subjectPtr-- == stack.currentFrame->locals.subjectPtrAtStartOfInstruction) break; /* Stop if tried at original pos */ } RRETURN; } /* Control never reaches here */ }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -