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)
52 return ONIGENC_MBC_MINLEN(enc)==1 && !((enc)->ruby_encoding_index & ENC_DUMMY_FLAG);
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))
68is_mbc_newline_ex(
OnigEncoding enc,
const UChar *p,
const UChar *start,
69 const UChar *end, OnigOptionType option,
int check_prev)
71 if (IS_NEWLINE_CRLF(option)) {
72 if (ONIGENC_MBC_TO_CODE(enc, p, end) == 0x0a) {
74 const UChar *prev = onigenc_get_prev_char_head(enc, start, p, end);
75 if ((prev != NULL) && ONIGENC_MBC_TO_CODE(enc, prev, end) == 0x0d)
84 const UChar *pnext = p + enclen(enc, p, end);
86 ONIGENC_MBC_TO_CODE(enc, p, end) == 0x0d &&
87 ONIGENC_MBC_TO_CODE(enc, pnext, end) == 0x0a)
89 if (ONIGENC_IS_MBC_NEWLINE(enc, p, end))
95 return ONIGENC_IS_MBC_NEWLINE(enc, p, end);
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)
111 if (IS_NOT_NULL(node)) {
112 for (i = 0; i < node->num_childs; i++) {
113 if (IS_NOT_NULL(node->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;
121 node->beg = ONIG_REGION_NOTPOS;
122 node->end = ONIG_REGION_NOTPOS;
125 node->childs = (OnigCaptureTreeNode** )0;
130history_tree_free(OnigCaptureTreeNode* node)
132 history_tree_clear(node);
139 if (IS_NOT_NULL(r->history_root)) {
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));
151 CHECK_NULL_RETURN(node);
152 node->childs = (OnigCaptureTreeNode** )0;
154 node->num_childs = 0;
156 node->beg = ONIG_REGION_NOTPOS;
157 node->end = ONIG_REGION_NOTPOS;
163history_tree_add_child(OnigCaptureTreeNode* parent, OnigCaptureTreeNode* child)
165# define HISTORY_TREE_INIT_ALLOC_SIZE 8
167 if (parent->num_childs >= parent->allocated) {
170 if (IS_NULL(parent->childs)) {
171 n = HISTORY_TREE_INIT_ALLOC_SIZE;
173 (OnigCaptureTreeNode** )
xmalloc(
sizeof(OnigCaptureTreeNode*) * n);
174 CHECK_NULL_RETURN_MEMERR(parent->childs);
177 OnigCaptureTreeNode** tmp;
178 n = parent->allocated * 2;
180 (OnigCaptureTreeNode** )
xrealloc(parent->childs,
181 sizeof(OnigCaptureTreeNode*) * n);
183 history_tree_clear(parent);
184 return ONIGERR_MEMORY;
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();
206 CHECK_NULL_RETURN(clone);
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]);
212 if (IS_NULL(child)) {
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;
234#ifdef USE_MATCH_CACHE
263count_num_cache_opcodes(
const regex_t* reg,
long* num_cache_opcodes_ptr)
266 UChar* pend = p + reg->used;
268 MemNumType repeat_mem;
270 MemNumType current_repeat_mem = -1;
271 long num_cache_opcodes = 0;
272 int lookaround_nesting = 0;
280 case OP_EXACT1: p++;
break;
281 case OP_EXACT2: p += 2;
break;
282 case OP_EXACT3: p += 3;
break;
283 case OP_EXACT4: p += 4;
break;
284 case OP_EXACT5: p += 5;
break;
286 GET_LENGTH_INC(
len, p); p +=
len;
break;
287 case OP_EXACTMB2N1: p += 2;
break;
288 case OP_EXACTMB2N2: p += 4;
break;
289 case OP_EXACTMB2N3: p += 6;
break;
291 GET_LENGTH_INC(
len, p); p +=
len * 2;
break;
293 GET_LENGTH_INC(
len, p); p +=
len * 3;
break;
297 GET_LENGTH_INC(mb_len, p);
298 GET_LENGTH_INC(
len, p);
304 len = enclen(enc, p, pend); p +=
len;
break;
306 GET_LENGTH_INC(
len, p); p +=
len;
break;
310 p += SIZE_BITSET;
break;
312 case OP_CCLASS_MB_NOT:
313 GET_LENGTH_INC(
len, p); p +=
len;
break;
315 case OP_CCLASS_MIX_NOT:
317 GET_LENGTH_INC(
len, p);
324 case OP_ANYCHAR_STAR:
325 case OP_ANYCHAR_ML_STAR:
326 num_cache_opcodes++;
break;
327 case OP_ANYCHAR_STAR_PEEK_NEXT:
328 case OP_ANYCHAR_ML_STAR_PEEK_NEXT:
329 p++; num_cache_opcodes++;
break;
334 case OP_NOT_WORD_BOUND:
340 case OP_NOT_ASCII_WORD:
341 case OP_ASCII_WORD_BOUND:
342 case OP_NOT_ASCII_WORD_BOUND:
343 case OP_ASCII_WORD_BEGIN:
344 case OP_ASCII_WORD_END:
351 case OP_SEMI_END_BUF:
352 case OP_BEGIN_POSITION:
359 case OP_BACKREF_MULTI:
360 case OP_BACKREF_MULTI_IC:
361 case OP_BACKREF_WITH_LEVEL:
364 case OP_MEMORY_START:
365 case OP_MEMORY_START_PUSH:
366 case OP_MEMORY_END_PUSH:
367 case OP_MEMORY_END_PUSH_REC:
369 case OP_MEMORY_END_REC:
372 if (lookaround_nesting != 0) {
391 case OP_PUSH_OR_JUMP_EXACT1:
392 case OP_PUSH_IF_PEEK_NEXT:
393 p += SIZE_RELADDR + 1; num_cache_opcodes++;
break;
396 if (current_repeat_mem != -1) {
400 GET_MEMNUM_INC(repeat_mem, p);
402 if (reg->repeat_range[repeat_mem].lower == 0) {
405 current_repeat_mem = repeat_mem;
408 case OP_REPEAT_INC_NG:
409 GET_MEMNUM_INC(repeat_mem, p);
410 if (repeat_mem != current_repeat_mem) {
416 if (repeat_range->lower < repeat_range->upper) {
419 current_repeat_mem = -1;
422 case OP_REPEAT_INC_SG:
423 case OP_REPEAT_INC_NG_SG:
425 case OP_NULL_CHECK_START:
428 case OP_NULL_CHECK_END:
429 case OP_NULL_CHECK_END_MEMST_PUSH:
432 case OP_NULL_CHECK_END_MEMST:
437 if (lookaround_nesting < 0) {
441 lookaround_nesting++;
443 case OP_PUSH_POS_NOT:
444 if (lookaround_nesting < 0) {
449 lookaround_nesting++;
451 case OP_PUSH_LOOK_BEHIND_NOT:
452 if (lookaround_nesting < 0) {
458 lookaround_nesting++;
462 case OP_FAIL_LOOK_BEHIND_NOT:
463 lookaround_nesting--;
465 case OP_PUSH_STOP_BT:
466 if (lookaround_nesting != 0) {
470 lookaround_nesting++;
471 lookaround_nesting *= -1;
474 lookaround_nesting *= -1;
475 lookaround_nesting--;
481 case OP_PUSH_ABSENT_POS:
493 case OP_STATE_CHECK_PUSH:
494 case OP_STATE_CHECK_PUSH_OR_JUMP:
496 case OP_STATE_CHECK_ANYCHAR_STAR:
497 case OP_STATE_CHECK_ANYCHAR_ML_STAR:
500 case OP_SET_OPTION_PUSH:
510 *num_cache_opcodes_ptr = num_cache_opcodes;
514 *num_cache_opcodes_ptr = NUM_CACHE_OPCODES_IMPOSSIBLE;
518 return ONIGERR_UNDEFINED_BYTECODE;
527 UChar* pend = p + reg->used;
529 MemNumType repeat_mem;
531 MemNumType current_repeat_mem = -1;
532 long cache_point = 0;
533 long num_cache_points_at_repeat = 0;
534 int lookaround_nesting = 0;
538# define INC_CACHE_OPCODES do {\
539 cache_opcodes->addr = pbegin;\
540 cache_opcodes->cache_point = cache_point - num_cache_points_at_repeat;\
541 cache_opcodes->outer_repeat_mem = current_repeat_mem;\
542 cache_opcodes->num_cache_points_at_outer_repeat = num_cache_points_at_repeat;\
543 cache_opcodes->num_cache_points_in_outer_repeat = 0;\
544 cache_opcodes->lookaround_nesting = lookaround_nesting;\
545 cache_point += lookaround_nesting > 0 ? 2 : 1;\
549# define INC_LOOKAROUND_NESTING lookaround_nesting++
550# define DEC_LOOKAROUND_NESTING do {\
551 UChar* match_addr = p - 1;\
552 OnigCacheOpcode* cache_opcodes_in_lookaround = cache_opcodes - 1;\
554 cache_opcodes_in_lookaround >= cache_opcodes_begin &&\
555 cache_opcodes_in_lookaround->lookaround_nesting == lookaround_nesting\
557 cache_opcodes_in_lookaround->match_addr = match_addr;\
558 cache_opcodes_in_lookaround--;\
560 lookaround_nesting--;\
570 case OP_EXACT1: p++;
break;
571 case OP_EXACT2: p += 2;
break;
572 case OP_EXACT3: p += 3;
break;
573 case OP_EXACT4: p += 4;
break;
574 case OP_EXACT5: p += 5;
break;
576 GET_LENGTH_INC(
len, p); p +=
len;
break;
577 case OP_EXACTMB2N1: p += 2;
break;
578 case OP_EXACTMB2N2: p += 4;
break;
579 case OP_EXACTMB2N3: p += 6;
break;
581 GET_LENGTH_INC(
len, p); p +=
len * 2;
break;
583 GET_LENGTH_INC(
len, p); p +=
len * 3;
break;
587 GET_LENGTH_INC(mb_len, p);
588 GET_LENGTH_INC(
len, p);
594 len = enclen(enc, p, pend); p +=
len;
break;
596 GET_LENGTH_INC(
len, p); p +=
len;
break;
600 p += SIZE_BITSET;
break;
602 case OP_CCLASS_MB_NOT:
603 GET_LENGTH_INC(
len, p); p +=
len;
break;
605 case OP_CCLASS_MIX_NOT:
607 GET_LENGTH_INC(
len, p);
614 case OP_ANYCHAR_STAR:
615 case OP_ANYCHAR_ML_STAR:
618 case OP_ANYCHAR_STAR_PEEK_NEXT:
619 case OP_ANYCHAR_ML_STAR_PEEK_NEXT:
627 case OP_NOT_WORD_BOUND:
633 case OP_NOT_ASCII_WORD:
634 case OP_ASCII_WORD_BOUND:
635 case OP_NOT_ASCII_WORD_BOUND:
636 case OP_ASCII_WORD_BEGIN:
637 case OP_ASCII_WORD_END:
644 case OP_SEMI_END_BUF:
645 case OP_BEGIN_POSITION:
652 case OP_BACKREF_MULTI:
653 case OP_BACKREF_MULTI_IC:
654 case OP_BACKREF_WITH_LEVEL:
655 goto unexpected_bytecode_error;
657 case OP_MEMORY_START:
658 case OP_MEMORY_START_PUSH:
659 case OP_MEMORY_END_PUSH:
660 case OP_MEMORY_END_PUSH_REC:
662 case OP_MEMORY_END_REC:
664 if (lookaround_nesting != 0) {
665 goto unexpected_bytecode_error;
683 case OP_PUSH_OR_JUMP_EXACT1:
684 case OP_PUSH_IF_PEEK_NEXT:
685 p += SIZE_RELADDR + 1;
690 GET_MEMNUM_INC(repeat_mem, p);
692 if (reg->repeat_range[repeat_mem].lower == 0) {
695 current_repeat_mem = repeat_mem;
696 num_cache_points_at_repeat = cache_point;
697 cache_opcodes_at_repeat = cache_opcodes;
700 case OP_REPEAT_INC_NG:
701 GET_MEMNUM_INC(repeat_mem, p);
703 long num_cache_points_in_repeat = cache_point - num_cache_points_at_repeat;
705 if (repeat_range->lower < repeat_range->upper) {
709 cache_point -= num_cache_points_in_repeat;
710 int repeat_bounds = repeat_range->upper == 0x7fffffff ? 1 : repeat_range->upper - repeat_range->lower;
711 cache_point += num_cache_points_in_repeat * repeat_range->lower + (num_cache_points_in_repeat + 1) * repeat_bounds;
713 while (cache_opcodes_at_repeat <= cache_opcodes_in_repeat) {
714 cache_opcodes_in_repeat->num_cache_points_in_outer_repeat = num_cache_points_in_repeat;
715 cache_opcodes_in_repeat--;
717 current_repeat_mem = -1;
718 num_cache_points_at_repeat = 0;
719 cache_opcodes_at_repeat = NULL;
722 case OP_REPEAT_INC_SG:
723 case OP_REPEAT_INC_NG_SG:
724 goto unexpected_bytecode_error;
725 case OP_NULL_CHECK_START:
728 case OP_NULL_CHECK_END:
729 case OP_NULL_CHECK_END_MEMST_PUSH:
732 case OP_NULL_CHECK_END_MEMST:
737 INC_LOOKAROUND_NESTING;
739 case OP_PUSH_POS_NOT:
741 INC_LOOKAROUND_NESTING;
743 case OP_PUSH_LOOK_BEHIND_NOT:
746 INC_LOOKAROUND_NESTING;
750 case OP_FAIL_LOOK_BEHIND_NOT:
751 DEC_LOOKAROUND_NESTING;
753 case OP_PUSH_STOP_BT:
754 INC_LOOKAROUND_NESTING;
755 lookaround_nesting *= -1;
758 lookaround_nesting *= -1;
759 DEC_LOOKAROUND_NESTING;
767 goto unexpected_bytecode_error;
771 goto unexpected_bytecode_error;
774 goto unexpected_bytecode_error;
776 case OP_STATE_CHECK_PUSH:
777 case OP_STATE_CHECK_PUSH_OR_JUMP:
779 case OP_STATE_CHECK_ANYCHAR_STAR:
780 case OP_STATE_CHECK_ANYCHAR_ML_STAR:
781 goto unexpected_bytecode_error;
783 case OP_SET_OPTION_PUSH:
793 *num_cache_points_ptr = cache_point;
796unexpected_bytecode_error:
797 return ONIGERR_UNEXPECTED_BYTECODE;
800 return ONIGERR_UNDEFINED_BYTECODE;
804count_num_cache_opcodes(
regex_t* reg,
long* num_cache_opcodes)
806 *num_cache_opcodes = NUM_CACHE_OPCODES_IMPOSSIBLE;
814 long num_cache_opcodes = 0;
815 count_num_cache_opcodes(reg, &num_cache_opcodes);
816 return num_cache_opcodes != NUM_CACHE_OPCODES_IMPOSSIBLE;
824 for (i = 0; i < region->num_regs; i++) {
825 region->beg[i] = region->end[i] = ONIG_REGION_NOTPOS;
827#ifdef USE_CAPTURE_HISTORY
828 history_root_free(region);
835 region->num_regs = n;
837 if (n < ONIG_NREGION)
840 if (region->allocated == 0) {
841 region->beg = (OnigPosition* )
xmalloc(n *
sizeof(OnigPosition));
842 if (region->beg == 0)
843 return ONIGERR_MEMORY;
845 region->end = (OnigPosition* )
xmalloc(n *
sizeof(OnigPosition));
846 if (region->end == 0) {
848 return ONIGERR_MEMORY;
851 region->allocated = n;
853 else if (region->allocated < n) {
856 region->allocated = 0;
857 tmp = (OnigPosition* )
xrealloc(region->beg, n *
sizeof(OnigPosition));
861 return ONIGERR_MEMORY;
864 tmp = (OnigPosition* )
xrealloc(region->end, n *
sizeof(OnigPosition));
868 return ONIGERR_MEMORY;
872 region->allocated = n;
879onig_region_resize_clear(
OnigRegion* region,
int n)
883 r = onig_region_resize(region, n);
884 if (r != 0)
return r;
885 onig_region_clear(region);
890onig_region_set(
OnigRegion* region,
int at,
int beg,
int end)
892 if (at < 0)
return ONIGERR_INVALID_ARGUMENT;
894 if (at >= region->allocated) {
895 int r = onig_region_resize(region, at + 1);
899 region->beg[at] = beg;
900 region->end[at] = end;
907 region->num_regs = 0;
908 region->allocated = 0;
909 region->beg = (OnigPosition* )0;
910 region->end = (OnigPosition* )0;
911#ifdef USE_CAPTURE_HISTORY
912 region->history_root = (OnigCaptureTreeNode* )0;
931 if (r->allocated > 0) {
935#ifdef USE_CAPTURE_HISTORY
936 history_root_free(r);
950#define RREGC_SIZE (sizeof(int) * from->num_regs)
953 if (to == from)
return;
955 r = onig_region_resize(to, from->num_regs);
958 for (i = 0; i < from->num_regs; i++) {
959 to->beg[i] = from->beg[i];
960 to->end[i] = from->end[i];
962 to->num_regs = from->num_regs;
964#ifdef USE_CAPTURE_HISTORY
965 history_root_free(to);
967 if (IS_NOT_NULL(from->history_root)) {
968 to->history_root = history_tree_clone(from->history_root);
975#define INVALID_STACK_INDEX -1
979#define STK_ALT 0x0001
980#define STK_LOOK_BEHIND_NOT 0x0002
981#define STK_POS_NOT 0x0003
983#define STK_MEM_START 0x0100
984#define STK_MEM_END 0x8200
985#define STK_REPEAT_INC 0x0300
986#define STK_STATE_CHECK_MARK 0x1000
988#define STK_NULL_CHECK_START 0x3000
989#define STK_NULL_CHECK_END 0x5000
990#define STK_MEM_END_MARK 0x8400
991#define STK_POS 0x0500
992#define STK_STOP_BT 0x0600
993#define STK_REPEAT 0x0700
994#define STK_CALL_FRAME 0x0800
995#define STK_RETURN 0x0900
996#define STK_VOID 0x0a00
997#define STK_ABSENT_POS 0x0b00
998#define STK_ABSENT 0x0c00
999#define STK_MATCH_CACHE_POINT 0x0d00
1000#define STK_ATOMIC_MATCH_CACHE_POINT 0x0e00
1003#define STK_MASK_POP_USED 0x00ff
1004#define STK_MASK_TO_VOID_TARGET 0x10ff
1005#define STK_MASK_MEM_END_OR_MARK 0x8000
1007#ifdef USE_MATCH_CACHE
1008#define MATCH_ARG_INIT_MATCH_CACHE(msa) do {\
1009 (msa).match_cache_status = MATCH_CACHE_STATUS_UNINIT;\
1010 (msa).num_fails = 0;\
1011 (msa).num_cache_opcodes = NUM_CACHE_OPCODES_UNINIT;\
1012 (msa).cache_opcodes = (OnigCacheOpcode*)NULL;\
1013 (msa).num_cache_points = 0;\
1014 (msa).match_cache_buf = (uint8_t*)NULL;\
1016#define MATCH_ARG_FREE_MATCH_CACHE(msa) do {\
1017 xfree((msa).cache_opcodes);\
1018 xfree((msa).match_cache_buf);\
1019 (msa).cache_opcodes = (OnigCacheOpcode*)NULL;\
1020 (msa).match_cache_buf = (uint8_t*)NULL;\
1023#define MATCH_ARG_INIT_MATCH_CACHE(msa)
1024#define MATCH_ARG_FREE_MATCH_CACHE(msa)
1027#ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
1028# define MATCH_ARG_INIT(msa, arg_option, arg_region, arg_start, arg_gpos) do {\
1029 (msa).stack_p = (void* )0;\
1030 (msa).options = (arg_option);\
1031 (msa).region = (arg_region);\
1032 (msa).start = (arg_start);\
1033 (msa).gpos = (arg_gpos);\
1034 (msa).best_len = ONIG_MISMATCH;\
1036 (msa).end_time = 0;\
1037 MATCH_ARG_INIT_MATCH_CACHE(msa);\
1040# define MATCH_ARG_INIT(msa, arg_option, arg_region, arg_start, arg_gpos) do {\
1041 (msa).stack_p = (void* )0;\
1042 (msa).options = (arg_option);\
1043 (msa).region = (arg_region);\
1044 (msa).start = (arg_start);\
1045 (msa).gpos = (arg_gpos);\
1047 (msa).end_time = 0;\
1048 MATCH_ARG_INIT_MATCH_CACHE(msa);\
1052#ifdef USE_COMBINATION_EXPLOSION_CHECK
1054# define STATE_CHECK_BUFF_MALLOC_THRESHOLD_SIZE 16
1056# define STATE_CHECK_BUFF_INIT(msa, str_len, offset, state_num) do { \
1057 if ((state_num) > 0 && str_len >= STATE_CHECK_STRING_THRESHOLD_LEN) {\
1058 unsigned int size = (unsigned int )(((str_len) + 1) * (state_num) + 7) >> 3;\
1059 offset = ((offset) * (state_num)) >> 3;\
1060 if (size > 0 && offset < size && size < STATE_CHECK_BUFF_MAX_SIZE) {\
1061 if (size >= STATE_CHECK_BUFF_MALLOC_THRESHOLD_SIZE) {\
1062 (msa).state_check_buff = (void* )xmalloc(size);\
1063 CHECK_NULL_RETURN_MEMERR((msa).state_check_buff);\
1066 (msa).state_check_buff = (void* )xalloca(size);\
1067 xmemset(((char* )((msa).state_check_buff)+(offset)), 0, \
1068 (size_t )(size - (offset))); \
1069 (msa).state_check_buff_size = size;\
1072 (msa).state_check_buff = (void* )0;\
1073 (msa).state_check_buff_size = 0;\
1077 (msa).state_check_buff = (void* )0;\
1078 (msa).state_check_buff_size = 0;\
1082# define MATCH_ARG_FREE(msa) do {\
1083 xfree((msa).stack_p);\
1084 if ((msa).state_check_buff_size >= STATE_CHECK_BUFF_MALLOC_THRESHOLD_SIZE) { \
1085 xfree((msa).state_check_buff);\
1087 MATCH_ARG_FREE_MATCH_CACHE(msa);\
1090# define MATCH_ARG_FREE(msa) do {\
1091 xfree((msa).stack_p);\
1092 MATCH_ARG_FREE_MATCH_CACHE(msa);\
1098#define MAX_PTR_NUM 100
1100#define STACK_INIT(alloc_addr, heap_addr, ptr_num, stack_num) do {\
1101 if (ptr_num > MAX_PTR_NUM) {\
1102 alloc_addr = (char* )xmalloc(sizeof(OnigStackIndex) * (ptr_num));\
1103 heap_addr = alloc_addr;\
1104 if (msa->stack_p) {\
1105 stk_alloc = (OnigStackType* )(msa->stack_p);\
1106 stk_base = stk_alloc;\
1108 stk_end = stk_base + msa->stack_n;\
1110 stk_alloc = (OnigStackType* )xalloca(sizeof(OnigStackType) * (stack_num));\
1111 stk_base = stk_alloc;\
1113 stk_end = stk_base + (stack_num);\
1115 } else if (msa->stack_p) {\
1116 alloc_addr = (char* )xalloca(sizeof(OnigStackIndex) * (ptr_num));\
1118 stk_alloc = (OnigStackType* )(msa->stack_p);\
1119 stk_base = stk_alloc;\
1121 stk_end = stk_base + msa->stack_n;\
1124 alloc_addr = (char* )xalloca(sizeof(OnigStackIndex) * (ptr_num)\
1125 + sizeof(OnigStackType) * (stack_num));\
1127 stk_alloc = (OnigStackType* )(alloc_addr + sizeof(OnigStackIndex) * (ptr_num));\
1128 stk_base = stk_alloc;\
1130 stk_end = stk_base + (stack_num);\
1134#define STACK_SAVE do{\
1135 if (stk_base != stk_alloc) {\
1136 msa->stack_p = stk_base;\
1137 msa->stack_n = stk_end - stk_base; \
1141static unsigned int MatchStackLimitSize = DEFAULT_MATCH_STACK_LIMIT_SIZE;
1144onig_get_match_stack_limit_size(
void)
1146 return MatchStackLimitSize;
1150onig_set_match_stack_limit_size(
unsigned int size)
1152 MatchStackLimitSize = size;
1163 stk_base = *arg_stk_base;
1164 stk_end = *arg_stk_end;
1167 n = stk_end - stk_base;
1168 if (stk_base == stk_alloc && IS_NULL(msa->stack_p)) {
1172 return ONIGERR_MEMORY;
1178 unsigned int limit_size = MatchStackLimitSize;
1180 if (limit_size != 0 && n > limit_size) {
1181 if ((
unsigned int )(stk_end - stk_base) == limit_size)
1182 return ONIGERR_MATCH_STACK_LIMIT_OVER;
1189 return ONIGERR_MEMORY;
1192 *arg_stk = x + (stk - stk_base);
1194 *arg_stk_end = x + n;
1198#define STACK_ENSURE(n) do {\
1199 if (stk_end - stk < (n)) {\
1200 int r = stack_double(&stk_base, &stk_end, &stk, stk_alloc, msa);\
1203 xfree(xmalloc_base);\
1209#define STACK_AT(index) (stk_base + (index))
1210#define GET_STACK_INDEX(stk) ((stk) - stk_base)
1212#define STACK_PUSH_TYPE(stack_type) do {\
1214 stk->type = (stack_type);\
1215 stk->null_check = stk == stk_base ? 0 : (stk-1)->null_check;\
1219#define IS_TO_VOID_TARGET(stk) (((stk)->type & STK_MASK_TO_VOID_TARGET) != 0)
1221#ifdef USE_COMBINATION_EXPLOSION_CHECK
1222# define STATE_CHECK_POS(s,snum) \
1223 (((s) - str) * num_comb_exp_check + ((snum) - 1))
1224# define STATE_CHECK_VAL(v,snum) do {\
1225 if (state_check_buff != NULL) {\
1226 ptrdiff_t x = STATE_CHECK_POS(s,snum);\
1227 (v) = state_check_buff[x/8] & (1<<(x%8));\
1233# define ELSE_IF_STATE_CHECK_MARK(stk) \
1234 else if ((stk)->type == STK_STATE_CHECK_MARK) { \
1235 ptrdiff_t x = STATE_CHECK_POS(stk->u.state.pstr, stk->u.state.state_check);\
1236 state_check_buff[x/8] |= (1<<(x%8)); \
1239# define STACK_PUSH(stack_type,pat,s,sprev,keep) do {\
1241 stk->type = (stack_type);\
1242 stk->u.state.pcode = (pat);\
1243 stk->u.state.pstr = (s);\
1244 stk->u.state.pstr_prev = (sprev);\
1245 stk->u.state.state_check = 0;\
1246 stk->u.state.pkeep = (keep);\
1250# define STACK_PUSH_ENSURED(stack_type,pat) do {\
1251 stk->type = (stack_type);\
1252 stk->u.state.pcode = (pat);\
1253 stk->u.state.state_check = 0;\
1257# define STACK_PUSH_ALT_WITH_STATE_CHECK(pat,s,sprev,snum,keep) do {\
1259 stk->type = STK_ALT;\
1260 stk->u.state.pcode = (pat);\
1261 stk->u.state.pstr = (s);\
1262 stk->u.state.pstr_prev = (sprev);\
1263 stk->u.state.state_check = ((state_check_buff != NULL) ? (snum) : 0);\
1264 stk->u.state.pkeep = (keep);\
1268# define STACK_PUSH_STATE_CHECK(s,snum) do {\
1269 if (state_check_buff != NULL) {\
1271 stk->type = STK_STATE_CHECK_MARK;\
1272 stk->u.state.pstr = (s);\
1273 stk->u.state.state_check = (snum);\
1280# define ELSE_IF_STATE_CHECK_MARK(stk)
1282# define STACK_PUSH(stack_type,pat,s,sprev,keep) do {\
1284 stk->type = (stack_type);\
1285 stk->null_check = stk == stk_base ? 0 : (stk-1)->null_check;\
1286 stk->u.state.pcode = (pat);\
1287 stk->u.state.pstr = (s);\
1288 stk->u.state.pstr_prev = (sprev);\
1289 stk->u.state.pkeep = (keep);\
1293# define STACK_PUSH_ENSURED(stack_type,pat) do {\
1294 stk->type = (stack_type);\
1295 stk->null_check = stk == stk_base ? 0 : (stk-1)->null_check;\
1296 stk->u.state.pcode = (pat);\
1301#define STACK_PUSH_ALT(pat,s,sprev,keep) STACK_PUSH(STK_ALT,pat,s,sprev,keep)
1302#define STACK_PUSH_POS(s,sprev,keep) STACK_PUSH(STK_POS,NULL_UCHARP,s,sprev,keep)
1303#define STACK_PUSH_POS_NOT(pat,s,sprev,keep) STACK_PUSH(STK_POS_NOT,pat,s,sprev,keep)
1304#define STACK_PUSH_ABSENT STACK_PUSH_TYPE(STK_ABSENT)
1305#define STACK_PUSH_STOP_BT STACK_PUSH_TYPE(STK_STOP_BT)
1306#define STACK_PUSH_LOOK_BEHIND_NOT(pat,s,sprev,keep) \
1307 STACK_PUSH(STK_LOOK_BEHIND_NOT,pat,s,sprev,keep)
1309#define STACK_PUSH_REPEAT(id, pat) do {\
1311 stk->type = STK_REPEAT;\
1312 stk->null_check = stk == stk_base ? 0 : (stk-1)->null_check;\
1313 stk->u.repeat.num = (id);\
1314 stk->u.repeat.pcode = (pat);\
1315 stk->u.repeat.count = 0;\
1319#define STACK_PUSH_REPEAT_INC(sindex) do {\
1321 stk->type = STK_REPEAT_INC;\
1322 stk->null_check = stk == stk_base ? 0 : (stk-1)->null_check;\
1323 stk->u.repeat_inc.si = (sindex);\
1327#define STACK_PUSH_MEM_START(mnum, s) do {\
1329 stk->type = STK_MEM_START;\
1330 stk->null_check = stk == stk_base ? 0 : (stk-1)->null_check;\
1331 stk->u.mem.num = (mnum);\
1332 stk->u.mem.pstr = (s);\
1333 stk->u.mem.start = mem_start_stk[mnum];\
1334 stk->u.mem.end = mem_end_stk[mnum];\
1335 mem_start_stk[mnum] = GET_STACK_INDEX(stk);\
1336 mem_end_stk[mnum] = INVALID_STACK_INDEX;\
1340#define STACK_PUSH_MEM_END(mnum, s) do {\
1342 stk->type = STK_MEM_END;\
1343 stk->null_check = stk == stk_base ? 0 : (stk-1)->null_check;\
1344 stk->u.mem.num = (mnum);\
1345 stk->u.mem.pstr = (s);\
1346 stk->u.mem.start = mem_start_stk[mnum];\
1347 stk->u.mem.end = mem_end_stk[mnum];\
1348 mem_end_stk[mnum] = GET_STACK_INDEX(stk);\
1352#define STACK_PUSH_MEM_END_MARK(mnum) do {\
1354 stk->type = STK_MEM_END_MARK;\
1355 stk->null_check = stk == stk_base ? 0 : (stk-1)->null_check;\
1356 stk->u.mem.num = (mnum);\
1360#define STACK_GET_MEM_START(mnum, k) do {\
1363 while (k > stk_base) {\
1365 if ((k->type & STK_MASK_MEM_END_OR_MARK) != 0 \
1366 && k->u.mem.num == (mnum)) {\
1369 else if (k->type == STK_MEM_START && k->u.mem.num == (mnum)) {\
1370 if (level == 0) break;\
1376#define STACK_GET_MEM_RANGE(k, mnum, start, end) do {\
1379 if (k->type == STK_MEM_START && k->u.mem.num == (mnum)) {\
1380 if (level == 0) (start) = k->u.mem.pstr;\
1383 else if (k->type == STK_MEM_END && k->u.mem.num == (mnum)) {\
1386 (end) = k->u.mem.pstr;\
1394#define STACK_PUSH_NULL_CHECK_START(cnum, s) do {\
1396 stk->type = STK_NULL_CHECK_START;\
1397 stk->null_check = (OnigStackIndex)(stk - stk_base);\
1398 stk->u.null_check.num = (cnum);\
1399 stk->u.null_check.pstr = (s);\
1403#define STACK_PUSH_NULL_CHECK_END(cnum) do {\
1405 stk->type = STK_NULL_CHECK_END;\
1406 stk->null_check = (OnigStackIndex)(stk - stk_base);\
1407 stk->u.null_check.num = (cnum);\
1411#define STACK_PUSH_CALL_FRAME(pat) do {\
1413 stk->type = STK_CALL_FRAME;\
1414 stk->null_check = stk == stk_base ? 0 : (stk-1)->null_check;\
1415 stk->u.call_frame.ret_addr = (pat);\
1419#define STACK_PUSH_RETURN do {\
1421 stk->type = STK_RETURN;\
1422 stk->null_check = stk == stk_base ? 0 : (stk-1)->null_check;\
1426#define STACK_PUSH_ABSENT_POS(start, end) do {\
1428 stk->type = STK_ABSENT_POS;\
1429 stk->null_check = stk == stk_base ? 0 : (stk-1)->null_check;\
1430 stk->u.absent_pos.abs_pstr = (start);\
1431 stk->u.absent_pos.end_pstr = (end);\
1435#define STACK_PUSH_MATCH_CACHE_POINT(match_cache_point_index, match_cache_point_mask) do {\
1437 stk->type = STK_MATCH_CACHE_POINT;\
1438 stk->null_check = stk == stk_base ? 0 : (stk-1)->null_check;\
1439 stk->u.match_cache_point.index = (match_cache_point_index);\
1440 stk->u.match_cache_point.mask = (match_cache_point_mask);\
1446# define STACK_BASE_CHECK(p, at) \
1447 if ((p) < stk_base) {\
1448 fprintf(stderr, "at %s\n", at);\
1452# define STACK_BASE_CHECK(p, at)
1455#ifdef ONIG_DEBUG_MATCH_CACHE
1456# define MATCH_CACHE_DEBUG_MEMOIZE(stkp) fprintf(stderr, "MATCH CACHE: memoize (index=%ld mask=%d)\n", stkp->u.match_cache_point.index, stkp->u.match_cache_point.mask);
1458# define MATCH_CACHE_DEBUG_MEMOIZE(stkp) ((void) 0)
1461#ifdef USE_MATCH_CACHE
1462# define INC_NUM_FAILS msa->num_fails++
1463# define MEMOIZE_MATCH_CACHE_POINT do {\
1464 if (stk->type == STK_MATCH_CACHE_POINT) {\
1465 msa->match_cache_buf[stk->u.match_cache_point.index] |= stk->u.match_cache_point.mask;\
1466 MATCH_CACHE_DEBUG_MEMOIZE(stk);\
1467 } else if (stk->type == STK_ATOMIC_MATCH_CACHE_POINT) {\
1468 memoize_extended_match_cache_point(msa->match_cache_buf, stk->u.match_cache_point.index, stk->u.match_cache_point.mask);\
1469 MATCH_CACHE_DEBUG_MEMOIZE(stkp);\
1472# define MEMOIZE_LOOKAROUND_MATCH_CACHE_POINT(stkp) do {\
1473 if (stkp->type == STK_MATCH_CACHE_POINT) {\
1474 stkp->type = STK_VOID;\
1475 memoize_extended_match_cache_point(msa->match_cache_buf, stkp->u.match_cache_point.index, stkp->u.match_cache_point.mask);\
1476 MATCH_CACHE_DEBUG_MEMOIZE(stkp);\
1479# define MEMOIZE_ATOMIC_MATCH_CACHE_POINT do {\
1480 if (stk->type == STK_MATCH_CACHE_POINT) {\
1481 memoize_extended_match_cache_point(msa->match_cache_buf, stk->u.match_cache_point.index, stk->u.match_cache_point.mask);\
1482 MATCH_CACHE_DEBUG_MEMOIZE(stkp);\
1486# define INC_NUM_FAILS ((void) 0)
1487# define MEMOIZE_MATCH_CACHE_POINT ((void) 0)
1488# define MEMOIZE_LOOKAROUND_MATCH_CACHE_POINT ((void) 0)
1491#define STACK_POP_ONE do {\
1493 STACK_BASE_CHECK(stk, "STACK_POP_ONE"); \
1496#define STACK_POP do {\
1497 switch (pop_level) {\
1498 case STACK_POP_LEVEL_FREE:\
1501 STACK_BASE_CHECK(stk, "STACK_POP"); \
1502 if ((stk->type & STK_MASK_POP_USED) != 0) break;\
1503 ELSE_IF_STATE_CHECK_MARK(stk);\
1504 MEMOIZE_MATCH_CACHE_POINT;\
1507 case STACK_POP_LEVEL_MEM_START:\
1510 STACK_BASE_CHECK(stk, "STACK_POP 2"); \
1511 if ((stk->type & STK_MASK_POP_USED) != 0) break;\
1512 else if (stk->type == STK_MEM_START) {\
1513 mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
1514 mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\
1516 ELSE_IF_STATE_CHECK_MARK(stk);\
1517 MEMOIZE_MATCH_CACHE_POINT;\
1523 STACK_BASE_CHECK(stk, "STACK_POP 3"); \
1524 if ((stk->type & STK_MASK_POP_USED) != 0) break;\
1525 else if (stk->type == STK_MEM_START) {\
1526 mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
1527 mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\
1529 else if (stk->type == STK_REPEAT_INC) {\
1530 STACK_AT(stk->u.repeat_inc.si)->u.repeat.count--;\
1532 else if (stk->type == STK_MEM_END) {\
1533 mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
1534 mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\
1536 ELSE_IF_STATE_CHECK_MARK(stk);\
1537 MEMOIZE_MATCH_CACHE_POINT;\
1543#define STACK_POP_TIL_POS_NOT do {\
1546 STACK_BASE_CHECK(stk, "STACK_POP_TIL_POS_NOT"); \
1547 if (stk->type == STK_POS_NOT) break;\
1548 else if (stk->type == STK_MEM_START) {\
1549 mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
1550 mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\
1552 else if (stk->type == STK_REPEAT_INC) {\
1553 STACK_AT(stk->u.repeat_inc.si)->u.repeat.count--;\
1555 else if (stk->type == STK_MEM_END) {\
1556 mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
1557 mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\
1559 else if (IS_TO_VOID_TARGET(stk)) {\
1562 ELSE_IF_STATE_CHECK_MARK(stk);\
1563 MEMOIZE_LOOKAROUND_MATCH_CACHE_POINT(stk);\
1567#define STACK_POP_TIL_LOOK_BEHIND_NOT do {\
1570 STACK_BASE_CHECK(stk, "STACK_POP_TIL_LOOK_BEHIND_NOT"); \
1571 if (stk->type == STK_LOOK_BEHIND_NOT) break;\
1572 else if (stk->type == STK_MEM_START) {\
1573 mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
1574 mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\
1576 else if (stk->type == STK_REPEAT_INC) {\
1577 STACK_AT(stk->u.repeat_inc.si)->u.repeat.count--;\
1579 else if (stk->type == STK_MEM_END) {\
1580 mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
1581 mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\
1583 ELSE_IF_STATE_CHECK_MARK(stk);\
1587#define STACK_POP_TIL_ABSENT do {\
1590 STACK_BASE_CHECK(stk, "STACK_POP_TIL_ABSENT"); \
1591 if (stk->type == STK_ABSENT) break;\
1592 else if (stk->type == STK_MEM_START) {\
1593 mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
1594 mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\
1596 else if (stk->type == STK_REPEAT_INC) {\
1597 STACK_AT(stk->u.repeat_inc.si)->u.repeat.count--;\
1599 else if (stk->type == STK_MEM_END) {\
1600 mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
1601 mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\
1603 ELSE_IF_STATE_CHECK_MARK(stk);\
1607#define STACK_POP_ABSENT_POS(start, end) do {\
1609 STACK_BASE_CHECK(stk, "STACK_POP_ABSENT_POS"); \
1610 (start) = stk->u.absent_pos.abs_pstr;\
1611 (end) = stk->u.absent_pos.end_pstr;\
1614#define STACK_POS_END(k) do {\
1618 STACK_BASE_CHECK(k, "STACK_POS_END"); \
1619 if (IS_TO_VOID_TARGET(k)) {\
1621 k->type = STK_VOID;\
1623 else if (k->type == STK_POS) {\
1624 k->type = STK_VOID;\
1627 MEMOIZE_LOOKAROUND_MATCH_CACHE_POINT(k);\
1631#define STACK_STOP_BT_END do {\
1632 OnigStackType *k = stk;\
1635 STACK_BASE_CHECK(k, "STACK_STOP_BT_END"); \
1636 if (IS_TO_VOID_TARGET(k)) {\
1638 k->type = STK_VOID;\
1640 else if (k->type == STK_STOP_BT) {\
1641 k->type = STK_VOID;\
1644 else if (k->type == STK_MATCH_CACHE_POINT) {\
1645 k->type = STK_ATOMIC_MATCH_CACHE_POINT;\
1650#define STACK_STOP_BT_FAIL do {\
1653 STACK_BASE_CHECK(stk, "STACK_STOP_BT_END"); \
1654 if (stk->type == STK_STOP_BT) {\
1655 stk->type = STK_VOID;\
1658 MEMOIZE_ATOMIC_MATCH_CACHE_POINT;\
1662#define STACK_NULL_CHECK(isnull,id,s) do {\
1663 OnigStackType* k = STACK_AT((stk-1)->null_check)+1;\
1666 STACK_BASE_CHECK(k, "STACK_NULL_CHECK"); \
1667 if (k->type == STK_NULL_CHECK_START) {\
1668 if (k->u.null_check.num == (id)) {\
1669 (isnull) = (k->u.null_check.pstr == (s));\
1676#define STACK_NULL_CHECK_REC(isnull,id,s) do {\
1678 OnigStackType* k = STACK_AT((stk-1)->null_check)+1;\
1681 STACK_BASE_CHECK(k, "STACK_NULL_CHECK_REC"); \
1682 if (k->type == STK_NULL_CHECK_START) {\
1683 if (k->u.null_check.num == (id)) {\
1685 (isnull) = (k->u.null_check.pstr == (s));\
1691 else if (k->type == STK_NULL_CHECK_END) {\
1697#define STACK_NULL_CHECK_MEMST(isnull,id,s,reg) do {\
1698 OnigStackType* k = STACK_AT((stk-1)->null_check)+1;\
1701 STACK_BASE_CHECK(k, "STACK_NULL_CHECK_MEMST"); \
1702 if (k->type == STK_NULL_CHECK_START) {\
1703 if (k->u.null_check.num == (id)) {\
1704 if (k->u.null_check.pstr != (s)) {\
1712 if (k->type == STK_MEM_START) {\
1713 if (k->u.mem.end == INVALID_STACK_INDEX) {\
1714 (isnull) = 0; break;\
1716 if (BIT_STATUS_AT(reg->bt_mem_end, k->u.mem.num))\
1717 endp = STACK_AT(k->u.mem.end)->u.mem.pstr;\
1719 endp = (UChar* )k->u.mem.end;\
1720 if (STACK_AT(k->u.mem.start)->u.mem.pstr != endp) {\
1721 (isnull) = 0; break;\
1723 else if (endp != s) {\
1736#define STACK_NULL_CHECK_MEMST_REC(isnull,id,s,reg) do {\
1738 OnigStackType* k = STACK_AT((stk-1)->null_check)+1;\
1741 STACK_BASE_CHECK(k, "STACK_NULL_CHECK_MEMST_REC"); \
1742 if (k->type == STK_NULL_CHECK_START) {\
1743 if (k->u.null_check.num == (id)) {\
1745 if (k->u.null_check.pstr != (s)) {\
1753 if (k->type == STK_MEM_START) {\
1754 if (k->u.mem.end == INVALID_STACK_INDEX) {\
1755 (isnull) = 0; break;\
1757 if (BIT_STATUS_AT(reg->bt_mem_end, k->u.mem.num))\
1758 endp = STACK_AT(k->u.mem.end)->u.mem.pstr;\
1760 endp = (UChar* )k->u.mem.end;\
1761 if (STACK_AT(k->u.mem.start)->u.mem.pstr != endp) {\
1762 (isnull) = 0; break;\
1764 else if (endp != s) {\
1778 else if (k->type == STK_NULL_CHECK_END) {\
1779 if (k->u.null_check.num == (id)) level++;\
1784#define STACK_GET_REPEAT(id, k) do {\
1789 STACK_BASE_CHECK(k, "STACK_GET_REPEAT"); \
1790 if (k->type == STK_REPEAT) {\
1792 if (k->u.repeat.num == (id)) {\
1797 else if (k->type == STK_CALL_FRAME) level--;\
1798 else if (k->type == STK_RETURN) level++;\
1802#define STACK_RETURN(addr) do {\
1804 OnigStackType* k = stk;\
1807 STACK_BASE_CHECK(k, "STACK_RETURN"); \
1808 if (k->type == STK_CALL_FRAME) {\
1810 (addr) = k->u.call_frame.ret_addr;\
1815 else if (k->type == STK_RETURN)\
1821#define STRING_CMP(s1,s2,len) do {\
1822 while (len-- > 0) {\
1823 if (*s1++ != *s2++) goto fail;\
1827#define STRING_CMP_IC(case_fold_flag,s1,ps2,len,text_end) do {\
1828 if (string_cmp_ic(encode, case_fold_flag, s1, ps2, len, text_end) == 0) \
1832static int string_cmp_ic(
OnigEncoding enc,
int case_fold_flag,
1833 UChar* s1, UChar** ps2, OnigDistance mblen,
const UChar* text_end)
1835 UChar buf1[ONIGENC_MBC_CASE_FOLD_MAXLEN];
1836 UChar buf2[ONIGENC_MBC_CASE_FOLD_MAXLEN];
1837 UChar *p1, *p2, *end1, *s2;
1843 len1 = ONIGENC_MBC_CASE_FOLD(enc, case_fold_flag, &s1, text_end, buf1);
1844 len2 = ONIGENC_MBC_CASE_FOLD(enc, case_fold_flag, &s2, text_end, buf2);
1845 if (len1 != len2)
return 0;
1848 while (len1-- > 0) {
1849 if (*p1 != *p2)
return 0;
1859#define STRING_CMP_VALUE(s1,s2,len,is_fail) do {\
1861 while (len-- > 0) {\
1862 if (*s1++ != *s2++) {\
1863 is_fail = 1; break;\
1868#define STRING_CMP_VALUE_IC(case_fold_flag,s1,ps2,len,text_end,is_fail) do {\
1869 if (string_cmp_ic(encode, case_fold_flag, s1, ps2, len, text_end) == 0) \
1876#define IS_EMPTY_STR (str == end)
1877#define ON_STR_BEGIN(s) ((s) == str)
1878#define ON_STR_END(s) ((s) == end)
1879#ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
1880# define DATA_ENSURE_CHECK1 (s < right_range)
1881# define DATA_ENSURE_CHECK(n) (s + (n) <= right_range)
1882# define DATA_ENSURE(n) if (s + (n) > right_range) goto fail
1883# define DATA_ENSURE_CONTINUE(n) if (s + (n) > right_range) continue
1884# define ABSENT_END_POS right_range
1886# define DATA_ENSURE_CHECK1 (s < end)
1887# define DATA_ENSURE_CHECK(n) (s + (n) <= end)
1888# define DATA_ENSURE(n) if (s + (n) > end) goto fail
1889# define DATA_ENSURE_CONTINUE(n) if (s + (n) > end) continue
1890# define ABSENT_END_POS end
1894#ifdef USE_CAPTURE_HISTORY
1896make_capture_history_tree(OnigCaptureTreeNode* node,
OnigStackType** kp,
1900 OnigCaptureTreeNode* child;
1903 while (k < stk_top) {
1904 if (k->type == STK_MEM_START) {
1906 if (n <= ONIG_MAX_CAPTURE_HISTORY_GROUP &&
1907 BIT_STATUS_AT(reg->capture_history, n) != 0) {
1908 child = history_node_new();
1909 CHECK_NULL_RETURN_MEMERR(child);
1911 child->beg = k->u.mem.pstr - str;
1912 r = history_tree_add_child(node, child);
1914 history_tree_free(child);
1918 r = make_capture_history_tree(child, kp, stk_top, str, reg);
1919 if (r != 0)
return r;
1922 child->end = k->u.mem.pstr - str;
1925 else if (k->type == STK_MEM_END) {
1926 if (k->u.mem.num == node->group) {
1927 node->end = k->u.mem.pstr - str;
1939#ifdef USE_BACKREF_WITH_LEVEL
1941mem_is_in_memp(
int mem,
int num, UChar* memp)
1946 for (i = 0; i < num; i++) {
1947 GET_MEMNUM_INC(m, memp);
1948 if (mem == (
int )m)
return 1;
1953static int backref_match_at_nested_level(
regex_t* reg,
1955 int ignore_case,
int case_fold_flag,
1956 int nest,
int mem_num, UChar* memp, UChar** s,
const UChar* send)
1958 UChar *ss, *p, *pstart, *pend = NULL_UCHARP;
1965 while (k >= stk_base) {
1966 if (k->type == STK_CALL_FRAME) {
1969 else if (k->type == STK_RETURN) {
1972 else if (level == nest) {
1973 if (k->type == STK_MEM_START) {
1974 if (mem_is_in_memp(k->u.mem.num, mem_num, memp)) {
1975 pstart = k->u.mem.pstr;
1976 if (pend != NULL_UCHARP) {
1977 if (pend - pstart > send - *s)
return 0;
1981 if (ignore_case != 0) {
1982 if (string_cmp_ic(reg->enc, case_fold_flag,
1983 pstart, &ss, pend - pstart, send) == 0)
1988 if (*p++ != *ss++)
return 0;
1997 else if (k->type == STK_MEM_END) {
1998 if (mem_is_in_memp(k->u.mem.num, mem_num, memp)) {
1999 pend = k->u.mem.pstr;
2011#ifdef ONIG_DEBUG_STATISTICS
2014# include <windows.h>
2015static LARGE_INTEGER ts, te, freq;
2016# define GETTIME(t) QueryPerformanceCounter(&(t))
2017# define TIMEDIFF(te,ts) (unsigned long )(((te).QuadPart - (ts).QuadPart) \
2018 * 1000000 / freq.QuadPart)
2021# define USE_TIMEOFDAY
2023# ifdef USE_TIMEOFDAY
2024# ifdef HAVE_SYS_TIME_H
2025# include <sys/time.h>
2027# ifdef HAVE_UNISTD_H
2031# define GETTIME(t) gettimeofday(&(t), (struct timezone* )0)
2032# define TIMEDIFF(te,ts) (((te).tv_usec - (ts).tv_usec) + \
2033 (((te).tv_sec - (ts).tv_sec)*1000000))
2035# ifdef HAVE_SYS_TIMES_H
2036# include <sys/times.h>
2038static struct tms ts, te;
2039# define GETTIME(t) times(&(t))
2040# define TIMEDIFF(te,ts) ((te).tms_utime - (ts).tms_utime)
2045static int OpCounter[256];
2046static int OpPrevCounter[256];
2047static unsigned long OpTime[256];
2048static int OpCurr = OP_FINISH;
2049static int OpPrevTarget = OP_FAIL;
2050static int MaxStackDepth = 0;
2052# define MOP_IN(opcode) do {\
2053 if (opcode == OpPrevTarget) OpPrevCounter[OpCurr]++;\
2055 OpCounter[opcode]++;\
2059# define MOP_OUT do {\
2061 OpTime[OpCurr] += TIMEDIFF(te, ts);\
2065onig_statistics_init(
void)
2068 for (i = 0; i < 256; i++) {
2069 OpCounter[i] = OpPrevCounter[i] = 0; OpTime[i] = 0;
2073 QueryPerformanceFrequency(&freq);
2078onig_print_statistics(
FILE* f)
2081 fprintf(f,
" count prev time\n");
2082 for (i = 0; OnigOpInfo[i].opcode >= 0; i++) {
2083 fprintf(f,
"%8d: %8d: %10lu: %s\n",
2084 OpCounter[i], OpPrevCounter[i], OpTime[i], OnigOpInfo[i].name);
2086 fprintf(f,
"\nmax stack depth: %d\n", MaxStackDepth);
2089# define STACK_INC do {\
2091 if (stk - stk_base > MaxStackDepth) \
2092 MaxStackDepth = stk - stk_base;\
2096# define STACK_INC stk++
2098# define MOP_IN(opcode)
2103#ifdef ONIG_DEBUG_MATCH
2105stack_type_str(
int stack_type)
2107 switch (stack_type) {
2108 case STK_ALT:
return "Alt ";
2109 case STK_LOOK_BEHIND_NOT:
return "LBNot ";
2110 case STK_POS_NOT:
return "PosNot";
2111 case STK_MEM_START:
return "MemS ";
2112 case STK_MEM_END:
return "MemE ";
2113 case STK_REPEAT_INC:
return "RepInc";
2114 case STK_STATE_CHECK_MARK:
return "StChMk";
2115 case STK_NULL_CHECK_START:
return "NulChS";
2116 case STK_NULL_CHECK_END:
return "NulChE";
2117 case STK_MEM_END_MARK:
return "MemEMk";
2118 case STK_POS:
return "Pos ";
2119 case STK_STOP_BT:
return "StopBt";
2120 case STK_REPEAT:
return "Rep ";
2121 case STK_CALL_FRAME:
return "Call ";
2122 case STK_RETURN:
return "Ret ";
2123 case STK_VOID:
return "Void ";
2124 case STK_ABSENT_POS:
return "AbsPos";
2125 case STK_ABSENT:
return "Absent";
2126 case STK_MATCH_CACHE_POINT:
return "MCache";
2127 default:
return " ";
2131#ifdef USE_MATCH_CACHE
2134bsearch_cache_opcodes(
const OnigCacheOpcode *cache_opcodes,
long num_cache_opcodes,
const UChar* p)
2136 long l = 0, r = num_cache_opcodes - 1, m = 0;
2140 if (cache_opcodes[m].addr == p)
break;
2141 if (cache_opcodes[m].addr < p) l = m + 1;
2155 int is_inc = *p == OP_REPEAT_INC || *p == OP_REPEAT_INC_NG;
2157 long num_cache_points_at_outer_repeat;
2158 long num_cache_points_in_outer_repeat;
2160 m = bsearch_cache_opcodes(cache_opcodes, num_cache_opcodes, p);
2162 if (!(0 <= m && m < num_cache_opcodes && cache_opcodes[m].addr == p)) {
2166 cache_opcode = &cache_opcodes[m];
2167 *cache_opcode_ptr = &cache_opcodes[m];
2168 cache_point = cache_opcode->cache_point;
2169 if (cache_opcode->outer_repeat_mem == -1) {
2173 num_cache_points_at_outer_repeat = cache_opcode->num_cache_points_at_outer_repeat;
2174 num_cache_points_in_outer_repeat = cache_opcode->num_cache_points_in_outer_repeat;
2176 range = ®->repeat_range[cache_opcode->outer_repeat_mem];
2178 stkp = &stk[repeat_stk[cache_opcode->outer_repeat_mem]];
2179 count = is_inc ? stkp->u.repeat.count - 1 : stkp->u.repeat.count;
2181 if (count < range->lower) {
2182 return num_cache_points_at_outer_repeat +
2183 num_cache_points_in_outer_repeat * count +
2187 if (range->upper == 0x7fffffff) {
2188 return num_cache_points_at_outer_repeat +
2189 num_cache_points_in_outer_repeat * (range->lower - (is_inc ? 1 : 0)) + (is_inc ? 0 : 1) +
2193 return num_cache_points_at_outer_repeat +
2194 num_cache_points_in_outer_repeat * (range->lower - 1) +
2195 (num_cache_points_in_outer_repeat + 1) * (count - range->lower + 1) +
2199static int check_extended_match_cache_point(uint8_t *match_cache_buf,
long match_cache_point_index, uint8_t match_cache_point_mask) {
2200 if (match_cache_point_mask & 0x80) {
2201 return (match_cache_buf[match_cache_point_index + 1] & 0x01) > 0;
2203 return (match_cache_buf[match_cache_point_index] & (match_cache_point_mask << 1)) > 0;
2207static void memoize_extended_match_cache_point(uint8_t *match_cache_buf,
long match_cache_point_index, uint8_t match_cache_point_mask) {
2208 match_cache_buf[match_cache_point_index] |= match_cache_point_mask;
2209 if (match_cache_point_mask & 0x80) {
2210 match_cache_buf[match_cache_point_index + 1] |= 0x01;
2212 match_cache_buf[match_cache_point_index] |= match_cache_point_mask << 1;
2221match_at(
regex_t* reg,
const UChar* str,
const UChar* end,
2222#ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
2223 const UChar* right_range,
2227 static const UChar FinishCode[] = { OP_FINISH };
2229 int i, num_mem, pop_level;
2230 ptrdiff_t n, best_len;
2231 LengthType tlen, tlen2;
2234 OnigOptionType option = reg->options;
2236 OnigCaseFoldType case_fold_flag = reg->case_fold_flag;
2237 UChar *s, *q, *sbegin;
2242 char *xmalloc_base = NULL;
2246 OnigStackIndex *repeat_stk;
2247 OnigStackIndex *mem_start_stk, *mem_end_stk;
2248#ifdef USE_COMBINATION_EXPLOSION_CHECK
2250 unsigned char* state_check_buff = msa->state_check_buff;
2251 int num_comb_exp_check = reg->num_comb_exp_check;
2254#if USE_TOKEN_THREADED_VM
2256# define VM_LOOP JUMP;
2258# define CASE(x) L_##x: sbegin = s; OPCODE_EXEC_HOOK;
2259# define DEFAULT L_DEFAULT:
2260# define NEXT sprev = sbegin; JUMP
2261# define JUMP pbegin = p; RB_GNUC_EXTENSION_BLOCK(goto *oplabels[*p++])
2287 &&L_OP_CCLASS_MB_NOT,
2288 &&L_OP_CCLASS_MIX_NOT,
2292 &&L_OP_ANYCHAR_STAR,
2293 &&L_OP_ANYCHAR_ML_STAR,
2294 &&L_OP_ANYCHAR_STAR_PEEK_NEXT,
2295 &&L_OP_ANYCHAR_ML_STAR_PEEK_NEXT,
2300 &&L_OP_NOT_WORD_BOUND,
2301# ifdef USE_WORD_BEGIN_END
2309 &&L_OP_NOT_ASCII_WORD,
2310 &&L_OP_ASCII_WORD_BOUND,
2311 &&L_OP_NOT_ASCII_WORD_BOUND,
2312# ifdef USE_WORD_BEGIN_END
2313 &&L_OP_ASCII_WORD_BEGIN,
2314 &&L_OP_ASCII_WORD_END,
2324 &&L_OP_SEMI_END_BUF,
2325 &&L_OP_BEGIN_POSITION,
2331 &&L_OP_BACKREF_MULTI,
2332 &&L_OP_BACKREF_MULTI_IC,
2333# ifdef USE_BACKREF_WITH_LEVEL
2334 &&L_OP_BACKREF_WITH_LEVEL,
2338 &&L_OP_MEMORY_START,
2339 &&L_OP_MEMORY_START_PUSH,
2340 &&L_OP_MEMORY_END_PUSH,
2341# ifdef USE_SUBEXP_CALL
2342 &&L_OP_MEMORY_END_PUSH_REC,
2347# ifdef USE_SUBEXP_CALL
2348 &&L_OP_MEMORY_END_REC,
2359# ifdef USE_OP_PUSH_OR_JUMP_EXACT
2360 &&L_OP_PUSH_OR_JUMP_EXACT1,
2364 &&L_OP_PUSH_IF_PEEK_NEXT,
2368 &&L_OP_REPEAT_INC_NG,
2369 &&L_OP_REPEAT_INC_SG,
2370 &&L_OP_REPEAT_INC_NG_SG,
2371 &&L_OP_NULL_CHECK_START,
2372 &&L_OP_NULL_CHECK_END,
2373# ifdef USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT
2374 &&L_OP_NULL_CHECK_END_MEMST,
2378# ifdef USE_SUBEXP_CALL
2379 &&L_OP_NULL_CHECK_END_MEMST_PUSH,
2386 &&L_OP_PUSH_POS_NOT,
2388 &&L_OP_PUSH_STOP_BT,
2391 &&L_OP_PUSH_LOOK_BEHIND_NOT,
2392 &&L_OP_FAIL_LOOK_BEHIND_NOT,
2393 &&L_OP_PUSH_ABSENT_POS,
2397# ifdef USE_SUBEXP_CALL
2406# ifdef USE_COMBINATION_EXPLOSION_CHECK
2407 &&L_OP_STATE_CHECK_PUSH,
2408 &&L_OP_STATE_CHECK_PUSH_OR_JUMP,
2415# ifdef USE_COMBINATION_EXPLOSION_CHECK
2416 &&L_OP_STATE_CHECK_ANYCHAR_STAR,
2417 &&L_OP_STATE_CHECK_ANYCHAR_ML_STAR,
2424 &&L_OP_SET_OPTION_PUSH,
2440# define VM_LOOP_END } sprev = sbegin; }
2441# define CASE(x) case x:
2442# define DEFAULT default:
2444# define JUMP continue; break
2448#ifdef USE_SUBEXP_CALL
2451# define ADD_NUMMEM 1
2454# define ADD_NUMMEM 0
2457 n = reg->num_repeat + (reg->num_mem + ADD_NUMMEM) * 2;
2459 STACK_INIT(alloca_base, xmalloc_base, n, INIT_MATCH_STACK_SIZE);
2460 pop_level = reg->stack_pop_level;
2461 num_mem = reg->num_mem;
2462 repeat_stk = (OnigStackIndex* )alloca_base;
2464 mem_start_stk = (OnigStackIndex* )(repeat_stk + reg->num_repeat);
2465 mem_end_stk = mem_start_stk + (num_mem + ADD_NUMMEM);
2467 OnigStackIndex *pp = mem_start_stk;
2468 for (; pp < repeat_stk + n; pp += 2) {
2469 pp[0] = INVALID_STACK_INDEX;
2470 pp[1] = INVALID_STACK_INDEX;
2473#ifndef USE_SUBEXP_CALL
2480#ifdef ONIG_DEBUG_MATCH
2481 fprintf(stderr,
"match_at: str: %"PRIuPTR
" (%p), end: %"PRIuPTR
" (%p), start: %"PRIuPTR
" (%p), sprev: %"PRIuPTR
" (%p)\n",
2482 (uintptr_t )str, str, (uintptr_t )end, end, (uintptr_t )sstart, sstart, (uintptr_t )sprev, sprev);
2483 fprintf(stderr,
"size: %d, start offset: %d\n",
2484 (
int )(end - str), (
int )(sstart - str));
2485 fprintf(stderr,
"\n ofs> str stk:type addr:opcode\n");
2488 STACK_PUSH_ENSURED(STK_ALT, (UChar* )FinishCode);
2489 best_len = ONIG_MISMATCH;
2490 s = (UChar* )sstart;
2491 pkeep = (UChar* )sstart;
2494#ifdef ONIG_DEBUG_MATCH
2495# define OPCODE_EXEC_HOOK \
2497 UChar *op, *q, *bp, buf[50]; \
2499 op = p - OP_OFFSET; \
2500 fprintf(stderr, "%4"PRIdPTR"> \"", (*op == OP_FINISH) ? (ptrdiff_t )-1 : s - str); \
2503 if (*op != OP_FINISH) { \
2504 for (i = 0; i < 7 && q < end; i++) { \
2505 len = enclen(encode, q, end); \
2506 while (len-- > 0) *bp++ = *q++; \
2508 if (q < end) { xmemcpy(bp, "...", 3); bp += 3; } \
2510 xmemcpy(bp, "\"", 1); bp += 1; \
2512 fputs((char* )buf, stderr); \
2513 for (i = 0; i < 20 - (bp - buf); i++) fputc(' ', stderr); \
2514 fprintf(stderr, "%4"PRIdPTR":%s %4"PRIdPTR":", \
2515 stk - stk_base - 1, \
2516 (stk > stk_base) ? stack_type_str(stk[-1].type) : " ", \
2517 (op == FinishCode) ? (ptrdiff_t )-1 : op - reg->p); \
2518 onig_print_compiled_byte_code(stderr, op, reg->p+reg->used, NULL, encode); \
2519 fprintf(stderr, "\n"); \
2522# define OPCODE_EXEC_HOOK ((void) 0)
2525#ifdef USE_MATCH_CACHE
2526#ifdef ONIG_DEBUG_MATCH_CACHE
2527#define MATCH_CACHE_DEBUG fprintf(stderr, "MATCH CACHE: cache %ld (p=%p index=%ld mask=%d)\n", match_cache_point, pbegin, match_cache_point_index, match_cache_point_mask)
2528#define MATCH_CACHE_DEBUG_HIT fprintf(stderr, "MATCH CACHE: cache hit\n")
2530#define MATCH_CACHE_DEBUG ((void) 0)
2531#define MATCH_CACHE_DEBUG_HIT ((void) 0)
2534# define CHECK_MATCH_CACHE do {\
2535 if (msa->match_cache_status == MATCH_CACHE_STATUS_ENABLED) {\
2536 const OnigCacheOpcode *cache_opcode;\
2537 long cache_point = find_cache_point(reg, msa->cache_opcodes, msa->num_cache_opcodes, pbegin, stk_base, repeat_stk, &cache_opcode);\
2538 if (cache_point >= 0) {\
2539 long match_cache_point = msa->num_cache_points * (long)(s - str) + cache_point;\
2540 long match_cache_point_index = match_cache_point >> 3;\
2541 uint8_t match_cache_point_mask = 1 << (match_cache_point & 7);\
2543 if (msa->match_cache_buf[match_cache_point_index] & match_cache_point_mask) {\
2544 MATCH_CACHE_DEBUG_HIT;\
2545 if (cache_opcode->lookaround_nesting == 0) goto fail;\
2546 else if (cache_opcode->lookaround_nesting < 0) {\
2547 if (check_extended_match_cache_point(msa->match_cache_buf, match_cache_point_index, match_cache_point_mask)) {\
2548 STACK_STOP_BT_FAIL;\
2552 if (check_extended_match_cache_point(msa->match_cache_buf, match_cache_point_index, match_cache_point_mask)) {\
2553 p = cache_opcode->match_addr;\
2559 STACK_PUSH_MATCH_CACHE_POINT(match_cache_point_index, match_cache_point_mask);\
2564# define CHECK_MATCH_CACHE ((void) 0)
2568 CASE(OP_END) MOP_IN(OP_END);
2572#ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
2573 if (IS_FIND_LONGEST(option)) {
2574 if (n > msa->best_len) {
2576 msa->best_s = (UChar* )sstart;
2583 region = msa->region;
2585 region->beg[0] = ((pkeep > s) ? s : pkeep) - str;
2586 region->end[0] = s - str;
2587 for (i = 1; i <= num_mem; i++) {
2588 if (mem_end_stk[i] != INVALID_STACK_INDEX) {
2589 if (BIT_STATUS_AT(reg->bt_mem_start, i))
2590 region->beg[i] = STACK_AT(mem_start_stk[i])->u.mem.pstr - str;
2592 region->beg[i] = (UChar* )((
void* )mem_start_stk[i]) - str;
2594 region->end[i] = (BIT_STATUS_AT(reg->bt_mem_end, i)
2595 ? STACK_AT(mem_end_stk[i])->u.mem.pstr
2596 : (UChar* )((
void* )mem_end_stk[i])) - str;
2599 region->beg[i] = region->end[i] = ONIG_REGION_NOTPOS;
2603#ifdef USE_CAPTURE_HISTORY
2604 if (reg->capture_history != 0) {
2606 OnigCaptureTreeNode* node;
2608 if (IS_NULL(region->history_root)) {
2609 region->history_root = node = history_node_new();
2610 CHECK_NULL_RETURN_MEMERR(node);
2613 node = region->history_root;
2614 history_tree_clear(node);
2618 node->beg = ((pkeep > s) ? s : pkeep) - str;
2619 node->end = s - str;
2622 r = make_capture_history_tree(region->history_root, &stkp,
2623 stk, (UChar* )str, reg);
2633#ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
2638 if (IS_FIND_CONDITION(option)) {
2639 if (IS_FIND_NOT_EMPTY(option) && s == sstart) {
2640 best_len = ONIG_MISMATCH;
2643 if (IS_FIND_LONGEST(option) && DATA_ENSURE_CHECK1) {
2652 CASE(OP_EXACT1) MOP_IN(OP_EXACT1);
2654 if (*p != *s)
goto fail;
2659 CASE(OP_EXACT1_IC) MOP_IN(OP_EXACT1_IC);
2662 UChar *q, lowbuf[ONIGENC_MBC_CASE_FOLD_MAXLEN];
2665 len = ONIGENC_MBC_CASE_FOLD(encode,
2681 CASE(OP_EXACT2) MOP_IN(OP_EXACT2);
2683 if (*p != *s)
goto fail;
2685 if (*p != *s)
goto fail;
2691 CASE(OP_EXACT3) MOP_IN(OP_EXACT3);
2693 if (*p != *s)
goto fail;
2695 if (*p != *s)
goto fail;
2697 if (*p != *s)
goto fail;
2703 CASE(OP_EXACT4) MOP_IN(OP_EXACT4);
2705 if (*p != *s)
goto fail;
2707 if (*p != *s)
goto fail;
2709 if (*p != *s)
goto fail;
2711 if (*p != *s)
goto fail;
2717 CASE(OP_EXACT5) MOP_IN(OP_EXACT5);
2719 if (*p != *s)
goto fail;
2721 if (*p != *s)
goto fail;
2723 if (*p != *s)
goto fail;
2725 if (*p != *s)
goto fail;
2727 if (*p != *s)
goto fail;
2733 CASE(OP_EXACTN) MOP_IN(OP_EXACTN);
2734 GET_LENGTH_INC(tlen, p);
2736 while (tlen-- > 0) {
2737 if (*p++ != *s++)
goto fail;
2743 CASE(OP_EXACTN_IC) MOP_IN(OP_EXACTN_IC);
2746 UChar *q, *endp, lowbuf[ONIGENC_MBC_CASE_FOLD_MAXLEN];
2748 GET_LENGTH_INC(tlen, p);
2754 len = ONIGENC_MBC_CASE_FOLD(encode,
2761 if (*p != *q)
goto fail;
2770 CASE(OP_EXACTMB2N1) MOP_IN(OP_EXACTMB2N1);
2772 if (*p != *s)
goto fail;
2774 if (*p != *s)
goto fail;
2779 CASE(OP_EXACTMB2N2) MOP_IN(OP_EXACTMB2N2);
2781 if (*p != *s)
goto fail;
2783 if (*p != *s)
goto fail;
2786 if (*p != *s)
goto fail;
2788 if (*p != *s)
goto fail;
2793 CASE(OP_EXACTMB2N3) MOP_IN(OP_EXACTMB2N3);
2795 if (*p != *s)
goto fail;
2797 if (*p != *s)
goto fail;
2799 if (*p != *s)
goto fail;
2801 if (*p != *s)
goto fail;
2804 if (*p != *s)
goto fail;
2806 if (*p != *s)
goto fail;
2811 CASE(OP_EXACTMB2N) MOP_IN(OP_EXACTMB2N);
2812 GET_LENGTH_INC(tlen, p);
2813 DATA_ENSURE(tlen * 2);
2814 while (tlen-- > 0) {
2815 if (*p != *s)
goto fail;
2817 if (*p != *s)
goto fail;
2824 CASE(OP_EXACTMB3N) MOP_IN(OP_EXACTMB3N);
2825 GET_LENGTH_INC(tlen, p);
2826 DATA_ENSURE(tlen * 3);
2827 while (tlen-- > 0) {
2828 if (*p != *s)
goto fail;
2830 if (*p != *s)
goto fail;
2832 if (*p != *s)
goto fail;
2839 CASE(OP_EXACTMBN) MOP_IN(OP_EXACTMBN);
2840 GET_LENGTH_INC(tlen, p);
2841 GET_LENGTH_INC(tlen2, p);
2844 while (tlen2-- > 0) {
2845 if (*p != *s)
goto fail;
2852 CASE(OP_CCLASS) MOP_IN(OP_CCLASS);
2854 if (BITSET_AT(((BitSetRef )p), *s) == 0)
goto fail;
2856 s += enclen(encode, s, end);
2860 CASE(OP_CCLASS_MB) MOP_IN(OP_CCLASS_MB);
2861 if (! ONIGENC_IS_MBC_HEAD(encode, s, end))
goto fail;
2864 GET_LENGTH_INC(tlen, p);
2871 mb_len = enclen(encode, s, end);
2872 DATA_ENSURE(mb_len);
2875 code = ONIGENC_MBC_TO_CODE(encode, ss, s);
2877#ifdef PLATFORM_UNALIGNED_WORD_ACCESS
2878 if (! onig_is_in_code_range(p, code))
goto fail;
2882 if (! onig_is_in_code_range(q, code))
goto fail;
2889 CASE(OP_CCLASS_MIX) MOP_IN(OP_CCLASS_MIX);
2891 if (ONIGENC_IS_MBC_HEAD(encode, s, end)) {
2896 if (BITSET_AT(((BitSetRef )p), *s) == 0)
2900 GET_LENGTH_INC(tlen, p);
2907 CASE(OP_CCLASS_NOT) MOP_IN(OP_CCLASS_NOT);
2909 if (BITSET_AT(((BitSetRef )p), *s) != 0)
goto fail;
2911 s += enclen(encode, s, end);
2915 CASE(OP_CCLASS_MB_NOT) MOP_IN(OP_CCLASS_MB_NOT);
2917 if (! ONIGENC_IS_MBC_HEAD(encode, s, end)) {
2919 GET_LENGTH_INC(tlen, p);
2921 goto cc_mb_not_success;
2925 GET_LENGTH_INC(tlen, p);
2929 int mb_len = enclen(encode, s, end);
2931 if (! DATA_ENSURE_CHECK(mb_len)) {
2935 goto cc_mb_not_success;
2940 code = ONIGENC_MBC_TO_CODE(encode, ss, s);
2942#ifdef PLATFORM_UNALIGNED_WORD_ACCESS
2943 if (onig_is_in_code_range(p, code))
goto fail;
2947 if (onig_is_in_code_range(q, code))
goto fail;
2956 CASE(OP_CCLASS_MIX_NOT) MOP_IN(OP_CCLASS_MIX_NOT);
2958 if (ONIGENC_IS_MBC_HEAD(encode, s, end)) {
2963 if (BITSET_AT(((BitSetRef )p), *s) != 0)
2967 GET_LENGTH_INC(tlen, p);
2974 CASE(OP_ANYCHAR) MOP_IN(OP_ANYCHAR);
2976 n = enclen(encode, s, end);
2978 if (ONIGENC_IS_MBC_NEWLINE_EX(encode, s, str, end, option, 0))
goto fail;
2983 CASE(OP_ANYCHAR_ML) MOP_IN(OP_ANYCHAR_ML);
2985 n = enclen(encode, s, end);
2991 CASE(OP_ANYCHAR_STAR) MOP_IN(OP_ANYCHAR_STAR);
2992 while (DATA_ENSURE_CHECK1) {
2994 STACK_PUSH_ALT(p, s, sprev, pkeep);
2995 n = enclen(encode, s, end);
2997 if (ONIGENC_IS_MBC_NEWLINE_EX(encode, s, str, end, option, 0))
goto fail;
3004 CASE(OP_ANYCHAR_ML_STAR) MOP_IN(OP_ANYCHAR_ML_STAR);
3005 while (DATA_ENSURE_CHECK1) {
3007 STACK_PUSH_ALT(p, s, sprev, pkeep);
3008 n = enclen(encode, s, end);
3022 CASE(OP_ANYCHAR_STAR_PEEK_NEXT) MOP_IN(OP_ANYCHAR_STAR_PEEK_NEXT);
3023 while (DATA_ENSURE_CHECK1) {
3026 STACK_PUSH_ALT(p + 1, s, sprev, pkeep);
3028#ifdef USE_MATCH_CACHE
3034 n = enclen(encode, s, end);
3036 if (ONIGENC_IS_MBC_NEWLINE_EX(encode, s, str, end, option, 0))
goto fail;
3044 CASE(OP_ANYCHAR_ML_STAR_PEEK_NEXT)MOP_IN(OP_ANYCHAR_ML_STAR_PEEK_NEXT);
3045 while (DATA_ENSURE_CHECK1) {
3048 STACK_PUSH_ALT(p + 1, s, sprev, pkeep);
3050#ifdef USE_MATCH_CACHE
3056 n = enclen(encode, s, end);
3071#ifdef USE_COMBINATION_EXPLOSION_CHECK
3072 CASE(OP_STATE_CHECK_ANYCHAR_STAR) MOP_IN(OP_STATE_CHECK_ANYCHAR_STAR);
3073 GET_STATE_CHECK_NUM_INC(mem, p);
3074 while (DATA_ENSURE_CHECK1) {
3075 STATE_CHECK_VAL(scv, mem);
3078 STACK_PUSH_ALT_WITH_STATE_CHECK(p, s, sprev, mem, pkeep);
3079 n = enclen(encode, s, end);
3081 if (ONIGENC_IS_MBC_NEWLINE_EX(encode, s, str, end, option, 0))
goto fail;
3088 CASE(OP_STATE_CHECK_ANYCHAR_ML_STAR)
3089 MOP_IN(OP_STATE_CHECK_ANYCHAR_ML_STAR);
3091 GET_STATE_CHECK_NUM_INC(mem, p);
3092 while (DATA_ENSURE_CHECK1) {
3093 STATE_CHECK_VAL(scv, mem);
3096 STACK_PUSH_ALT_WITH_STATE_CHECK(p, s, sprev, mem, pkeep);
3097 n = enclen(encode, s, end);
3112 CASE(OP_WORD) MOP_IN(OP_WORD);
3114 if (! ONIGENC_IS_MBC_WORD(encode, s, end))
3117 s += enclen(encode, s, end);
3121 CASE(OP_ASCII_WORD) MOP_IN(OP_ASCII_WORD);
3123 if (! ONIGENC_IS_MBC_ASCII_WORD(encode, s, end))
3126 s += enclen(encode, s, end);
3130 CASE(OP_NOT_WORD) MOP_IN(OP_NOT_WORD);
3132 if (ONIGENC_IS_MBC_WORD(encode, s, end))
3135 s += enclen(encode, s, end);
3139 CASE(OP_NOT_ASCII_WORD) MOP_IN(OP_NOT_ASCII_WORD);
3141 if (ONIGENC_IS_MBC_ASCII_WORD(encode, s, end))
3144 s += enclen(encode, s, end);
3148 CASE(OP_WORD_BOUND) MOP_IN(OP_WORD_BOUND);
3149 if (ON_STR_BEGIN(s)) {
3151 if (! ONIGENC_IS_MBC_WORD(encode, s, end))
3154 else if (ON_STR_END(s)) {
3155 if (! ONIGENC_IS_MBC_WORD(encode, sprev, end))
3159 if (ONIGENC_IS_MBC_WORD(encode, s, end)
3160 == ONIGENC_IS_MBC_WORD(encode, sprev, end))
3166 CASE(OP_ASCII_WORD_BOUND) MOP_IN(OP_ASCII_WORD_BOUND);
3167 if (ON_STR_BEGIN(s)) {
3169 if (! ONIGENC_IS_MBC_ASCII_WORD(encode, s, end))
3172 else if (ON_STR_END(s)) {
3173 if (! ONIGENC_IS_MBC_ASCII_WORD(encode, sprev, end))
3177 if (ONIGENC_IS_MBC_ASCII_WORD(encode, s, end)
3178 == ONIGENC_IS_MBC_ASCII_WORD(encode, sprev, end))
3184 CASE(OP_NOT_WORD_BOUND) MOP_IN(OP_NOT_WORD_BOUND);
3185 if (ON_STR_BEGIN(s)) {
3186 if (DATA_ENSURE_CHECK1 && ONIGENC_IS_MBC_WORD(encode, s, end))
3189 else if (ON_STR_END(s)) {
3190 if (ONIGENC_IS_MBC_WORD(encode, sprev, end))
3194 if (ONIGENC_IS_MBC_WORD(encode, s, end)
3195 != ONIGENC_IS_MBC_WORD(encode, sprev, end))
3201 CASE(OP_NOT_ASCII_WORD_BOUND) MOP_IN(OP_NOT_ASCII_WORD_BOUND);
3202 if (ON_STR_BEGIN(s)) {
3203 if (DATA_ENSURE_CHECK1 && ONIGENC_IS_MBC_ASCII_WORD(encode, s, end))
3206 else if (ON_STR_END(s)) {
3207 if (ONIGENC_IS_MBC_ASCII_WORD(encode, sprev, end))
3211 if (ONIGENC_IS_MBC_ASCII_WORD(encode, s, end)
3212 != ONIGENC_IS_MBC_ASCII_WORD(encode, sprev, end))
3218#ifdef USE_WORD_BEGIN_END
3219 CASE(OP_WORD_BEGIN) MOP_IN(OP_WORD_BEGIN);
3220 if (DATA_ENSURE_CHECK1 && ONIGENC_IS_MBC_WORD(encode, s, end)) {
3221 if (ON_STR_BEGIN(s) || !ONIGENC_IS_MBC_WORD(encode, sprev, end)) {
3229 CASE(OP_ASCII_WORD_BEGIN) MOP_IN(OP_ASCII_WORD_BEGIN);
3230 if (DATA_ENSURE_CHECK1 && ONIGENC_IS_MBC_ASCII_WORD(encode, s, end)) {
3231 if (ON_STR_BEGIN(s) || !ONIGENC_IS_MBC_ASCII_WORD(encode, sprev, end)) {
3239 CASE(OP_WORD_END) MOP_IN(OP_WORD_END);
3240 if (!ON_STR_BEGIN(s) && ONIGENC_IS_MBC_WORD(encode, sprev, end)) {
3241 if (ON_STR_END(s) || !ONIGENC_IS_MBC_WORD(encode, s, end)) {
3249 CASE(OP_ASCII_WORD_END) MOP_IN(OP_ASCII_WORD_END);
3250 if (!ON_STR_BEGIN(s) && ONIGENC_IS_MBC_ASCII_WORD(encode, sprev, end)) {
3251 if (ON_STR_END(s) || !ONIGENC_IS_MBC_ASCII_WORD(encode, s, end)) {
3260 CASE(OP_BEGIN_BUF) MOP_IN(OP_BEGIN_BUF);
3261 if (! ON_STR_BEGIN(s))
goto fail;
3262 if (IS_NOTBOS(msa->options))
goto fail;
3267 CASE(OP_END_BUF) MOP_IN(OP_END_BUF);
3268 if (! ON_STR_END(s))
goto fail;
3269 if (IS_NOTEOS(msa->options))
goto fail;
3274 CASE(OP_BEGIN_LINE) MOP_IN(OP_BEGIN_LINE);
3275 if (ON_STR_BEGIN(s)) {
3276 if (IS_NOTBOL(msa->options))
goto fail;
3280 else if (ONIGENC_IS_MBC_NEWLINE(encode, sprev, end)
3281#ifdef USE_CRNL_AS_LINE_TERMINATOR
3282 && !(IS_NEWLINE_CRLF(option)
3283 && ONIGENC_IS_MBC_CRNL(encode, sprev, end))
3285 && !ON_STR_END(s)) {
3292 CASE(OP_END_LINE) MOP_IN(OP_END_LINE);
3293 if (ON_STR_END(s)) {
3294#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
3295 if (IS_EMPTY_STR || !ONIGENC_IS_MBC_NEWLINE_EX(encode, sprev, str, end, option, 1)) {
3297 if (IS_NOTEOL(msa->options))
goto fail;
3300#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
3304 else if (ONIGENC_IS_MBC_NEWLINE_EX(encode, s, str, end, option, 1)) {
3311 CASE(OP_SEMI_END_BUF) MOP_IN(OP_SEMI_END_BUF);
3312 if (ON_STR_END(s)) {
3313#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
3314 if (IS_EMPTY_STR || !ONIGENC_IS_MBC_NEWLINE_EX(encode, sprev, str, end, option, 1)) {
3316 if (IS_NOTEOL(msa->options))
goto fail;
3319#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
3323 else if (ONIGENC_IS_MBC_NEWLINE_EX(encode, s, str, end, option, 1)) {
3324 UChar* ss = s + enclen(encode, s, end);
3325 if (ON_STR_END(ss)) {
3329#ifdef USE_CRNL_AS_LINE_TERMINATOR
3330 else if (IS_NEWLINE_CRLF(option)
3331 && ONIGENC_IS_MBC_CRNL(encode, s, end)) {
3332 ss += enclen(encode, ss, end);
3333 if (ON_STR_END(ss)) {
3343 CASE(OP_BEGIN_POSITION) MOP_IN(OP_BEGIN_POSITION);
3350 CASE(OP_MEMORY_START_PUSH) MOP_IN(OP_MEMORY_START_PUSH);
3351 GET_MEMNUM_INC(mem, p);
3352 STACK_PUSH_MEM_START(mem, s);
3356 CASE(OP_MEMORY_START) MOP_IN(OP_MEMORY_START);
3357 GET_MEMNUM_INC(mem, p);
3358 mem_start_stk[mem] = (OnigStackIndex )((
void* )s);
3359 mem_end_stk[mem] = INVALID_STACK_INDEX;
3363 CASE(OP_MEMORY_END_PUSH) MOP_IN(OP_MEMORY_END_PUSH);
3364 GET_MEMNUM_INC(mem, p);
3365 STACK_PUSH_MEM_END(mem, s);
3369 CASE(OP_MEMORY_END) MOP_IN(OP_MEMORY_END);
3370 GET_MEMNUM_INC(mem, p);
3371 mem_end_stk[mem] = (OnigStackIndex )((
void* )s);
3375 CASE(OP_KEEP) MOP_IN(OP_KEEP);
3380#ifdef USE_SUBEXP_CALL
3381 CASE(OP_MEMORY_END_PUSH_REC) MOP_IN(OP_MEMORY_END_PUSH_REC);
3382 GET_MEMNUM_INC(mem, p);
3383 STACK_GET_MEM_START(mem, stkp);
3384 STACK_PUSH_MEM_END(mem, s);
3385 mem_start_stk[mem] = GET_STACK_INDEX(stkp);
3389 CASE(OP_MEMORY_END_REC) MOP_IN(OP_MEMORY_END_REC);
3390 GET_MEMNUM_INC(mem, p);
3391 mem_end_stk[mem] = (OnigStackIndex )((
void* )s);
3392 STACK_GET_MEM_START(mem, stkp);
3394 if (BIT_STATUS_AT(reg->bt_mem_start, mem))
3395 mem_start_stk[mem] = GET_STACK_INDEX(stkp);
3397 mem_start_stk[mem] = (OnigStackIndex )((
void* )stkp->u.mem.pstr);
3399 STACK_PUSH_MEM_END_MARK(mem);
3404 CASE(OP_BACKREF1) MOP_IN(OP_BACKREF1);
3409 CASE(OP_BACKREF2) MOP_IN(OP_BACKREF2);
3414 CASE(OP_BACKREFN) MOP_IN(OP_BACKREFN);
3415 GET_MEMNUM_INC(mem, p);
3419 UChar *pstart, *pend;
3423 if (mem > num_mem)
goto fail;
3424 if (mem_end_stk[mem] == INVALID_STACK_INDEX)
goto fail;
3425 if (mem_start_stk[mem] == INVALID_STACK_INDEX)
goto fail;
3427 if (BIT_STATUS_AT(reg->bt_mem_start, mem))
3428 pstart = STACK_AT(mem_start_stk[mem])->u.mem.pstr;
3430 pstart = (UChar* )((
void* )mem_start_stk[mem]);
3432 pend = (BIT_STATUS_AT(reg->bt_mem_end, mem)
3433 ? STACK_AT(mem_end_stk[mem])->u.mem.pstr
3434 : (UChar* )((
void* )mem_end_stk[mem]));
3438 STRING_CMP(pstart, s, n);
3439 while (sprev + (
len = enclen(encode, sprev, end)) < s)
3446 CASE(OP_BACKREFN_IC) MOP_IN(OP_BACKREFN_IC);
3447 GET_MEMNUM_INC(mem, p);
3450 UChar *pstart, *pend;
3454 if (mem > num_mem)
goto fail;
3455 if (mem_end_stk[mem] == INVALID_STACK_INDEX)
goto fail;
3456 if (mem_start_stk[mem] == INVALID_STACK_INDEX)
goto fail;
3458 if (BIT_STATUS_AT(reg->bt_mem_start, mem))
3459 pstart = STACK_AT(mem_start_stk[mem])->u.mem.pstr;
3461 pstart = (UChar* )((
void* )mem_start_stk[mem]);
3463 pend = (BIT_STATUS_AT(reg->bt_mem_end, mem)
3464 ? STACK_AT(mem_end_stk[mem])->u.mem.pstr
3465 : (UChar* )((
void* )mem_end_stk[mem]));
3469 STRING_CMP_IC(case_fold_flag, pstart, &s, (
int)n, end);
3470 while (sprev + (
len = enclen(encode, sprev, end)) < s)
3478 CASE(OP_BACKREF_MULTI) MOP_IN(OP_BACKREF_MULTI);
3481 UChar *pstart, *pend, *swork;
3483 GET_LENGTH_INC(tlen, p);
3484 for (i = 0; i < tlen; i++) {
3485 GET_MEMNUM_INC(mem, p);
3487 if (mem_end_stk[mem] == INVALID_STACK_INDEX)
continue;
3488 if (mem_start_stk[mem] == INVALID_STACK_INDEX)
continue;
3490 if (BIT_STATUS_AT(reg->bt_mem_start, mem))
3491 pstart = STACK_AT(mem_start_stk[mem])->u.mem.pstr;
3493 pstart = (UChar* )((
void* )mem_start_stk[mem]);
3495 pend = (BIT_STATUS_AT(reg->bt_mem_end, mem)
3496 ? STACK_AT(mem_end_stk[mem])->u.mem.pstr
3497 : (UChar* )((
void* )mem_end_stk[mem]));
3499 DATA_ENSURE_CONTINUE(n);
3502 STRING_CMP_VALUE(pstart, swork, n, is_fail);
3503 if (is_fail)
continue;
3505 while (sprev + (
len = enclen(encode, sprev, end)) < s)
3508 p += (SIZE_MEMNUM * (tlen - i - 1));
3511 if (i == tlen)
goto fail;
3517 CASE(OP_BACKREF_MULTI_IC) MOP_IN(OP_BACKREF_MULTI_IC);
3520 UChar *pstart, *pend, *swork;
3522 GET_LENGTH_INC(tlen, p);
3523 for (i = 0; i < tlen; i++) {
3524 GET_MEMNUM_INC(mem, p);
3526 if (mem_end_stk[mem] == INVALID_STACK_INDEX)
continue;
3527 if (mem_start_stk[mem] == INVALID_STACK_INDEX)
continue;
3529 if (BIT_STATUS_AT(reg->bt_mem_start, mem))
3530 pstart = STACK_AT(mem_start_stk[mem])->u.mem.pstr;
3532 pstart = (UChar* )((
void* )mem_start_stk[mem]);
3534 pend = (BIT_STATUS_AT(reg->bt_mem_end, mem)
3535 ? STACK_AT(mem_end_stk[mem])->u.mem.pstr
3536 : (UChar* )((
void* )mem_end_stk[mem]));
3538 DATA_ENSURE_CONTINUE(n);
3541 STRING_CMP_VALUE_IC(case_fold_flag, pstart, &swork, n, end, is_fail);
3542 if (is_fail)
continue;
3544 while (sprev + (
len = enclen(encode, sprev, end)) < s)
3547 p += (SIZE_MEMNUM * (tlen - i - 1));
3550 if (i == tlen)
goto fail;
3555#ifdef USE_BACKREF_WITH_LEVEL
3556 CASE(OP_BACKREF_WITH_LEVEL)
3562 GET_OPTION_INC(ic, p);
3563 GET_LENGTH_INC(level, p);
3564 GET_LENGTH_INC(tlen, p);
3567 if (backref_match_at_nested_level(reg, stk, stk_base, ic,
3568 case_fold_flag, (
int )level, (
int )tlen, p, &s, end)) {
3569 while (sprev + (
len = enclen(encode, sprev, end)) < s)
3572 p += (SIZE_MEMNUM * tlen);
3584 CASE(OP_SET_OPTION_PUSH) MOP_IN(OP_SET_OPTION_PUSH);
3585 GET_OPTION_INC(option, p);
3586 STACK_PUSH_ALT(p, s, sprev, pkeep);
3587 p += SIZE_OP_SET_OPTION + SIZE_OP_FAIL;
3591 CASE(OP_SET_OPTION) MOP_IN(OP_SET_OPTION);
3592 GET_OPTION_INC(option, p);
3597 CASE(OP_NULL_CHECK_START) MOP_IN(OP_NULL_CHECK_START);
3598 GET_MEMNUM_INC(mem, p);
3599 STACK_PUSH_NULL_CHECK_START(mem, s);
3603 CASE(OP_NULL_CHECK_END) MOP_IN(OP_NULL_CHECK_END);
3607 GET_MEMNUM_INC(mem, p);
3608 STACK_NULL_CHECK(isnull, mem, s);
3610#ifdef ONIG_DEBUG_MATCH
3611 fprintf(stderr,
"NULL_CHECK_END: skip id:%d, s:%"PRIuPTR
" (%p)\n",
3612 (
int )mem, (uintptr_t )s, s);
3622 case OP_REPEAT_INC_NG:
3623 case OP_REPEAT_INC_SG:
3624 case OP_REPEAT_INC_NG_SG:
3628 goto unexpected_bytecode_error;
3636#ifdef USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT
3637 CASE(OP_NULL_CHECK_END_MEMST) MOP_IN(OP_NULL_CHECK_END_MEMST);
3641 GET_MEMNUM_INC(mem, p);
3642 STACK_NULL_CHECK_MEMST(isnull, mem, s, reg);
3644# ifdef ONIG_DEBUG_MATCH
3645 fprintf(stderr,
"NULL_CHECK_END_MEMST: skip id:%d, s:%"PRIuPTR
" (%p)\n",
3646 (
int )mem, (uintptr_t )s, s);
3648 if (isnull == -1)
goto fail;
3649 goto null_check_found;
3656#ifdef USE_SUBEXP_CALL
3657 CASE(OP_NULL_CHECK_END_MEMST_PUSH)
3658 MOP_IN(OP_NULL_CHECK_END_MEMST_PUSH);
3662 GET_MEMNUM_INC(mem, p);
3663# ifdef USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT
3664 STACK_NULL_CHECK_MEMST_REC(isnull, mem, s, reg);
3666 STACK_NULL_CHECK_REC(isnull, mem, s);
3669# ifdef ONIG_DEBUG_MATCH
3670 fprintf(stderr,
"NULL_CHECK_END_MEMST_PUSH: skip id:%d, s:%"PRIuPTR
" (%p)\n",
3671 (
int )mem, (uintptr_t )s, s);
3673 if (isnull == -1)
goto fail;
3674 goto null_check_found;
3677 STACK_PUSH_NULL_CHECK_END(mem);
3684 CASE(OP_JUMP) MOP_IN(OP_JUMP);
3685 GET_RELADDR_INC(addr, p);
3688 CHECK_INTERRUPT_IN_MATCH_AT;
3691 CASE(OP_PUSH) MOP_IN(OP_PUSH);
3692 GET_RELADDR_INC(addr, p);
3694 STACK_PUSH_ALT(p + addr, s, sprev, pkeep);
3698#ifdef USE_COMBINATION_EXPLOSION_CHECK
3699 CASE(OP_STATE_CHECK_PUSH) MOP_IN(OP_STATE_CHECK_PUSH);
3700 GET_STATE_CHECK_NUM_INC(mem, p);
3701 STATE_CHECK_VAL(scv, mem);
3704 GET_RELADDR_INC(addr, p);
3705 STACK_PUSH_ALT_WITH_STATE_CHECK(p + addr, s, sprev, mem, pkeep);
3709 CASE(OP_STATE_CHECK_PUSH_OR_JUMP) MOP_IN(OP_STATE_CHECK_PUSH_OR_JUMP);
3710 GET_STATE_CHECK_NUM_INC(mem, p);
3711 GET_RELADDR_INC(addr, p);
3712 STATE_CHECK_VAL(scv, mem);
3717 STACK_PUSH_ALT_WITH_STATE_CHECK(p + addr, s, sprev, mem, pkeep);
3722 CASE(OP_STATE_CHECK) MOP_IN(OP_STATE_CHECK);
3723 GET_STATE_CHECK_NUM_INC(mem, p);
3724 STATE_CHECK_VAL(scv, mem);
3727 STACK_PUSH_STATE_CHECK(s, mem);
3732 CASE(OP_POP) MOP_IN(OP_POP);
3734#ifdef USE_MATCH_CACHE
3742#ifdef USE_OP_PUSH_OR_JUMP_EXACT
3743 CASE(OP_PUSH_OR_JUMP_EXACT1) MOP_IN(OP_PUSH_OR_JUMP_EXACT1);
3744 GET_RELADDR_INC(addr, p);
3745 if (*p == *s && DATA_ENSURE_CHECK1) {
3748 STACK_PUSH_ALT(p + addr, s, sprev, pkeep);
3757 CASE(OP_PUSH_IF_PEEK_NEXT) MOP_IN(OP_PUSH_IF_PEEK_NEXT);
3758 GET_RELADDR_INC(addr, p);
3762 STACK_PUSH_ALT(p + addr, s, sprev, pkeep);
3770 CASE(OP_REPEAT) MOP_IN(OP_REPEAT);
3772 GET_MEMNUM_INC(mem, p);
3773 GET_RELADDR_INC(addr, p);
3776 repeat_stk[mem] = GET_STACK_INDEX(stk);
3777 STACK_PUSH_REPEAT(mem, p);
3779 if (reg->repeat_range[mem].lower == 0) {
3781 STACK_PUSH_ALT(p + addr, s, sprev, pkeep);
3787 CASE(OP_REPEAT_NG) MOP_IN(OP_REPEAT_NG);
3789 GET_MEMNUM_INC(mem, p);
3790 GET_RELADDR_INC(addr, p);
3793 repeat_stk[mem] = GET_STACK_INDEX(stk);
3794 STACK_PUSH_REPEAT(mem, p);
3796 if (reg->repeat_range[mem].lower == 0) {
3798 STACK_PUSH_ALT(p, s, sprev, pkeep);
3805 CASE(OP_REPEAT_INC) MOP_IN(OP_REPEAT_INC);
3806 GET_MEMNUM_INC(mem, p);
3807 si = repeat_stk[mem];
3808 stkp = STACK_AT(si);
3811 stkp->u.repeat.count++;
3812 if (stkp->u.repeat.count >= reg->repeat_range[mem].upper) {
3815 else if (stkp->u.repeat.count >= reg->repeat_range[mem].lower) {
3816 if (*pbegin == OP_REPEAT_INC) {
3819 STACK_PUSH_ALT(p, s, sprev, pkeep);
3820 p = STACK_AT(si)->u.repeat.pcode;
3823 p = stkp->u.repeat.pcode;
3825 STACK_PUSH_REPEAT_INC(si);
3827 CHECK_INTERRUPT_IN_MATCH_AT;
3830 CASE(OP_REPEAT_INC_SG) MOP_IN(OP_REPEAT_INC_SG);
3831 GET_MEMNUM_INC(mem, p);
3832 STACK_GET_REPEAT(mem, stkp);
3833 si = GET_STACK_INDEX(stkp);
3837 CASE(OP_REPEAT_INC_NG) MOP_IN(OP_REPEAT_INC_NG);
3838 GET_MEMNUM_INC(mem, p);
3839 si = repeat_stk[mem];
3840 stkp = STACK_AT(si);
3843 stkp->u.repeat.count++;
3844 if (stkp->u.repeat.count < reg->repeat_range[mem].upper) {
3845 if (stkp->u.repeat.count >= reg->repeat_range[mem].lower) {
3846 UChar* pcode = stkp->u.repeat.pcode;
3848 STACK_PUSH_REPEAT_INC(si);
3849 if (*pbegin == OP_REPEAT_INC_NG) {
3852 STACK_PUSH_ALT(pcode, s, sprev, pkeep);
3855 p = stkp->u.repeat.pcode;
3856 STACK_PUSH_REPEAT_INC(si);
3859 else if (stkp->u.repeat.count == reg->repeat_range[mem].upper) {
3860 STACK_PUSH_REPEAT_INC(si);
3863 CHECK_INTERRUPT_IN_MATCH_AT;
3866 CASE(OP_REPEAT_INC_NG_SG) MOP_IN(OP_REPEAT_INC_NG_SG);
3867 GET_MEMNUM_INC(mem, p);
3868 STACK_GET_REPEAT(mem, stkp);
3869 si = GET_STACK_INDEX(stkp);
3873 CASE(OP_PUSH_POS) MOP_IN(OP_PUSH_POS);
3874 STACK_PUSH_POS(s, sprev, pkeep);
3878 CASE(OP_POP_POS) MOP_IN(OP_POP_POS);
3880 STACK_POS_END(stkp);
3881 s = stkp->u.state.pstr;
3882 sprev = stkp->u.state.pstr_prev;
3887 CASE(OP_PUSH_POS_NOT) MOP_IN(OP_PUSH_POS_NOT);
3888 GET_RELADDR_INC(addr, p);
3889 STACK_PUSH_POS_NOT(p + addr, s, sprev, pkeep);
3893 CASE(OP_FAIL_POS) MOP_IN(OP_FAIL_POS);
3894 STACK_POP_TIL_POS_NOT;
3898 CASE(OP_PUSH_STOP_BT) MOP_IN(OP_PUSH_STOP_BT);
3903 CASE(OP_POP_STOP_BT) MOP_IN(OP_POP_STOP_BT);
3908 CASE(OP_LOOK_BEHIND) MOP_IN(OP_LOOK_BEHIND);
3909 GET_LENGTH_INC(tlen, p);
3910 s = (UChar* )ONIGENC_STEP_BACK(encode, str, s, end, (
int )tlen);
3911 if (IS_NULL(s))
goto fail;
3912 sprev = (UChar* )onigenc_get_prev_char_head(encode, str, s, end);
3916 CASE(OP_PUSH_LOOK_BEHIND_NOT) MOP_IN(OP_PUSH_LOOK_BEHIND_NOT);
3917 GET_RELADDR_INC(addr, p);
3918 GET_LENGTH_INC(tlen, p);
3919 q = (UChar* )ONIGENC_STEP_BACK(encode, str, s, end, (
int )tlen);
3927 STACK_PUSH_LOOK_BEHIND_NOT(p + addr, s, sprev, pkeep);
3929 sprev = (UChar* )onigenc_get_prev_char_head(encode, str, s, end);
3934 CASE(OP_FAIL_LOOK_BEHIND_NOT) MOP_IN(OP_FAIL_LOOK_BEHIND_NOT);
3935 STACK_POP_TIL_LOOK_BEHIND_NOT;
3939 CASE(OP_PUSH_ABSENT_POS) MOP_IN(OP_PUSH_ABSENT_POS);
3941 STACK_PUSH_ABSENT_POS(s, ABSENT_END_POS);
3945 CASE(OP_ABSENT) MOP_IN(OP_ABSENT);
3947 const UChar* aend = ABSENT_END_POS;
3949 UChar* selfp = p - 1;
3951 STACK_POP_ABSENT_POS(absent, ABSENT_END_POS);
3952 GET_RELADDR_INC(addr, p);
3953#ifdef ONIG_DEBUG_MATCH
3954 fprintf(stderr,
"ABSENT: s:%p, end:%p, absent:%p, aend:%p\n", s, end, absent, aend);
3956 if ((absent > aend) && (s > absent)) {
3962 else if ((s >= aend) && (s > absent)) {
3972 else if (s == end) {
3978 STACK_PUSH_ALT(p + addr, s, sprev, pkeep);
3979 n = enclen(encode, s, end);
3980 STACK_PUSH_ABSENT_POS(absent, ABSENT_END_POS);
3981 STACK_PUSH_ALT(selfp, s + n, s, pkeep);
3983 ABSENT_END_POS = aend;
3989 CASE(OP_ABSENT_END) MOP_IN(OP_ABSENT_END);
3992 if (sprev < ABSENT_END_POS)
3993 ABSENT_END_POS = sprev;
3994#ifdef ONIG_DEBUG_MATCH
3995 fprintf(stderr,
"ABSENT_END: end:%p\n", ABSENT_END_POS);
3997 STACK_POP_TIL_ABSENT;
4001#ifdef USE_SUBEXP_CALL
4002 CASE(OP_CALL) MOP_IN(OP_CALL);
4003 GET_ABSADDR_INC(addr, p);
4004 STACK_PUSH_CALL_FRAME(p);
4009 CASE(OP_RETURN) MOP_IN(OP_RETURN);
4016 CASE(OP_CONDITION) MOP_IN(OP_CONDITION);
4017 GET_MEMNUM_INC(mem, p);
4018 GET_RELADDR_INC(addr, p);
4019 if ((mem > num_mem) ||
4020 (mem_end_stk[mem] == INVALID_STACK_INDEX) ||
4021 (mem_start_stk[mem] == INVALID_STACK_INDEX)) {
4039 p = stk->u.state.pcode;
4040 s = stk->u.state.pstr;
4041 sprev = stk->u.state.pstr_prev;
4042 pkeep = stk->u.state.pkeep;
4044#ifdef USE_MATCH_CACHE
4046 msa->match_cache_status != MATCH_CACHE_STATUS_DISABLED &&
4047 ++msa->num_fails >= (
long)(end - str) * msa->num_cache_opcodes
4049 if (msa->match_cache_status == MATCH_CACHE_STATUS_UNINIT) {
4050 msa->match_cache_status = MATCH_CACHE_STATUS_INIT;
4051 OnigPosition r = count_num_cache_opcodes(reg, &msa->num_cache_opcodes);
4052 if (r < 0)
goto bytecode_error;
4054 if (msa->num_cache_opcodes == NUM_CACHE_OPCODES_IMPOSSIBLE || msa->num_cache_opcodes == 0) {
4055 msa->match_cache_status = MATCH_CACHE_STATUS_DISABLED;
4056 goto fail_match_cache;
4058 if (msa->num_fails < (
long)(end - str) * msa->num_cache_opcodes) {
4059 goto fail_match_cache;
4061 if (msa->cache_opcodes == NULL) {
4062 msa->match_cache_status = MATCH_CACHE_STATUS_ENABLED;
4064 if (cache_opcodes == NULL) {
4065 return ONIGERR_MEMORY;
4067 OnigPosition r = init_cache_opcodes(reg, cache_opcodes, &msa->num_cache_points);
4069 if (r == ONIGERR_UNEXPECTED_BYTECODE)
goto unexpected_bytecode_error;
4070 else goto bytecode_error;
4072 msa->cache_opcodes = cache_opcodes;
4073#ifdef ONIG_DEBUG_MATCH_CACHE
4074 fprintf(stderr,
"MATCH CACHE: #cache opcodes = %ld\n", msa->num_cache_opcodes);
4075 fprintf(stderr,
"MATCH CACHE: #cache points = %ld\n", msa->num_cache_points);
4076 fprintf(stderr,
"MATCH CACHE: cache opcodes (%p):\n", msa->cache_opcodes);
4077 for (
int i = 0; i < msa->num_cache_opcodes; i++) {
4078 fprintf(stderr,
"MATCH CACHE: [%p] cache_point=%ld outer_repeat_mem=%d num_cache_opcodes_at_outer_repeat=%ld num_cache_opcodes_in_outer_repeat=%ld lookaround_nesting=%d match_addr=%p\n", msa->cache_opcodes[i].addr, msa->cache_opcodes[i].cache_point, msa->cache_opcodes[i].outer_repeat_mem, msa->cache_opcodes[i].num_cache_points_at_outer_repeat, msa->cache_opcodes[i].num_cache_points_in_outer_repeat, msa->cache_opcodes[i].lookaround_nesting, msa->cache_opcodes[i].match_addr);
4082 if (msa->match_cache_buf == NULL) {
4083 size_t length = (end - str) + 1;
4084 size_t num_match_cache_points = (size_t)msa->num_cache_points * length;
4085#ifdef ONIG_DEBUG_MATCH_CACHE
4086 fprintf(stderr,
"MATCH CACHE: #match cache points = %ld (length = %zu)\n", num_match_cache_points, length);
4089 if (num_match_cache_points / length != (
size_t)msa->num_cache_points) {
4090 return ONIGERR_MEMORY;
4092 if (num_match_cache_points >= LONG_MAX_LIMIT) {
4093 return ONIGERR_MEMORY;
4095 size_t match_cache_buf_length = (num_match_cache_points >> 3) + (num_match_cache_points & 7 ? 1 : 0) + 1;
4096 uint8_t* match_cache_buf = (uint8_t*)
xmalloc(match_cache_buf_length *
sizeof(uint8_t));
4097 if (match_cache_buf == NULL) {
4098 return ONIGERR_MEMORY;
4100 xmemset(match_cache_buf, 0, match_cache_buf_length *
sizeof(uint8_t));
4101 msa->match_cache_buf = match_cache_buf;
4107#ifdef USE_COMBINATION_EXPLOSION_CHECK
4108 if (stk->u.state.state_check != 0) {
4109 stk->type = STK_STATE_CHECK_MARK;
4115 CHECK_INTERRUPT_IN_MATCH_AT;
4119 goto bytecode_error;
4124 xfree(xmalloc_base);
4130 xfree(xmalloc_base);
4131 return ONIGERR_STACK_BUG;
4136 xfree(xmalloc_base);
4137 return ONIGERR_UNDEFINED_BYTECODE;
4139 unexpected_bytecode_error:
4141 xfree(xmalloc_base);
4142 return ONIGERR_UNEXPECTED_BYTECODE;
4147slow_search(
OnigEncoding enc, UChar* target, UChar* target_end,
4148 const UChar* text,
const UChar* text_end, UChar* text_range)
4150 UChar *t, *p, *s, *end;
4152 end = (UChar* )text_end;
4153 end -= target_end - target - 1;
4154 if (end > text_range)
4159 if (enc->max_enc_len == enc->min_enc_len) {
4160 int n = enc->max_enc_len;
4163 if (*s == *target) {
4166 if (target_end == t || memcmp(t, p, target_end - t) == 0)
4171 return (UChar* )NULL;
4174 if (*s == *target) {
4177 if (target_end == t || memcmp(t, p, target_end - t) == 0)
4180 s += enclen(enc, s, text_end);
4183 return (UChar* )NULL;
4187str_lower_case_match(
OnigEncoding enc,
int case_fold_flag,
4188 const UChar* t,
const UChar* tend,
4189 const UChar* p,
const UChar* end)
4192 UChar *q, lowbuf[ONIGENC_MBC_CASE_FOLD_MAXLEN];
4195 lowlen = ONIGENC_MBC_CASE_FOLD(enc, case_fold_flag, &p, end, lowbuf);
4197 while (lowlen > 0) {
4198 if (*t++ != *q++)
return 0;
4208 UChar* target, UChar* target_end,
4209 const UChar* text,
const UChar* text_end, UChar* text_range)
4213 end = (UChar* )text_end;
4214 end -= target_end - target - 1;
4215 if (end > text_range)
4221 if (str_lower_case_match(enc, case_fold_flag, target, target_end,
4225 s += enclen(enc, s, text_end);
4228 return (UChar* )NULL;
4232slow_search_backward(
OnigEncoding enc, UChar* target, UChar* target_end,
4233 const UChar* text,
const UChar* adjust_text,
4234 const UChar* text_end,
const UChar* text_start)
4238 s = (UChar* )text_end;
4239 s -= (target_end - target);
4241 s = (UChar* )text_start;
4243 s = ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc, adjust_text, s, text_end);
4246 if (*s == *target) {
4249 while (t < target_end) {
4254 if (t == target_end)
4257 s = (UChar* )onigenc_get_prev_char_head(enc, adjust_text, s, text_end);
4260 return (UChar* )NULL;
4264slow_search_backward_ic(
OnigEncoding enc,
int case_fold_flag,
4265 UChar* target, UChar* target_end,
4266 const UChar* text,
const UChar* adjust_text,
4267 const UChar* text_end,
const UChar* text_start)
4271 s = (UChar* )text_end;
4272 s -= (target_end - target);
4274 s = (UChar* )text_start;
4276 s = ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc, adjust_text, s, text_end);
4279 if (str_lower_case_match(enc, case_fold_flag,
4280 target, target_end, s, text_end))
4283 s = (UChar* )onigenc_get_prev_char_head(enc, adjust_text, s, text_end);
4286 return (UChar* )NULL;
4289#ifndef USE_SUNDAY_QUICK_SEARCH
4292bm_search_notrev(
regex_t* reg,
const UChar* target,
const UChar* target_end,
4293 const UChar* text,
const UChar* text_end,
4294 const UChar* text_range)
4296 const UChar *s, *se, *t, *p, *end;
4298 ptrdiff_t skip, tlen1;
4300# ifdef ONIG_DEBUG_SEARCH
4301 fprintf(stderr,
"bm_search_notrev: text: %"PRIuPTR
" (%p), text_end: %"PRIuPTR
" (%p), text_range: %"PRIuPTR
" (%p)\n",
4302 (uintptr_t )text, text, (uintptr_t )text_end, text_end, (uintptr_t )text_range, text_range);
4305 tail = target_end - 1;
4306 tlen1 = tail - target;
4308 if (end + tlen1 > text_end)
4309 end = text_end - tlen1;
4313 if (IS_NULL(reg->int_map)) {
4318 if (t == target)
return (UChar* )s;
4321 skip = reg->map[*se];
4324 s += enclen(reg->enc, s, end);
4325 }
while ((s - t) < skip && s < end);
4329# if OPT_EXACT_MAXLEN >= ONIG_CHAR_TABLE_SIZE
4334 if (t == target)
return (UChar* )s;
4337 skip = reg->int_map[*se];
4340 s += enclen(reg->enc, s, end);
4341 }
while ((s - t) < skip && s < end);
4346 return (UChar* )NULL;
4351bm_search(
regex_t* reg,
const UChar* target,
const UChar* target_end,
4352 const UChar* text,
const UChar* text_end,
const UChar* text_range)
4354 const UChar *s, *t, *p, *end;
4357# ifdef ONIG_DEBUG_SEARCH
4358 fprintf(stderr,
"bm_search: text: %"PRIuPTR
" (%p), text_end: %"PRIuPTR
" (%p), text_range: %"PRIuPTR
" (%p)\n",
4359 (uintptr_t )text, text, (uintptr_t )text_end, text_end, (uintptr_t )text_range, text_range);
4362 end = text_range + (target_end - target) - 1;
4366 tail = target_end - 1;
4367 s = text + (target_end - target) - 1;
4368 if (IS_NULL(reg->int_map)) {
4372# ifdef ONIG_DEBUG_SEARCH
4373 fprintf(stderr,
"bm_search_loop: pos: %"PRIdPTR
" %s\n",
4374 (intptr_t )(s - text), s);
4377 if (t == target)
return (UChar* )p;
4384# if OPT_EXACT_MAXLEN >= ONIG_CHAR_TABLE_SIZE
4389 if (t == target)
return (UChar* )p;
4392 s += reg->int_map[*s];
4396 return (UChar* )NULL;
4401bm_search_notrev_ic(
regex_t* reg,
const UChar* target,
const UChar* target_end,
4402 const UChar* text,
const UChar* text_end,
4403 const UChar* text_range)
4405 const UChar *s, *se, *t, *end;
4407 ptrdiff_t skip, tlen1;
4409 int case_fold_flag = reg->case_fold_flag;
4411# ifdef ONIG_DEBUG_SEARCH
4412 fprintf(stderr,
"bm_search_notrev_ic: text: %d (%p), text_end: %d (%p), text_range: %d (%p)\n",
4413 (
int )text, text, (
int )text_end, text_end, (
int )text_range, text_range);
4416 tail = target_end - 1;
4417 tlen1 = tail - target;
4419 if (end + tlen1 > text_end)
4420 end = text_end - tlen1;
4424 if (IS_NULL(reg->int_map)) {
4427 if (str_lower_case_match(enc, case_fold_flag, target, target_end,
4430 skip = reg->map[*se];
4433 s += enclen(reg->enc, s, end);
4434 }
while ((s - t) < skip && s < end);
4438# if OPT_EXACT_MAXLEN >= ONIG_CHAR_TABLE_SIZE
4441 if (str_lower_case_match(enc, case_fold_flag, target, target_end,
4444 skip = reg->int_map[*se];
4447 s += enclen(reg->enc, s, end);
4448 }
while ((s - t) < skip && s < end);
4453 return (UChar* )NULL;
4458bm_search_ic(
regex_t* reg,
const UChar* target,
const UChar* target_end,
4459 const UChar* text,
const UChar* text_end,
const UChar* text_range)
4461 const UChar *s, *p, *end;
4464 int case_fold_flag = reg->case_fold_flag;
4466# ifdef ONIG_DEBUG_SEARCH
4467 fprintf(stderr,
"bm_search_ic: text: %d (%p), text_end: %d (%p), text_range: %d (%p)\n",
4468 (
int )text, text, (
int )text_end, text_end, (
int )text_range, text_range);
4471 end = text_range + (target_end - target) - 1;
4475 tail = target_end - 1;
4476 s = text + (target_end - target) - 1;
4477 if (IS_NULL(reg->int_map)) {
4479 p = s - (target_end - target) + 1;
4480 if (str_lower_case_match(enc, case_fold_flag, target, target_end,
4487# if OPT_EXACT_MAXLEN >= ONIG_CHAR_TABLE_SIZE
4489 p = s - (target_end - target) + 1;
4490 if (str_lower_case_match(enc, case_fold_flag, target, target_end,
4493 s += reg->int_map[*s];
4497 return (UChar* )NULL;
4504bm_search_notrev(
regex_t* reg,
const UChar* target,
const UChar* target_end,
4505 const UChar* text,
const UChar* text_end,
4506 const UChar* text_range)
4508 const UChar *s, *se, *t, *p, *end;
4510 ptrdiff_t skip, tlen1;
4513# ifdef ONIG_DEBUG_SEARCH
4514 fprintf(stderr,
"bm_search_notrev: text: %"PRIuPTR
" (%p), text_end: %"PRIuPTR
" (%p), text_range: %"PRIuPTR
" (%p)\n",
4515 (uintptr_t )text, text, (uintptr_t )text_end, text_end, (uintptr_t )text_range, text_range);
4518 tail = target_end - 1;
4519 tlen1 = tail - target;
4521 if (end + tlen1 > text_end)
4522 end = text_end - tlen1;
4526 if (IS_NULL(reg->int_map)) {
4531 if (t == target)
return (UChar* )s;
4534 if (s + 1 >= end)
break;
4535 skip = reg->map[se[1]];
4538 s += enclen(enc, s, end);
4539 }
while ((s - t) < skip && s < end);
4543# if OPT_EXACT_MAXLEN >= ONIG_CHAR_TABLE_SIZE
4548 if (t == target)
return (UChar* )s;
4551 if (s + 1 >= end)
break;
4552 skip = reg->int_map[se[1]];
4555 s += enclen(enc, s, end);
4556 }
while ((s - t) < skip && s < end);
4561 return (UChar* )NULL;
4566bm_search(
regex_t* reg,
const UChar* target,
const UChar* target_end,
4567 const UChar* text,
const UChar* text_end,
const UChar* text_range)
4569 const UChar *s, *t, *p, *end;
4573# ifdef ONIG_DEBUG_SEARCH
4574 fprintf(stderr,
"bm_search: text: %"PRIuPTR
" (%p), text_end: %"PRIuPTR
" (%p), text_range: %"PRIuPTR
" (%p)\n",
4575 (uintptr_t )text, text, (uintptr_t )text_end, text_end, (uintptr_t )text_range, text_range);
4578 tail = target_end - 1;
4579 tlen1 = tail - target;
4580 end = text_range + tlen1;
4585 if (IS_NULL(reg->int_map)) {
4590 if (t == target)
return (UChar* )p;
4593 if (s + 1 >= end)
break;
4594 s += reg->map[s[1]];
4598# if OPT_EXACT_MAXLEN >= ONIG_CHAR_TABLE_SIZE
4603 if (t == target)
return (UChar* )p;
4606 if (s + 1 >= end)
break;
4607 s += reg->int_map[s[1]];
4611 return (UChar* )NULL;
4616bm_search_notrev_ic(
regex_t* reg,
const UChar* target,
const UChar* target_end,
4617 const UChar* text,
const UChar* text_end,
4618 const UChar* text_range)
4620 const UChar *s, *se, *t, *end;
4622 ptrdiff_t skip, tlen1;
4624 int case_fold_flag = reg->case_fold_flag;
4626# ifdef ONIG_DEBUG_SEARCH
4627 fprintf(stderr,
"bm_search_notrev_ic: text: %"PRIuPTR
" (%p), text_end: %"PRIuPTR
" (%p), text_range: %"PRIuPTR
" (%p)\n",
4628 (uintptr_t )text, text, (uintptr_t )text_end, text_end, (uintptr_t )text_range, text_range);
4631 tail = target_end - 1;
4632 tlen1 = tail - target;
4634 if (end + tlen1 > text_end)
4635 end = text_end - tlen1;
4639 if (IS_NULL(reg->int_map)) {
4642 if (str_lower_case_match(enc, case_fold_flag, target, target_end,
4645 if (s + 1 >= end)
break;
4646 skip = reg->map[se[1]];
4649 s += enclen(enc, s, end);
4650 }
while ((s - t) < skip && s < end);
4654# if OPT_EXACT_MAXLEN >= ONIG_CHAR_TABLE_SIZE
4657 if (str_lower_case_match(enc, case_fold_flag, target, target_end,
4660 if (s + 1 >= end)
break;
4661 skip = reg->int_map[se[1]];
4664 s += enclen(enc, s, end);
4665 }
while ((s - t) < skip && s < end);
4670 return (UChar* )NULL;
4675bm_search_ic(
regex_t* reg,
const UChar* target,
const UChar* target_end,
4676 const UChar* text,
const UChar* text_end,
const UChar* text_range)
4678 const UChar *s, *p, *end;
4682 int case_fold_flag = reg->case_fold_flag;
4684# ifdef ONIG_DEBUG_SEARCH
4685 fprintf(stderr,
"bm_search_ic: text: %"PRIuPTR
" (%p), text_end: %"PRIuPTR
" (%p), text_range: %"PRIuPTR
" (%p)\n",
4686 (uintptr_t )text, text, (uintptr_t )text_end, text_end, (uintptr_t )text_range, text_range);
4689 tail = target_end - 1;
4690 tlen1 = tail - target;
4691 end = text_range + tlen1;
4696 if (IS_NULL(reg->int_map)) {
4699 if (str_lower_case_match(enc, case_fold_flag, target, target_end,
4702 if (s + 1 >= end)
break;
4703 s += reg->map[s[1]];
4707# if OPT_EXACT_MAXLEN >= ONIG_CHAR_TABLE_SIZE
4710 if (str_lower_case_match(enc, case_fold_flag, target, target_end,
4713 if (s + 1 >= end)
break;
4714 s += reg->int_map[s[1]];
4718 return (UChar* )NULL;
4722#ifdef USE_INT_MAP_BACKWARD
4724set_bm_backward_skip(UChar* s, UChar* end,
OnigEncoding enc ARG_UNUSED,
4729 if (IS_NULL(*skip)) {
4730 *skip = (
int* )
xmalloc(
sizeof(
int) * ONIG_CHAR_TABLE_SIZE);
4731 if (IS_NULL(*skip))
return ONIGERR_MEMORY;
4734 len = (int )(end - s);
4735 for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++)
4738 for (i =
len - 1; i > 0; i--)
4745bm_search_backward(
regex_t* reg,
const UChar* target,
const UChar* target_end,
4746 const UChar* text,
const UChar* adjust_text,
4747 const UChar* text_end,
const UChar* text_start)
4749 const UChar *s, *t, *p;
4751 s = text_end - (target_end - target);
4755 s = ONIGENC_LEFT_ADJUST_CHAR_HEAD(reg->enc, adjust_text, s, text_end);
4760 while (t < target_end && *p == *t) {
4763 if (t == target_end)
4766 s -= reg->int_map_backward[*s];
4767 s = ONIGENC_LEFT_ADJUST_CHAR_HEAD(reg->enc, adjust_text, s, text_end);
4770 return (UChar* )NULL;
4776 const UChar* text,
const UChar* text_range,
const UChar* text_end)
4778 const UChar *s = text;
4780 while (s < text_range) {
4781 if (map[*s])
return (UChar* )s;
4783 s += enclen(enc, s, text_end);
4785 return (UChar* )NULL;
4790 const UChar* text,
const UChar* adjust_text,
4791 const UChar* text_start,
const UChar* text_end)
4793 const UChar *s = text_start;
4796 if (map[*s])
return (UChar* )s;
4798 s = onigenc_get_prev_char_head(enc, adjust_text, s, text_end);
4800 return (UChar* )NULL;
4804onig_match(
regex_t* reg,
const UChar* str,
const UChar* end,
const UChar* at,
OnigRegion* region,
4805 OnigOptionType option)
4811 MATCH_ARG_INIT(msa, option, region, at, at);
4812#ifdef USE_COMBINATION_EXPLOSION_CHECK
4814 ptrdiff_t offset = at - str;
4815 STATE_CHECK_BUFF_INIT(msa, end - str, offset, reg->num_comb_exp_check);
4820 r = onig_region_resize_clear(region, reg->num_mem + 1);
4826 prev = (UChar* )onigenc_get_prev_char_head(reg->enc, str, at, end);
4827 r = match_at(reg, str, end,
4828#ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
4834 MATCH_ARG_FREE(msa);
4839forward_search_range(
regex_t* reg,
const UChar* str,
const UChar* end, UChar* s,
4840 UChar* range, UChar** low, UChar** high, UChar** low_prev)
4842 UChar *p, *pprev = (UChar* )NULL;
4844#ifdef ONIG_DEBUG_SEARCH
4845 fprintf(stderr,
"forward_search_range: str: %"PRIuPTR
" (%p), end: %"PRIuPTR
" (%p), s: %"PRIuPTR
" (%p), range: %"PRIuPTR
" (%p)\n",
4846 (uintptr_t )str, str, (uintptr_t )end, end, (uintptr_t )s, s, (uintptr_t )range, range);
4850 if (reg->dmin > 0) {
4851 if (ONIGENC_IS_SINGLEBYTE(reg->enc)) {
4855 UChar *q = p + reg->dmin;
4857 if (q >= end)
return 0;
4858 while (p < q) p += enclen(reg->enc, p, end);
4863 switch (reg->optimize) {
4864 case ONIG_OPTIMIZE_EXACT:
4865 p = slow_search(reg->enc, reg->exact, reg->exact_end, p, end, range);
4867 case ONIG_OPTIMIZE_EXACT_IC:
4868 p = slow_search_ic(reg->enc, reg->case_fold_flag,
4869 reg->exact, reg->exact_end, p, end, range);
4872 case ONIG_OPTIMIZE_EXACT_BM:
4873 p = bm_search(reg, reg->exact, reg->exact_end, p, end, range);
4876 case ONIG_OPTIMIZE_EXACT_BM_NOT_REV:
4877 p = bm_search_notrev(reg, reg->exact, reg->exact_end, p, end, range);
4880 case ONIG_OPTIMIZE_EXACT_BM_IC:
4881 p = bm_search_ic(reg, reg->exact, reg->exact_end, p, end, range);
4884 case ONIG_OPTIMIZE_EXACT_BM_NOT_REV_IC:
4885 p = bm_search_notrev_ic(reg, reg->exact, reg->exact_end, p, end, range);
4888 case ONIG_OPTIMIZE_MAP:
4889 p = map_search(reg->enc, reg->map, p, range, end);
4893 if (p && p < range) {
4894 if (p - reg->dmin < s) {
4897 p += enclen(reg->enc, p, end);
4901 if (reg->sub_anchor) {
4904 switch (reg->sub_anchor) {
4905 case ANCHOR_BEGIN_LINE:
4906 if (!ON_STR_BEGIN(p)) {
4907 prev = onigenc_get_prev_char_head(reg->enc,
4908 (pprev ? pprev : str), p, end);
4909 if (!ONIGENC_IS_MBC_NEWLINE_EX(reg->enc, prev, str, end, reg->options, 0))
4914 case ANCHOR_END_LINE:
4915 if (ON_STR_END(p)) {
4916#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
4917 prev = (UChar* )onigenc_get_prev_char_head(reg->enc,
4918 (pprev ? pprev : str), p);
4919 if (prev && ONIGENC_IS_MBC_NEWLINE_EX(reg->enc, prev, str, end, reg->options, 1))
4923 else if (! ONIGENC_IS_MBC_NEWLINE_EX(reg->enc, p, str, end, reg->options, 1))
4929 if (reg->dmax == 0) {
4933 *low_prev = onigenc_get_prev_char_head(reg->enc, s, p, end);
4935 *low_prev = onigenc_get_prev_char_head(reg->enc,
4936 (pprev ? pprev : str), p, end);
4940 if (reg->dmax != ONIG_INFINITE_DISTANCE) {
4941 if (p < str + reg->dmax) {
4942 *low = (UChar* )str;
4944 *low_prev = onigenc_get_prev_char_head(reg->enc, str, *low, end);
4947 *low = p - reg->dmax;
4949 *low = onigenc_get_right_adjust_char_head_with_prev(reg->enc, s,
4950 *low, end, (
const UChar** )low_prev);
4951 if (low_prev && IS_NULL(*low_prev))
4952 *low_prev = onigenc_get_prev_char_head(reg->enc,
4953 (pprev ? pprev : s), *low, end);
4957 *low_prev = onigenc_get_prev_char_head(reg->enc,
4958 (pprev ? pprev : str), *low, end);
4964 *high = p - reg->dmin;
4966#ifdef ONIG_DEBUG_SEARCH
4968 "forward_search_range success: low: %"PRIdPTR
", high: %"PRIdPTR
", dmin: %"PRIdPTR
", dmax: %"PRIdPTR
"\n",
4969 *low - str, *high - str, reg->dmin, reg->dmax);
4977#define BM_BACKWARD_SEARCH_LENGTH_THRESHOLD 100
4980backward_search_range(
regex_t* reg,
const UChar* str,
const UChar* end,
4981 UChar* s,
const UChar* range, UChar* adjrange,
4982 UChar** low, UChar** high)
4990 switch (reg->optimize) {
4991 case ONIG_OPTIMIZE_EXACT:
4993 p = slow_search_backward(reg->enc, reg->exact, reg->exact_end,
4994 range, adjrange, end, p);
4997 case ONIG_OPTIMIZE_EXACT_IC:
4998 case ONIG_OPTIMIZE_EXACT_BM_IC:
4999 case ONIG_OPTIMIZE_EXACT_BM_NOT_REV_IC:
5000 p = slow_search_backward_ic(reg->enc, reg->case_fold_flag,
5001 reg->exact, reg->exact_end,
5002 range, adjrange, end, p);
5005 case ONIG_OPTIMIZE_EXACT_BM:
5006 case ONIG_OPTIMIZE_EXACT_BM_NOT_REV:
5007#ifdef USE_INT_MAP_BACKWARD
5008 if (IS_NULL(reg->int_map_backward)) {
5010 if (s - range < BM_BACKWARD_SEARCH_LENGTH_THRESHOLD)
5013 r = set_bm_backward_skip(reg->exact, reg->exact_end, reg->enc,
5014 &(reg->int_map_backward));
5017 p = bm_search_backward(reg, reg->exact, reg->exact_end, range, adjrange,
5024 case ONIG_OPTIMIZE_MAP:
5025 p = map_search_backward(reg->enc, reg->map, range, adjrange, p, end);
5030 if (reg->sub_anchor) {
5033 switch (reg->sub_anchor) {
5034 case ANCHOR_BEGIN_LINE:
5035 if (!ON_STR_BEGIN(p)) {
5036 prev = onigenc_get_prev_char_head(reg->enc, str, p, end);
5037 if (!ONIGENC_IS_MBC_NEWLINE_EX(reg->enc, prev, str, end, reg->options, 0)) {
5044 case ANCHOR_END_LINE:
5045 if (ON_STR_END(p)) {
5046#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
5047 prev = onigenc_get_prev_char_head(reg->enc, adjrange, p);
5048 if (IS_NULL(prev))
goto fail;
5049 if (ONIGENC_IS_MBC_NEWLINE_EX(reg->enc, prev, str, end, reg->options, 1)) {
5055 else if (! ONIGENC_IS_MBC_NEWLINE_EX(reg->enc, p, str, end, reg->options, 1)) {
5056 p = onigenc_get_prev_char_head(reg->enc, adjrange, p, end);
5057 if (IS_NULL(p))
goto fail;
5065 if (reg->dmax != ONIG_INFINITE_DISTANCE) {
5066 *low = p - reg->dmax;
5067 *high = p - reg->dmin;
5068 *high = onigenc_get_right_adjust_char_head(reg->enc, adjrange, *high, end);
5071#ifdef ONIG_DEBUG_SEARCH
5072 fprintf(stderr,
"backward_search_range: low: %d, high: %d\n",
5073 (
int )(*low - str), (
int )(*high - str));
5079#ifdef ONIG_DEBUG_SEARCH
5080 fprintf(stderr,
"backward_search_range: fail.\n");
5087onig_search(
regex_t* reg,
const UChar* str,
const UChar* end,
5088 const UChar* start,
const UChar* range,
OnigRegion* region, OnigOptionType option)
5090 return onig_search_gpos(reg, str, end, start, start, range, region, option);
5094onig_search_gpos(
regex_t* reg,
const UChar* str,
const UChar* end,
5095 const UChar* global_pos,
5096 const UChar* start,
const UChar* range,
OnigRegion* region, OnigOptionType option)
5101#ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
5102 const UChar *orig_start = start;
5103 const UChar *orig_range = range;
5106#ifdef ONIG_DEBUG_SEARCH
5108 "onig_search (entry point): str: %"PRIuPTR
" (%p), end: %"PRIuPTR
", start: %"PRIuPTR
", range: %"PRIuPTR
"\n",
5109 (uintptr_t )str, str, end - str, start - str, range - str);
5113 r = onig_region_resize_clear(region, reg->num_mem + 1);
5114 if (r)
goto finish_no_msa;
5117 if (start > end || start < str)
goto mismatch_no_msa;
5120#ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
5121# ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
5122# define MATCH_AND_RETURN_CHECK(upper_range) \
5123 r = match_at(reg, str, end, (upper_range), s, prev, &msa); \
5124 if (r != ONIG_MISMATCH) {\
5126 if (! IS_FIND_LONGEST(reg->options)) {\
5133# define MATCH_AND_RETURN_CHECK(upper_range) \
5134 r = match_at(reg, str, end, (upper_range), s, prev, &msa); \
5135 if (r != ONIG_MISMATCH) {\
5143# ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
5144# define MATCH_AND_RETURN_CHECK(none) \
5145 r = match_at(reg, str, end, s, prev, &msa);\
5146 if (r != ONIG_MISMATCH) {\
5148 if (! IS_FIND_LONGEST(reg->options)) {\
5155# define MATCH_AND_RETURN_CHECK(none) \
5156 r = match_at(reg, str, end, s, prev, &msa);\
5157 if (r != ONIG_MISMATCH) {\
5168 if (reg->anchor != 0 && str < end) {
5169 UChar *min_semi_end, *max_semi_end;
5171 if (reg->anchor & ANCHOR_BEGIN_POSITION) {
5176 if (global_pos > start)
5178 if (global_pos < range)
5179 range = global_pos + 1;
5187 else if (reg->anchor & ANCHOR_BEGIN_BUF) {
5189 if (range > start) {
5190 if (start != str)
goto mismatch_no_msa;
5199 goto mismatch_no_msa;
5202 else if (reg->anchor & ANCHOR_END_BUF) {
5203 min_semi_end = max_semi_end = (UChar* )end;
5206 if ((OnigDistance )(max_semi_end - str) < reg->anchor_dmin)
5207 goto mismatch_no_msa;
5209 if (range > start) {
5210 if ((OnigDistance )(min_semi_end - start) > reg->anchor_dmax) {
5211 start = min_semi_end - reg->anchor_dmax;
5213 start = onigenc_get_right_adjust_char_head(reg->enc, str, start, end);
5215 if ((OnigDistance )(max_semi_end - (range - 1)) < reg->anchor_dmin) {
5216 range = max_semi_end - reg->anchor_dmin + 1;
5219 if (start > range)
goto mismatch_no_msa;
5224 if ((OnigDistance )(min_semi_end - range) > reg->anchor_dmax) {
5225 range = min_semi_end - reg->anchor_dmax;
5227 if ((OnigDistance )(max_semi_end - start) < reg->anchor_dmin) {
5228 start = max_semi_end - reg->anchor_dmin;
5229 start = ONIGENC_LEFT_ADJUST_CHAR_HEAD(reg->enc, str, start, end);
5231 if (range > start)
goto mismatch_no_msa;
5234 else if (reg->anchor & ANCHOR_SEMI_END_BUF) {
5235 UChar* pre_end = ONIGENC_STEP_BACK(reg->enc, str, end, end, 1);
5237 max_semi_end = (UChar* )end;
5238 if (ONIGENC_IS_MBC_NEWLINE(reg->enc, pre_end, end)) {
5239 min_semi_end = pre_end;
5241#ifdef USE_CRNL_AS_LINE_TERMINATOR
5242 pre_end = ONIGENC_STEP_BACK(reg->enc, str, pre_end, end, 1);
5243 if (IS_NOT_NULL(pre_end) &&
5244 IS_NEWLINE_CRLF(reg->options) &&
5245 ONIGENC_IS_MBC_CRNL(reg->enc, pre_end, end)) {
5246 min_semi_end = pre_end;
5249 if (min_semi_end > str && start <= min_semi_end) {
5254 min_semi_end = (UChar* )end;
5258 else if ((reg->anchor & ANCHOR_ANYCHAR_STAR_ML)) {
5259 goto begin_position;
5262 else if (str == end) {
5263 static const UChar address_for_empty_string[] =
"";
5265#ifdef ONIG_DEBUG_SEARCH
5266 fprintf(stderr,
"onig_search: empty string.\n");
5269 if (reg->threshold_len == 0) {
5270 start = end = str = address_for_empty_string;
5272 prev = (UChar* )NULL;
5274 MATCH_ARG_INIT(msa, option, region, start, start);
5275#ifdef USE_COMBINATION_EXPLOSION_CHECK
5276 msa.state_check_buff = (
void* )0;
5277 msa.state_check_buff_size = 0;
5279 MATCH_AND_RETURN_CHECK(end);
5282 goto mismatch_no_msa;
5285#ifdef ONIG_DEBUG_SEARCH
5286 fprintf(stderr,
"onig_search(apply anchor): end: %d, start: %d, range: %d\n",
5287 (
int )(end - str), (
int )(start - str), (
int )(range - str));
5290 MATCH_ARG_INIT(msa, option, region, start, global_pos);
5291#ifdef USE_COMBINATION_EXPLOSION_CHECK
5293 ptrdiff_t offset = (MIN(start, range) - str);
5294 STATE_CHECK_BUFF_INIT(msa, end - str, offset, reg->num_comb_exp_check);
5299 if (range > start) {
5301 prev = onigenc_get_prev_char_head(reg->enc, str, s, end);
5303 prev = (UChar* )NULL;
5305 if (reg->optimize != ONIG_OPTIMIZE_NONE) {
5306 UChar *sch_range, *low, *high, *low_prev;
5308 sch_range = (UChar* )range;
5309 if (reg->dmax != 0) {
5310 if (reg->dmax == ONIG_INFINITE_DISTANCE)
5311 sch_range = (UChar* )end;
5313 sch_range += reg->dmax;
5314 if (sch_range > end) sch_range = (UChar* )end;
5318 if ((end - start) < reg->threshold_len)
5321 if (reg->dmax != ONIG_INFINITE_DISTANCE) {
5323 if (! forward_search_range(reg, str, end, s, sch_range,
5324 &low, &high, &low_prev))
goto mismatch;
5330 MATCH_AND_RETURN_CHECK(orig_range);
5332 s += enclen(reg->enc, s, end);
5334 }
while (s < range);
5338 if (! forward_search_range(reg, str, end, s, sch_range,
5339 &low, &high, (UChar** )NULL))
goto mismatch;
5341 if ((reg->anchor & ANCHOR_ANYCHAR_STAR) != 0) {
5343 MATCH_AND_RETURN_CHECK(orig_range);
5345 s += enclen(reg->enc, s, end);
5347 if ((reg->anchor & (ANCHOR_LOOK_BEHIND | ANCHOR_PREC_READ_NOT)) == 0) {
5348 while (!ONIGENC_IS_MBC_NEWLINE_EX(reg->enc, prev, str, end, reg->options, 0)
5351 s += enclen(reg->enc, s, end);
5354 }
while (s < range);
5361 MATCH_AND_RETURN_CHECK(orig_range);
5363 s += enclen(reg->enc, s, end);
5364 }
while (s < range);
5367 MATCH_AND_RETURN_CHECK(orig_range);
5371 if (reg->optimize != ONIG_OPTIMIZE_NONE) {
5372 UChar *low, *high, *adjrange, *sch_start;
5375 adjrange = ONIGENC_LEFT_ADJUST_CHAR_HEAD(reg->enc, str, range, end);
5377 adjrange = (UChar* )end;
5379 if (reg->dmax != ONIG_INFINITE_DISTANCE &&
5380 (end - range) >= reg->threshold_len) {
5382 sch_start = s + reg->dmax;
5383 if (sch_start > end) sch_start = (UChar* )end;
5384 if (backward_search_range(reg, str, end, sch_start, range, adjrange,
5392 prev = onigenc_get_prev_char_head(reg->enc, str, s, end);
5393 MATCH_AND_RETURN_CHECK(orig_start);
5396 }
while (s >= range);
5400 if ((end - range) < reg->threshold_len)
goto mismatch;
5403 if (reg->dmax != 0) {
5404 if (reg->dmax == ONIG_INFINITE_DISTANCE)
5405 sch_start = (UChar* )end;
5407 sch_start += reg->dmax;
5408 if (sch_start > end) sch_start = (UChar* )end;
5410 sch_start = ONIGENC_LEFT_ADJUST_CHAR_HEAD(reg->enc,
5411 start, sch_start, end);
5414 if (backward_search_range(reg, str, end, sch_start, range, adjrange,
5415 &low, &high) <= 0)
goto mismatch;
5420 prev = onigenc_get_prev_char_head(reg->enc, str, s, end);
5421 MATCH_AND_RETURN_CHECK(orig_start);
5423 }
while (s >= range);
5427#ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
5428 if (IS_FIND_LONGEST(reg->options)) {
5429 if (msa.best_len >= 0) {
5438 MATCH_ARG_FREE(msa);
5442 if (IS_FIND_NOT_EMPTY(reg->options) && region) {
5443 onig_region_clear(region);
5447 if (r != ONIG_MISMATCH)
5448 fprintf(stderr,
"onig_search: error %"PRIdPTRDIFF
"\n", r);
5456 if (r != ONIG_MISMATCH)
5457 fprintf(stderr,
"onig_search: error %"PRIdPTRDIFF
"\n", r);
5462 MATCH_ARG_FREE(msa);
5467onig_scan(
regex_t* reg,
const UChar* str,
const UChar* end,
5469 int (*scan_callback)(OnigPosition, OnigPosition,
OnigRegion*,
void*),
5480 r = onig_search(reg, str, end, start, end, region, option);
5482 rs = scan_callback(n, r, region, callback_arg);
5487 if (region->end[0] == start - str) {
5488 if (start >= end)
break;
5489 start += enclen(reg->enc, start, end);
5492 start = str + region->end[0];
5497 else if (r == ONIG_MISMATCH) {
5509onig_get_encoding(
const regex_t* reg)
5514extern OnigOptionType
5515onig_get_options(
const regex_t* reg)
5517 return reg->options;
5520extern OnigCaseFoldType
5521onig_get_case_fold_flag(
const regex_t* reg)
5523 return reg->case_fold_flag;
5527onig_get_syntax(
const regex_t* reg)
5533onig_number_of_captures(
const regex_t* reg)
5535 return reg->num_mem;
5539onig_number_of_capture_histories(
const regex_t* reg)
5541#ifdef USE_CAPTURE_HISTORY
5545 for (i = 0; i <= ONIG_MAX_CAPTURE_HISTORY_GROUP; i++) {
5546 if (BIT_STATUS_AT(reg->capture_history, i) != 0)
#define xfree
Old name of ruby_xfree.
#define xrealloc
Old name of ruby_xrealloc.
#define xmalloc
Old name of ruby_xmalloc.
#define RB_GNUC_EXTENSION
This is expanded to nothing for non-GCC compilers.
int len
Length of the buffer.