34# undef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
36# define USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
39#ifndef USE_TOKEN_THREADED_VM
41# define USE_TOKEN_THREADED_VM 1
43# define USE_TOKEN_THREADED_VM 0
48# define ENC_DUMMY_FLAG (1<<24)
54# undef ONIGENC_IS_MBC_ASCII_WORD
55# define ONIGENC_IS_MBC_ASCII_WORD(enc,s,end) \
56 (rb_enc_asciicompat(enc) ? (ISALNUM(*s) || *s=='_') : \
57 onigenc_ascii_is_code_ctype( \
58 ONIGENC_MBC_TO_CODE(enc,s,end),ONIGENC_CTYPE_WORD,enc))
61#ifdef USE_CRNL_AS_LINE_TERMINATOR
62# define ONIGENC_IS_MBC_CRNL(enc,p,end) \
63 (ONIGENC_MBC_TO_CODE(enc,p,end) == 13 && \
64 ONIGENC_MBC_TO_CODE(enc,(p+enclen(enc,p,end)),end) == 10)
65# define ONIGENC_IS_MBC_NEWLINE_EX(enc,p,start,end,option,check_prev) \
66 is_mbc_newline_ex((enc),(p),(start),(end),(option),(check_prev))
99# define ONIGENC_IS_MBC_NEWLINE_EX(enc,p,start,end,option,check_prev) \
100 ONIGENC_IS_MBC_NEWLINE((enc), (p), (end))
103#ifdef USE_CAPTURE_HISTORY
104static void history_tree_free(OnigCaptureTreeNode* node);
107history_tree_clear(OnigCaptureTreeNode* node)
112 for (
i = 0;
i < node->num_childs;
i++) {
114 history_tree_free(node->childs[
i]);
117 for (
i = 0;
i < node->allocated;
i++) {
118 node->childs[
i] = (OnigCaptureTreeNode* )0;
120 node->num_childs = 0;
125 node->childs = (OnigCaptureTreeNode** )0;
130history_tree_free(OnigCaptureTreeNode* node)
132 history_tree_clear(node);
140 history_tree_free(r->history_root);
141 r->history_root = (OnigCaptureTreeNode* )0;
145static OnigCaptureTreeNode*
146history_node_new(
void)
148 OnigCaptureTreeNode* node;
150 node = (OnigCaptureTreeNode* )
xmalloc(
sizeof(OnigCaptureTreeNode));
152 node->childs = (OnigCaptureTreeNode** )0;
154 node->num_childs = 0;
163history_tree_add_child(OnigCaptureTreeNode* parent, OnigCaptureTreeNode* child)
165# define HISTORY_TREE_INIT_ALLOC_SIZE 8
167 if (parent->num_childs >= parent->allocated) {
171 n = HISTORY_TREE_INIT_ALLOC_SIZE;
173 (OnigCaptureTreeNode** )
xmalloc(
sizeof(OnigCaptureTreeNode*) *
n);
177 OnigCaptureTreeNode** tmp;
178 n = parent->allocated * 2;
180 (OnigCaptureTreeNode** )
xrealloc(parent->childs,
181 sizeof(OnigCaptureTreeNode*) *
n);
183 history_tree_clear(parent);
186 parent->childs = tmp;
188 for (
i = parent->allocated;
i <
n;
i++) {
189 parent->childs[
i] = (OnigCaptureTreeNode* )0;
191 parent->allocated =
n;
194 parent->childs[parent->num_childs] = child;
195 parent->num_childs++;
199static OnigCaptureTreeNode*
200history_tree_clone(OnigCaptureTreeNode* node)
203 OnigCaptureTreeNode *clone, *child;
205 clone = history_node_new();
208 clone->beg = node->beg;
209 clone->end = node->end;
210 for (
i = 0;
i < node->num_childs;
i++) {
211 child = history_tree_clone(node->childs[
i]);
213 history_tree_free(clone);
214 return (OnigCaptureTreeNode* )0;
216 r = history_tree_add_child(clone, child);
218 history_tree_free(child);
219 history_tree_free(clone);
220 return (OnigCaptureTreeNode* )0;
227extern OnigCaptureTreeNode*
230 return region->history_root;
242#ifdef USE_CAPTURE_HISTORY
243 history_root_free(region);
257 if (region->
beg == 0)
261 if (region->
end == 0) {
299 if (r != 0)
return r;
314 region->
beg[at] = beg;
315 region->
end[at] = end;
326#ifdef USE_CAPTURE_HISTORY
327 region->history_root = (OnigCaptureTreeNode* )0;
351#ifdef USE_CAPTURE_HISTORY
352 history_root_free(r);
354 if (free_self)
xfree(r);
361#define RREGC_SIZE (sizeof(int) * from->num_regs)
364 if (to == from)
return;
375#ifdef USE_CAPTURE_HISTORY
376 history_root_free(to);
379 to->history_root = history_tree_clone(from->history_root);
386#define INVALID_STACK_INDEX -1
390#define STK_ALT 0x0001
391#define STK_LOOK_BEHIND_NOT 0x0002
392#define STK_POS_NOT 0x0003
394#define STK_MEM_START 0x0100
395#define STK_MEM_END 0x8200
396#define STK_REPEAT_INC 0x0300
397#define STK_STATE_CHECK_MARK 0x1000
399#define STK_NULL_CHECK_START 0x3000
400#define STK_NULL_CHECK_END 0x5000
401#define STK_MEM_END_MARK 0x8400
402#define STK_POS 0x0500
403#define STK_STOP_BT 0x0600
404#define STK_REPEAT 0x0700
405#define STK_CALL_FRAME 0x0800
406#define STK_RETURN 0x0900
407#define STK_VOID 0x0a00
408#define STK_ABSENT_POS 0x0b00
409#define STK_ABSENT 0x0c00
412#define STK_MASK_POP_USED 0x00ff
413#define STK_MASK_TO_VOID_TARGET 0x10ff
414#define STK_MASK_MEM_END_OR_MARK 0x8000
416#ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
417# define MATCH_ARG_INIT(msa, arg_option, arg_region, arg_start, arg_gpos) do {\
418 (msa).stack_p = (void* )0;\
419 (msa).options = (arg_option);\
420 (msa).region = (arg_region);\
421 (msa).start = (arg_start);\
422 (msa).gpos = (arg_gpos);\
423 (msa).best_len = ONIG_MISMATCH;\
426# define MATCH_ARG_INIT(msa, arg_option, arg_region, arg_start, arg_gpos) do {\
427 (msa).stack_p = (void* )0;\
428 (msa).options = (arg_option);\
429 (msa).region = (arg_region);\
430 (msa).start = (arg_start);\
431 (msa).gpos = (arg_gpos);\
435#ifdef USE_COMBINATION_EXPLOSION_CHECK
437# define STATE_CHECK_BUFF_MALLOC_THRESHOLD_SIZE 16
439# define STATE_CHECK_BUFF_INIT(msa, str_len, offset, state_num) do { \
440 if ((state_num) > 0 && str_len >= STATE_CHECK_STRING_THRESHOLD_LEN) {\
441 unsigned int size = (unsigned int )(((str_len) + 1) * (state_num) + 7) >> 3;\
442 offset = ((offset) * (state_num)) >> 3;\
443 if (size > 0 && offset < size && size < STATE_CHECK_BUFF_MAX_SIZE) {\
444 if (size >= STATE_CHECK_BUFF_MALLOC_THRESHOLD_SIZE) {\
445 (msa).state_check_buff = (void* )xmalloc(size);\
446 CHECK_NULL_RETURN_MEMERR((msa).state_check_buff);\
449 (msa).state_check_buff = (void* )xalloca(size);\
450 xmemset(((char* )((msa).state_check_buff)+(offset)), 0, \
451 (size_t )(size - (offset))); \
452 (msa).state_check_buff_size = size;\
455 (msa).state_check_buff = (void* )0;\
456 (msa).state_check_buff_size = 0;\
460 (msa).state_check_buff = (void* )0;\
461 (msa).state_check_buff_size = 0;\
465# define MATCH_ARG_FREE(msa) do {\
466 if ((msa).stack_p) xfree((msa).stack_p);\
467 if ((msa).state_check_buff_size >= STATE_CHECK_BUFF_MALLOC_THRESHOLD_SIZE) { \
468 if ((msa).state_check_buff) xfree((msa).state_check_buff);\
472# define MATCH_ARG_FREE(msa) if ((msa).stack_p) xfree((msa).stack_p)
477#define MAX_PTR_NUM 100
479#define STACK_INIT(alloc_addr, heap_addr, ptr_num, stack_num) do {\
480 if (ptr_num > MAX_PTR_NUM) {\
481 alloc_addr = (char* )xmalloc(sizeof(OnigStackIndex) * (ptr_num));\
482 heap_addr = alloc_addr;\
484 stk_alloc = (OnigStackType* )(msa->stack_p);\
485 stk_base = stk_alloc;\
487 stk_end = stk_base + msa->stack_n;\
489 stk_alloc = (OnigStackType* )xalloca(sizeof(OnigStackType) * (stack_num));\
490 stk_base = stk_alloc;\
492 stk_end = stk_base + (stack_num);\
494 } else if (msa->stack_p) {\
495 alloc_addr = (char* )xalloca(sizeof(OnigStackIndex) * (ptr_num));\
497 stk_alloc = (OnigStackType* )(msa->stack_p);\
498 stk_base = stk_alloc;\
500 stk_end = stk_base + msa->stack_n;\
503 alloc_addr = (char* )xalloca(sizeof(OnigStackIndex) * (ptr_num)\
504 + sizeof(OnigStackType) * (stack_num));\
506 stk_alloc = (OnigStackType* )(alloc_addr + sizeof(OnigStackIndex) * (ptr_num));\
507 stk_base = stk_alloc;\
509 stk_end = stk_base + (stack_num);\
513#define STACK_SAVE do{\
514 if (stk_base != stk_alloc) {\
515 msa->stack_p = stk_base;\
516 msa->stack_n = stk_end - stk_base; \
525 return MatchStackLimitSize;
531 MatchStackLimitSize =
size;
542 stk_base = *arg_stk_base;
543 stk_end = *arg_stk_end;
546 n = stk_end - stk_base;
557 unsigned int limit_size = MatchStackLimitSize;
559 if (limit_size != 0 &&
n > limit_size) {
560 if ((
unsigned int )(stk_end - stk_base) == limit_size)
571 *arg_stk = x + (stk - stk_base);
573 *arg_stk_end = x +
n;
577#define STACK_ENSURE(n) do {\
578 if (stk_end - stk < (n)) {\
579 int r = stack_double(&stk_base, &stk_end, &stk, stk_alloc, msa);\
582 if (xmalloc_base) xfree(xmalloc_base);\
588#define STACK_AT(index) (stk_base + (index))
589#define GET_STACK_INDEX(stk) ((stk) - stk_base)
591#define STACK_PUSH_TYPE(stack_type) do {\
593 stk->type = (stack_type);\
597#define IS_TO_VOID_TARGET(stk) (((stk)->type & STK_MASK_TO_VOID_TARGET) != 0)
599#ifdef USE_COMBINATION_EXPLOSION_CHECK
600# define STATE_CHECK_POS(s,snum) \
601 (((s) - str) * num_comb_exp_check + ((snum) - 1))
602# define STATE_CHECK_VAL(v,snum) do {\
603 if (state_check_buff != NULL) {\
604 int x = STATE_CHECK_POS(s,snum);\
605 (v) = state_check_buff[x/8] & (1<<(x%8));\
611# define ELSE_IF_STATE_CHECK_MARK(stk) \
612 else if ((stk)->type == STK_STATE_CHECK_MARK) { \
613 int x = STATE_CHECK_POS(stk->u.state.pstr, stk->u.state.state_check);\
614 state_check_buff[x/8] |= (1<<(x%8)); \
617# define STACK_PUSH(stack_type,pat,s,sprev,keep) do {\
619 stk->type = (stack_type);\
620 stk->u.state.pcode = (pat);\
621 stk->u.state.pstr = (s);\
622 stk->u.state.pstr_prev = (sprev);\
623 stk->u.state.state_check = 0;\
624 stk->u.state.pkeep = (keep);\
628# define STACK_PUSH_ENSURED(stack_type,pat) do {\
629 stk->type = (stack_type);\
630 stk->u.state.pcode = (pat);\
631 stk->u.state.state_check = 0;\
635# define STACK_PUSH_ALT_WITH_STATE_CHECK(pat,s,sprev,snum,keep) do {\
637 stk->type = STK_ALT;\
638 stk->u.state.pcode = (pat);\
639 stk->u.state.pstr = (s);\
640 stk->u.state.pstr_prev = (sprev);\
641 stk->u.state.state_check = ((state_check_buff != NULL) ? (snum) : 0);\
642 stk->u.state.pkeep = (keep);\
646# define STACK_PUSH_STATE_CHECK(s,snum) do {\
647 if (state_check_buff != NULL) {\
649 stk->type = STK_STATE_CHECK_MARK;\
650 stk->u.state.pstr = (s);\
651 stk->u.state.state_check = (snum);\
658# define ELSE_IF_STATE_CHECK_MARK(stk)
660# define STACK_PUSH(stack_type,pat,s,sprev,keep) do {\
662 stk->type = (stack_type);\
663 stk->u.state.pcode = (pat);\
664 stk->u.state.pstr = (s);\
665 stk->u.state.pstr_prev = (sprev);\
666 stk->u.state.pkeep = (keep);\
670# define STACK_PUSH_ENSURED(stack_type,pat) do {\
671 stk->type = (stack_type);\
672 stk->u.state.pcode = (pat);\
677#define STACK_PUSH_ALT(pat,s,sprev,keep) STACK_PUSH(STK_ALT,pat,s,sprev,keep)
678#define STACK_PUSH_POS(s,sprev,keep) STACK_PUSH(STK_POS,NULL_UCHARP,s,sprev,keep)
679#define STACK_PUSH_POS_NOT(pat,s,sprev,keep) STACK_PUSH(STK_POS_NOT,pat,s,sprev,keep)
680#define STACK_PUSH_ABSENT STACK_PUSH_TYPE(STK_ABSENT)
681#define STACK_PUSH_STOP_BT STACK_PUSH_TYPE(STK_STOP_BT)
682#define STACK_PUSH_LOOK_BEHIND_NOT(pat,s,sprev,keep) \
683 STACK_PUSH(STK_LOOK_BEHIND_NOT,pat,s,sprev,keep)
685#define STACK_PUSH_REPEAT(id, pat) do {\
687 stk->type = STK_REPEAT;\
688 stk->u.repeat.num = (id);\
689 stk->u.repeat.pcode = (pat);\
690 stk->u.repeat.count = 0;\
694#define STACK_PUSH_REPEAT_INC(sindex) do {\
696 stk->type = STK_REPEAT_INC;\
697 stk->u.repeat_inc.si = (sindex);\
701#define STACK_PUSH_MEM_START(mnum, s) do {\
703 stk->type = STK_MEM_START;\
704 stk->u.mem.num = (mnum);\
705 stk->u.mem.pstr = (s);\
706 stk->u.mem.start = mem_start_stk[mnum];\
707 stk->u.mem.end = mem_end_stk[mnum];\
708 mem_start_stk[mnum] = GET_STACK_INDEX(stk);\
709 mem_end_stk[mnum] = INVALID_STACK_INDEX;\
713#define STACK_PUSH_MEM_END(mnum, s) do {\
715 stk->type = STK_MEM_END;\
716 stk->u.mem.num = (mnum);\
717 stk->u.mem.pstr = (s);\
718 stk->u.mem.start = mem_start_stk[mnum];\
719 stk->u.mem.end = mem_end_stk[mnum];\
720 mem_end_stk[mnum] = GET_STACK_INDEX(stk);\
724#define STACK_PUSH_MEM_END_MARK(mnum) do {\
726 stk->type = STK_MEM_END_MARK;\
727 stk->u.mem.num = (mnum);\
731#define STACK_GET_MEM_START(mnum, k) do {\
734 while (k > stk_base) {\
736 if ((k->type & STK_MASK_MEM_END_OR_MARK) != 0 \
737 && k->u.mem.num == (mnum)) {\
740 else if (k->type == STK_MEM_START && k->u.mem.num == (mnum)) {\
741 if (level == 0) break;\
747#define STACK_GET_MEM_RANGE(k, mnum, start, end) do {\
750 if (k->type == STK_MEM_START && k->u.mem.num == (mnum)) {\
751 if (level == 0) (start) = k->u.mem.pstr;\
754 else if (k->type == STK_MEM_END && k->u.mem.num == (mnum)) {\
757 (end) = k->u.mem.pstr;\
765#define STACK_PUSH_NULL_CHECK_START(cnum, s) do {\
767 stk->type = STK_NULL_CHECK_START;\
768 stk->u.null_check.num = (cnum);\
769 stk->u.null_check.pstr = (s);\
773#define STACK_PUSH_NULL_CHECK_END(cnum) do {\
775 stk->type = STK_NULL_CHECK_END;\
776 stk->u.null_check.num = (cnum);\
780#define STACK_PUSH_CALL_FRAME(pat) do {\
782 stk->type = STK_CALL_FRAME;\
783 stk->u.call_frame.ret_addr = (pat);\
787#define STACK_PUSH_RETURN do {\
789 stk->type = STK_RETURN;\
793#define STACK_PUSH_ABSENT_POS(start, end) do {\
795 stk->type = STK_ABSENT_POS;\
796 stk->u.absent_pos.abs_pstr = (start);\
797 stk->u.absent_pos.end_pstr = (end);\
803# define STACK_BASE_CHECK(p, at) \
804 if ((p) < stk_base) {\
805 fprintf(stderr, "at %s\n", at);\
809# define STACK_BASE_CHECK(p, at)
812#define STACK_POP_ONE do {\
814 STACK_BASE_CHECK(stk, "STACK_POP_ONE"); \
817#define STACK_POP do {\
818 switch (pop_level) {\
819 case STACK_POP_LEVEL_FREE:\
822 STACK_BASE_CHECK(stk, "STACK_POP"); \
823 if ((stk->type & STK_MASK_POP_USED) != 0) break;\
824 ELSE_IF_STATE_CHECK_MARK(stk);\
827 case STACK_POP_LEVEL_MEM_START:\
830 STACK_BASE_CHECK(stk, "STACK_POP 2"); \
831 if ((stk->type & STK_MASK_POP_USED) != 0) break;\
832 else if (stk->type == STK_MEM_START) {\
833 mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
834 mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\
836 ELSE_IF_STATE_CHECK_MARK(stk);\
842 STACK_BASE_CHECK(stk, "STACK_POP 3"); \
843 if ((stk->type & STK_MASK_POP_USED) != 0) break;\
844 else if (stk->type == STK_MEM_START) {\
845 mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
846 mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\
848 else if (stk->type == STK_REPEAT_INC) {\
849 STACK_AT(stk->u.repeat_inc.si)->u.repeat.count--;\
851 else if (stk->type == STK_MEM_END) {\
852 mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
853 mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\
855 ELSE_IF_STATE_CHECK_MARK(stk);\
861#define STACK_POP_TIL_POS_NOT do {\
864 STACK_BASE_CHECK(stk, "STACK_POP_TIL_POS_NOT"); \
865 if (stk->type == STK_POS_NOT) break;\
866 else if (stk->type == STK_MEM_START) {\
867 mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
868 mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\
870 else if (stk->type == STK_REPEAT_INC) {\
871 STACK_AT(stk->u.repeat_inc.si)->u.repeat.count--;\
873 else if (stk->type == STK_MEM_END) {\
874 mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
875 mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\
877 ELSE_IF_STATE_CHECK_MARK(stk);\
881#define STACK_POP_TIL_LOOK_BEHIND_NOT do {\
884 STACK_BASE_CHECK(stk, "STACK_POP_TIL_LOOK_BEHIND_NOT"); \
885 if (stk->type == STK_LOOK_BEHIND_NOT) break;\
886 else if (stk->type == STK_MEM_START) {\
887 mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
888 mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\
890 else if (stk->type == STK_REPEAT_INC) {\
891 STACK_AT(stk->u.repeat_inc.si)->u.repeat.count--;\
893 else if (stk->type == STK_MEM_END) {\
894 mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
895 mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\
897 ELSE_IF_STATE_CHECK_MARK(stk);\
901#define STACK_POP_TIL_ABSENT do {\
904 STACK_BASE_CHECK(stk, "STACK_POP_TIL_ABSENT"); \
905 if (stk->type == STK_ABSENT) break;\
906 else if (stk->type == STK_MEM_START) {\
907 mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
908 mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\
910 else if (stk->type == STK_REPEAT_INC) {\
911 STACK_AT(stk->u.repeat_inc.si)->u.repeat.count--;\
913 else if (stk->type == STK_MEM_END) {\
914 mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
915 mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\
917 ELSE_IF_STATE_CHECK_MARK(stk);\
921#define STACK_POP_ABSENT_POS(start, end) do {\
923 STACK_BASE_CHECK(stk, "STACK_POP_ABSENT_POS"); \
924 (start) = stk->u.absent_pos.abs_pstr;\
925 (end) = stk->u.absent_pos.end_pstr;\
928#define STACK_POS_END(k) do {\
932 STACK_BASE_CHECK(k, "STACK_POS_END"); \
933 if (IS_TO_VOID_TARGET(k)) {\
936 else if (k->type == STK_POS) {\
943#define STACK_STOP_BT_END do {\
944 OnigStackType *k = stk;\
947 STACK_BASE_CHECK(k, "STACK_STOP_BT_END"); \
948 if (IS_TO_VOID_TARGET(k)) {\
951 else if (k->type == STK_STOP_BT) {\
958#define STACK_NULL_CHECK(isnull,id,s) do {\
959 OnigStackType* k = stk;\
962 STACK_BASE_CHECK(k, "STACK_NULL_CHECK"); \
963 if (k->type == STK_NULL_CHECK_START) {\
964 if (k->u.null_check.num == (id)) {\
965 (isnull) = (k->u.null_check.pstr == (s));\
972#define STACK_NULL_CHECK_REC(isnull,id,s) do {\
974 OnigStackType* k = stk;\
977 STACK_BASE_CHECK(k, "STACK_NULL_CHECK_REC"); \
978 if (k->type == STK_NULL_CHECK_START) {\
979 if (k->u.null_check.num == (id)) {\
981 (isnull) = (k->u.null_check.pstr == (s));\
987 else if (k->type == STK_NULL_CHECK_END) {\
993#define STACK_NULL_CHECK_MEMST(isnull,id,s,reg) do {\
994 OnigStackType* k = stk;\
997 STACK_BASE_CHECK(k, "STACK_NULL_CHECK_MEMST"); \
998 if (k->type == STK_NULL_CHECK_START) {\
999 if (k->u.null_check.num == (id)) {\
1000 if (k->u.null_check.pstr != (s)) {\
1008 if (k->type == STK_MEM_START) {\
1009 if (k->u.mem.end == INVALID_STACK_INDEX) {\
1010 (isnull) = 0; break;\
1012 if (BIT_STATUS_AT(reg->bt_mem_end, k->u.mem.num))\
1013 endp = STACK_AT(k->u.mem.end)->u.mem.pstr;\
1015 endp = (UChar* )k->u.mem.end;\
1016 if (STACK_AT(k->u.mem.start)->u.mem.pstr != endp) {\
1017 (isnull) = 0; break;\
1019 else if (endp != s) {\
1032#define STACK_NULL_CHECK_MEMST_REC(isnull,id,s,reg) do {\
1034 OnigStackType* k = stk;\
1037 STACK_BASE_CHECK(k, "STACK_NULL_CHECK_MEMST_REC"); \
1038 if (k->type == STK_NULL_CHECK_START) {\
1039 if (k->u.null_check.num == (id)) {\
1041 if (k->u.null_check.pstr != (s)) {\
1049 if (k->type == STK_MEM_START) {\
1050 if (k->u.mem.end == INVALID_STACK_INDEX) {\
1051 (isnull) = 0; break;\
1053 if (BIT_STATUS_AT(reg->bt_mem_end, k->u.mem.num))\
1054 endp = STACK_AT(k->u.mem.end)->u.mem.pstr;\
1056 endp = (UChar* )k->u.mem.end;\
1057 if (STACK_AT(k->u.mem.start)->u.mem.pstr != endp) {\
1058 (isnull) = 0; break;\
1060 else if (endp != s) {\
1074 else if (k->type == STK_NULL_CHECK_END) {\
1075 if (k->u.null_check.num == (id)) level++;\
1080#define STACK_GET_REPEAT(id, k) do {\
1085 STACK_BASE_CHECK(k, "STACK_GET_REPEAT"); \
1086 if (k->type == STK_REPEAT) {\
1088 if (k->u.repeat.num == (id)) {\
1093 else if (k->type == STK_CALL_FRAME) level--;\
1094 else if (k->type == STK_RETURN) level++;\
1098#define STACK_RETURN(addr) do {\
1100 OnigStackType* k = stk;\
1103 STACK_BASE_CHECK(k, "STACK_RETURN"); \
1104 if (k->type == STK_CALL_FRAME) {\
1106 (addr) = k->u.call_frame.ret_addr;\
1111 else if (k->type == STK_RETURN)\
1117#define STRING_CMP(s1,s2,len) do {\
1118 while (len-- > 0) {\
1119 if (*s1++ != *s2++) goto fail;\
1123#define STRING_CMP_IC(case_fold_flag,s1,ps2,len,text_end) do {\
1124 if (string_cmp_ic(encode, case_fold_flag, s1, ps2, len, text_end) == 0) \
1128static int string_cmp_ic(
OnigEncoding enc,
int case_fold_flag,
1141 if (len1 != len2)
return 0;
1144 while (len1-- > 0) {
1145 if (*p1 != *p2)
return 0;
1155#define STRING_CMP_VALUE(s1,s2,len,is_fail) do {\
1157 while (len-- > 0) {\
1158 if (*s1++ != *s2++) {\
1159 is_fail = 1; break;\
1164#define STRING_CMP_VALUE_IC(case_fold_flag,s1,ps2,len,text_end,is_fail) do {\
1165 if (string_cmp_ic(encode, case_fold_flag, s1, ps2, len, text_end) == 0) \
1172#define IS_EMPTY_STR (str == end)
1173#define ON_STR_BEGIN(s) ((s) == str)
1174#define ON_STR_END(s) ((s) == end)
1175#ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
1176# define DATA_ENSURE_CHECK1 (s < right_range)
1177# define DATA_ENSURE_CHECK(n) (s + (n) <= right_range)
1178# define DATA_ENSURE(n) if (s + (n) > right_range) goto fail
1179# define ABSENT_END_POS right_range
1181# define DATA_ENSURE_CHECK1 (s < end)
1182# define DATA_ENSURE_CHECK(n) (s + (n) <= end)
1183# define DATA_ENSURE(n) if (s + (n) > end) goto fail
1184# define ABSENT_END_POS end
1188#ifdef USE_CAPTURE_HISTORY
1190make_capture_history_tree(OnigCaptureTreeNode* node,
OnigStackType** kp,
1194 OnigCaptureTreeNode* child;
1197 while (k < stk_top) {
1202 child = history_node_new();
1206 r = history_tree_add_child(node, child);
1208 history_tree_free(child);
1212 r = make_capture_history_tree(child, kp, stk_top,
str, reg);
1213 if (r != 0)
return r;
1220 if (k->
u.
mem.
num == node->group) {
1233#ifdef USE_BACKREF_WITH_LEVEL
1234static int mem_is_in_memp(
int mem,
int num,
UChar* memp)
1239 for (
i = 0;
i < num;
i++) {
1241 if (mem == (
int )m)
return 1;
1246static int backref_match_at_nested_level(
regex_t* reg,
1248 int ignore_case,
int case_fold_flag,
1258 while (k >= stk_base) {
1265 else if (level == nest) {
1267 if (mem_is_in_memp(k->
u.
mem.
num, mem_num, memp)) {
1270 if (pend - pstart > send - *s)
return 0;
1274 if (ignore_case != 0) {
1275 if (string_cmp_ic(reg->
enc, case_fold_flag,
1276 pstart, &ss, pend - pstart, send) == 0)
1281 if (*p++ != *ss++)
return 0;
1291 if (mem_is_in_memp(k->
u.
mem.
num, mem_num, memp)) {
1304#ifdef ONIG_DEBUG_STATISTICS
1307# include <windows.h>
1308static LARGE_INTEGER ts, te, freq;
1309# define GETTIME(t) QueryPerformanceCounter(&(t))
1310# define TIMEDIFF(te,ts) (unsigned long )(((te).QuadPart - (ts).QuadPart) \
1311 * 1000000 / freq.QuadPart)
1314# define USE_TIMEOFDAY
1316# ifdef USE_TIMEOFDAY
1317# ifdef HAVE_SYS_TIME_H
1318# include <sys/time.h>
1320# ifdef HAVE_UNISTD_H
1324# define GETTIME(t) gettimeofday(&(t), (struct timezone* )0)
1325# define TIMEDIFF(te,ts) (((te).tv_usec - (ts).tv_usec) + \
1326 (((te).tv_sec - (ts).tv_sec)*1000000))
1328# ifdef HAVE_SYS_TIMES_H
1329# include <sys/times.h>
1331static struct tms ts, te;
1332# define GETTIME(t) times(&(t))
1333# define TIMEDIFF(te,ts) ((te).tms_utime - (ts).tms_utime)
1338static int OpCounter[256];
1339static int OpPrevCounter[256];
1340static unsigned long OpTime[256];
1342static int OpPrevTarget =
OP_FAIL;
1343static int MaxStackDepth = 0;
1345# define MOP_IN(opcode) do {\
1346 if (opcode == OpPrevTarget) OpPrevCounter[OpCurr]++;\
1348 OpCounter[opcode]++;\
1352# define MOP_OUT do {\
1354 OpTime[OpCurr] += TIMEDIFF(te, ts);\
1358onig_statistics_init(
void)
1361 for (
i = 0;
i < 256;
i++) {
1362 OpCounter[
i] = OpPrevCounter[
i] = 0; OpTime[
i] = 0;
1366 QueryPerformanceFrequency(&freq);
1371onig_print_statistics(
FILE*
f)
1375 for (
i = 0; OnigOpInfo[
i].opcode >= 0;
i++) {
1376 fprintf(
f,
"%8d: %8d: %10lu: %s\n",
1377 OpCounter[
i], OpPrevCounter[
i], OpTime[
i], OnigOpInfo[
i].
name);
1379 fprintf(
f,
"\nmax stack depth: %d\n", MaxStackDepth);
1382# define STACK_INC do {\
1384 if (stk - stk_base > MaxStackDepth) \
1385 MaxStackDepth = stk - stk_base;\
1389# define STACK_INC stk++
1391# define MOP_IN(opcode)
1396#ifdef ONIG_DEBUG_MATCH
1419 default:
return " ";
1428#ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
1429 const UChar* right_range,
1435 int i, num_mem, pop_level;
1443 UChar *s, *q, *sbegin;
1447 char *xmalloc_base =
NULL;
1453#ifdef USE_COMBINATION_EXPLOSION_CHECK
1455 unsigned char* state_check_buff = msa->state_check_buff;
1459#if USE_TOKEN_THREADED_VM
1461# define VM_LOOP JUMP;
1463# define CASE(x) L_##x: sbegin = s; OPCODE_EXEC_HOOK;
1464# define DEFAULT L_DEFAULT:
1465# define NEXT sprev = sbegin; JUMP
1466# define JUMP RB_GNUC_EXTENSION_BLOCK(goto *oplabels[*p++])
1492 &&L_OP_CCLASS_MB_NOT,
1493 &&L_OP_CCLASS_MIX_NOT,
1497 &&L_OP_ANYCHAR_STAR,
1498 &&L_OP_ANYCHAR_ML_STAR,
1499 &&L_OP_ANYCHAR_STAR_PEEK_NEXT,
1500 &&L_OP_ANYCHAR_ML_STAR_PEEK_NEXT,
1505 &&L_OP_NOT_WORD_BOUND,
1506# ifdef USE_WORD_BEGIN_END
1514 &&L_OP_NOT_ASCII_WORD,
1515 &&L_OP_ASCII_WORD_BOUND,
1516 &&L_OP_NOT_ASCII_WORD_BOUND,
1517# ifdef USE_WORD_BEGIN_END
1518 &&L_OP_ASCII_WORD_BEGIN,
1519 &&L_OP_ASCII_WORD_END,
1529 &&L_OP_SEMI_END_BUF,
1530 &&L_OP_BEGIN_POSITION,
1536 &&L_OP_BACKREF_MULTI,
1537 &&L_OP_BACKREF_MULTI_IC,
1538# ifdef USE_BACKREF_WITH_LEVEL
1539 &&L_OP_BACKREF_WITH_LEVEL,
1543 &&L_OP_MEMORY_START,
1544 &&L_OP_MEMORY_START_PUSH,
1545 &&L_OP_MEMORY_END_PUSH,
1546# ifdef USE_SUBEXP_CALL
1547 &&L_OP_MEMORY_END_PUSH_REC,
1552# ifdef USE_SUBEXP_CALL
1553 &&L_OP_MEMORY_END_REC,
1564# ifdef USE_OP_PUSH_OR_JUMP_EXACT
1565 &&L_OP_PUSH_OR_JUMP_EXACT1,
1569 &&L_OP_PUSH_IF_PEEK_NEXT,
1573 &&L_OP_REPEAT_INC_NG,
1574 &&L_OP_REPEAT_INC_SG,
1575 &&L_OP_REPEAT_INC_NG_SG,
1576 &&L_OP_NULL_CHECK_START,
1577 &&L_OP_NULL_CHECK_END,
1578# ifdef USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT
1579 &&L_OP_NULL_CHECK_END_MEMST,
1583# ifdef USE_SUBEXP_CALL
1584 &&L_OP_NULL_CHECK_END_MEMST_PUSH,
1591 &&L_OP_PUSH_POS_NOT,
1593 &&L_OP_PUSH_STOP_BT,
1596 &&L_OP_PUSH_LOOK_BEHIND_NOT,
1597 &&L_OP_FAIL_LOOK_BEHIND_NOT,
1598 &&L_OP_PUSH_ABSENT_POS,
1602# ifdef USE_SUBEXP_CALL
1611# ifdef USE_COMBINATION_EXPLOSION_CHECK
1612 &&L_OP_STATE_CHECK_PUSH,
1613 &&L_OP_STATE_CHECK_PUSH_OR_JUMP,
1620# ifdef USE_COMBINATION_EXPLOSION_CHECK
1621 &&L_OP_STATE_CHECK_ANYCHAR_STAR,
1622 &&L_OP_STATE_CHECK_ANYCHAR_ML_STAR,
1629 &&L_OP_SET_OPTION_PUSH,
1644# define VM_LOOP_END } sprev = sbegin; }
1645# define CASE(x) case x:
1646# define DEFAULT default:
1648# define JUMP continue; break
1652#ifdef USE_SUBEXP_CALL
1655# define ADD_NUMMEM 1
1658# define ADD_NUMMEM 0
1669 mem_end_stk = mem_start_stk + (num_mem +
ADD_NUMMEM);
1672 for (; pp < repeat_stk +
n; pp += 2) {
1677#ifndef USE_SUBEXP_CALL
1684#ifdef ONIG_DEBUG_MATCH
1688 (
int )(end -
str), (
int )(sstart -
str));
1694 s = (
UChar* )sstart;
1695 pkeep = (
UChar* )sstart;
1698#ifdef ONIG_DEBUG_MATCH
1699# define OPCODE_EXEC_HOOK \
1701 UChar *op, *q, *bp, buf[50]; \
1703 op = p - OP_OFFSET; \
1704 fprintf(stderr, "%4"PRIdPTR"> \"", (*op == OP_FINISH) ? (ptrdiff_t )-1 : s - str); \
1707 if (*op != OP_FINISH) {
\
1708 for (i = 0; i < 7 && q < end; i++) { \
1709 len = enclen(encode, q, end); \
1710 while (len-- > 0) *bp++ = *q++; \
1712 if (q < end) { xmemcpy(bp, "...", 3); bp += 3; } \
1714 xmemcpy(bp, "\"", 1); bp += 1; \
1716 fputs((char* )buf, stderr); \
1717 for (i = 0; i < 20 - (bp - buf); i++) fputc(' ', stderr); \
1718 fprintf(stderr, "%4"PRIdPTR":%s %4"PRIdPTR":", \
1719 stk - stk_base - 1, \
1720 (stk > stk_base) ? stack_type_str(stk[-1].type) : " ", \
1721 (op == FinishCode) ? (ptrdiff_t )-1 : op - reg->p); \
1722 onig_print_compiled_byte_code(stderr, op, reg->p+reg->used, NULL, encode); \
1723 fprintf(stderr, "\n"); \
1726# define OPCODE_EXEC_HOOK ((void) 0)
1735#ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
1748 region->
beg[0] = ((pkeep > s) ? s : pkeep) -
str;
1749 region->
end[0] = s -
str;
1750 for (
i = 1;
i <= num_mem;
i++) {
1759 : (
UChar* )((
void* )mem_end_stk[
i])) -
str;
1766#ifdef USE_CAPTURE_HISTORY
1769 OnigCaptureTreeNode* node;
1771 if (
IS_NULL(region->history_root)) {
1772 region->history_root = node = history_node_new();
1776 node = region->history_root;
1777 history_tree_clear(node);
1781 node->beg = ((pkeep > s) ? s : pkeep) -
str;
1782 node->end = s -
str;
1785 r = make_capture_history_tree(region->history_root, &stkp,
1796#ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
1817 if (*p != *s)
goto fail;
1846 if (*p != *s)
goto fail;
1848 if (*p != *s)
goto fail;
1856 if (*p != *s)
goto fail;
1858 if (*p != *s)
goto fail;
1860 if (*p != *s)
goto fail;
1868 if (*p != *s)
goto fail;
1870 if (*p != *s)
goto fail;
1872 if (*p != *s)
goto fail;
1874 if (*p != *s)
goto fail;
1882 if (*p != *s)
goto fail;
1884 if (*p != *s)
goto fail;
1886 if (*p != *s)
goto fail;
1888 if (*p != *s)
goto fail;
1890 if (*p != *s)
goto fail;
1899 while (tlen-- > 0) {
1900 if (*p++ != *s++)
goto fail;
1924 if (*p != *q)
goto fail;
1935 if (*p != *s)
goto fail;
1937 if (*p != *s)
goto fail;
1944 if (*p != *s)
goto fail;
1946 if (*p != *s)
goto fail;
1949 if (*p != *s)
goto fail;
1951 if (*p != *s)
goto fail;
1958 if (*p != *s)
goto fail;
1960 if (*p != *s)
goto fail;
1962 if (*p != *s)
goto fail;
1964 if (*p != *s)
goto fail;
1967 if (*p != *s)
goto fail;
1969 if (*p != *s)
goto fail;
1977 while (tlen-- > 0) {
1978 if (*p != *s)
goto fail;
1980 if (*p != *s)
goto fail;
1990 while (tlen-- > 0) {
1991 if (*p != *s)
goto fail;
1993 if (*p != *s)
goto fail;
1995 if (*p != *s)
goto fail;
2007 while (tlen2-- > 0) {
2008 if (*p != *s)
goto fail;
2019 s +=
enclen(encode, s, end);
2034 mb_len =
enclen(encode, s, end);
2040#ifdef PLATFORM_UNALIGNED_WORD_ACCESS
2074 s +=
enclen(encode, s, end);
2084 goto cc_mb_not_success;
2092 int mb_len =
enclen(encode, s, end);
2098 goto cc_mb_not_success;
2105#ifdef PLATFORM_UNALIGNED_WORD_ACCESS
2218#ifdef USE_COMBINATION_EXPLOSION_CHECK
2222 STATE_CHECK_VAL(scv, mem);
2225 STACK_PUSH_ALT_WITH_STATE_CHECK(p, s, sprev, mem, pkeep);
2240 STATE_CHECK_VAL(scv, mem);
2243 STACK_PUSH_ALT_WITH_STATE_CHECK(p, s, sprev, mem, pkeep);
2264 s +=
enclen(encode, s, end);
2273 s +=
enclen(encode, s, end);
2282 s +=
enclen(encode, s, end);
2291 s +=
enclen(encode, s, end);
2365#ifdef USE_WORD_BEGIN_END
2441#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
2447#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
2460#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
2466#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
2476#ifdef USE_CRNL_AS_LINE_TERMINATOR
2479 ss +=
enclen(encode, ss, end);
2527#ifdef USE_SUBEXP_CALL
2566 UChar *pstart, *pend;
2570 if (mem > num_mem)
goto fail;
2575 pstart =
STACK_AT(mem_start_stk[mem])->u.mem.pstr;
2577 pstart = (
UChar* )((
void* )mem_start_stk[mem]);
2580 ?
STACK_AT(mem_end_stk[mem])->u.mem.pstr
2581 : (
UChar* )((
void* )mem_end_stk[mem]));
2586 while (sprev + (
len =
enclen(encode, sprev, end)) < s)
2597 UChar *pstart, *pend;
2601 if (mem > num_mem)
goto fail;
2606 pstart =
STACK_AT(mem_start_stk[mem])->u.mem.pstr;
2608 pstart = (
UChar* )((
void* )mem_start_stk[mem]);
2611 ?
STACK_AT(mem_end_stk[mem])->u.mem.pstr
2612 : (
UChar* )((
void* )mem_end_stk[mem]));
2617 while (sprev + (
len =
enclen(encode, sprev, end)) < s)
2628 UChar *pstart, *pend, *swork;
2631 for (
i = 0;
i < tlen;
i++) {
2638 pstart =
STACK_AT(mem_start_stk[mem])->u.mem.pstr;
2640 pstart = (
UChar* )((
void* )mem_start_stk[mem]);
2643 ?
STACK_AT(mem_end_stk[mem])->u.mem.pstr
2644 : (
UChar* )((
void* )mem_end_stk[mem]));
2650 if (is_fail)
continue;
2652 while (sprev + (
len =
enclen(encode, sprev, end)) < s)
2658 if (
i == tlen)
goto fail;
2667 UChar *pstart, *pend, *swork;
2670 for (
i = 0;
i < tlen;
i++) {
2677 pstart =
STACK_AT(mem_start_stk[mem])->u.mem.pstr;
2679 pstart = (
UChar* )((
void* )mem_start_stk[mem]);
2682 ?
STACK_AT(mem_end_stk[mem])->u.mem.pstr
2683 : (
UChar* )((
void* )mem_end_stk[mem]));
2689 if (is_fail)
continue;
2691 while (sprev + (
len =
enclen(encode, sprev, end)) < s)
2697 if (
i == tlen)
goto fail;
2702#ifdef USE_BACKREF_WITH_LEVEL
2714 if (backref_match_at_nested_level(reg, stk, stk_base, ic,
2715 case_fold_flag, (
int )level, (
int )tlen, p, &s, end)) {
2716 while (sprev + (
len =
enclen(encode, sprev, end)) < s)
2757#ifdef ONIG_DEBUG_MATCH
2775 goto unexpected_bytecode_error;
2783#ifdef USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT
2791# ifdef ONIG_DEBUG_MATCH
2795 if (isnull == -1)
goto fail;
2796 goto null_check_found;
2803#ifdef USE_SUBEXP_CALL
2810# ifdef USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT
2816# ifdef ONIG_DEBUG_MATCH
2820 if (isnull == -1)
goto fail;
2821 goto null_check_found;
2844#ifdef USE_COMBINATION_EXPLOSION_CHECK
2847 STATE_CHECK_VAL(scv, mem);
2851 STACK_PUSH_ALT_WITH_STATE_CHECK(p + addr, s, sprev, mem, pkeep);
2858 STATE_CHECK_VAL(scv, mem);
2863 STACK_PUSH_ALT_WITH_STATE_CHECK(p + addr, s, sprev, mem, pkeep);
2870 STATE_CHECK_VAL(scv, mem);
2873 STACK_PUSH_STATE_CHECK(s, mem);
2883#ifdef USE_OP_PUSH_OR_JUMP_EXACT
2944 si = repeat_stk[mem];
2973 si = repeat_stk[mem];
3080 UChar* selfp = p - 1;
3084#ifdef ONIG_DEBUG_MATCH
3085 fprintf(
stderr,
"ABSENT: s:%p, end:%p, absent:%p, aend:%p\n", s, end, absent, aend);
3087 if ((absent > aend) && (s > absent)) {
3093 else if ((s >= aend) && (s > absent)) {
3120#ifdef ONIG_DEBUG_MATCH
3127#ifdef USE_SUBEXP_CALL
3145 if ((mem > num_mem) ||
3170#ifdef USE_COMBINATION_EXPLOSION_CHECK
3171 if (stk->
u.
state.state_check != 0) {
3181 goto bytecode_error;
3186 if (xmalloc_base)
xfree(xmalloc_base);
3192 if (xmalloc_base)
xfree(xmalloc_base);
3198 if (xmalloc_base)
xfree(xmalloc_base);
3201 unexpected_bytecode_error:
3203 if (xmalloc_base)
xfree(xmalloc_base);
3212 UChar *t, *p, *s, *end;
3214 end = (
UChar* )text_end;
3215 end -= target_end - target - 1;
3216 if (end > text_range)
3225 if (*s == *target) {
3228 if (target_end == t ||
memcmp(t, p, target_end - t) == 0)
3236 if (*s == *target) {
3239 if (target_end == t ||
memcmp(t, p, target_end - t) == 0)
3242 s +=
enclen(enc, s, text_end);
3249str_lower_case_match(
OnigEncoding enc,
int case_fold_flag,
3259 while (lowlen > 0) {
3260 if (*t++ != *q++)
return 0;
3275 end = (
UChar* )text_end;
3276 end -= target_end - target - 1;
3277 if (end > text_range)
3283 if (str_lower_case_match(enc, case_fold_flag, target, target_end,
3287 s +=
enclen(enc, s, text_end);
3296 const UChar* text_end,
const UChar* text_start)
3300 s = (
UChar* )text_end;
3301 s -= (target_end - target);
3303 s = (
UChar* )text_start;
3308 if (*s == *target) {
3311 while (t < target_end) {
3316 if (t == target_end)
3326slow_search_backward_ic(
OnigEncoding enc,
int case_fold_flag,
3329 const UChar* text_end,
const UChar* text_start)
3333 s = (
UChar* )text_end;
3334 s -= (target_end - target);
3336 s = (
UChar* )text_start;
3341 if (str_lower_case_match(enc, case_fold_flag,
3342 target, target_end, s, text_end))
3351#ifndef USE_SUNDAY_QUICK_SEARCH
3356 const UChar* text_range)
3358 const UChar *s, *se, *t, *p, *end;
3362# ifdef ONIG_DEBUG_SEARCH
3367 tail = target_end - 1;
3368 tlen1 = tail - target;
3370 if (end + tlen1 > text_end)
3371 end = text_end - tlen1;
3380 if (t == target)
return (
UChar* )s;
3383 skip = reg->
map[*se];
3387 }
while ((s - t) < skip && s < end);
3391# if OPT_EXACT_MAXLEN >= ONIG_CHAR_TABLE_SIZE
3396 if (t == target)
return (
UChar* )s;
3403 }
while ((s - t) < skip && s < end);
3416 const UChar *s, *t, *p, *end;
3419# ifdef ONIG_DEBUG_SEARCH
3424 end = text_range + (target_end - target) - 1;
3428 tail = target_end - 1;
3429 s = text + (target_end - target) - 1;
3434# ifdef ONIG_DEBUG_SEARCH
3439 if (t == target)
return (
UChar* )p;
3446# if OPT_EXACT_MAXLEN >= ONIG_CHAR_TABLE_SIZE
3451 if (t == target)
return (
UChar* )p;
3465 const UChar* text_range)
3467 const UChar *s, *se, *t, *end;
3473# ifdef ONIG_DEBUG_SEARCH
3474 fprintf(
stderr,
"bm_search_notrev_ic: text: %d (%p), text_end: %d (%p), text_range: %d (%p)\n",
3475 (
int )text, text, (
int )text_end, text_end, (
int )text_range, text_range);
3478 tail = target_end - 1;
3479 tlen1 = tail - target;
3481 if (end + tlen1 > text_end)
3482 end = text_end - tlen1;
3489 if (str_lower_case_match(enc, case_fold_flag, target, target_end,
3492 skip = reg->
map[*se];
3496 }
while ((s - t) < skip && s < end);
3500# if OPT_EXACT_MAXLEN >= ONIG_CHAR_TABLE_SIZE
3503 if (str_lower_case_match(enc, case_fold_flag, target, target_end,
3510 }
while ((s - t) < skip && s < end);
3523 const UChar *s, *p, *end;
3528# ifdef ONIG_DEBUG_SEARCH
3529 fprintf(
stderr,
"bm_search_ic: text: %d (%p), text_end: %d (%p), text_range: %d (%p)\n",
3530 (
int )text, text, (
int )text_end, text_end, (
int )text_range, text_range);
3533 end = text_range + (target_end - target) - 1;
3537 tail = target_end - 1;
3538 s = text + (target_end - target) - 1;
3541 p = s - (target_end - target) + 1;
3542 if (str_lower_case_match(enc, case_fold_flag, target, target_end,
3549# if OPT_EXACT_MAXLEN >= ONIG_CHAR_TABLE_SIZE
3551 p = s - (target_end - target) + 1;
3552 if (str_lower_case_match(enc, case_fold_flag, target, target_end,
3568 const UChar* text_range)
3570 const UChar *s, *se, *t, *p, *end;
3575# ifdef ONIG_DEBUG_SEARCH
3580 tail = target_end - 1;
3581 tlen1 = tail - target;
3583 if (end + tlen1 > text_end)
3584 end = text_end - tlen1;
3593 if (t == target)
return (
UChar* )s;
3596 if (s + 1 >= end)
break;
3597 skip = reg->
map[se[1]];
3600 s +=
enclen(enc, s, end);
3601 }
while ((s - t) < skip && s < end);
3605# if OPT_EXACT_MAXLEN >= ONIG_CHAR_TABLE_SIZE
3610 if (t == target)
return (
UChar* )s;
3613 if (s + 1 >= end)
break;
3617 s +=
enclen(enc, s, end);
3618 }
while ((s - t) < skip && s < end);
3631 const UChar *s, *t, *p, *end;
3635# ifdef ONIG_DEBUG_SEARCH
3640 tail = target_end - 1;
3641 tlen1 = tail - target;
3642 end = text_range + tlen1;
3652 if (t == target)
return (
UChar* )p;
3655 if (s + 1 >= end)
break;
3656 s += reg->
map[s[1]];
3660# if OPT_EXACT_MAXLEN >= ONIG_CHAR_TABLE_SIZE
3665 if (t == target)
return (
UChar* )p;
3668 if (s + 1 >= end)
break;
3680 const UChar* text_range)
3682 const UChar *s, *se, *t, *end;
3688# ifdef ONIG_DEBUG_SEARCH
3693 tail = target_end - 1;
3694 tlen1 = tail - target;
3696 if (end + tlen1 > text_end)
3697 end = text_end - tlen1;
3704 if (str_lower_case_match(enc, case_fold_flag, target, target_end,
3707 if (s + 1 >= end)
break;
3708 skip = reg->
map[se[1]];
3711 s +=
enclen(enc, s, end);
3712 }
while ((s - t) < skip && s < end);
3716# if OPT_EXACT_MAXLEN >= ONIG_CHAR_TABLE_SIZE
3719 if (str_lower_case_match(enc, case_fold_flag, target, target_end,
3722 if (s + 1 >= end)
break;
3726 s +=
enclen(enc, s, end);
3727 }
while ((s - t) < skip && s < end);
3740 const UChar *s, *p, *end;
3746# ifdef ONIG_DEBUG_SEARCH
3751 tail = target_end - 1;
3752 tlen1 = tail - target;
3753 end = text_range + tlen1;
3761 if (str_lower_case_match(enc, case_fold_flag, target, target_end,
3764 if (s + 1 >= end)
break;
3765 s += reg->
map[s[1]];
3769# if OPT_EXACT_MAXLEN >= ONIG_CHAR_TABLE_SIZE
3772 if (str_lower_case_match(enc, case_fold_flag, target, target_end,
3775 if (s + 1 >= end)
break;
3784#ifdef USE_INT_MAP_BACKWARD
3800 for (
i =
len - 1;
i > 0;
i--)
3809 const UChar* text_end,
const UChar* text_start)
3811 const UChar *s, *t, *p;
3813 s = text_end - (target_end - target);
3822 while (t < target_end && *p == *t) {
3825 if (t == target_end)
3840 const UChar *s = text;
3842 while (s < text_range) {
3843 if (map[*s])
return (
UChar* )s;
3845 s +=
enclen(enc, s, text_end);
3853 const UChar* text_start,
const UChar* text_end)
3855 const UChar *s = text_start;
3858 if (map[*s])
return (
UChar* )s;
3874#ifdef USE_COMBINATION_EXPLOSION_CHECK
3876 int offset = at -
str;
3882 r = onig_region_resize_clear(region, reg->
num_mem + 1);
3889 r = match_at(reg,
str, end,
3890#ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
3906#ifdef ONIG_DEBUG_SEARCH
3912 if (reg->
dmin > 0) {
3919 if (q >= end)
return 0;
3920 while (p < q) p +=
enclen(reg->
enc, p, end);
3951 p = map_search(reg->
enc, reg->
map, p,
range, end);
3955 if (p && p <
range) {
3956 if (p - reg->
dmin < s) {
3970 (pprev ? pprev :
str), p, end);
3978#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
3980 (pprev ? pprev :
str), p);
3991 if (reg->
dmax == 0) {
3998 (pprev ? pprev :
str), p, end);
4003 if (p < str + reg->dmax) {
4009 *low = p - reg->
dmax;
4012 *low, end, (
const UChar** )low_prev);
4013 if (low_prev &&
IS_NULL(*low_prev))
4015 (pprev ? pprev : s), *low, end);
4020 (pprev ? pprev :
str), *low, end);
4026 *high = p - reg->
dmin;
4028#ifdef ONIG_DEBUG_SEARCH
4039#define BM_BACKWARD_SEARCH_LENGTH_THRESHOLD 100
4056 range, adjrange, end, p);
4064 range, adjrange, end, p);
4069#ifdef USE_INT_MAP_BACKWARD
4087 p = map_search_backward(reg->
enc, reg->
map,
range, adjrange, p, end);
4108#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
4128 *low = p - reg->
dmax;
4129 *high = p - reg->
dmin;
4133#ifdef ONIG_DEBUG_SEARCH
4134 fprintf(
stderr,
"backward_search_range: low: %d, high: %d\n",
4135 (
int )(*low -
str), (
int )(*high -
str));
4141#ifdef ONIG_DEBUG_SEARCH
4157 const UChar* global_pos,
4163#ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
4164 const UChar *orig_start = start;
4168#ifdef ONIG_DEBUG_SEARCH
4175 r = onig_region_resize_clear(region, reg->
num_mem + 1);
4176 if (r)
goto finish_no_msa;
4179 if (start > end || start <
str)
goto mismatch_no_msa;
4182#ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
4183# ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
4184# define MATCH_AND_RETURN_CHECK(upper_range) \
4185 r = match_at(reg, str, end, (upper_range), s, prev, &msa); \
4186 if (r != ONIG_MISMATCH) {\
4188 if (! IS_FIND_LONGEST(reg->options)) {\
4195# define MATCH_AND_RETURN_CHECK(upper_range) \
4196 r = match_at(reg, str, end, (upper_range), s, prev, &msa); \
4197 if (r != ONIG_MISMATCH) {\
4205# ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
4206# define MATCH_AND_RETURN_CHECK(none) \
4207 r = match_at(reg, str, end, s, prev, &msa);\
4208 if (r != ONIG_MISMATCH) {\
4210 if (! IS_FIND_LONGEST(reg->options)) {\
4217# define MATCH_AND_RETURN_CHECK(none) \
4218 r = match_at(reg, str, end, s, prev, &msa);\
4219 if (r != ONIG_MISMATCH) {\
4231 UChar *min_semi_end, *max_semi_end;
4238 if (global_pos > start)
4240 if (global_pos <
range)
4241 range = global_pos + 1;
4251 if (
range > start) {
4252 if (start !=
str)
goto mismatch_no_msa;
4261 goto mismatch_no_msa;
4265 min_semi_end = max_semi_end = (
UChar* )end;
4269 goto mismatch_no_msa;
4271 if (
range > start) {
4281 if (start >
range)
goto mismatch_no_msa;
4293 if (
range > start)
goto mismatch_no_msa;
4299 max_semi_end = (
UChar* )end;
4301 min_semi_end = pre_end;
4303#ifdef USE_CRNL_AS_LINE_TERMINATOR
4308 min_semi_end = pre_end;
4311 if (min_semi_end >
str && start <= min_semi_end) {
4316 min_semi_end = (
UChar* )end;
4321 goto begin_position;
4324 else if (
str == end) {
4325 static const UChar address_for_empty_string[] =
"";
4327#ifdef ONIG_DEBUG_SEARCH
4332 start = end =
str = address_for_empty_string;
4337#ifdef USE_COMBINATION_EXPLOSION_CHECK
4338 msa.state_check_buff = (
void* )0;
4339 msa.state_check_buff_size = 0;
4344 goto mismatch_no_msa;
4347#ifdef ONIG_DEBUG_SEARCH
4348 fprintf(
stderr,
"onig_search(apply anchor): end: %d, start: %d, range: %d\n",
4353#ifdef USE_COMBINATION_EXPLOSION_CHECK
4361 if (
range > start) {
4368 UChar *sch_range, *low, *high, *low_prev;
4371 if (reg->
dmax != 0) {
4373 sch_range = (
UChar* )end;
4375 sch_range += reg->
dmax;
4376 if (sch_range > end) sch_range = (
UChar* )end;
4385 if (! forward_search_range(reg,
str, end, s, sch_range,
4386 &low, &high, &low_prev))
goto mismatch;
4396 }
while (s <
range);
4400 if (! forward_search_range(reg,
str, end, s, sch_range,
4401 &low, &high, (
UChar** )
NULL))
goto mismatch;
4416 }
while (s <
range);
4426 }
while (s <
range);
4434 UChar *low, *high, *adjrange, *sch_start;
4439 adjrange = (
UChar* )end;
4444 sch_start = s + reg->
dmax;
4445 if (sch_start > end) sch_start = (
UChar* )end;
4446 if (backward_search_range(reg,
str, end, sch_start,
range, adjrange,
4458 }
while (s >=
range);
4465 if (reg->
dmax != 0) {
4467 sch_start = (
UChar* )end;
4469 sch_start += reg->
dmax;
4470 if (sch_start > end) sch_start = (
UChar* )end;
4473 start, sch_start, end);
4476 if (backward_search_range(reg,
str, end, sch_start,
range, adjrange,
4477 &low, &high) <= 0)
goto mismatch;
4485 }
while (s >=
range);
4489#ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
4544 rs = scan_callback(
n, r, region, callback_arg);
4549 if (region->
end[0] == start -
str) {
4550 if (start >= end)
break;
4554 start =
str + region->
end[0];
4603#ifdef USE_CAPTURE_HISTORY
#define range(low, item, hi)
#define rb_enc_asciicompat(enc)
char str[HTML_ESCAPE_MAX_LEN+1]
#define ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc, start, s, end)
#define ONIG_INFINITE_DISTANCE
#define ONIGERR_UNDEFINED_BYTECODE
ONIG_EXTERN OnigUChar * onigenc_get_right_adjust_char_head(OnigEncoding enc, const OnigUChar *start, const OnigUChar *s, const OnigUChar *end)
#define ONIG_REGION_NOTPOS
unsigned int OnigCaseFoldType
#define ONIGENC_MBC_TO_CODE(enc, p, end)
#define ONIGERR_INVALID_ARGUMENT
unsigned int OnigCodePoint
#define ONIGENC_STEP_BACK(enc, start, s, end, n)
#define ONIG_MAX_CAPTURE_HISTORY_GROUP
#define ONIGENC_MBC_MINLEN(enc)
#define ONIGENC_MBC_CASE_FOLD(enc, flag, pp, end, buf)
#define ONIG_CHAR_TABLE_SIZE
#define ONIGENC_MBC_CASE_FOLD_MAXLEN
ONIG_EXTERN OnigUChar * onigenc_get_right_adjust_char_head_with_prev(OnigEncoding enc, const OnigUChar *start, const OnigUChar *s, const OnigUChar *end, const OnigUChar **prev)
ONIG_EXTERN OnigUChar * onigenc_get_prev_char_head(OnigEncoding enc, const OnigUChar *start, const OnigUChar *s, const OnigUChar *end)
#define ONIGENC_IS_SINGLEBYTE(enc)
#define ONIGERR_UNEXPECTED_BYTECODE
unsigned int OnigOptionType
#define ONIGENC_IS_MBC_NEWLINE(enc, p, end)
#define ONIGENC_IS_MBC_HEAD(enc, p, e)
#define ONIGERR_STACK_BUG
#define ONIGERR_MATCH_STACK_LIMIT_OVER
#define ONIGENC_IS_MBC_WORD(enc, s, end)
int onig_is_in_code_range(const UChar *p, OnigCodePoint code)
#define USE_CRNL_AS_LINE_TERMINATOR
#define enclen(enc, p, e)
unsigned int onig_get_match_stack_limit_size(void)
void onig_region_copy(OnigRegion *to, const OnigRegion *from)
int onig_number_of_capture_histories(const regex_t *reg)
#define STACK_PUSH_LOOK_BEHIND_NOT(pat, s, sprev, keep)
void onig_region_init(OnigRegion *region)
#define STACK_NULL_CHECK_REC(isnull, id, s)
#define STACK_STOP_BT_END
#define STACK_PUSH_REPEAT(id, pat)
#define STACK_PUSH_ABSENT
int onig_region_set(OnigRegion *region, int at, int beg, int end)
#define STACK_PUSH_MEM_START(mnum, s)
#define DATA_ENSURE_CHECK(n)
OnigPosition onig_match(regex_t *reg, const UChar *str, const UChar *end, const UChar *at, OnigRegion *region, OnigOptionType option)
#define STRING_CMP_VALUE(s1, s2, len, is_fail)
#define STACK_PUSH_NULL_CHECK_START(cnum, s)
#define STK_NULL_CHECK_END
OnigOptionType onig_get_options(const regex_t *reg)
OnigPosition onig_search(regex_t *reg, const UChar *str, const UChar *end, const UChar *start, const UChar *range, OnigRegion *region, OnigOptionType option)
#define STACK_POP_TIL_LOOK_BEHIND_NOT
void onig_region_free(OnigRegion *r, int free_self)
#define STACK_PUSH_POS(s, sprev, keep)
#define STACK_PUSH_CALL_FRAME(pat)
#define ONIGENC_IS_MBC_ASCII_WORD(enc, s, end)
#define STACK_POP_ABSENT_POS(start, end)
#define STACK_PUSH_MEM_END(mnum, s)
#define STACK_PUSH_POS_NOT(pat, s, sprev, keep)
int onig_number_of_captures(const regex_t *reg)
#define STACK_POP_TIL_POS_NOT
#define STACK_NULL_CHECK_MEMST(isnull, id, s, reg)
#define MATCH_AND_RETURN_CHECK(none)
int onig_region_resize(OnigRegion *region, int n)
#define STRING_CMP_IC(case_fold_flag, s1, ps2, len, text_end)
#define STACK_PUSH_RETURN
#define STACK_PUSH_STOP_BT
#define GET_STACK_INDEX(stk)
#define DATA_ENSURE_CHECK1
#define STACK_GET_MEM_START(mnum, k)
#define STACK_NULL_CHECK_MEMST_REC(isnull, id, s, reg)
#define STACK_PUSH_ENSURED(stack_type, pat)
OnigEncoding onig_get_encoding(const regex_t *reg)
#define STK_STATE_CHECK_MARK
#define ONIGENC_IS_MBC_CRNL(enc, p, end)
#define ONIGENC_IS_MBC_NEWLINE_EX(enc, p, start, end, option, check_prev)
void onig_copy_encoding(OnigEncodingType *to, OnigEncoding from)
#define STRING_CMP(s1, s2, len)
#define STACK_INIT(alloc_addr, heap_addr, ptr_num, stack_num)
OnigCaseFoldType onig_get_case_fold_flag(const regex_t *reg)
#define STACK_PUSH_ALT(pat, s, sprev, keep)
OnigPosition onig_search_gpos(regex_t *reg, const UChar *str, const UChar *end, const UChar *global_pos, const UChar *start, const UChar *range, OnigRegion *region, OnigOptionType option)
#define STACK_PUSH_ABSENT_POS(start, end)
#define MATCH_ARG_INIT(msa, arg_option, arg_region, arg_start, arg_gpos)
OnigPosition onig_scan(regex_t *reg, const UChar *str, const UChar *end, OnigRegion *region, OnigOptionType option, int(*scan_callback)(OnigPosition, OnigPosition, OnigRegion *, void *), void *callback_arg)
#define STACK_NULL_CHECK(isnull, id, s)
const OnigSyntaxType * onig_get_syntax(const regex_t *reg)
#define STACK_GET_REPEAT(id, k)
#define STACK_PUSH_REPEAT_INC(sindex)
#define INVALID_STACK_INDEX
stack
void onig_region_clear(OnigRegion *region)
#define STACK_RETURN(addr)
OnigRegion * onig_region_new(void)
#define STACK_PUSH_MEM_END_MARK(mnum)
#define STACK_POP_TIL_ABSENT
#define MATCH_ARG_FREE(msa)
#define STK_LOOK_BEHIND_NOT
#define STACK_PUSH_NULL_CHECK_END(cnum)
#define BM_BACKWARD_SEARCH_LENGTH_THRESHOLD
int onig_set_match_stack_limit_size(unsigned int size)
#define STRING_CMP_VALUE_IC(case_fold_flag, s1, ps2, len, text_end, is_fail)
#define STK_NULL_CHECK_START
#define ANCHOR_BEGIN_LINE
#define CHECK_NULL_RETURN_MEMERR(p)
#define ANCHOR_PREC_READ_NOT
#define ONIG_OPTIMIZE_EXACT_BM_NOT_REV_IC
#define INIT_MATCH_STACK_SIZE
#define ONIG_OPTIMIZE_MAP
#define ONIG_OPTIMIZE_EXACT
#define GET_OPTION_INC(option, p)
#define IS_NOTBOL(option)
#define ANCHOR_BEGIN_POSITION
#define GET_MEMNUM_INC(num, p)
#define IS_FIND_LONGEST(option)
#define ONIG_OPTIMIZE_EXACT_BM
#define BITSET_AT(bs, pos)
#define CHECK_NULL_RETURN(p)
#define ANCHOR_LOOK_BEHIND
#define ONIG_OPTIMIZE_EXACT_BM_NOT_REV
#define IS_NOTEOL(option)
#define ANCHOR_ANYCHAR_STAR_ML
#define GET_STATE_CHECK_NUM_INC(num, p)
#define GET_LENGTH_INC(len, p)
#define IS_FIND_NOT_EMPTY(option)
#define IS_NOTEOS(option)
#define ANCHOR_SEMI_END_BUF
#define ALIGNMENT_RIGHT(addr)
#define ONIG_OPTIMIZE_EXACT_IC
#define ONIG_OPTIMIZE_NONE
@ OP_STATE_CHECK_PUSH_OR_JUMP
@ OP_STATE_CHECK_ANYCHAR_STAR
@ OP_ANYCHAR_STAR_PEEK_NEXT
@ OP_PUSH_LOOK_BEHIND_NOT
@ OP_NOT_ASCII_WORD_BOUND
@ OP_NULL_CHECK_END_MEMST_PUSH
@ OP_STATE_CHECK_ANYCHAR_ML_STAR
@ OP_ANYCHAR_ML_STAR_PEEK_NEXT
@ OP_FAIL_LOOK_BEHIND_NOT
@ OP_NULL_CHECK_END_MEMST
#define IS_FIND_CONDITION(option)
#define IS_NOTBOS(option)
#define ANCHOR_ANYCHAR_STAR
#define ONIG_OPTIMIZE_EXACT_BM_IC
#define GET_ABSADDR_INC(addr, p)
#define CHECK_INTERRUPT_IN_MATCH_AT
#define DEFAULT_MATCH_STACK_LIMIT_SIZE
#define BIT_STATUS_AT(stats, n)
#define IS_NEWLINE_CRLF(option)
#define GET_RELADDR_INC(addr, p)
#define SIZE_OP_SET_OPTION
union _OnigStackType::@198 u
struct _OnigStackType::@198::@199 state
struct _OnigStackType::@198::@200 repeat
struct _OnigStackType::@198::@202 mem
unsigned char * exact_end
unsigned int capture_history
unsigned int bt_mem_start
OnigCaseFoldType case_fold_flag
const OnigSyntaxType * syntax
OnigRepeatRange * repeat_range
unsigned char map[ONIG_CHAR_TABLE_SIZE]