📄 regexec.c
字号:
int level = 0;\ k = stk;\ while (k > stk_base) {\ k--;\ if ((k->type == STK_MEM_END_MARK || k->type == STK_MEM_END) \ && k->u.mem.num == (mnum)) {\ level++;\ }\ else if (k->type == STK_MEM_START && k->u.mem.num == (mnum)) {\ if (level == 0) break;\ level--;\ }\ }\} while (0)#define STACK_GET_MEM_RANGE(k, mnum, start, end) do {\ int level = 0;\ while (k < stk) {\ if (k->type == STK_MEM_START && k->u.mem.num == (mnum)) {\ if (level == 0) (start) = k->u.mem.pstr;\ level++;\ }\ else if (k->type == STK_MEM_END && k->u.mem.num == (mnum)) {\ level--;\ if (level == 0) {\ (end) = k->u.mem.pstr;\ break;\ }\ }\ k++;\ }\} while (0)#define STACK_PUSH_NULL_CHECK_START(cnum, s) do {\ STACK_ENSURE(1);\ stk->type = STK_NULL_CHECK_START;\ stk->u.null_check.num = (cnum);\ stk->u.null_check.pstr = (s);\ STACK_INC;\} while(0)#define STACK_PUSH_NULL_CHECK_END(cnum) do {\ STACK_ENSURE(1);\ stk->type = STK_NULL_CHECK_END;\ stk->u.null_check.num = (cnum);\ STACK_INC;\} while(0)#define STACK_PUSH_CALL_FRAME(pat) do {\ STACK_ENSURE(1);\ stk->type = STK_CALL_FRAME;\ stk->u.call_frame.ret_addr = (pat);\ STACK_INC;\} while(0)#define STACK_PUSH_RETURN do {\ STACK_ENSURE(1);\ stk->type = STK_RETURN;\ STACK_INC;\} while(0)#ifdef ONIG_DEBUG#define STACK_BASE_CHECK(p) \ if ((p) < stk_base) goto stack_error;#else#define STACK_BASE_CHECK(p)#endif#define STACK_POP_ONE do {\ stk--;\ STACK_BASE_CHECK(stk); \} while(0)#define STACK_POP do {\ switch (pop_level) {\ case STACK_POP_LEVEL_FREE:\ while (1) {\ stk--;\ STACK_BASE_CHECK(stk); \ if ((stk->type & STK_MASK_POP_USED) != 0) break;\ }\ break;\ case STACK_POP_LEVEL_MEM_START:\ while (1) {\ stk--;\ STACK_BASE_CHECK(stk); \ if ((stk->type & STK_MASK_POP_USED) != 0) break;\ else if (stk->type == STK_MEM_START) {\ mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\ mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\ }\ }\ break;\ default:\ while (1) {\ stk--;\ STACK_BASE_CHECK(stk); \ if ((stk->type & STK_MASK_POP_USED) != 0) break;\ else if (stk->type == STK_MEM_START) {\ mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\ mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\ }\ else if (stk->type == STK_REPEAT_INC) {\ STACK_AT(stk->u.repeat_inc.si)->u.repeat.count--;\ }\ else if (stk->type == STK_MEM_END) {\ mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\ mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\ }\ }\ break;\ }\} while(0)#define STACK_POP_TIL_POS_NOT do {\ while (1) {\ stk--;\ STACK_BASE_CHECK(stk); \ if (stk->type == STK_POS_NOT) break;\ else if (stk->type == STK_MEM_START) {\ mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\ mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\ }\ else if (stk->type == STK_REPEAT_INC) {\ STACK_AT(stk->u.repeat_inc.si)->u.repeat.count--;\ }\ else if (stk->type == STK_MEM_END) {\ mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\ mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\ }\ }\} while(0)#define STACK_POP_TIL_LOOK_BEHIND_NOT do {\ while (1) {\ stk--;\ STACK_BASE_CHECK(stk); \ if (stk->type == STK_LOOK_BEHIND_NOT) break;\ else if (stk->type == STK_MEM_START) {\ mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\ mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\ }\ else if (stk->type == STK_REPEAT_INC) {\ STACK_AT(stk->u.repeat_inc.si)->u.repeat.count--;\ }\ else if (stk->type == STK_MEM_END) {\ mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\ mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\ }\ }\} while(0)#define STACK_POS_END(k) do {\ k = stk;\ while (1) {\ k--;\ STACK_BASE_CHECK(k); \ if (IS_TO_VOID_TARGET(k)) {\ k->type = STK_VOID;\ }\ else if (k->type == STK_POS) {\ k->type = STK_VOID;\ break;\ }\ }\} while(0)#define STACK_STOP_BT_END do {\ StackType *k = stk;\ while (1) {\ k--;\ STACK_BASE_CHECK(k); \ if (IS_TO_VOID_TARGET(k)) {\ k->type = STK_VOID;\ }\ else if (k->type == STK_STOP_BT) {\ k->type = STK_VOID;\ break;\ }\ }\} while(0)#define STACK_NULL_CHECK(isnull,id,s) do {\ StackType* k = stk;\ while (1) {\ k--;\ STACK_BASE_CHECK(k); \ if (k->type == STK_NULL_CHECK_START) {\ if (k->u.null_check.num == (id)) {\ (isnull) = (k->u.null_check.pstr == (s));\ break;\ }\ }\ }\} while(0)#define STACK_NULL_CHECK_REC(isnull,id,s) do {\ int level = 0;\ StackType* k = stk;\ while (1) {\ k--;\ STACK_BASE_CHECK(k); \ if (k->type == STK_NULL_CHECK_START) {\ if (k->u.null_check.num == (id)) {\ if (level == 0) {\ (isnull) = (k->u.null_check.pstr == (s));\ break;\ }\ else level--;\ }\ }\ else if (k->type == STK_NULL_CHECK_END) {\ level++;\ }\ }\} while(0)#define STACK_NULL_CHECK_MEMST(isnull,id,s,reg) do {\ StackType* k = stk;\ while (1) {\ k--;\ STACK_BASE_CHECK(k); \ if (k->type == STK_NULL_CHECK_START) {\ if (k->u.null_check.num == (id)) {\ if (k->u.null_check.pstr != (s)) {\ (isnull) = 0;\ break;\ }\ else {\ UChar* endp;\ (isnull) = 1;\ while (k < stk) {\ if (k->type == STK_MEM_START) {\ if (k->u.mem.end == INVALID_STACK_INDEX) {\ (isnull) = 0; break;\ }\ if (BIT_STATUS_AT(reg->bt_mem_end, k->u.mem.num))\ endp = STACK_AT(k->u.mem.end)->u.mem.pstr;\ else\ endp = (UChar* )k->u.mem.end;\ if (STACK_AT(k->u.mem.start)->u.mem.pstr != endp) {\ (isnull) = 0; break;\ }\ else if (endp != s) {\ (isnull) = -1; /* empty, but position changed */ \ }\ }\ k++;\ }\ break;\ }\ }\ }\ }\} while(0)#define STACK_NULL_CHECK_MEMST_REC(isnull,id,s,reg) do {\ int level = 0;\ StackType* k = stk;\ while (1) {\ k--;\ STACK_BASE_CHECK(k); \ if (k->type == STK_NULL_CHECK_START) {\ if (k->u.null_check.num == (id)) {\ if (level == 0) {\ if (k->u.null_check.pstr != (s)) {\ (isnull) = 0;\ break;\ }\ else {\ UChar* endp;\ (isnull) = 1;\ while (k < stk) {\ if (k->type == STK_MEM_START) {\ if (k->u.mem.end == INVALID_STACK_INDEX) {\ (isnull) = 0; break;\ }\ if (BIT_STATUS_AT(reg->bt_mem_end, k->u.mem.num))\ endp = STACK_AT(k->u.mem.end)->u.mem.pstr;\ else\ endp = (UChar* )k->u.mem.end;\ if (STACK_AT(k->u.mem.start)->u.mem.pstr != endp) {\ (isnull) = 0; break;\ }\ else if (endp != s) {\ (isnull) = -1; /* empty, but position changed */ \ }\ }\ k++;\ }\ break;\ }\ }\ else {\ level--;\ }\ }\ }\ else if (k->type == STK_NULL_CHECK_END) {\ if (k->u.null_check.num == (id)) level++;\ }\ }\} while(0)#define STACK_GET_REPEAT(id, k) do {\ int level = 0;\ k = stk;\ while (1) {\ k--;\ STACK_BASE_CHECK(k); \ if (k->type == STK_REPEAT) {\ if (level == 0) {\ if (k->u.repeat.num == (id)) {\ break;\ }\ }\ }\ else if (k->type == STK_CALL_FRAME) level--;\ else if (k->type == STK_RETURN) level++;\ }\} while (0)#define STACK_RETURN(addr) do {\ int level = 0;\ StackType* k = stk;\ while (1) {\ k--;\ STACK_BASE_CHECK(k); \ if (k->type == STK_CALL_FRAME) {\ if (level == 0) {\ (addr) = k->u.call_frame.ret_addr;\ break;\ }\ else level--;\ }\ else if (k->type == STK_RETURN)\ level++;\ }\} while(0)#define STRING_CMP(s1,s2,len) do {\ while (len-- > 0) {\ if (*s1++ != *s2++) goto fail;\ }\} while(0)#define STRING_CMP_IC(ambig_flag,s1,ps2,len) do {\ if (string_cmp_ic(encode, ambig_flag, s1, ps2, len) == 0) \ goto fail; \} while(0)static int string_cmp_ic(OnigEncoding enc, int ambig_flag, UChar* s1, UChar** ps2, int mblen){ UChar buf1[ONIGENC_MBC_NORMALIZE_MAXLEN]; UChar buf2[ONIGENC_MBC_NORMALIZE_MAXLEN]; UChar *p1, *p2, *end, *s2, *end2; int len1, len2; s2 = *ps2; end = s1 + mblen; end2 = s2 + mblen; while (s1 < end) { len1 = ONIGENC_MBC_TO_NORMALIZE(enc, ambig_flag, &s1, end, buf1); len2 = ONIGENC_MBC_TO_NORMALIZE(enc, ambig_flag, &s2, end2, buf2); if (len1 != len2) return 0; p1 = buf1; p2 = buf2; while (len1-- > 0) { if (*p1 != *p2) return 0; p1++; p2++; } } *ps2 = s2; return 1;}#define STRING_CMP_VALUE(s1,s2,len,is_fail) do {\ is_fail = 0;\ while (len-- > 0) {\ if (*s1++ != *s2++) {\ is_fail = 1; break;\ }\ }\} while(0)#define STRING_CMP_VALUE_IC(ambig_flag,s1,ps2,len,is_fail) do {\ if (string_cmp_ic(encode, ambig_flag, s1, ps2, len) == 0) \ is_fail = 1; \ else \ is_fail = 0; \} while(0)#define ON_STR_BEGIN(s) ((s) == str)#define ON_STR_END(s) ((s) == end)#define IS_EMPTY_STR (str == end)#define DATA_ENSURE(n) \ if (s + (n) > end) goto fail#define DATA_ENSURE_CHECK(n) (s + (n) <= end)#ifdef USE_CAPTURE_HISTORYstatic intmake_capture_history_tree(OnigCaptureTreeNode* node, StackType** kp, StackType* stk_top, UChar* str, regex_t* reg){ int n, r; OnigCaptureTreeNode* child; StackType* k = *kp; while (k < stk_top) { if (k->type == STK_MEM_START) { n = k->u.mem.num; if (n <= ONIG_MAX_CAPTURE_HISTORY_GROUP && BIT_STATUS_AT(reg->capture_history, n) != 0) { child = history_node_new(); CHECK_NULL_RETURN_VAL(child, ONIGERR_MEMORY); child->group = n; child->beg = (int )(k->u.mem.pstr - str); r = history_tree_add_child(node, child); if (r != 0) return r; *kp = (k + 1); r = make_capture_history_tree(child, kp, stk_top, str, reg); if (r != 0) return r; k = *kp; child->end = (int )(k->u.mem.pstr - str); } } else if (k->type == STK_MEM_END) { if (k->u.mem.num == node->group) { node->end = (int )(k->u.mem.pstr - str); *kp = k; return 0; } } k++; } return 1; /* 1: root node ending. */}#endif#ifdef RUBY_PLATFORMtypedef struct { int state; regex_t* reg; MatchArg* msa; StackType* stk_base;} TrapEnsureArg;static VALUEtrap_ensure(VALUE arg){ TrapEnsureArg* ta = (TrapEnsureArg* )arg; if (ta->state == 0) { /* trap_exec() is not normal return */ ONIG_STATE_DEC(ta->reg); if (! IS_NULL(ta->msa->stack_p) && ta->stk_base != ta->msa->stack_p) xfree(ta->stk_base); MATCH_ARG_FREE(*(ta->msa)); } return Qnil;}static VALUEtrap_exec(VALUE arg){ TrapEnsureArg* ta; rb_trap_exec(); ta = (TrapEnsureArg* )arg; ta->state = 1; /* normal return */ return Qnil;}extern voidonig_exec_trap(regex_t* reg, MatchArg* msa, StackType* stk_base){ VALUE arg; TrapEnsureArg ta; ta.state = 0; ta.reg = reg; ta.msa = msa; ta.stk_base = stk_base; arg = (VALUE )(&ta); rb_ensure(trap_exec, arg, trap_ensure, arg);}#define CHECK_INTERRUPT_IN_MATCH_AT do {\ if (rb_trap_pending) {\ if (! rb_prohibit_interrupt) {\ onig_exec_trap(reg, msa, stk_base);\ }\ }\} while (0)#else#define CHECK_INTERRUPT_IN_MATCH_AT#endif /* RUBY_PLATFORM */#ifdef ONIG_DEBUG_STATISTICS#define USE_TIMEOFDAY#ifdef USE_TIMEOFDAY#ifdef HAVE_SYS_TIME_H#include <sys/time.h>#endif#ifdef HAVE_UNISTD_H#include <unistd.h>#endifstatic struct timeval ts, te;#define GETTIME(t) gettimeofday(&(t), (struct timezone* )0)#define TIMEDIFF(te,ts) (((te).tv_usec - (ts).tv_usec) + \ (((te).tv_sec - (ts).tv_sec)*1000000))#else#ifdef HAVE_SYS_TIMES_H#include <sys/times.h>#endifstatic struct tms ts, te;#define GETTIME(t) times(&(t))#define TIMEDIFF(te,ts) ((te).tms_utime - (ts).tms_utime)#endifstatic int OpCounter[256];static int OpPrevCounter[256];static unsigned long OpTime[256];static int OpCurr = OP_FINISH;static int OpPrevTarget = OP_FAIL;static int MaxStackDepth = 0;#define STAT_OP_IN(opcode) do {\
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -