📄 regexec.c
字号:
pend = (BIT_STATUS_AT(reg->bt_mem_end, mem) ? STACK_AT(mem_end_stk[mem])->u.mem.pstr : (UChar* )((void* )mem_end_stk[mem])); n = pend - pstart; DATA_ENSURE(n); sprev = s; swork = s; STRING_CMP_VALUE_IC(ambig_flag, pstart, &swork, n, is_fail); if (is_fail) continue; s = swork; while (sprev + (len = enc_len(encode, sprev)) < s) sprev += len; p += (SIZE_MEMNUM * (tlen - i - 1)); break; /* success */ } if (i == tlen) goto fail; STAT_OP_OUT; continue; } break; case OP_SET_OPTION_PUSH: STAT_OP_IN(OP_SET_OPTION_PUSH); GET_OPTION_INC(option, p); STACK_PUSH_ALT(p, s, sprev); p += SIZE_OP_SET_OPTION + SIZE_OP_FAIL; STAT_OP_OUT; continue; break; case OP_SET_OPTION: STAT_OP_IN(OP_SET_OPTION); GET_OPTION_INC(option, p); STAT_OP_OUT; continue; break; case OP_NULL_CHECK_START: STAT_OP_IN(OP_NULL_CHECK_START); GET_MEMNUM_INC(mem, p); /* mem: null check id */ STACK_PUSH_NULL_CHECK_START(mem, s); STAT_OP_OUT; continue; break; case OP_NULL_CHECK_END: STAT_OP_IN(OP_NULL_CHECK_END); { int isnull; GET_MEMNUM_INC(mem, p); /* mem: null check id */ STACK_NULL_CHECK(isnull, mem, s); if (isnull) {#ifdef ONIG_DEBUG_MATCH fprintf(stderr, "NULL_CHECK_END: skip id:%d, s:%d\n", (int )mem, (int )s);#endif null_check_found: /* empty loop founded, skip next instruction */ switch (*p++) { case OP_JUMP: case OP_PUSH: p += SIZE_RELADDR; break; case OP_REPEAT_INC: case OP_REPEAT_INC_NG: case OP_REPEAT_INC_SG: case OP_REPEAT_INC_NG_SG: p += SIZE_MEMNUM; break; default: goto unexpected_bytecode_error; break; } } } STAT_OP_OUT; continue; break;#ifdef USE_INFINITE_REPEAT_MONOMANIAC_MEM_STATUS_CHECK case OP_NULL_CHECK_END_MEMST: STAT_OP_IN(OP_NULL_CHECK_END_MEMST); { int isnull; GET_MEMNUM_INC(mem, p); /* mem: null check id */ STACK_NULL_CHECK_MEMST(isnull, mem, s, reg); if (isnull) {#ifdef ONIG_DEBUG_MATCH fprintf(stderr, "NULL_CHECK_END_MEMST: skip id:%d, s:%d\n", (int )mem, (int )s);#endif if (isnull == -1) goto fail; goto null_check_found; } } STAT_OP_OUT; continue; break;#endif#ifdef USE_SUBEXP_CALL case OP_NULL_CHECK_END_MEMST_PUSH: STAT_OP_IN(OP_NULL_CHECK_END_MEMST_PUSH); { int isnull; GET_MEMNUM_INC(mem, p); /* mem: null check id */#ifdef USE_INFINITE_REPEAT_MONOMANIAC_MEM_STATUS_CHECK STACK_NULL_CHECK_MEMST_REC(isnull, mem, s, reg);#else STACK_NULL_CHECK_REC(isnull, mem, s);#endif if (isnull) {#ifdef ONIG_DEBUG_MATCH fprintf(stderr, "NULL_CHECK_END_MEMST_PUSH: skip id:%d, s:%d\n", (int )mem, (int )s);#endif if (isnull == -1) goto fail; goto null_check_found; } else { STACK_PUSH_NULL_CHECK_END(mem); } } STAT_OP_OUT; continue; break;#endif case OP_JUMP: STAT_OP_IN(OP_JUMP); GET_RELADDR_INC(addr, p); p += addr; STAT_OP_OUT; CHECK_INTERRUPT_IN_MATCH_AT; continue; break; case OP_PUSH: STAT_OP_IN(OP_PUSH); GET_RELADDR_INC(addr, p); STACK_PUSH_ALT(p + addr, s, sprev); STAT_OP_OUT; continue; break; case OP_POP: STAT_OP_IN(OP_POP); STACK_POP_ONE; STAT_OP_OUT; continue; break; case OP_PUSH_OR_JUMP_EXACT1: STAT_OP_IN(OP_PUSH_OR_JUMP_EXACT1); GET_RELADDR_INC(addr, p); if (*p == *s && DATA_ENSURE_CHECK(1)) { p++; STACK_PUSH_ALT(p + addr, s, sprev); STAT_OP_OUT; continue; } p += (addr + 1); STAT_OP_OUT; continue; break; case OP_PUSH_IF_PEEK_NEXT: STAT_OP_IN(OP_PUSH_IF_PEEK_NEXT); GET_RELADDR_INC(addr, p); if (*p == *s) { p++; STACK_PUSH_ALT(p + addr, s, sprev); STAT_OP_OUT; continue; } p++; STAT_OP_OUT; continue; break; case OP_REPEAT: STAT_OP_IN(OP_REPEAT); { GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */ GET_RELADDR_INC(addr, p); STACK_ENSURE(1); repeat_stk[mem] = GET_STACK_INDEX(stk); STACK_PUSH_REPEAT(mem, p); if (reg->repeat_range[mem].lower == 0) { STACK_PUSH_ALT(p + addr, s, sprev); } } STAT_OP_OUT; continue; break; case OP_REPEAT_NG: STAT_OP_IN(OP_REPEAT_NG); { GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */ GET_RELADDR_INC(addr, p); STACK_ENSURE(1); repeat_stk[mem] = GET_STACK_INDEX(stk); STACK_PUSH_REPEAT(mem, p); if (reg->repeat_range[mem].lower == 0) { STACK_PUSH_ALT(p, s, sprev); p += addr; } } STAT_OP_OUT; continue; break; case OP_REPEAT_INC: STAT_OP_IN(OP_REPEAT_INC); GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */ si = repeat_stk[mem]; stkp = STACK_AT(si); repeat_inc: stkp->u.repeat.count++; if (stkp->u.repeat.count == reg->repeat_range[mem].upper) { /* end of repeat. Nothing to do. */ } else if (stkp->u.repeat.count >= reg->repeat_range[mem].lower) { STACK_PUSH_ALT(p, s, sprev); p = STACK_AT(si)->u.repeat.pcode; /* Don't use stkp after PUSH. */ } else { p = stkp->u.repeat.pcode; } STACK_PUSH_REPEAT_INC(si); STAT_OP_OUT; CHECK_INTERRUPT_IN_MATCH_AT; continue; break; case OP_REPEAT_INC_SG: STAT_OP_IN(OP_REPEAT_INC_SG); GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */ STACK_GET_REPEAT(mem, stkp); si = GET_STACK_INDEX(stkp); goto repeat_inc; break; case OP_REPEAT_INC_NG: STAT_OP_IN(OP_REPEAT_INC_NG); GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */ si = repeat_stk[mem]; stkp = STACK_AT(si); repeat_inc_ng: stkp->u.repeat.count++; if (stkp->u.repeat.count < reg->repeat_range[mem].upper || IS_REPEAT_INFINITE(reg->repeat_range[mem].upper)) { if (stkp->u.repeat.count >= reg->repeat_range[mem].lower) { UChar* pcode = stkp->u.repeat.pcode; STACK_PUSH_REPEAT_INC(si); STACK_PUSH_ALT(pcode, s, sprev); } else { p = stkp->u.repeat.pcode; STACK_PUSH_REPEAT_INC(si); } } else if (stkp->u.repeat.count == reg->repeat_range[mem].upper) { STACK_PUSH_REPEAT_INC(si); } STAT_OP_OUT; CHECK_INTERRUPT_IN_MATCH_AT; continue; break; case OP_REPEAT_INC_NG_SG: STAT_OP_IN(OP_REPEAT_INC_NG_SG); GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */ STACK_GET_REPEAT(mem, stkp); si = GET_STACK_INDEX(stkp); goto repeat_inc_ng; break; case OP_PUSH_POS: STAT_OP_IN(OP_PUSH_POS); STACK_PUSH_POS(s, sprev); STAT_OP_OUT; continue; break; case OP_POP_POS: STAT_OP_IN(OP_POP_POS); { STACK_POS_END(stkp); s = stkp->u.state.pstr; sprev = stkp->u.state.pstr_prev; } STAT_OP_OUT; continue; break; case OP_PUSH_POS_NOT: STAT_OP_IN(OP_PUSH_POS_NOT); GET_RELADDR_INC(addr, p); STACK_PUSH_POS_NOT(p + addr, s, sprev); STAT_OP_OUT; continue; break; case OP_FAIL_POS: STAT_OP_IN(OP_FAIL_POS); STACK_POP_TIL_POS_NOT; goto fail; break; case OP_PUSH_STOP_BT: STAT_OP_IN(OP_PUSH_STOP_BT); STACK_PUSH_STOP_BT; STAT_OP_OUT; continue; break; case OP_POP_STOP_BT: STAT_OP_IN(OP_POP_STOP_BT); STACK_STOP_BT_END; STAT_OP_OUT; continue; break; case OP_LOOK_BEHIND: STAT_OP_IN(OP_LOOK_BEHIND); GET_LENGTH_INC(tlen, p); s = (UChar* )ONIGENC_STEP_BACK(encode, str, s, (int )tlen); if (IS_NULL(s)) goto fail; sprev = (UChar* )onigenc_get_prev_char_head(encode, str, s); STAT_OP_OUT; continue; break; case OP_PUSH_LOOK_BEHIND_NOT: STAT_OP_IN(OP_PUSH_LOOK_BEHIND_NOT); GET_RELADDR_INC(addr, p); GET_LENGTH_INC(tlen, p); q = (UChar* )ONIGENC_STEP_BACK(encode, str, s, (int )tlen); if (IS_NULL(q)) { /* too short case -> success. ex. /(?<!XXX)a/.match("a") If you want to change to fail, replace following line. */ p += addr; /* goto fail; */ } else { STACK_PUSH_LOOK_BEHIND_NOT(p + addr, s, sprev); s = q; sprev = (UChar* )onigenc_get_prev_char_head(encode, str, s); } STAT_OP_OUT; continue; break; case OP_FAIL_LOOK_BEHIND_NOT: STAT_OP_IN(OP_FAIL_LOOK_BEHIND_NOT); STACK_POP_TIL_LOOK_BEHIND_NOT; goto fail; break;#ifdef USE_SUBEXP_CALL case OP_CALL: STAT_OP_IN(OP_CALL); GET_ABSADDR_INC(addr, p); STACK_PUSH_CALL_FRAME(p); p = reg->p + addr; STAT_OP_OUT; continue; break; case OP_RETURN: STAT_OP_IN(OP_RETURN); STACK_RETURN(p); STACK_PUSH_RETURN; STAT_OP_OUT; continue; break;#endif case OP_FINISH: goto finish; break; fail: STAT_OP_OUT; /* fall */ case OP_FAIL: STAT_OP_IN(OP_FAIL); STACK_POP; p = stk->u.state.pcode; s = stk->u.state.pstr; sprev = stk->u.state.pstr_prev; STAT_OP_OUT; continue; break; default: goto bytecode_error; } /* end of switch */ sprev = sbegin; } /* end of while(1) */ finish: STACK_SAVE; return best_len;#ifdef ONIG_DEBUG stack_error: STACK_SAVE; return ONIGERR_STACK_BUG;#endif bytecode_error: STACK_SAVE; return ONIGERR_UNDEFINED_BYTECODE; unexpected_bytecode_error: STACK_SAVE; return ONIGERR_UNEXPECTED_BYTECODE;}static UChar*slow_search(OnigEncoding enc, UChar* target, UChar* target_end, const UChar* text, const UChar* text_end, UChar* text_range){ UChar *t, *p, *s, *end; end = (UChar* )text_end; end -= target_end - target - 1; if (end > text_range) end = text_range; s = (UChar* )text; while (s < end) { if (*s == *target) { p = s + 1; t = target + 1; while (t < target_end) { if (*t != *p++) break; t++; } if (t == target_end) return s; } s += enc_len(enc, s); } return (UChar* )NULL;}static intstr_lower_case_match(OnigEncoding enc, int ambig_flag, const UChar* t, const UChar* tend, const UChar* p, const UChar* end){ int lowlen; UChar *q, lowbuf[ONIGENC_MBC_NORMALIZE_MAXLEN]; const UChar* tsave; const UChar* psave; tsave = t; psave = p; retry: while (t < tend) { lowlen = ONIGENC_MBC_TO_NORMALIZE(enc, ambig_flag, &p, end, lowbuf); q = lowbuf; while (lowlen > 0) { if (*t++ != *q++) { if ((ambig_flag & ONIGENC_AMBIGUOUS_MATCH_COMPOUND) != 0) { ambig_flag &= ~ONIGENC_AMBIGUOUS_MATCH_COMPOUND; t = tsave; p = psave; goto retry; } else return 0; } lowlen--; } } return 1;}static UChar*slow_search_ic(OnigEncoding enc, int ambig_flag, UChar* target, UChar* target_end, const UChar* text, const UChar* text_end, UChar* text_range){ UChar *s, *end; end = (UChar* )text_end; end -= target_end - target - 1; if (end > text_range) end = text_range; s = (UChar* )text; while (s < end) { if (str_lower_case_match(enc, ambig_flag, target, target_end, s, text_end)) return s; s += enc_len(enc, s); } return (UChar* )NULL;}static UChar*slow_search_backward(OnigEncoding enc, UChar* target, UChar* target_end, const UChar* text, const UChar* adjust_text, const UChar* text_end, const UChar* text_start){ UChar *t, *p, *s; s = (UChar* )text_end; s -= (target_end - target); if (s > text_start) s = (UChar* )text_start; else s = ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc, adjust_text, s); while (s >= text) { if (*s == *target) { p = s + 1; t = target + 1; while (t < target_end) { if (*t != *p++) break; t++; } if (t == target_end) return s; } s = (UChar* )onigenc_get_prev_char_head(enc, adjust_text, s); } return (UChar* )NULL;}static UChar*slow_search_backward_ic(OnigEncoding enc, int ambig_flag, UChar* target, UChar* target_end, const UChar* text, const UChar* adjust_text, const UChar* text_end, const UChar* text_start){ UChar *s; s = (UChar* )text_end; s -= (
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -